You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)在绑定组布局中没有对应条目。需要:

    1. 检查渲染管线的bindGroupLayouts配置,确保已添加对应绑定号的条目,且类型与纹理一致(比如颜色纹理对应sampleType: "float")。
    2. 保证着色器中的绑定号、绑定组布局中的条目、绑定组创建时的条目三者完全对应,无错位。
  • 修正纹理采样类型不匹配问题
    第二个错误是因为绑定3的布局预期是深度纹理,但你传入的是RGBA8颜色纹理——这说明你误将颜色纹理绑定到了原阴影深度贴图的位置:

    1. 为自己的颜色纹理新增一个独立的绑定位置(比如绑定4),不要复用深度纹理的绑定槽位。
    2. 更新绑定组布局,新增颜色纹理和采样器的条目:
      // 示例:在原有绑定组布局中新增条目
      const bindGroupLayout = device.createBindGroupLayout({
        entries: [
          // 保留原有的所有条目...
          {
            binding: 4,
            visibility: GPUShaderStage.FRAGMENT,
            texture: { sampleType: "float", viewDimension: "2d" }
          },
          {
            binding: 5,
            visibility: GPUShaderStage.FRAGMENT,
            sampler: { type: "filtering" }
          }
        ]
      });
      
    3. 在WGSL着色器中声明对应的绑定:
      @group(0) @binding(4) var myTexture: texture_2d<f32>;
      @group(0) @binding(5) var mySampler: sampler;
      
    4. 创建绑定时,将你的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 01:49:53