2

In Open GL, is it possible to render a polygon with a regular depth test enabled, but when the depth buffer value is actually written to the depth buffer, I want to write a custom value?

(The reason is I'm rendering a particle system, which should be depth-tested against the geometry in the scene, but I want to write a very large depth value where the particle system is located, thus utilizing the depth-blur post-processing step to further blur the particle system)

Update To further refine the question, is it possible without rendering in multiple passes?

Viktor Sehr
  • 12,825
  • 5
  • 58
  • 90
  • 1
    If the question is "is it possible" then the answer is yes. Render your scene in a FBO, use its depth texture attachment to do a "manual" depth test in your fragment shader (`discard`ing fragments that would fail the depth test) and output an arbitrary value of depth into another depth buffer (possibly initialized by blitting from the FBO, if you want). No guarantees on the performances of all of this... – peppe Feb 20 '17 at 12:34
  • Thank's updated the question. – Viktor Sehr Feb 20 '17 at 14:14
  • I've never used ARB_conservative_depth, but it could solve your problem. – pleluron Feb 20 '17 at 15:49

3 Answers3

3

You don't.

OpenGL does not permit you to lie. The depth test tests the value in the depth buffer against the incoming value to be written in the depth buffer. Once that test passes, the tested depth value will be written to the depth buffer. Period.

You cannot (ab)use the depth test to do something other than testing depth values.

ARB_conservative_depth/GL 4.2 does allow you a very limited form of this. Basically, you promise the implementation that you will only change the depth in a way that makes it smaller or larger than the original value. But even then, it would only work in specific cases, and then only so long as you stay within the limits you specified.

Enforcing early fragment tests will similarly not allow you to do this. The specification explicitly states that the depth will be written before your shader executes. So anything you write to gl_FragDepth will be ignored.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Thank you, basically conservative depth would have helped me, but as I'm opengl es 3.0 I will just have to rethink my algorithm – Viktor Sehr Feb 21 '17 at 19:46
1

One way to do it in a single pass is by doing the depth-test "manually".

Set glDepthFunc to GL_ALWAYS

Then in the fragment shader, sample the current value of the depth buffer and depending on it discard the fragment using discard;

To sample the current value of the depth buffer, you either need ARM_shader_framebuffer_fetch_depth_stencil (usually on mobile platforms) or NV_texture_barrier. The later however will yield undefined results if multiple particles of the same drawcall render on top of each other, while the former in this case will use the written depth value of the last particle rendered at the same location.

You can also do it without any extension by copying the current depth buffer into a depth texture before you render the particles and then use that depth texture for your manual depth test. That also avoids that particles which render on top of each other would interfere, as they'll all use the old depth value for the manual test.

matthias_buehlmann
  • 4,641
  • 6
  • 34
  • 76
0

You can use gl_FragDepth in fragment shader to write your custom values.

gl_FragDepth = 0.3;

https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/gl_FragDepth.xhtml

Alex Sokolowski
  • 222
  • 2
  • 4
  • 3
    If you write to gl_FragDepth, this value will also be used to do the depth comparison. The question ask explicitly for a way to modify the depth written, but not the depth testing itself. Afaik, it is not possible to use different values for testing and writing unless one renders the geometry twice. – BDL Feb 20 '17 at 11:25