Repository navigation
how to use StencilTest #150
Copy link
Copy link
Open
Labels
sample requestRequest for a new sampleRequest for a new sample
Description
Activity
a simple demo
async function init() { const gpu = navigator.gpu; const adapter = await gpu.requestAdapter(); const device = await adapter.requestDevice(); const cvs = document.createElement('canvas'); cvs.width = 1024; cvs.height = 768; document.body.appendChild(cvs); const depthTexture = device.createTexture({ size: { width: cvs.width, height: cvs.height, depthOrArrayLayers: 1 }, format: "depth24plus-stencil8", usage: GPUTextureUsage.RENDER_ATTACHMENT }); const ctx = cvs.getContext('webgpu'); const swapChainFormat = "bgra8unorm"; const presentationFormat = ctx.getPreferredFormat(adapter); ctx.configure({ device: device, format: swapChainFormat }); let data=new Float32Array( [ -1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, -1.0, 0.0, 1.0 ]); let vertexBuffer = device.createBuffer({ size: data.byteLength, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST }); device.queue.writeBuffer(vertexBuffer, 0, data); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const uniformsBindGroupLayout = device.createBindGroupLayout({ entries: [ { binding: 0, visibility: GPUShaderStage.VERTEX, buffer: { type: 'uniform', }, } ] }); const uniformsBindGroupLayout1 = device.createBindGroupLayout({ entries: [ { binding: 0, visibility: GPUShaderStage.VERTEX, buffer: { type: 'uniform', }, } ] }); const matrixSize = 16 * Float32Array.BYTES_PER_ELEMENT; // 4x4 matrix const uniformBufferSize = matrixSize ; const uniformBuffer = device.createBuffer({ size: uniformBufferSize, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, }); const uniformBuffer1 = device.createBuffer({ size: uniformBufferSize, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, }); const uniformBindGroup = device.createBindGroup({ layout: uniformsBindGroupLayout, entries: [ { binding: 0, resource: { buffer: uniformBuffer, offset: 0, size: uniformBufferSize } } ] }); const uniformBindGroup1 = device.createBindGroup({ layout: uniformsBindGroupLayout1, entries: [ { binding: 0, resource: { buffer: uniformBuffer1, offset: 0, size: uniformBufferSize } } ] }); const pipelineWriteMask = device.createRenderPipeline({ layout: device.createPipelineLayout({bindGroupLayouts: [uniformsBindGroupLayout]}), vertex: { module: device.createShaderModule({ code: basicVertWGSL, }), entryPoint: 'main', buffers: [ { arrayStride: 4 * 4, attributes: [ { // position shaderLocation: 0, offset: 0, format: "float32x4" } ] } ] }, fragment: { module: device.createShaderModule({ code: basicFragWGSL, }), entryPoint: 'main', targets: [ { format: presentationFormat, writeMask:0x00,//关闭color写入 }, ], }, primitive: { topology: 'triangle-list', }, depthStencil: { depthWriteEnabled: true, depthCompare: "always", format: "depth24plus-stencil8", stencilFront:{ compare:"always", failOp:"keep", depthFailOp:"keep", passOp:"replace", }, stencilBack:{ compare:"always", failOp:"keep", depthFailOp:"keep", passOp:"replace", }, }, }); const pipelineUseMask = device.createRenderPipeline({ layout: device.createPipelineLayout({bindGroupLayouts: [uniformsBindGroupLayout1]}), vertex: { module: device.createShaderModule({ code: basicVertWGSL, }), entryPoint: 'main', buffers: [ { arrayStride: 4 * 4, attributes: [ { // position shaderLocation: 0, offset: 0, format: "float32x4" } ] } ] }, fragment: { module: device.createShaderModule({ code: basicFragWGSL, }), entryPoint: 'main', targets: [ { format: presentationFormat, }, ], }, primitive: { topology: 'triangle-list', }, depthStencil: { depthWriteEnabled: false, depthCompare: "always", format: "depth24plus-stencil8", stencilFront:{ compare: "equal", }, stencilBack:{ compare:"equal", }, }, }); let modelMatrix = mat4.create(); let modelMatrix1 = mat4.create(); let render = async function () { const commandEncoder = device.createCommandEncoder(); const passEncoder = commandEncoder.beginRenderPass({ colorAttachments: [{ view: ctx.getCurrentTexture().createView(), loadValue: {r: 0.0, g: 0.0, b: 0.0, a: 1.0}, }], depthStencilAttachment: { view: depthTexture.createView(), depthLoadValue: 0.0, depthStoreOp: "store", stencilLoadValue: 0.0, stencilStoreOp: "store", } }); /*******************第一次渲染**********************/ passEncoder.setVertexBuffer(0, vertexBuffer); passEncoder.setPipeline(pipelineWriteMask); mat4.identity(modelMatrix); mat4.scale(modelMatrix, modelMatrix, [-0.2,-0.2, 1]); passEncoder.setBindGroup(0, uniformBindGroup); //将三角区域模板值写入1 passEncoder.setStencilReference(1) device.queue.writeBuffer(uniformBuffer, 0, modelMatrix); passEncoder.draw(3, 1, 0, 0); /****************第二次渲染********************/ mat4.identity(modelMatrix1); mat4.scale(modelMatrix1, modelMatrix1, [0.6,0.6, 1]); passEncoder.setVertexBuffer(0, vertexBuffer); passEncoder.setPipeline(pipelineUseMask); passEncoder.setBindGroup(0,uniformBindGroup1); //渲染模板值等于0的区域 passEncoder.setStencilReference(0) device.queue.writeBuffer(uniformBuffer1, 0, modelMatrix1); passEncoder.draw(3, 1, 0, 0); passEncoder.endPass(); const test = commandEncoder.finish(); device.queue.submit([test]); }; render(); } init() const basicVertWGSL = ` [[block]] struct Uniforms { modelMatrix : mat4x4<f32>; }; [[binding(0), group(0)]] var<uniform> uniforms : Uniforms; struct VertexOutput { [[builtin(position)]] Position : vec4<f32>; }; [[stage(vertex)]] fn main([[location(0)]] position : vec4<f32>) -> VertexOutput { var output : VertexOutput; output.Position = uniforms.modelMatrix * position; return output; } `; const basicFragWGSL = ` [[stage(fragment)]] fn main() -> [[location(0)]] vec4<f32> { return vec4<f32>(1.0, 0.0, 0.0, 1.0); } `;I think Dawn used to have a sample that used stencil testing to render a reflective floor?
Something like that would make a good sample.
Metadata
Metadata
Assignees
Labels
sample requestRequest for a new sampleRequest for a new sample
A simple demo can be provided?
I tried it, but it didn't work
``