Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sometimes depth prepass inaccuracies leak the background color. #101118

Open
basicer opened this issue Jan 4, 2025 · 2 comments
Open

Sometimes depth prepass inaccuracies leak the background color. #101118

basicer opened this issue Jan 4, 2025 · 2 comments

Comments

@basicer
Copy link
Contributor

basicer commented Jan 4, 2025

Tested versions

  • Reproducible in master
  • Reproducible in 4.3stable

System information

Windows 11 - Vulkan 1.3.280 - Forward+ - Using Device #0: NVIDIA - NVIDIA GeForce RTX 3070 Ti

Issue description

When using a shader that writes to DEPTH along with depth prepass, sometimes fragments are lost.

Image

Steps to reproduce

  1. Load the attached project into the editor
  2. The scene is a white sphere, intersected by a green box with a yellow sphere in the center.
  3. Set the useless_work variable of the shader to get a low frame rate.
  4. Move the camera around inside the green box, from time to time red static will appear on the green box where the clear color leaks though.

Minimal reproduction project (MRP)

prepass-leak.zip

@clayjohn
Copy link
Member

clayjohn commented Jan 4, 2025

I can't reproduce this problem on an M2 Macbook which indicates it is a GPU/driver-specific.

I strongly suspect this is an issue of NVidia doing very aggressive shader optimizations that end up causing a slight difference between the shader used for the depth prepass and the shader used for the render pass.

This issue commonly arises in Vertex shaders with gl_Position. In that case you can use the invariant qualifier. Newer versions of GLSL also have precise for situations like your shader.

I suspect that this could be solved by exposing precise to user shaders.

That being said, I don't think your shader gains anything by using the depth prepass. The depth prepass is nice because it allows you to avoid running the fragment shader for occluded fragments. But, writing to DEPTH fully disables that optimization, so you get no benefit from using the prepass. In fact, since the raymarch is expensive, you are essentially doubling the cost of your shader for no practical gain.

@Calinou
Copy link
Member

Calinou commented Jan 4, 2025

That being said, I don't think your shader gains anything by using the depth prepass. The depth prepass is nice because it allows you to avoid running the fragment shader for occluded fragments. But, writing to DEPTH fully disables that optimization, so you get no benefit from using the prepass. In fact, since the raymarch is expensive, you are essentially doubling the cost of your shader for no practical gain.

Is there a way to reliably disable the depth prepass on a single material without making it go through the transparent pipeline? I couldn't figure out a way to do this, other than using if (false) discard; which is likely slower than it needs to be.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants