15158846557 在线咨询 在线咨询
15158846557 在线咨询
所在位置: 首页 > 营销资讯 > 网站运营 > WebGPU使用模板测试

WebGPU使用模板测试

时间:2023-06-09 21:57:01 | 来源:网站运营

时间:2023-06-09 21:57:01 来源:网站运营

WebGPU使用模板测试:最近一直在研究WebGPU,前两天在看官方API的时候突然看到了模板测试的API,发现与WebGL设置模板方法还不太一样,就想找个demo看看具体怎么用,奈何翻遍全网没找到一个webgpu使用模板测试的案例,那我就在这里写一个吧,废话不多说上干货:

一、相关参数

与模板测试相关的参数设置:

depthStencil: { //深度纹理,能否写入 depthWriteEnabled: true, //深度度操作函数 depthCompare: 'less', //深度纹理的格式 format: 'depth24plus', //正面操作函数, stencilFront:{ compare:"always";//详见https://gpuweb.github.io/gpuweb/#enumdef-gpucomparefunction failOp:"keep";//详见GPUStencilOperation depthFailOp:"keep"; passOp:"keep"; }; //背面操作函数 stencilBack:{}; stencilReadMask:0xFFFFFFFF; stencilWriteMask:0xFFFFFFFF; depthBias:0; depthBiasSlopeScale:0; depthBiasClamp:0; },stencilFront与stencilBack和webgl一样正、反面操作函数,ReadMask/WriteMask表示取stencil buffer的值时用按位与(&)操作,readMask取值范围也是0-255的整数,默认值为255,二进制位11111111,即读取的时候不对referenceValue和stencilBufferValue产生效果,读取的还是原始值。writeMask取值范围是0-255的整数,默认值也是255,即当修改stencilBufferValue值时,写入的仍然是原始值。

GPURenderPassEncoder.setStencilReference(reference)setStencilReference主要用来设置referenceValue,取值范围0~255.

二、渲染相关

1、原理:分两次渲染,第一次做写入模板值(关闭颜色写入),第二次使用模板值。

2、两次管线Depth/Stencil State参数设置

2.1、pipelineWriteMask设置(伪代码):

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", }, }, });2.2、pipelineUseMask设置:

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", }, }, });2.3、两次refValue设置:

2.3.1:第一次ref:

passEncoder.setStencilReference(1)2.3.2: 第二次ref:

passEncoder.setStencilReference(0)三、效果图:

四、全部代码:

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); }`;参考:



关键词:测试,模板,使用

74
73
25
news

版权所有© 亿企邦 1997-2025 保留一切法律许可权利。

为了最佳展示效果,本站不支持IE9及以下版本的浏览器,建议您使用谷歌Chrome浏览器。 点击下载Chrome浏览器
关闭