How does the "Hardware Occlusion Queries" culling work?

There is this nice explanation of UE4s culling by [MENTION=4894]Tim Hobson[/MENTION]:

It says

But it can’t be true that only the bounding box is used for this culling.

I’ve tested the culling with a small test case. Here you have a cone and a cube:

The cube is behind the cones bounding box, so if the bounding box would be the only thing that is considered for culling, the cube would have to be culled. But of course it isn’t culled, that would be wrong in this case since the cone is not occluding the cube.

Only in this case, when the cube is really behind the cone, the cube should be culled:

Regarding the bounding box nothing has changed though.

I’ve tested it with the “FreezeRendering” command and the culling works correctly, if the cube is behind the cone, it is culled:

So there has to be something else than the bounds that determines if the cube should be culled or not. It’s not the bounding box or the view frustum in this case. What is it? :confused:

Occlusion queries render bounding boxes of objects after normal scene is rendered. Then query simply ask would bounding box mesh rendering resulted any visible pixels. So test is done against precise depth buffer. Bounding box of object is conservative so it won’t ever result false positives.(expect when camera moves and renderer use previous frame data)


It would be nice if it would work like that, but for some reason it doesn’t as far as I can tell.

This is a different test case:

There is the ground, which is just a stretched cube. Then there is the cone, which is just a cone. And then there is the white wall, which is also just a stretched cube. You see that the wall cube is quite big in Z.

Now take a look at this gif:

First I am looking at the wall. Then I’m turning the camera so that it looks straight down, only the ground is visible. I’m calling “FreezeRendering” and looking back up at the wall. And you see that the wall is not occluded by the ground, even though it was completely hidden behind the ground when I called “FreezeRendering”. The cone is not rendered, so the cone was occluded correctly. If the wall would count as occluded once no pixel of its bounding box is visible, then it would not have been rendered. But it is rendered, and I don’t understand why :confused:

Cone is not occluded it’s frustum culled. I know there is problems with large meshes. I have seen that out sea plane is not getting occlusion culled for some reason too. I guess it’s related to how bounding volume is used. If ue4 use bounding spheres instead of boxes it would expain that.

Looks like this particular case of the large vertical wall not being occlusion culled can be traced down to the fact, that occlusion query is not being run for bounds, that intersect near clipping plane.

But bounding box of the wall is not intersecting the near plane. Is that test done with bounding sphere?

Nope, it is done with bounding box, and the wall does intersect near plane, when camera is tilted enough.

Yup you are right. Maybe test should be box vs sphere which is centered in camera position and radius would be near distance instead of this box vs plane.