Published
Edited
Jul 1, 2020
14 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
picogl = require('picogl@0.17.3/build/picogl.min.js')
Insert cell
import {slider,checkbox,radio} from "@jashkenas/inputs"
Insert cell
d3 = import('https://unpkg.com/d3-color@1.4.1/src/index.js?module')
Insert cell
Insert cell
app = picogl.createApp(canvas, {premultipliedAlpha: false, preserveDrawingBuffer: true})
.clearColor(0.0, 0.0, 0.0, 1.0)
.enable(picogl.BLEND)
.blendFunc(picogl.ONE, picogl.ONE_MINUS_SRC_ALPHA)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
program = app.createProgram(vertexShader, fragShader, {transformFeedbackVaryings: ["tfPosition","tfVelocity"]})
Insert cell
Insert cell
VB = {
gravity;
var positionData = new Float32Array(numParticles * 3);
var colorData = new Float32Array(numParticles * 3);

for (var i = 0; i < numParticles; ++i) {
var vec3i = i * 3;

positionData[vec3i] = Math.random() * 2 - 1;
positionData[vec3i + 1] = Math.random() * 2 - 1;
positionData[vec3i + 2] = Math.random() * 2 - 1;

let [r,g,b] = colorSettings.particleColor();
colorData[vec3i] = r;
colorData[vec3i + 1] = g;
colorData[vec3i + 2] = b;
}

var positionsA = app.createVertexBuffer(picogl.FLOAT, 3, positionData);
var velocitiesA = app.createVertexBuffer(picogl.FLOAT, 3, positionData.length);
var positionsB = app.createVertexBuffer(picogl.FLOAT, 3, positionData.length);
var velocitiesB = app.createVertexBuffer(picogl.FLOAT, 3, positionData.length);

var colors = app.createVertexBuffer(picogl.FLOAT, 3, colorData);
return {positionsA, velocitiesA, positionsB, velocitiesB, colors};
}
Insert cell
Insert cell
vertexArrayA = app.createVertexArray()
.vertexAttributeBuffer(0, VB.positionsA)
.vertexAttributeBuffer(1, VB.velocitiesA)
.vertexAttributeBuffer(2, VB.colors)
Insert cell
vertexArrayB = app.createVertexArray()
.vertexAttributeBuffer(0, VB.positionsB)
.vertexAttributeBuffer(1, VB.velocitiesB)
.vertexAttributeBuffer(2, VB.colors)
Insert cell
Insert cell
transformFeedbackA = app.createTransformFeedback()
.feedbackBuffer(0, VB.positionsA)
.feedbackBuffer(1, VB.velocitiesA)
Insert cell
transformFeedbackB = app.createTransformFeedback()
.feedbackBuffer(0, VB.positionsB)
.feedbackBuffer(1, VB.velocitiesB)

Insert cell
Insert cell
mutable masses = {
let masses = [];
for (let i = 0; i < 3; i++) {
masses.push(new Float32Array([
Math.random() * 2.0 - 1.0,
Math.random() * 2.0 - 1.0,
Math.random() * 2.0 - 1.0,
gravity]))
}
return masses
}
Insert cell
massUniforms = {
let massUniforms =
app.createUniformBuffer(new Array(3).fill(picogl.FLOAT_VEC4));
masses.forEach((m,i) => massUniforms.set(i,m));
massUniforms.update();
return massUniforms
}
Insert cell
Insert cell
drawCallA = app.createDrawCall(program, vertexArrayA)
.transformFeedback(transformFeedbackB)
.uniformBlock("Mass", massUniforms)
.primitive(picogl.POINTS)
Insert cell
drawCallB = app.createDrawCall(program, vertexArrayB)
.transformFeedback(transformFeedbackA)
.uniformBlock("Mass", massUniforms)
.primitive(picogl.POINTS)
Insert cell
Insert cell
app.gl.getContextAttributes()
Insert cell
Insert cell
Insert cell
fragShaderMass = `#version 300 es
precision highp float;

layout(std140) uniform Mass {
vec4 massPosition [3];
};

out vec4 fragColor;

vec2 screenSize = vec2 (640.0,480.0);

void main() {
float minDist = 10000.0;
for (int i = 0; i < 3; i++) {
vec2 distVec = gl_FragCoord.xy - (massPosition[i].xy + vec2(1.0,1.0)) * screenSize * 0.5;
float dist2 = dot(distVec,distVec);
minDist = min(minDist,dist2);
}
if (minDist > 5.0*5.0) fragColor = vec4(${colorSettings.backgroundColor},
${clearAttenuation.toFixed(2)});
else fragColor = vec4(1.0,0.0,0.0,1.0);
}`
Insert cell
Insert cell
massProgram = app.createProgram(vertexShaderMass, fragShaderMass)
Insert cell
Insert cell
quadVA = {
let vb = app.createVertexBuffer(picogl.FLOAT, 2, new Float32Array([
-1, -1,
1, -1,
-1, 1,
1,1
]));
let va = app.createVertexArray().vertexAttributeBuffer(0, vb)
return va;
}
Insert cell
Insert cell
massDrawCall = app.createDrawCall(massProgram, quadVA)
.uniformBlock("Mass", massUniforms)
.primitive(picogl.TRIANGLE_STRIP)
Insert cell
Insert cell
draw = {
let frame = 0;
app.clear();
for (let i = 0; i < 100000; i++) {
massDrawCall.draw();
drawCallA.draw();
yield frame++;
massDrawCall.draw();
drawCallB.draw();
yield frame++;
}
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more