mirror of
https://github.com/Rezmason/matrix.git
synced 2026-04-14 12:29:30 -07:00
WebGPU and REGL projects now flipY again, and they properly flip the symbolY glyph coordinate in the rain pass's fragment shader. Switching on some older code that was disabled for FF Nightly support— it makes more sense to wait for that support as implementations finalize. Added mipmap to images loaded into REGL project.
109 lines
3.3 KiB
JavaScript
109 lines
3.3 KiB
JavaScript
const loadTexture = async (device, url) => {
|
|
if (url == null) {
|
|
return device.createTexture({
|
|
size: [1, 1, 1],
|
|
format: "rgba8unorm",
|
|
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,
|
|
});
|
|
}
|
|
|
|
const response = await fetch(url);
|
|
const data = await response.blob();
|
|
const source = await createImageBitmap(data);
|
|
const size = [source.width, source.height, 1];
|
|
|
|
const texture = device.createTexture({
|
|
size,
|
|
format: "rgba8unorm",
|
|
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,
|
|
});
|
|
|
|
device.queue.copyExternalImageToTexture({ source, flipY: true }, { texture }, size);
|
|
|
|
return texture;
|
|
};
|
|
|
|
const makeRenderTarget = (device, size, format, mipLevelCount = 1) =>
|
|
device.createTexture({
|
|
size: [...size, 1],
|
|
mipLevelCount,
|
|
format,
|
|
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,
|
|
});
|
|
|
|
const makeComputeTarget = (device, size, mipLevelCount = 1) =>
|
|
device.createTexture({
|
|
size: [...size, 1],
|
|
mipLevelCount,
|
|
format: "rgba8unorm",
|
|
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC | GPUTextureUsage.COPY_DST | GPUTextureUsage.STORAGE_BINDING,
|
|
});
|
|
|
|
const loadShader = async (device, url) => {
|
|
const response = await fetch(url);
|
|
const code = await response.text();
|
|
return {
|
|
code,
|
|
module: device.createShaderModule({ code }),
|
|
};
|
|
};
|
|
|
|
const makeUniformBuffer = (device, uniforms, data = null) => {
|
|
const buffer = device.createBuffer({
|
|
size: uniforms.minSize,
|
|
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
mappedAtCreation: data != null,
|
|
});
|
|
if (data != null) {
|
|
uniforms.toBuffer(data, 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 makeBindGroup = (device, pipeline, index, entries) =>
|
|
device.createBindGroup({
|
|
layout: pipeline.getBindGroupLayout(index),
|
|
entries: entries
|
|
.map((resource) => (resource instanceof GPUBuffer ? { buffer: resource } : resource))
|
|
.map((resource, binding) => ({
|
|
binding,
|
|
resource,
|
|
})),
|
|
});
|
|
|
|
const makePass = (name, loaded, build, run) => ({
|
|
loaded: loaded ?? Promise.resolve(),
|
|
build: build ?? ((size, inputs) => inputs),
|
|
run: (encoder, shouldRender) => {
|
|
encoder.pushDebugGroup(`Pass "${name}"`);
|
|
run?.(encoder, shouldRender);
|
|
encoder.popDebugGroup();
|
|
},
|
|
});
|
|
|
|
const makePipeline = async (context, steps) => {
|
|
steps = steps.filter((f) => f != null).map((f) => f(context));
|
|
await Promise.all(steps.map((step) => step.loaded));
|
|
return {
|
|
steps,
|
|
build: (canvasSize) => steps.reduce((outputs, step) => step.build(canvasSize, outputs), null),
|
|
run: (encoder, shouldRender) => steps.forEach((step) => step.run(encoder, shouldRender)),
|
|
};
|
|
};
|
|
|
|
export { makeRenderTarget, makeComputeTarget, make1DTexture, loadTexture, loadShader, makeUniformBuffer, makePass, makePipeline, makeBindGroup };
|