mirror of
https://github.com/Rezmason/matrix.git
synced 2026-04-14 04:19:29 -07:00
84 lines
2.5 KiB
JavaScript
84 lines
2.5 KiB
JavaScript
const getCanvasSize = (canvas) => {
|
|
const devicePixelRatio = window.devicePixelRatio ?? 1;
|
|
return [canvas.clientWidth * devicePixelRatio, canvas.clientHeight * devicePixelRatio];
|
|
};
|
|
|
|
const loadTexture = async (device, url) => {
|
|
const response = await fetch(url);
|
|
const data = await response.blob();
|
|
const imageBitmap = await createImageBitmap(data);
|
|
|
|
const texture = device.createTexture({
|
|
size: [imageBitmap.width, imageBitmap.height, 1],
|
|
format: "rgba8unorm",
|
|
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,
|
|
});
|
|
|
|
device.queue.copyExternalImageToTexture(
|
|
{
|
|
source: imageBitmap,
|
|
},
|
|
{
|
|
texture: texture,
|
|
},
|
|
[imageBitmap.width, imageBitmap.height]
|
|
);
|
|
|
|
return texture;
|
|
};
|
|
|
|
const makePassFBO = (device, width, height, format = "rgba8unorm") =>
|
|
device.createTexture({
|
|
size: [width, height, 1],
|
|
format,
|
|
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,
|
|
// TODO: whittle these down
|
|
});
|
|
|
|
const loadShader = async (device, url) => {
|
|
const response = await fetch(url);
|
|
const code = await response.text();
|
|
return {
|
|
code,
|
|
module: device.createShaderModule({ code }),
|
|
};
|
|
};
|
|
|
|
const makeUniformBuffer = (device, structLayout, values = null) => {
|
|
const buffer = device.createBuffer({
|
|
size: structLayout.size,
|
|
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
mappedAtCreation: values != null,
|
|
});
|
|
if (values != null) {
|
|
structLayout.build(values, buffer.getMappedRange());
|
|
buffer.unmap();
|
|
}
|
|
return buffer;
|
|
};
|
|
|
|
const make1DTexture = (device, rgbas) => {
|
|
const size = [rgbas.length];
|
|
const texture = device.createTexture({
|
|
size,
|
|
// dimension: "1d",
|
|
format: "rgba8unorm",
|
|
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,
|
|
});
|
|
const data = new Uint8ClampedArray(rgbas.map((color) => color.map((f) => f * 0xff)).flat());
|
|
device.queue.writeTexture({ texture }, data, {}, size);
|
|
return texture;
|
|
};
|
|
|
|
const makePass = (ready, setSize, getOutputs, execute) => ({
|
|
ready: ready ?? Promise.resolve(),
|
|
setSize: setSize ?? (() => {}),
|
|
getOutputs: getOutputs ?? (() => ({})),
|
|
execute: execute ?? (() => {}),
|
|
});
|
|
|
|
const makePipeline = (context, steps) =>
|
|
steps.filter((f) => f != null).reduce((pipeline, f, i) => [...pipeline, f(context, i == 0 ? null : pipeline[i - 1].getOutputs)], []);
|
|
|
|
export { getCanvasSize, makePassFBO, make1DTexture, loadTexture, loadShader, makeUniformBuffer, makePass, makePipeline };
|