mirror of
https://github.com/Rezmason/matrix.git
synced 2026-04-14 12:29:30 -07:00
Fetching WebGPU shaders. Created my first bona fide pipeline. The vertex shader compares the built-in vertex index and the numRows/numColumns uniforms to produce a grid of quads with no vertex or index buffer whatsoever!
This commit is contained in:
@@ -6,6 +6,9 @@ const getCanvasSize = (canvas) => {
|
||||
export default async (canvas, config) => {
|
||||
console.log(config);
|
||||
|
||||
const numColumns = config.numColumns;
|
||||
const numRows = config.numColumns;
|
||||
|
||||
if (navigator.gpu == null) {
|
||||
return;
|
||||
}
|
||||
@@ -36,14 +39,78 @@ export default async (canvas, config) => {
|
||||
|
||||
// TODO: create buffers, uniforms, textures, samplers
|
||||
|
||||
const uniformBufferSize = 4 * (1 + 1);
|
||||
const uniformBuffer = device.createBuffer({
|
||||
size: uniformBufferSize,
|
||||
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST, // Which of these are necessary?
|
||||
mappedAtCreation: true,
|
||||
});
|
||||
new Int32Array(uniformBuffer.getMappedRange()).set([numColumns, numRows]);
|
||||
uniformBuffer.unmap();
|
||||
|
||||
// TODO: create pipelines, bind groups, shaders
|
||||
|
||||
const [vert, frag] = await Promise.all(["shaders/rainPass.vert.wgsl", "shaders/rainPass.frag.wgsl"].map(async (path) => (await fetch(path)).text()));
|
||||
|
||||
const additiveBlendComponent = {
|
||||
operation: "add",
|
||||
srcFactor: "one",
|
||||
dstFactor: "one",
|
||||
};
|
||||
|
||||
const additiveBlending = {
|
||||
color: additiveBlendComponent,
|
||||
alpha: additiveBlendComponent,
|
||||
};
|
||||
|
||||
const rainRenderPipeline = device.createRenderPipeline({
|
||||
vertex: {
|
||||
module: device.createShaderModule({
|
||||
code: vert,
|
||||
}),
|
||||
entryPoint: "main",
|
||||
},
|
||||
fragment: {
|
||||
module: device.createShaderModule({
|
||||
code: frag,
|
||||
}),
|
||||
entryPoint: "main",
|
||||
targets: [
|
||||
{
|
||||
format: presentationFormat,
|
||||
blend: additiveBlending,
|
||||
},
|
||||
],
|
||||
},
|
||||
primitive: {
|
||||
// What happens if this isn't here?
|
||||
topology: "triangle-list", // What happens if this isn't here?
|
||||
cullMode: "none", // What happens if this isn't here?
|
||||
},
|
||||
});
|
||||
|
||||
const uniformBindGroup = device.createBindGroup({
|
||||
layout: rainRenderPipeline.getBindGroupLayout(0),
|
||||
entries: [
|
||||
{
|
||||
binding: 0,
|
||||
resource: {
|
||||
buffer: uniformBuffer,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const bundleEncoder = device.createRenderBundleEncoder({
|
||||
colorFormats: [presentationFormat],
|
||||
});
|
||||
// TODO: create render bundle(s)
|
||||
const bundle = bundleEncoder.finish();
|
||||
const renderBundles = [bundle];
|
||||
|
||||
bundleEncoder.setPipeline(rainRenderPipeline);
|
||||
bundleEncoder.setBindGroup(0, uniformBindGroup);
|
||||
bundleEncoder.draw(6 * numColumns * numRows, 1, 0, 0);
|
||||
const renderBundles = [bundleEncoder.finish()];
|
||||
|
||||
// queue.writeBuffer(uniformBuffer, 0, new Int32Array([numColumns, numRows]));
|
||||
|
||||
const frame = (now) => {
|
||||
const canvasSize = getCanvasSize(canvas);
|
||||
@@ -58,7 +125,7 @@ export default async (canvas, config) => {
|
||||
|
||||
// TODO: update the uniforms that change, write to queue
|
||||
|
||||
renderPassConfig.colorAttachments[0].loadValue.g = Math.sin((now / 1000) * 2) / 2 + 0.5;
|
||||
renderPassConfig.colorAttachments[0].loadValue.r = Math.sin((now / 1000) * 2) / 2 + 0.5;
|
||||
renderPassConfig.colorAttachments[0].view = canvasContext.getCurrentTexture().createView();
|
||||
|
||||
const encoder = device.createCommandEncoder();
|
||||
|
||||
3
shaders/rainPass.frag.wgsl
Normal file
3
shaders/rainPass.frag.wgsl
Normal file
@@ -0,0 +1,3 @@
|
||||
[[stage(fragment)]] fn main([[location(0)]] UV : vec2<f32>) -> [[location(0)]] vec4<f32> {
|
||||
return vec4<f32>(0.0, UV, 1.0);
|
||||
}
|
||||
39
shaders/rainPass.vert.wgsl
Normal file
39
shaders/rainPass.vert.wgsl
Normal file
@@ -0,0 +1,39 @@
|
||||
[[block]] struct Uniforms {
|
||||
numColumns: i32;
|
||||
numRows: i32;
|
||||
};
|
||||
[[binding(0), group(0)]] var<uniform> uniforms : Uniforms;
|
||||
|
||||
struct VertexOutput {
|
||||
[[builtin(position)]] Position : vec4<f32>;
|
||||
[[location(0)]] UV : vec2<f32>;
|
||||
};
|
||||
|
||||
[[stage(vertex)]] fn main([[builtin(vertex_index)]] VertexIndex : u32) -> VertexOutput {
|
||||
|
||||
var i = i32(VertexIndex);
|
||||
var quadIndex = i / 6;
|
||||
|
||||
var cornerPosition = vec2<f32>(
|
||||
f32(i % 2),
|
||||
f32(((i + 1) % 6 / 3))
|
||||
);
|
||||
|
||||
var x = uniforms.numColumns;
|
||||
|
||||
var position = cornerPosition;
|
||||
position = position + vec2<f32>(
|
||||
f32(quadIndex % uniforms.numColumns),
|
||||
f32(quadIndex / uniforms.numColumns)
|
||||
);
|
||||
position = position / vec2<f32>(
|
||||
f32(uniforms.numColumns),
|
||||
f32(uniforms.numRows)
|
||||
);
|
||||
position = position * 2.0 - 1.0;
|
||||
|
||||
return VertexOutput(
|
||||
vec4<f32>(position, 1.0, 1.0),
|
||||
cornerPosition
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user