Files
matrix/js/utils.js
2020-01-21 12:17:17 -08:00

92 lines
1.8 KiB
JavaScript

const makePassTexture = regl =>
regl.texture({
width: 1,
height: 1,
type: "half float",
wrap: "clamp",
min: "linear",
mag: "linear"
});
const makePassFBO = regl => regl.framebuffer({ color: makePassTexture(regl) });
const makePyramid = (regl, height) =>
Array(height)
.fill()
.map(_ => makePassFBO(regl));
const resizePyramid = (pyramid, vw, vh, scale) =>
pyramid.forEach((fbo, index) =>
fbo.resize(
Math.floor((vw * scale) / 2 ** index),
Math.floor((vh * scale) / 2 ** index)
)
);
const loadImages = async (regl, manifest) => {
const keys = Object.keys(manifest);
const urls = Object.values(manifest);
const images = await Promise.all(urls.map(url => loadImage(regl, url)));
return Object.fromEntries(images.map((image, index) => [keys[index], image]));
};
const loadImage = async (regl, url) => {
if (url == null) {
return null;
}
const image = new Image();
image.crossOrigin = "anonymous";
image.src = url;
await image.decode();
return regl.texture({
data: image,
mag: "linear",
min: "linear",
flipY: true
});
};
const makeFullScreenQuad = (regl, uniforms) =>
regl({
vert: `
precision mediump float;
attribute vec2 aPosition;
varying vec2 vUV;
void main() {
vUV = 0.5 * (aPosition + 1.0);
gl_Position = vec4(aPosition, 0, 1);
}
`,
frag: `
precision mediump float;
varying vec2 vUV;
uniform sampler2D tex;
void main() {
gl_FragColor = texture2D(tex, vUV);
}
`,
attributes: {
aPosition: [-4, -4, 4, -4, 0, 4]
},
uniforms: {
...uniforms,
time: regl.context("time")
},
depth: { enable: false },
count: 3
});
export {
makePassTexture,
makePassFBO,
makePyramid,
resizePyramid,
loadImage,
loadImages,
makeFullScreenQuad
};