{
const { device, context } = await gpu.init(1024, 1024)
const DISPATCH_SIZE = [Math.ceil(1024 / 16), Math.ceil(1024 / 16), 1]
const texInput = gpu.canvasTexture(device, sample.canvas)
const texOutput = device.createTexture({
size: [1024, 1024],
format: 'rgba8unorm',
usage:
GPUTextureUsage.STORAGE_BINDING |
GPUTextureUsage.COPY_SRC |
GPUTextureUsage.TEXTURE_BINDING
})
const shaderModule = device.createShaderModule({
code: `
@group(0) @binding(0) var texInput: texture_2d<f32>;
@group(0) @binding(1) var texOutput: texture_storage_2d<rgba8unorm, write>;
const tileSize: vec2<u32> = vec2<u32>(16, 16);
@compute
@workgroup_size(16, 16, 1)
fn cs(@builtin(global_invocation_id) global_id: vec3<u32>) {
let texSize: vec2<u32> = textureDimensions(texInput).xy;
let tileNW: vec2<u32> = (global_id.xy / tileSize) * tileSize;
let localPos: vec2<u32> = global_id.xy % tileSize;
let texPos: vec2<u32> = tileNW + localPos;
if (texPos.x < texSize.x && texPos.y < texSize.y && textureLoad(texInput, texPos, 0).a > 0.0) {
// let color =
// vec4f(f32(localPos.x) / f32(tileSize.x), f32(localPos.y) / f32(tileSize.y), 0.0, 1.0) *
// vec4f(f32(tileNW.x) / f32(texSize.x), f32(tileNW.y) / f32(texSize.y), 0.0, 1.0);
let color = vec4f(f32(localPos.x) / f32(tileSize.x), f32(localPos.y) / f32(tileSize.y), 0.0, 1.0);
textureStore(texOutput, texPos, color);
}
}
`
});
const bindGroupLayout = device.createBindGroupLayout({
entries: [
{
binding: 0,
visibility: GPUShaderStage.COMPUTE,
texture: { format: 'rgba8unorm' }
},
{
binding: 1,
visibility: GPUShaderStage.COMPUTE | GPUShaderStage.FRAGMENT,
storageTexture: { format: 'rgba8unorm' }
}
]
});
const pipelineLayout = device.createPipelineLayout({
bindGroupLayouts: [bindGroupLayout]
});
const pipeline = device.createComputePipeline({
layout: pipelineLayout,
compute: {
module: shaderModule,
entryPoint: 'cs'
}
});
const bindGroup = device.createBindGroup({
layout: bindGroupLayout,
entries: [
{ binding: 0, resource: texInput.createView() },
{ binding: 1, resource: texOutput.createView() }
]
});
const commandEncoder = device.createCommandEncoder();
const passEncoder = commandEncoder.beginComputePass();
passEncoder.setPipeline(pipeline);
passEncoder.setBindGroup(0, bindGroup);
passEncoder.dispatchWorkgroups(...DISPATCH_SIZE);
passEncoder.end();
device.queue.submit([commandEncoder.finish()]);
const debug = new TextureRenderer(device, texOutput)
debug.render()
return debug.canvas
}