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.

Revisions

  1. Popov72 created this gist Nov 2, 2020.
    136 changes: 136 additions & 0 deletions webgpu_shadow.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,136 @@
    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;
    }