Search code examples
openglstencil-bufferculling

Early-stencil culling without early-z culling


I already have an idea of the answer but I need to be sure.

I render a scene in two pass. In the first pass, if depth test succeeds, I mark stencil bit as 1 :

glEnable(GL_STENCIL_TEST);
glStencilMask(GL_TRUE);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glStencilFunc(GL_ALWAYS, 1, GL_TRUE);

The second pass only writes where stencil is 1 :

glStencilFunc(GL_EQUAL, 1, GL_TRUE); // Pass test if stencil value is 1
glStencilMask(GL_FALSE); // Don't write anything to stencil buffer

In fact, this works properly but I expected a huge increase in terms of performance. The shader used in the second pass is particular : it uses discard and gl_FragDepth affectation. That makes early-z culling impossible. Fortunately, I'm only interested in early-stencil culling.

So there is my question : is there a way to take advantage from early-stencil culling without early-z culling ?


This thread is very related to this one, but I really need to use discard and gl_FragDepth affectation in the second shader...


Solution

  • There is no such thing as early stencil tests. Or early Z/depth tests for that matter. There are only early fragment tests, which happen to include the stencil and depth tests, but also other operations. They cannot be performed early in piecemeal; it's all early or all late.