Sign in to follow this  

PixelShaders: out.depth = <something_bigger_than_1> vs discard();

This topic is 407 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've got the following code in my PIXEL shader

void PSmain(){
 // ....
    if(OUT.col.a == 0.0f){
         OUT.depth = 111111; // gl_FragDepth in GLSL
    }
}

when I was that "OUT.depth = 111111;" I thanked that "hay this can be replaced by discard():" but unfortunately it doesn't produce the same logical result.

Can somebody point at me what am I missing (Depth read/write is enabled)?

 

EDIT:

Hmm could it be If my comparison func is LessEqual and the depth value is clamped in the (0;1) range... I will check, all suggestions are still wellcome

Edited by imoogiBG

Share this post


Link to post
Share on other sites
What you're doing is the equivalent of alpha-testing in D3D9 or lower.  You don't say which D3D version you're using, but if it's D3D 9 or lower then you should probably just implement alpha testing (via SetRenderState commands) instead.  If you're on D3D 10 or higher, read-on.
 
Microsoft's own comment on this is at the MSDN page for Output-Merger Stage:

Direct3D 10 and higher does not implement an alpha test (or alpha testing state). This can be controlled using a pixel shader or with depth/stencil functionality.

 
Unfortunately they don't say what exactly they mean by "using a pixel shader", but if we look at the MSDN page for the HLSL clip function, we find the following:

Also, use the clip function to test for alpha behavior, as shown in the following example:

clip( Input.Color.A < 0.1f ? -1:1 );


This, then, is your answer: use neither, use clip instead.
 
The first reason is because it's Microsoft's own recommended way.
 
The second reason is because, even though it's unspecified, the shader compiler may be able to recognise the pattern and route it through any alpha-testing hardware that your GPU may have.

Share this post


Link to post
Share on other sites

This, then, is your answer: use neither, use clip instead.
 
The first reason is because it's Microsoft's own recommended way.
 
The second reason is because, even though it's unspecified, the shader compiler may be able to recognise the pattern and route it through any alpha-testing hardware that your GPU may have.


Isn't that kind of optimization performed on the IL? Both clip and discard emit a discard_nz.

Share this post


Link to post
Share on other sites

when I was that "OUT.depth = 111111;" I thanked that "hay this can be replaced by discard():" but unfortunately it doesn't produce the same logical result.

It's not logically the same. Discard/clip will always be there, whereas depth-based clipping depends on fixed function states...
 

In D3D land:
Whether or not there's a clipping plane at NDC Z=1 depends on whether you set D3D11_RASTERIZER_DESC::DepthClipEnable to TRUE or FALSE.
I'm also pretty sure that if not clipped, the Z value is clamped to the [0,1] range, and then goes through the viewport transform before being converted to the depth texture format:
Z = Viewport.MinDepth + Z * (Viewport.MaxDepth - Viewport.MinDepth)

 

Keep in mind that GL has it's weird [-1,1] NDC Z range...

Share this post


Link to post
Share on other sites

Using the discard instruction has an other benefit, it will mask the pixel thread out of execution while it continues to run on a wavegroup with non discarded pixels. That way, the GPU can ignore later texture and buffer fetch, if you use the depth value instead, even the discarded pixel will execute the full shader ( as there is no such thing as early exit unless every pixel in the wave take the short path ).

 

Writing depth in a shader will also impact the efficiency of early z-cull. it is true that discard also impact it, but hardware would likely be less impacted from the discard than the depth write.

Share this post


Link to post
Share on other sites

This topic is 407 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this