WebGPU阴影映射(shadowMapping)示例添加纹理的实现问题求助
问题:为WebGPU阴影映射示例添加纹理时的绑定兼容性错误
背景
我在WebGPU官方示例库的阴影映射示例中尝试添加纹理,编写了loadTex0方法加载纹理:
async loadTex0(texturesPaths, device) { return new Promise(async (resolve) => { const response = await fetch(texturesPaths[0]); const imageBitmap = await createImageBitmap(await response.blob()); this.texture0 = device.createTexture({ size: [imageBitmap.width, imageBitmap.height, 1], format: 'rgba8unorm', usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT, }); var texture0 = this.texture0 device.queue.copyExternalImageToTexture( {source: imageBitmap}, {texture: texture0}, [imageBitmap.width, imageBitmap.height] ); resolve() }) }
尝试添加纹理到渲染绑定组并更新WGSL片段着色器后,先后出现以下错误:
第一个错误日志
Binding doesn't exist in [BindGroupLayout]. - While validating that the entry-point's declaration for @group(0) @binding(3) matches [BindGroupLayout] - While validating the entry-point's compatibility for group 0 with [BindGroupLayout] - While validating fragment stage ([ShaderModule], entryPoint: ). - While validating fragment state. - While calling [Device].CreateRenderPipeline([RenderPipelineDescriptor]).
第二个错误日志
The sample type in the shader is not compatible with the sample type of the layout. None of the supported sample types (Float|UnfilterableFloat) of [Texture] match the expected sample types (Depth). - While validating entries[3] as a Texture. Expected entry layout: { binding: 3, visibility: ShaderStage::(Vertex|Fragment), texture: { sampleType: TextureSampleType::Depth, viewDimension: TextureViewDimension::e2D, multisampled: 0 } } - While validating [BindGroupDescriptor] against [BindGroupLayout] - While calling [Device].CreateBindGroup([BindGroupDescriptor]).
解决建议
修正绑定组布局与着色器的匹配问题
第一个错误表明着色器中声明的@group(0) @binding(3)在绑定组布局中没有对应条目。需要:- 检查渲染管线的
bindGroupLayouts配置,确保已添加对应绑定号的条目,且类型与纹理一致(比如颜色纹理对应sampleType: "float")。 - 保证着色器中的绑定号、绑定组布局中的条目、绑定组创建时的条目三者完全对应,无错位。
- 检查渲染管线的
修正纹理采样类型不匹配问题
第二个错误是因为绑定3的布局预期是深度纹理,但你传入的是RGBA8颜色纹理——这说明你误将颜色纹理绑定到了原阴影深度贴图的位置:- 为自己的颜色纹理新增一个独立的绑定位置(比如绑定4),不要复用深度纹理的绑定槽位。
- 更新绑定组布局,新增颜色纹理和采样器的条目:
// 示例:在原有绑定组布局中新增条目 const bindGroupLayout = device.createBindGroupLayout({ entries: [ // 保留原有的所有条目... { binding: 4, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: "float", viewDimension: "2d" } }, { binding: 5, visibility: GPUShaderStage.FRAGMENT, sampler: { type: "filtering" } } ] }); - 在WGSL着色器中声明对应的绑定:
@group(0) @binding(4) var myTexture: texture_2d<f32>; @group(0) @binding(5) var mySampler: sampler; - 创建绑定时,将你的
texture0.createView()和采样器对应到新增的绑定位置。
优化纹理加载代码
原loadTex0方法无需额外包裹Promise(async函数本身返回Promise),可简化为:async loadTex0(texturesPaths, device) { const response = await fetch(texturesPaths[0]); const imageBitmap = await createImageBitmap(await response.blob()); this.texture0 = device.createTexture({ size: [imageBitmap.width, imageBitmap.height, 1], format: 'rgba8unorm', usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST, // 若无需将该纹理作为渲染附件,可移除RENDER_ATTACHMENT }); device.queue.copyExternalImageToTexture( { source: imageBitmap }, { texture: this.texture0 }, [imageBitmap.width, imageBitmap.height] ); }
内容的提问来源于stack exchange,提问作者Nikola Lukic
相关产品推荐
相关产品推荐

