WebGPU中写入存储纹理后读取始终返回相同值的问题求助
WebGPU存储纹理跨渲染通道读写异常问题
我尝试在第一个渲染通道写入存储纹理,第二个通道读取该纹理,但无论第一个通道写入什么值,第二个通道读取到的始终是默认0值。预期第二个通道读取到1.0,画面显示红色,但实际全黑。
初始化代码
const storageTexture = this._device.createTexture({ dimension: '2d', size: [512, 512, 1], format: 'r32float', usage: GPUTextureUsage.STORAGE_BINDING }) const textureView = storageTexture.createView({ dimension: '2d-array', format: 'r32float', }) const bindGroup = this.device.createBindGroup({ layout: this.lightsBindGroupLayout, entries: [ .....irrelevant stuff { binding: 3, resource: textureView, }, ], }) const firstPass = commandEncoder.beginRenderPass(this._renderPassDescriptor) ...... firstPass.setBindGroup(2, bindGroup) ...... firstPass.end() const secondPass = commandEncoder.beginRenderPass(this._renderPassDescriptor) ..... secondPass.setBindGroup(3, bindGroup) ..... secondPass.end()
第一个渲染通道片段着色器
@fragment fn fragment_main(in: VertexOutput) -> @location(0) float4 { textureStore(texture, vec2u(0, 0), 0, vec4f(1, 1, 1, 1)); return in.position; }
第二个渲染通道片段着色器
@fragment fn fragment_main(in: VertexOutput) -> @location(0) float4 { let a = textureLoad(texture, vec2u(0, 0), 0); return vec4(a.r, 0, 0, 0); }
排查方向
- 纹理视图维度不匹配:创建的纹理是
2d维度,但纹理视图用了2d-array,虽然单图层数组理论上可行,但建议把视图维度改成2d,避免维度不兼容导致读写失效。 - 绑定组布局的访问权限配置:检查
lightsBindGroupLayout中binding 3的配置,写入通道需要设置storage访问权限为write,读取通道需要设置为read;如果两个通道共用同一布局,要确保权限支持读写。 - 显式添加内存屏障:在两个渲染通道之间插入内存屏障,确保写入操作完成后再执行读取:
commandEncoder.memoryBarrier({ type: 'texture', textures: [storageTexture] }); - 纹理使用标志补充:尝试给纹理添加
GPUTextureUsage.TEXTURE_BINDING标志,虽然STORAGE_BINDING已支持存储读写,但部分设备可能需要显式声明。 - 着色器绑定匹配检查:确认着色器中
texture变量的绑定声明与绑定组完全对应,比如第一个通道的着色器需有@group(2) @binding(3),第二个通道需有@group(3) @binding(3),确保组索引和绑定号无偏差。 - 验证第一个通道执行状态:修改第一个通道的片段着色器直接输出红色,确认该通道是否正常执行、是否有片段被处理,避免因通道未运行导致写入操作未执行。
内容的提问来源于stack exchange,提问作者Hauuagdb Hshg
相关产品推荐
相关产品推荐

