0

I can toggle depth testing on/off in OpenGL using glEnable( GL_DEPTH_TEST ); But this switches the test on/off for the entire draw call.

I would like to control the test on a per-fragment basis.

This is to achieve the following effect: in a chess-board pattern, half the pixels of the primitive are potentially occluded, but the other half are always drawn, even if there is an occluding object in the frame-buffer that is nearer to the camera.

To illustrate, see this example where only half the pixels of the pyramid are potentially occluded by the box in front of it.

Note that the red box is drawn first, and is already in the frame-buffer when the green pyramid is drawn.

Also note: I will draw the object with the special depth test last, so the case where the red box is drawn first would not happen.

For my purposes, all objects drawn this way are convex and will never occlude itself.

illustration of the effect

I know how to get a chessboard pattern in my fragment shader:

                float xm2 = mod( gl_FragCoord.x, 2.0 );
                float ym2 = mod( gl_FragCoord.y, 2.0 );
                if ( int(xm2) != int(ym2) )
                        discard;

But in my case, I don't want to flat out discard on a per-fragment basis, I just want the depth test toggled on a per-fragment basis.

I am targeting OpenGL-ES 3.0.

Bram
  • 7,440
  • 3
  • 52
  • 94
  • 4
    That is simply not how the depth test works. What you ask for is just not possible. You can achieve such an effect by doing two draw calls and switching the depth test in between, drawing only one group of your checkerboard pattern each (i.e. using the stencil buffer, discard in the FS would also work, is just much less efficient). Another approach might be just setting `gl_FragDepth` to 0 for those fragments you want to always pass the test . – derhass Oct 15 '19 at 22:48
  • "*To illustrate, see this example where only half the pixels of the pyramid are potentially occluded by the box in front of it.*" Well, what exactly do you want to happen if you draw the objects in the opposite order? – Nicol Bolas Oct 15 '19 at 22:52
  • And what should happen if part of the object overlaps itself? – Nicol Bolas Oct 15 '19 at 23:26
  • I think the X of this XY problem is a situation where the OP wants to be able to partially view an object even though it's obscured by foreground stuff. e.g. When taking a shot in a golf game, you want to see the ball even if there's scenery in front of it. I think that @derhass `gl_FragDepth` suggestion will solve the OPs problem and should be offered as an andwer. – Columbo Oct 16 '19 at 11:42
  • @derhass Your first suggestion worked for me. If you write it up I will mark it as the answer. Setting depth to 0 was not suitable for my application, as I need the z-buffer intact for object-picking. – Bram Oct 17 '19 at 15:24
  • What if you wrote the depth (gl_FragCoord.z) into the alpha channel for every fragment, and then use EXT_shader_framebuffer_fetch to get the alpha value behind the current fragment (i.e. the previously written depth)? I might be misunderstanding how both of these work :p – Andrea Dec 05 '19 at 21:20

1 Answers1

0

This is easily achieved by drawing the (red) mesh twice:

  • First draw it normally, all fragments, with depth test enabled.
  • Next draw it again, without depth-test, and discarding half the fragments.

The solution was prompted by the comment made by @derhass.

Bram
  • 7,440
  • 3
  • 52
  • 94