2

Do occlusion queries still work if I disable depth testing altogether when the obstacle set is known a priori to be strictly in-between the camera and the object to be tested? This is an attempt to improve performance, as, logically, I don't need complex z-tests if none of the occluders are behind the occludee.

I'm using the following commands to initialize color/depth/stencil buffers:

SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 0);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 0);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 0);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
...
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

glDisable(GL_CULL_FACE);

glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);

glEnable(GL_STENCIL_TEST);
glStencilMask(0x00000001);
...
glClear(GL_STENCIL_BUFFER_BIT);
user2464424
  • 1,536
  • 1
  • 14
  • 28
  • Why not try it and find out? – Colonel Thirty Two Oct 16 '14 at 18:19
  • Occlusion queries only count samples that pass the depth test; the stencil buffer is irrelevant. https://www.opengl.org/wiki/Occlusion_Query#Occlusion_queries – Colonel Thirty Two Oct 16 '14 at 18:47
  • @ColonelThirtyTwo I accidentally posted the previous comment. Will rewrite it in a sec. – user2464424 Oct 16 '14 at 18:49
  • @ColonelThirtyTwo Because I don't know how the situation is handled by Opengl. It may work, it may not work, it may work sometimes... And google isn't telling me "hey you cannot use queries with depth testing disabled" so I'm better off asking people on the internet. – user2464424 Oct 16 '14 at 18:50
  • 1
    I found this page that states: "It returns as its result the number of samples that pass the depth and stencil tests". https://www.opengl.org/registry/specs/ARB/occlusion_query.txt In multiple occasions in that page it looks like the stencil and depth are both cooperating to calculate the result. – user2464424 Oct 16 '14 at 18:55
  • Huh, looks like there's `ARB_occlusion_query` and a more recent `ARB_occlusion_query2`. Didn't know that. – Colonel Thirty Two Oct 16 '14 at 18:58

2 Answers2

2

The most conclusive document is the latest OpenGL spec. From the OpenGL 4.5 spec, section "17.3.7 Occlusion Queries", on page 476 (with emphasis added by me):

Occlusion queries use query objects to track the number of fragments or samples that pass the depth test.

When an occlusion query is active, the samples-passed count is incremented for each fragment that passes the depth test.

Therefore, the real question becomes: What does "pass the depth test" mean? Does a pixel pass the depth test if there is no depth test? And how does the stencil test come into play?

The key is that the stencil test is applied before the depth test, which is the behavior defined in the spec. So only fragments that pass the stencil test will go through the depth test, and will therefore be counted in the occlusion query. Or in other words, only fragments that pass both the stencil and depth test are counted.

One approach that will definitely work is that you enable the depth test, and let all fragments pass the depth test. This will then count all the fragments that passed the stencil test. The settings to use for this are:

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS);

glEnable(GL_STENCIL_TEST);
...

Now, will it also work as desired without having a depth buffer, or with the depth buffer disabled? The first part of this is answered at the end of section "17.3.6 Depth Buffer Test":

If there is no depth buffer, it is as if the depth buffer test always passes.

In this case, the answer is yes, you can use an occlusion query without a depth buffer, and it will count the fragments that pass the stencil test.

The second case is covered earlier in section "17.3.6 Depth Buffer Test":

When disabled, the depth comparison and subsequent possible updates to the depth buffer value are bypassed and the fragment is passed to the next operation.

Figure 17.1 in the spec shows "Occlusion Query" as the next operation following "Depth Buffer Test". Therefore, all fragments that passed the earlier tests (including stencil) will be counted by the occlusion query if the depth test is disabled.

And the final answer is: YES, you can use occlusion queries with just a stencil test.

Acknowledgement: Latest version revised based on feedback by @jozxyqk and @user2464424

Community
  • 1
  • 1
Reto Koradi
  • 53,228
  • 8
  • 93
  • 133
  • I like your solution of a pass-through depth test just to make the documentation happy :p I think it would work. Only consideration, as jozxyqk said: "With the depth test off, I'd assume all fragments pass" which is true on an average object-displaying scenario (i tried it in my system, triangles still get rendered, but in random z-order). It all depends on how occlusion queries are coded. Do they consider a disabled depth buffer as an equivalent glDepthFunc(GL_ALWAYS)? Is it manufacturer-dependent? Humanity will never know. I will test then. – user2464424 Oct 17 '14 at 09:09
  • @user2464424 my assumption would be that the counter is inserted in the rendering pipeline after the depth test. Regardless of the depth test being enabled or any previous tests before the counter, if the fragment is still alive after the depth test part of the pipeline, it's counted. Maybe [these pipeline diagrams](http://openglinsights.com/pipeline.html) give a better picture. – jozxyqk Oct 17 '14 at 11:04
  • @jozxyqk After some more thought and digging, that sounds completely right. And I believe I found all the spec language to support that this is indeed the behavior. See the thoroughly revised version of the answer above. – Reto Koradi Oct 17 '14 at 15:40
  • @RetoKoradi Very well done. For now I accept your answer, but I'm yet to do on-field testing, will report back if problems arise. – user2464424 Oct 17 '14 at 16:15
  • @RetoKoradi Yes it does work. Was a nightmare to demolish half of my codes just to display and debug that stencil, but in the end it worked. For science. – user2464424 Oct 17 '14 at 20:27
1

From www.opengl.org/registry/specs/ARB/occlusion_query.txt

This extension solves both of those [HP_occlusion_test] problems. It returns as its result the number of samples that pass the depth and stencil tests

...

Exactly what stage in the pipeline are we counting samples at?

RESOLVED: We are counting immediately after both the depth and stencil tests, i.e., samples that pass both. Note that the depth test comes after the stencil test, so to say that it is the number that pass the depth test is sufficient; though it is often conceptually helpful to think of the depth and stencil tests as being combined, because the depth test's result impacts the stencil operation used.

From www.opengl.org/registry/specs/ARB/occlusion_query2.txt

This extension trivially adds a boolean occlusion query to ARB_occlusion_query

With the depth test off, I'd assume all fragments pass. From the above it sounds like you can rely on the stencil test alone affecting occlusion query results, which is at odds with the following from opengl.org/wiki.

The stencil test, alpha test, or fragment shader discard​ is irrelevant with queries

The extension does not mention discard. The occlusion query section in GL 4.5 core/compat specs only mentions counting fragments that pass the depth test. If the fragment doesn't make it to the depth test, then I guess it isn't considered to pass it.

A bit of a side note, but I think it's also worth mentioning the early fragment test.

jozxyqk
  • 16,424
  • 12
  • 91
  • 180