Ran all the JS through prettier.

This commit is contained in:
Rezmason
2021-10-20 03:25:04 -07:00
parent d8a1409907
commit 91deea34d6
10 changed files with 776 additions and 864 deletions

View File

@@ -2,10 +2,7 @@
<head>
<title>Matrix digital rain</title>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"
/>
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
<style>
body {
background: black;

View File

@@ -1,39 +1,24 @@
import {
loadText,
extractEntries,
makePassFBO,
makePyramid,
resizePyramid,
makePass
} from "./utils.js";
import { loadText, extractEntries, makePassFBO, makePyramid, resizePyramid, makePass } from "./utils.js";
// The bloom pass is basically an added high-pass blur.
const pyramidHeight = 5;
const levelStrengths = Array(pyramidHeight)
.fill()
.map((_, index) =>
Math.pow(index / (pyramidHeight * 2) + 0.5, 1 / 3).toPrecision(5)
)
.map((_, index) => Math.pow(index / (pyramidHeight * 2) + 0.5, 1 / 3).toPrecision(5))
.reverse();
export default (regl, config, inputs) => {
const enabled = config.bloomSize > 0 && config.bloomStrength > 0;
if (!enabled) {
return makePass(
{
return makePass({
primary: inputs.primary,
bloom: makePassFBO(regl)
}
);
bloom: makePassFBO(regl),
});
}
const uniforms = extractEntries(config, [
"bloomStrength",
"highPassThreshold"
]);
const uniforms = extractEntries(config, ["bloomStrength", "highPassThreshold"]);
const highPassPyramid = makePyramid(regl, pyramidHeight, config.useHalfFloat);
const hBlurPyramid = makePyramid(regl, pyramidHeight, config.useHalfFloat);
@@ -47,9 +32,9 @@ export default (regl, config, inputs) => {
frag: regl.prop("frag"),
uniforms: {
...uniforms,
tex: regl.prop("tex")
tex: regl.prop("tex"),
},
framebuffer: regl.prop("fbo")
framebuffer: regl.prop("fbo"),
});
// A 2D gaussian blur is just a 1D blur done horizontally, then done vertically.
@@ -64,9 +49,9 @@ export default (regl, config, inputs) => {
tex: regl.prop("tex"),
direction: regl.prop("direction"),
height: regl.context("viewportWidth"),
width: regl.context("viewportHeight")
width: regl.context("viewportHeight"),
},
framebuffer: regl.prop("fbo")
framebuffer: regl.prop("fbo"),
});
// The pyramid of textures gets flattened onto the source texture.
@@ -74,34 +59,25 @@ export default (regl, config, inputs) => {
frag: `
precision mediump float;
varying vec2 vUV;
${vBlurPyramid
.map((_, index) => `uniform sampler2D pyr_${index};`)
.join("\n")}
${vBlurPyramid.map((_, index) => `uniform sampler2D pyr_${index};`).join("\n")}
uniform float bloomStrength;
void main() {
vec4 total = vec4(0.);
${vBlurPyramid
.map(
(_, index) =>
`total += texture2D(pyr_${index}, vUV) * ${levelStrengths[index]};`
)
.join("\n")}
${vBlurPyramid.map((_, index) => `total += texture2D(pyr_${index}, vUV) * ${levelStrengths[index]};`).join("\n")}
gl_FragColor = total * bloomStrength;
}
`,
uniforms: {
...uniforms,
...Object.fromEntries(
vBlurPyramid.map((fbo, index) => [`pyr_${index}`, fbo])
)
...Object.fromEntries(vBlurPyramid.map((fbo, index) => [`pyr_${index}`, fbo])),
},
framebuffer: output
framebuffer: output,
});
return makePass(
{
primary: inputs.primary,
bloom: output
bloom: output,
},
() => {
for (let i = 0; i < pyramidHeight; i++) {

View File

@@ -2,18 +2,18 @@ const fonts = {
coptic: {
glyphTexURL: "coptic_msdf.png",
glyphSequenceLength: 32,
glyphTextureColumns: 8
glyphTextureColumns: 8,
},
gothic: {
glyphTexURL: "gothic_msdf.png",
glyphSequenceLength: 27,
glyphTextureColumns: 8
glyphTextureColumns: 8,
},
matrixcode: {
glyphTexURL: "matrixcode_msdf.png",
glyphSequenceLength: 57,
glyphTextureColumns: 8
}
glyphTextureColumns: 8,
},
};
const defaults = {
@@ -48,7 +48,7 @@ const defaults = {
{ hsl: [0.3, 0.9, 0.0], at: 0.0 },
{ hsl: [0.3, 0.9, 0.2], at: 0.2 },
{ hsl: [0.3, 0.9, 0.7], at: 0.7 },
{ hsl: [0.3, 0.9, 0.8], at: 0.8 }
{ hsl: [0.3, 0.9, 0.8], at: 0.8 },
],
raindropLength: 1,
slant: 0,
@@ -59,7 +59,7 @@ const defaults = {
const versions = {
classic: {
...defaults,
...fonts.matrixcode
...fonts.matrixcode,
},
operator: {
...defaults,
@@ -80,9 +80,9 @@ const versions = {
paletteEntries: [
{ hsl: [0.4, 0.8, 0.0], at: 0.0 },
{ hsl: [0.4, 0.8, 0.5], at: 0.5 },
{ hsl: [0.4, 0.8, 1.0], at: 1.0 }
{ hsl: [0.4, 0.8, 1.0], at: 1.0 },
],
raindropLength: 1.5
raindropLength: 1.5,
},
nightmare: {
...defaults,
@@ -97,10 +97,10 @@ const versions = {
{ hsl: [0.0, 1.0, 0.2], at: 0.2 },
{ hsl: [0.0, 1.0, 0.4], at: 0.4 },
{ hsl: [0.1, 1.0, 0.7], at: 0.7 },
{ hsl: [0.2, 1.0, 1.0], at: 1.0 }
{ hsl: [0.2, 1.0, 1.0], at: 1.0 },
],
raindropLength: 0.6,
slant: (22.5 * Math.PI) / 180
slant: (22.5 * Math.PI) / 180,
},
paradise: {
...defaults,
@@ -120,9 +120,9 @@ const versions = {
{ hsl: [0.0, 0.8, 0.3], at: 0.3 },
{ hsl: [0.1, 0.8, 0.5], at: 0.5 },
{ hsl: [0.1, 1.0, 0.6], at: 0.6 },
{ hsl: [0.1, 1.0, 0.9], at: 0.9 }
{ hsl: [0.1, 1.0, 0.9], at: 0.9 },
],
raindropLength: 0.4
raindropLength: 0.4,
},
resurrections: {
...defaults,
@@ -133,49 +133,48 @@ const versions = {
volumetric: true,
density: 1.5,
fallSpeed: 1.2,
raindropLength:1.25
}
raindropLength: 1.25,
},
};
versions.throwback = versions.operator;
versions["1999"] = versions.classic;
const range = (f, min = -Infinity, max = Infinity) =>
Math.max(min, Math.min(max, f));
const nullNaN = f => (isNaN(f) ? null : f);
const range = (f, min = -Infinity, max = Infinity) => Math.max(min, Math.min(max, f));
const nullNaN = (f) => (isNaN(f) ? null : f);
const paramMapping = {
version: { key: "version", parser: s => s },
effect: { key: "effect", parser: s => s },
width: { key: "numColumns", parser: s => nullNaN(parseInt(s)) },
numColumns: { key: "numColumns", parser: s => nullNaN(parseInt(s)) },
density: { key: "density", parser: s => nullNaN(range(parseFloat(s), 0)) },
resolution: { key: "resolution", parser: s => nullNaN(parseFloat(s)) },
version: { key: "version", parser: (s) => s },
effect: { key: "effect", parser: (s) => s },
width: { key: "numColumns", parser: (s) => nullNaN(parseInt(s)) },
numColumns: { key: "numColumns", parser: (s) => nullNaN(parseInt(s)) },
density: { key: "density", parser: (s) => nullNaN(range(parseFloat(s), 0)) },
resolution: { key: "resolution", parser: (s) => nullNaN(parseFloat(s)) },
animationSpeed: {
key: "animationSpeed",
parser: s => nullNaN(parseFloat(s))
parser: (s) => nullNaN(parseFloat(s)),
},
forwardSpeed: {
key: "forwardSpeed",
parser: s => nullNaN(parseFloat(s))
parser: (s) => nullNaN(parseFloat(s)),
},
cycleSpeed: { key: "cycleSpeed", parser: s => nullNaN(parseFloat(s)) },
fallSpeed: { key: "fallSpeed", parser: s => nullNaN(parseFloat(s)) },
cycleSpeed: { key: "cycleSpeed", parser: (s) => nullNaN(parseFloat(s)) },
fallSpeed: { key: "fallSpeed", parser: (s) => nullNaN(parseFloat(s)) },
raindropLength: {
key: "raindropLength",
parser: s => nullNaN(parseFloat(s))
parser: (s) => nullNaN(parseFloat(s)),
},
slant: {
key: "slant",
parser: s => nullNaN((parseFloat(s) * Math.PI) / 180)
parser: (s) => nullNaN((parseFloat(s) * Math.PI) / 180),
},
bloomSize: {
key: "bloomSize",
parser: s => nullNaN(range(parseFloat(s), 0, 1))
parser: (s) => nullNaN(range(parseFloat(s), 0, 1)),
},
url: { key: "bgURL", parser: s => s },
stripeColors: { key: "stripeColors", parser: s => s },
backgroundColor: { key: "backgroundColor", parser: s => s.split(",").map(parseFloat) },
volumetric: { key: "volumetric", parser: s => s.toLowerCase().includes("true") }
url: { key: "bgURL", parser: (s) => s },
stripeColors: { key: "stripeColors", parser: (s) => s },
backgroundColor: { key: "backgroundColor", parser: (s) => s.split(",").map(parseFloat) },
volumetric: { key: "volumetric", parser: (s) => s.toLowerCase().includes("true") },
};
paramMapping.dropLength = paramMapping.raindropLength;
paramMapping.angle = paramMapping.slant;
@@ -185,20 +184,14 @@ export default (searchString, make1DTexture) => {
const urlParams = Object.fromEntries(
Array.from(new URLSearchParams(searchString).entries())
.filter(([key]) => key in paramMapping)
.map(([key, value]) => [
paramMapping[key].key,
paramMapping[key].parser(value)
])
.map(([key, value]) => [paramMapping[key].key, paramMapping[key].parser(value)])
.filter(([_, value]) => value != null)
);
const version =
urlParams.version in versions
? versions[urlParams.version]
: versions.classic;
const version = urlParams.version in versions ? versions[urlParams.version] : versions.classic;
return {
...version,
...urlParams
...urlParams,
};
};

View File

@@ -1,7 +1,6 @@
import { loadImage, loadText, makePassFBO, makePass } from "./utils.js";
const defaultBGURL =
"https://upload.wikimedia.org/wikipedia/commons/0/0a/Flammarion_Colored.jpg";
const defaultBGURL = "https://upload.wikimedia.org/wikipedia/commons/0/0a/Flammarion_Colored.jpg";
export default (regl, config, inputs) => {
const output = makePassFBO(regl, config.useHalfFloat);
@@ -13,13 +12,13 @@ export default (regl, config, inputs) => {
uniforms: {
backgroundTex: background.texture,
tex: inputs.primary,
bloomTex: inputs.bloom
bloomTex: inputs.bloom,
},
framebuffer: output
framebuffer: output,
});
return makePass(
{
primary: output
primary: output,
},
() => render({ frag: imagePassFrag.text() }),
null,

View File

@@ -9,19 +9,15 @@ import makeResurrectionPass from "./resurrectionPass.js";
const canvas = document.createElement("canvas");
document.body.appendChild(canvas);
document.addEventListener("touchmove", e => e.preventDefault(), {
passive: false
document.addEventListener("touchmove", (e) => e.preventDefault(), {
passive: false,
});
const regl = createREGL({
canvas,
extensions: ["OES_texture_half_float", "OES_texture_half_float_linear"],
// These extensions are also needed, but Safari misreports that they are missing
optionalExtensions: [
"EXT_color_buffer_half_float",
"WEBGL_color_buffer_float",
"OES_standard_derivatives"
]
optionalExtensions: ["EXT_color_buffer_half_float", "WEBGL_color_buffer_float", "OES_standard_derivatives"],
});
const effects = {
@@ -32,7 +28,7 @@ const effects = {
pride: makeStripePass,
image: makeImagePass,
resurrection: makeResurrectionPass,
resurrections: makeResurrectionPass
resurrections: makeResurrectionPass,
};
const config = makeConfig(window.location.search);
@@ -51,28 +47,16 @@ const dimensions = { width: 1, height: 1 };
document.body.onload = async () => {
// All this takes place in a full screen quad.
const fullScreenQuad = makeFullScreenQuad(regl);
const pipeline = makePipeline(
[
makeMatrixRenderer,
effect === "none" ? null : makeBloomPass,
effects[effect]
],
p => p.outputs,
regl,
config
);
const pipeline = makePipeline([makeMatrixRenderer, effect === "none" ? null : makeBloomPass, effects[effect]], (p) => p.outputs, regl, config);
const drawToScreen = regl({
uniforms: {
tex: pipeline[pipeline.length - 1].outputs.primary
}
tex: pipeline[pipeline.length - 1].outputs.primary,
},
});
await Promise.all(pipeline.map(({ ready }) => ready));
const tick = regl.frame(({ viewportWidth, viewportHeight }) => {
// tick.cancel();
if (
dimensions.width !== viewportWidth ||
dimensions.height !== viewportHeight
) {
if (dimensions.width !== viewportWidth || dimensions.height !== viewportHeight) {
dimensions.width = viewportWidth;
dimensions.height = viewportHeight;
for (const step of pipeline) {

View File

@@ -15,16 +15,14 @@ const makePalette = (regl, entries) => {
const sortedEntries = entries
.slice()
.sort((e1, e2) => e1.at - e2.at)
.map(entry => ({
.map((entry) => ({
rgb: colorToRGB(entry.hsl),
arrayIndex: Math.floor(
Math.max(Math.min(1, entry.at), 0) * (PALETTE_SIZE - 1)
)
arrayIndex: Math.floor(Math.max(Math.min(1, entry.at), 0) * (PALETTE_SIZE - 1)),
}));
sortedEntries.unshift({ rgb: sortedEntries[0].rgb, arrayIndex: 0 });
sortedEntries.push({
rgb: sortedEntries[sortedEntries.length - 1].rgb,
arrayIndex: PALETTE_SIZE - 1
arrayIndex: PALETTE_SIZE - 1,
});
sortedEntries.forEach((entry, index) => {
paletteColors[entry.arrayIndex] = entry.rgb.slice();
@@ -36,7 +34,7 @@ const makePalette = (regl, entries) => {
paletteColors[entry.arrayIndex + i] = [
entry.rgb[0] * (1 - ratio) + nextEntry.rgb[0] * ratio,
entry.rgb[1] * (1 - ratio) + nextEntry.rgb[1] * ratio,
entry.rgb[2] * (1 - ratio) + nextEntry.rgb[2] * ratio
entry.rgb[2] * (1 - ratio) + nextEntry.rgb[2] * ratio,
];
}
}
@@ -44,7 +42,7 @@ const makePalette = (regl, entries) => {
return make1DTexture(
regl,
paletteColors.flat().map(i => i * 0xff)
paletteColors.flat().map((i) => i * 0xff)
);
};
@@ -64,20 +62,18 @@ export default (regl, config, inputs) => {
frag: regl.prop("frag"),
uniforms: {
...extractEntries(config, [
"backgroundColor",
]),
...extractEntries(config, ["backgroundColor"]),
tex: inputs.primary,
bloomTex: inputs.bloom,
palette,
ditherMagnitude: 0.05
ditherMagnitude: 0.05,
},
framebuffer: output
framebuffer: output,
});
return makePass(
{
primary: output
primary: output,
},
() => render({ frag: palettePassFrag.text() }),
null,

View File

@@ -1,26 +1,18 @@
import {
extractEntries,
loadImage,
loadText,
makePassFBO,
makeDoubleBuffer,
makePass
} from "./utils.js";
import { extractEntries, loadImage, loadText, makePassFBO, makeDoubleBuffer, makePass } from "./utils.js";
const rippleTypes = {
box: 0,
circle: 1
circle: 1,
};
const cycleStyles = {
cycleFasterWhenDimmed: 0,
cycleRandomly: 1
cycleRandomly: 1,
};
const numVerticesPerQuad = 2 * 3;
export default (regl, config) => {
const volumetric = config.volumetric;
const density = volumetric && config.effect !== "none" ? config.density : 1;
const [numRows, numColumns] = [config.numColumns, config.numColumns * density];
@@ -39,10 +31,9 @@ export default (regl, config) => {
width: numColumns,
height: numRows,
wrapT: "clamp",
type: "half float"
type: "half float",
});
const output = makePassFBO(regl, config.useHalfFloat);
const uniforms = {
@@ -79,20 +70,13 @@ export default (regl, config) => {
numQuadRows,
numQuadColumns,
quadSize,
volumetric
volumetric,
};
uniforms.rippleType =
config.rippleTypeName in rippleTypes
? rippleTypes[config.rippleTypeName]
: -1;
uniforms.cycleStyle =
config.cycleStyleName in cycleStyles
? cycleStyles[config.cycleStyleName]
: 0;
uniforms.rippleType = config.rippleTypeName in rippleTypes ? rippleTypes[config.rippleTypeName] : -1;
uniforms.cycleStyle = config.cycleStyleName in cycleStyles ? cycleStyles[config.cycleStyleName] : 0;
uniforms.slantVec = [Math.cos(config.slant), Math.sin(config.slant)];
uniforms.slantScale =
1 / (Math.abs(Math.sin(2 * config.slant)) * (Math.sqrt(2) - 1) + 1);
uniforms.slantScale = 1 / (Math.abs(Math.sin(2 * config.slant)) * (Math.sqrt(2) - 1) + 1);
uniforms.showComputationTexture = config.effect === "none";
const msdf = loadImage(regl, config.glyphTexURL);
@@ -102,19 +86,28 @@ export default (regl, config) => {
frag: regl.prop("frag"),
uniforms: {
...uniforms,
lastState: doubleBuffer.back
lastState: doubleBuffer.back,
},
framebuffer: doubleBuffer.front
framebuffer: doubleBuffer.front,
});
const quadPositions = Array(numQuadRows).fill().map((_, y) =>
Array(numQuadColumns).fill().map((_, x) =>
Array(numVerticesPerQuad).fill([x, y])
)
const quadPositions = Array(numQuadRows)
.fill()
.map((_, y) =>
Array(numQuadColumns)
.fill()
.map((_, x) => Array(numVerticesPerQuad).fill([x, y]))
);
const quadCorners = Array(numQuads).fill([[0, 0], [0, 1], [1, 1], [0, 0], [1, 1], [1, 0]]);
const quadCorners = Array(numQuads).fill([
[0, 0],
[0, 1],
[1, 1],
[0, 0],
[1, 1],
[1, 0],
]);
// We render the code into an FBO using MSDFs: https://github.com/Chlumsky/msdfgen
const renderVert = loadText("../shaders/render.vert");
@@ -126,8 +119,8 @@ export default (regl, config) => {
srcRGB: "src alpha",
srcAlpha: 1,
dstRGB: "dst alpha",
dstAlpha: 1
}
dstAlpha: 1,
},
},
vert: regl.prop("vert"),
frag: regl.prop("frag"),
@@ -140,16 +133,16 @@ export default (regl, config) => {
camera: regl.prop("camera"),
transform: regl.prop("transform"),
screenSize: regl.prop("screenSize")
screenSize: regl.prop("screenSize"),
},
attributes: {
aPosition: quadPositions,
aCorner: quadCorners
aCorner: quadCorners,
},
count: numQuads * numVerticesPerQuad,
framebuffer: output
framebuffer: output,
});
const screenSize = [1, 1];
@@ -163,7 +156,7 @@ export default (regl, config) => {
return makePass(
{
primary: output
primary: output,
},
() => {
const time = Date.now();
@@ -172,7 +165,7 @@ export default (regl, config) => {
regl.clear({
depth: 1,
color: [0, 0, 0, 1],
framebuffer: output
framebuffer: output,
});
render({ camera, transform, screenSize, vert: renderVert.text(), frag: renderFrag.text() });
},

View File

@@ -18,19 +18,17 @@ export default (regl, config, inputs) => {
frag: regl.prop("frag"),
uniforms: {
...extractEntries(config, [
"backgroundColor",
]),
...extractEntries(config, ["backgroundColor"]),
tex: inputs.primary,
bloomTex: inputs.bloom,
ditherMagnitude: 0.05
ditherMagnitude: 0.05,
},
framebuffer: output
framebuffer: output,
});
return makePass(
{
primary: output
primary: output,
},
() => render({ frag: resurrectionPassFrag.text() })
);

View File

@@ -6,7 +6,7 @@ const neapolitanStripeColors = [
[0.8, 0.8, 0.6],
[0.8, 0.8, 0.6],
[1.0, 0.7, 0.8],
[1.0, 0.7, 0.8]
[1.0, 0.7, 0.8],
].flat();
const prideStripeColors = [
@@ -15,22 +15,18 @@ const prideStripeColors = [
[1, 1, 0],
[0, 1, 0],
[0, 0, 1],
[0.8, 0, 1]
[0.8, 0, 1],
].flat();
export default (regl, config, inputs) => {
const output = makePassFBO(regl, config.useHalfFloat);
const stripeColors =
"stripeColors" in config
? config.stripeColors.split(",").map(parseFloat)
: config.effect === "pride"
? prideStripeColors
: neapolitanStripeColors;
"stripeColors" in config ? config.stripeColors.split(",").map(parseFloat) : config.effect === "pride" ? prideStripeColors : neapolitanStripeColors;
const numStripeColors = Math.floor(stripeColors.length / 3);
const stripes = make1DTexture(
regl,
stripeColors.slice(0, numStripeColors * 3).map(f => Math.floor(f * 0xff))
stripeColors.slice(0, numStripeColors * 3).map((f) => Math.floor(f * 0xff))
);
const stripePassFrag = loadText("../shaders/stripePass.frag");
@@ -39,20 +35,18 @@ export default (regl, config, inputs) => {
frag: regl.prop("frag"),
uniforms: {
...extractEntries(config, [
"backgroundColor",
]),
...extractEntries(config, ["backgroundColor"]),
tex: inputs.primary,
bloomTex: inputs.bloom,
stripes,
ditherMagnitude: 0.05
ditherMagnitude: 0.05,
},
framebuffer: output
framebuffer: output,
});
return makePass(
{
primary: output
primary: output,
},
() => render({ frag: stripePassFrag.text() }),
null,

View File

@@ -1,7 +1,4 @@
const extractEntries = (src, keys) =>
Object.fromEntries(
Array.from(Object.entries(src)).filter(([key]) => keys.includes(key))
);
const extractEntries = (src, keys) => Object.fromEntries(Array.from(Object.entries(src)).filter(([key]) => keys.includes(key)));
const makePassTexture = (regl, halfFloat) =>
regl.texture({
@@ -10,7 +7,7 @@ const makePassTexture = (regl, halfFloat) =>
type: halfFloat ? "half float" : "uint8",
wrap: "clamp",
min: "linear",
mag: "linear"
mag: "linear",
});
const makePassFBO = (regl, halfFloat) => regl.framebuffer({ color: makePassTexture(regl, halfFloat) });
@@ -20,7 +17,7 @@ const makePassFBO = (regl, halfFloat) => regl.framebuffer({ color: makePassTextu
const makePyramid = (regl, height, halfFloat) =>
Array(height)
.fill()
.map(_ => makePassFBO(regl, halfFloat));
.map((_) => makePassFBO(regl, halfFloat));
const makeDoubleBuffer = (regl, props) => {
const state = Array(2)
@@ -28,22 +25,17 @@ const makeDoubleBuffer = (regl, props) => {
.map(() =>
regl.framebuffer({
color: regl.texture(props),
depthStencil: false
depthStencil: false,
})
);
return {
front: ({ tick }) => state[tick % 2],
back: ({ tick }) => state[(tick + 1) % 2]
back: ({ tick }) => state[(tick + 1) % 2],
};
};
const resizePyramid = (pyramid, vw, vh, scale) =>
pyramid.forEach((fbo, index) =>
fbo.resize(
Math.floor((vw * scale) / 2 ** index),
Math.floor((vh * scale) / 2 ** index)
)
);
pyramid.forEach((fbo, index) => fbo.resize(Math.floor((vw * scale) / 2 ** index), Math.floor((vh * scale) / 2 ** index)));
const loadImage = (regl, url) => {
let texture = regl.texture([[0]]);
@@ -66,10 +58,10 @@ const loadImage = (regl, url) => {
data,
mag: "linear",
min: "linear",
flipY: true
flipY: true,
});
}
})()
})(),
};
};
@@ -94,10 +86,10 @@ const loadShader = (regl, url) => {
data,
mag: "linear",
min: "linear",
flipY: true
flipY: true,
});
}
})()
})(),
};
};
@@ -116,7 +108,7 @@ const loadText = (url) => {
text = await (await fetch(url)).text();
loaded = true;
}
})()
})(),
};
};
@@ -142,19 +134,18 @@ const makeFullScreenQuad = (regl, uniforms = {}, context = {}) =>
`,
attributes: {
aPosition: [-4, -4, 4, -4, 0, 4]
aPosition: [-4, -4, 4, -4, 0, 4],
},
count: 3,
uniforms: {
...uniforms,
time: regl.context("time")
time: regl.context("time"),
},
context,
depth: { enable: false },
});
const make1DTexture = (regl, data) =>
@@ -164,7 +155,7 @@ const make1DTexture = (regl, data) =>
height: 1,
format: "rgb",
mag: "linear",
min: "linear"
min: "linear",
});
const makePass = (outputs, render, resize, ready) => {
@@ -172,8 +163,7 @@ const makePass = (outputs, render, resize, ready) => {
render = () => {};
}
if (resize == null) {
resize = (w, h) =>
Object.values(outputs).forEach(output => output.resize(w, h));
resize = (w, h) => Object.values(outputs).forEach((output) => output.resize(w, h));
}
if (ready == null) {
ready = Promise.resolve();
@@ -184,20 +174,12 @@ const makePass = (outputs, render, resize, ready) => {
outputs,
render,
resize,
ready
ready,
};
};
const makePipeline = (steps, getInputs, ...params) =>
steps
.filter(f => f != null)
.reduce(
(pipeline, f, i) => [
...pipeline,
f(...params, i == 0 ? null : getInputs(pipeline[i - 1]))
],
[]
);
steps.filter((f) => f != null).reduce((pipeline, f, i) => [...pipeline, f(...params, i == 0 ? null : getInputs(pipeline[i - 1]))], []);
export {
extractEntries,
@@ -211,5 +193,5 @@ export {
makeFullScreenQuad,
make1DTexture,
makePass,
makePipeline
makePipeline,
};