3
\$\begingroup\$

Can a fragment shader make per-fragment decisions on whether the fragment updates the depth buffer or not, even if the fragment is not discarded and the color is written?

\$\endgroup\$
3
  • \$\begingroup\$ I think if you kill the fragment, everything is thrown away.. \$\endgroup\$ Commented Sep 8, 2011 at 11:24
  • \$\begingroup\$ use discard opcode in GLSL (if OpenGL). Warning that's not performant. \$\endgroup\$
    – Ellis
    Commented Sep 8, 2011 at 13:24
  • \$\begingroup\$ discard will discard the colour information too. \$\endgroup\$
    – Will
    Commented Sep 8, 2011 at 14:16

1 Answer 1

2
\$\begingroup\$

I don't think so. If you don't write into gl_FragDepth, OpenGL writes the interpolated depth. There is no magic "discard" value you could write into gl_FragDepth and like you yourself say, discard also discards colors.

And as a side note I'm also sure to have read, that if you write into gl_FragDepth in one dynamic branch of a shader, you have to write into it in all branches, otherwise the results are undefined. But maybe this has changed on newer hardware.

EDIT: Maybe you can use a (though quite strange) workaround using ARB_shader_stencil_export extension (or perhaps some newer core version supporting it). In the first pass disable depth update (depth mask false) and write a special stencil value (maybe 1) for the fragments you want to write the depth for and another (0) for the ones you don't. Then in the second pass you draw the scene/objects/whatever again enabling depth write and configuring the stencil test to only pass where the stencil buffer is set. So only the depth of the fragments you (dynamically) selected are written. But the two-pass nature of this might bring some problems whith "underdraw" that shouldn't be, as in the first pass no fragment writes any depth value.

\$\endgroup\$
4
  • \$\begingroup\$ this was my understanding and I was hoping someone would prove me wrong ;) \$\endgroup\$
    – Will
    Commented Sep 8, 2011 at 20:44
  • \$\begingroup\$ yeah at the moment I have a two pass approach, simply one with glDepthMask(GL_TRUE) and the second with GL_FALSE. Its straightforward, but I'd like to move the glDepthMask into the shader so I can do it all in one pass. \$\endgroup\$
    – Will
    Commented Sep 8, 2011 at 21:00
  • \$\begingroup\$ @Will So in your case it seems you don't need to decide dynamically for each fragment if it should write to depth or not? Then it might be faster anyway to not bloat the shader with conditional code for something you know beforehand. \$\endgroup\$ Commented Sep 8, 2011 at 21:07
  • \$\begingroup\$ My fragments are pretty 33/33/33 between writing depth, not writing depth and discarding. So I have to have two passes with the same geometry and textures that cause this decision, only doing 33% updates each time. \$\endgroup\$
    – Will
    Commented Sep 8, 2011 at 21:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .