Recommended Posts

I want to add a depth-only pass before my forward and deferred shading. In order to do this, I bind a nullptr as PS and a nullptr as RTV. But I get huge amounts of flickering and background leaking in a static scene? Is this z-fighting?

I use D3D11_COMPARISON_LESS_EQUAL. The VSs are slightly different in the sense that the depth VS uses an object_to_projection transform whereas the other VSs use a object_to_view, view_to_projection transform chain. The object_to_projection, however, is constructed by multiplying the same matrices on the CPU.

Edited September 3, 2017 by matt77hias

0

Share this post

Link to post

Share on other sites

For a Z prepass to work correctly, the part of your VS that computes the position needs to exactly match between your Z-only pass and your main pass. This means that they must use the same matrix or chain of matrices: what you described will result in small variations due to finite floating point precision, which is why you're getting Z fighting. I would recommend using the object_to_view + view_to_project in your depth prepass shader, as this has been shown to result in improved precision compared to a pre-composed view * projection matrix.

Share this post

Link to post

Share on other sites

MJP explained it well, your VS math has to match exactly due to floating point inconsistencies

What I wanted to add, is that a depth prepass does no performance benefit to a deferred shader. A depth prepass has a cost (CPU wise all the commands issued twice, GPU wise vertex shader is ran twice, rasterizer works twice as hard); and it is only an optimization if this cost is lower than the cost of running expensive pixel shaders multiple times for the same pixel.

This can be true for forward shading, but for Deferred Shading, this is rarely the case as the pixel shaders tend to be very cheap (sample albedo, sample some other parameters, calculate normals, finally export to render target)

Link to post

Share on other sites

MJP explained it well, your VS math has to match exactly due to floating point inconsistencies

What I wanted to add, is that a depth prepass does no performance benefit to a deferred shader. A depth prepass has a cost (CPU wise all the commands issued twice, GPU wise vertex shader is ran twice, rasterizer works twice as hard); and it is only an optimization if this cost is lower than the cost of running expensive pixel shaders multiple times for the same pixel.

This can be true for forward shading, but for Deferred Shading, this is rarely the case as the pixel shaders tend to be very cheap (sample albedo, sample some other parameters, calculate normals, finally export to render target)

Apparently, Frostbite uses a depth pre-pass before their GBuffer pass.

Share this post

Link to post

Share on other sites

Apparently, Frostbite uses a depth pre-pass before their GBuffer pass.

I doubt they do that anymore, Z-pre passes have been phased out after the transition to modern consoles. It was worth it on the previous generation because polycount could scale far better than memory bandwidth, but that's no longer the case today.

-1

Share this post

Link to post

Share on other sites

For deferred it totally depends on your content, your G-Buffer depth, your hardware, how well you can sort front-to-back, etc. It's certainly less of an obvious win vs. the forward case, but my no means is it assured to be worthless (FWIW UE4 still uses a Z prepass). You just have to be careful to profile, and judge whether or not it's worth the CPU cost of submitting your geometry twice. As a very talented programmer once said "a Z prepass is a day-to-day decision, not a lifestyle choice."