Skip to content

Instantly share code, notes, and snippets.

@Popov72
Created November 2, 2020 21:39
Show Gist options
  • Save Popov72/7f1388c0b35fef351014a1946b40dabd to your computer and use it in GitHub Desktop.
Save Popov72/7f1388c0b35fef351014a1946b40dabd to your computer and use it in GitHub Desktop.
Simple WebGPU sample using shadow sampler
import glslangModule from '../glslang';
export const title = 'Hello Triangle';
export const description = 'Shows rendering a basic triangle.';
export async function init(canvas: HTMLCanvasElement) {
const vertexShaderGLSL = `#version 450
const vec2 pos[3] = vec2[3](vec2(0.0f, 0.5f), vec2(-0.5f, -0.5f), vec2(0.5f, -0.5f));
void main() {
gl_Position = vec4(pos[gl_VertexIndex], 0.0, 1.0);
}
`;
const fragmentShaderGLSL = `#version 450
layout(location = 0) out vec4 outColor;
layout(set = 0, binding = 0) uniform samplerShadow shadowSampler0Sampler;
layout(set = 0, binding = 1) uniform texture2D shadowSampler0Texture;
#define shadowSampler0 sampler2DShadow(shadowSampler0Texture, shadowSampler0Sampler)
void main() {
float c = texture(shadowSampler0, vec3(0.5, 0.5, 0.0), 0.);
outColor = vec4(c);//vec4(1.0, 0.0, 0.0, 1.0);
}
`;
const glslang = await glslangModule();
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const context = canvas.getContext('gpupresent');
const swapChainFormat = "bgra8unorm";
// @ts-ignore:
const swapChain: GPUSwapChain = context.configureSwapChain({
device,
format: swapChainFormat,
});
const bindGroupLayout = device.createBindGroupLayout({
entries: [{
binding: 0,
visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
type: "comparison-sampler"
}, {
binding: 1,
visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
type: "sampled-texture",
viewDimension: "2d",
textureComponentType: "float",
}]
});
const pipelineLayout = device.createPipelineLayout({ bindGroupLayouts: [bindGroupLayout] });
const pipeline = device.createRenderPipeline({
layout: pipelineLayout,
vertexStage: {
module: device.createShaderModule({
code: glslang.compileGLSL(vertexShaderGLSL, "vertex"),
}),
entryPoint: "main"
},
fragmentStage: {
module: device.createShaderModule({
code: glslang.compileGLSL(fragmentShaderGLSL, "fragment"),
}),
entryPoint: "main"
},
primitiveTopology: "triangle-list",
colorStates: [{
format: swapChainFormat,
}],
});
const width = 1024, height = 1024;
const textureExtent = {
width,
height,
depth: 1
};
const gpuTexture = device.createTexture({
size: textureExtent,
dimension: "2d",
format: "rgba8unorm",
usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.SAMPLED,
sampleCount: 1,
mipLevelCount: 1
});
const bindGroup = device.createBindGroup({
layout: bindGroupLayout,
entries: [
{
binding: 0,
resource: device.createSampler({
compare: "less-equal"
}),
},
{
binding: 1,
resource: gpuTexture.createView(),
}
]
});
function frame() {
const commandEncoder = device.createCommandEncoder({});
const textureView = swapChain.getCurrentTexture().createView();
const renderPassDescriptor: GPURenderPassDescriptor = {
colorAttachments: [{
attachment: textureView,
loadValue: { r: 0.0, g: 0.0, b: 0.0, a: 1.0 },
}],
};
const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
passEncoder.setPipeline(pipeline);
passEncoder.setBindGroup(0, bindGroup);
passEncoder.draw(3, 1, 0, 0);
passEncoder.endPass();
device.defaultQueue.submit([commandEncoder.finish()]);
}
return frame;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment