Skip to content

Depth textures are consistently read as 0 in compute shaders #30070

@Spiri0

Description

@Spiri0

Description

Meanwhile I try to solve problems myself and do PRs. But that always takes a lot of time because I still have a lot to learn about threejs.
It looks like depthTextures don't work in compute shaders. I noticed this when I tried to do culling in the GPU. The depth values ​​are all 0. This leads to all objects being viewed as covered and becoming invisible.
I thought of an example that makes the problem visible by trying to copy the depthTexture with a compute shader. And in fact, everything is 0, so a black image. This means the depthTexture really doesn't work in the compute shader. For further control, I simply used a scalar value in the texture var depth = 0.95; As expected, this delivers a gray texture that the postProcessing shader outputs.

In fragment shaders I use depthTexture: f32 But in compute shader you have to use texture_depth_2d because with f32 you get an error message. I suspect the problem is that multisampling is used, which is problematic in compute shaders.

Reproduction steps

Create a depthTexture with depthPass.
Create a compute shader that copies textures and assign the depthTexture to it as the texture to be copied.
Create a postProcessing shader that uses the copied depthTexture for control.

But the example is simpler, I've already done it

Code

It's not about copying depth textures in this way. This is just an example to get visual feedback as to whether the depthTexture is being read in the compute shader.
See example. I currently used the depthTexture directly in the postProcessing shader so that you can see what would be expected if the copy from the compute shader worked.

For the texture from the compute shader you have to use // 1 in the postProcessing shader and comment out // 2. Additionally depthTexture: f32, replace with depthTexture: texture_2d<f32>.

this.sceneDepthPass = depthPass( this.scene, this.camera );
this.sceneDepthPassTexture = this.sceneDepthPass.getTextureNode( 'depth' );

const copyDepthTextureWGSL = wgslFn(`
  fn computeWGSL( 
    writeTex: texture_storage_2d<rgba32float, write>,
    readTex: texture_depth_2d,
    index: u32,
    size: f32,
  ) -> void {
        
    var posX = index % u32( size );
    var posY = index / u32( size );
    var idx = vec2u( posX, posY );
        
    var depth = textureLoad( readTex, idx, 0 );
    textureStore(writeTex, idx, vec4<f32>( depth, depth, depth, 1 ) );
  }
`);

this.copyDepthTexture = new THREE.StorageTexture( window.innerWidth, window.innerHeight );
this.copyDepthTexture.type = THREE.FloatType;

this.computeCopyDepthTexture = copyDepthTextureWGSL( { 
  size: uniform( window.innerWidth ),
  readTex: this.sceneDepthPassTexture,
  writeTex: textureStore( this.copyDepthTexture ),
  index: instanceIndex 
} ).compute( window.innerWidth * window.innerHeight );

this.renderer.compute( this.computeCopyDepthTexture );

Live example

https://codepen.io/Spiri0/pen/LEPNdBd

Screenshots

No response

Version

171

Device

No response

Browser

No response

OS

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions