Public
Edited
Sep 21, 2023
2 forks
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
shaderSource = {
const vert = `
${customGlsl.precision}

attribute vec2 aPosition;

varying vec2 vPosition;

void main () {
vPosition = aPosition;
gl_Position = vec4(aPosition, 0.0, 1.0);
}
`,
frag = await glsl`
${customGlsl.useStandardDerivatives}
${customGlsl.precision}
${customGlsl.wireframe}

#pragma glslify: snoise = require('glsl-noise/simplex/3d')
#pragma glslify: jet = require('glsl-colormap/jet')

varying vec2 vPosition;

uniform float noiseScale, t, gridWidth, gridFeather, contours;

void main () {
float f = snoise(vec3(vPosition*noiseScale, t * 20.0 / ${refreshRatio}));

float wf = 0.8 - wireframe(vec3(f * contours), gridWidth, gridFeather);

// Draw the black-white graph
// gl_FragColor = vec4(vec3(f), 1.0);

// Draw colorful graph
gl_FragColor = mix(jet(f * 0.5 + 0.5), vec4(vec3(0.3), 1.0), wf);
}
`;

return { vert, frag };
}
Insert cell
{
const { regl, blend } = reglDrawer;

function redraw(t = 0) {
regl.clear({ color: backgroundColorForWebGL });

const position = [
[-1, -1],
[1, -1],
[-1, 1],
[1, -1],
[1, 1],
[-1, 1]
];

regl({
vert: shaderSource.vert,
frag: shaderSource.frag,
attributes: { aPosition: position },
uniforms: Object.assign({ t }, uniforms),
count: 6,
blend,
depth: { enable: false }
})();

statsMonitor.update();
}

for (;;) {
const t = performance.now() / 1000;

redraw(t);

yield t;
}
redraw();
}
Insert cell
backgroundColorForWebGL = [d3.color(backgroundColor)].map(
({ r, g, b, opacity }) => [r / 255, g / 255, b / 255, opacity]
)[0]
Insert cell
reglDrawer = {
const canvas = DOM.canvas(width, height),
pixelRatio = 2.0,
extensions = ["oes_standard_derivatives"],
regl = wrapREGL({
canvas,
pixelRatio,
extensions
}),
blend = {
enable: true,
func: {
srcRGB: "src alpha",
srcAlpha: 1,
dstRGB: "one minus src alpha",
dstAlpha: 1
},
equation: {
rgb: "add",
alpha: "add"
}
};

Object.assign(canvas, { width, height });

{
const div = document.getElementById("canvasDivForWebGL");
div.innerHTML = "";
div.appendChild(canvas);
}

updateDivForREGL(shaderSource);

return { canvas, regl, blend };
}
Insert cell
updateDivForREGL = (shaderSource) => {
const { vert, frag } = shaderSource;

{
const div = document.getElementById("vertDivForREGL");
div.innerHTML = "";

d3.select(div)
.append("pre")
.attr("class", "prettyprint linenums lang-c")
.append("code")
.text(vert.trim());
}

{
const div = document.getElementById("fragDivForREGL");
div.innerHTML = "";

d3.select(div)
.append("pre")
.attr("class", "prettyprint linenums lang-c")
.append("code")
.text(frag.trim());
}

PR.prettyPrint();
}
Insert cell
width = 600
Insert cell
height = 600
Insert cell
statsMonitor = {
const stats = new Stats(),
{ dom } = stats;
dom.style.position = "relative";

return stats;
}
Insert cell
Stats = require("https://cdn.jsdelivr.net/npm/stats-js@1.0.1/build/stats.min.js")
Insert cell
PR = require("https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js")
Insert cell
wrapREGL = require("regl")
Insert cell
/**
* Get repaint interval, the value is used to compute the refreshRatio
* The result is of milliseconds
* Inspired by https://stackoverflow.com/questions/6131051/is-it-possible-to-find-out-what-is-the-monitor-frame-rate-in-javascript
*/
getRepaintInterval = () => {
return new Promise((resolve) => {
requestAnimationFrame((t1) => {
requestAnimationFrame((t2) => {
resolve(t2 - t1);
});
});
});
}
Insert cell
import { glsl, glslify } from '@aman-tiwari/glslify'
Insert cell
customGlsl = ({
useStandardDerivatives: `
#extension GL_OES_standard_derivatives : enable
`,
constants: `
#define PI 3.141592653589793238
#define HALF_PI 1.57079632679
#define HALF_PI_INV 0.15915494309
#define LOG_2 0.69314718056
#define C_ONE (vec2(1.0, 0.0))
#define C_I (vec2(0.0, 1.0))
#define TO_RADIANS 0.01745329251
`,
precision: `
precision highp float;
`,
dist: `
float dist(vec2 d) {
return sqrt(pow(d.x, 2.0) + pow(d.y, 2.0));
}

float dist(vec2 a, vec2 b) {
vec2 d = a - b;
return dist(d);
}
`,
hsv2rgb: `
vec3 hsv2rgb(vec3 c) {
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}
`,
wireframe: `
float wireframe (vec3 parameter, float width, float feather) {
float w1 = width - feather * 0.5;
vec3 d = fwidth(parameter);
vec3 looped = 0.5 - abs(mod(parameter, 1.0) - 0.5);
vec3 a3 = smoothstep(d * w1, d * (w1 + feather), looped);
return min(min(a3.x, a3.y), a3.z);
}
`
})
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