6
$\begingroup$

In a project where I want to select visible objects using using a screen-aligned polygon and various conditions for what "selected" means with regards to that polygon, I'm basically drawing the polygon into the stencil buffer and then drawing the individual objects with stencil testing and using occlusion queries for measuring how much the object and selection polygon overlap in screen space.

This works pretty well. But imagine my surprise when stumbling over the statement that, according to the OpenGL Wiki, occlusion queries supposedly don't actually care about the stencil test:

They detect whether the scoped drawing commands pass the depth test and if so, how many samples in those triangles passed the Depth Test. Note that the sample count and pass/fail are based only on the depth test. The Stencil Test, or fragment shader discard is irrelevant with queries, even though they technically happen after the fragment shader...

This clearly contradicts my practical experience and made me a little worried/confused. I took a look at the specification (both the newest 4.6 core as well as good old 2.0, which we're actually targetting in our project for compatibility) and it also says that occlusion queries count the number of samples passing the depth test. It does however not make such a definite statement as the wiki pertaining to the stencil test. And since the depth test technically comes after the stencil test, I'm not entirely sure if that maybe already includes the stencil test anyway and the wording of the specification is simply using the last stage for convenience.

So, my question is, do occlusion queries respect the stencil test (or any other earlier per-fragment tests, I'm actually using scissor testing with occlusion queries in another unrelated algorithm)? I see a few possiblities here:

  • They do definitely respect all tests and the wording in the spec is just using the last test for convenience reasons. This would mean that fragments failing earlier tests and thus not even reaching the depth test would technically count as failing that. I'm not sure this comes too clearly out of the specification's wording, though, but maybe I'm missing something and people better-versed in the intricacies of specification laywering can shed more light on this. This would also mean the above Wiki article is slightly misleading (or I just misread it).
  • They definitely don't respect the stencil test and really only care about the depth test. This would mean that a fragment failing the stencil test would have to still go through depth testing. It would also mean that what I experience on my specific hardware (it's an nVidia GeForce GTX 1xxx) is clearly a bug.
  • Or this might simply not be a well-specified part of the API and it leaves room for interpretation. This might be rather odd, though, as this isn't a particularly rarely used feature I'd suppose.

(In practice, I could definitely restrucure my algorithm to use depth testing instead, but it is a problem that makes me curious about the theoretic implications and underpinnings nevertheless.)

$\endgroup$
0

1 Answer 1

4
$\begingroup$

The specification has been clarified on this point, as has the Wiki article. So let's explain that.

The new wording in the spec says:

the samples-passed count is incremented for each fragment still being processed after the depth test

This is better wording, as it makes clear that the order in which things are processed matters. OpenGL defines the depth test as happening after the stencil test, scissor test, etc. So this wording clearly states that the depth test, and everything before it, matter.

So it does respect the stencil test. And fragment shader discard, since the FS is specified to come before all of these tests.

Well, unless you force these tests to happen before the fragment shader. If you do that, then discarding the fragment in the FS will not prevent that fragment from being counted by the occlusion query. So if you enforce early tests, you lose the right to use discard to affect the occlusion query count.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.