Advertisement

Occluder from AABB, near plane 'fix'?

Started by October 27, 2024 11:53 AM
4 comments, last by All8Up 12 hours, 51 minutes ago

Hi,

I've implemented Occlusion culling by selecting a number of big occluders and extracting planes from their AABB, forming an occlusion volume. In principe this works, but the thing is that the near plane(s) I'm using have a ‘d’ based on the front of the occluder instead of the back, meaning that the intended culling only happens when the camera is super close to the near plane(s). I've added some screenshots to illustrate:

  1. view before constructing the debug drawn edges of the planes
  2. hiding the occluder’s meshrenderer and debug draw the 5 planes (in this specific case)
  3. moving closer to the near plane, stuff gets occluded
  4. moving to almost the exact edge of the near plane
  5. occluder planes visualized (the edges), pDebugPoints in the code

This is the code I'm using: https://pastebin.com/DkdaGAx2.

I'm basically trying to find a way to let the near plane(s) distance (plane.d) be based on the rear of the occluder instead of the front. Any ideas on how I could achieve that?

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

cozzie said:
I'm basically trying to find a way to let the near plane(s) distance (plane.d) be based on the rear of the occluder instead of the front. Any ideas on how I could achieve that?

Just some ideas:

You could use a special pixel shader for back facing triangles and modify the depth value to be the near clipping plane. (But changing depth disables HW optimizations and has a cost.)
Maybe there is a better trick for that, but idk.

You could do polygon clipping on the box to find the polygon which cuts it at the near plane, then render this polygon together with the box. (Similar to the general frustum clipping done in software rendering.)
Could run entirely on GPU with compute shaders generating indirect draws.

cozzie said:
but the thing is that the near plane(s) I'm using have a ‘d’ based on the front of the occluder instead of the back, meaning that the intended culling only happens when the camera is super close to the near plane(s).

I'm confused. I assume if you render both front and back faces of the occluder box, culling should work no matter if the near plane cuts a hole into the front faces or not. The back faces should still cull the buildings behind them, and failure cases should only affect the geometry inside the box, e.g. the rooms inside the building which gives the box.

Advertisement

Thanks for the reply @joej . The thing is that this is all happening on CPU side, not perse about rendering and depth read/writes.

I just take the worldspace AABB and the camera position, and using those, I construct N occlusion planes for the AABB, defining the invisible volume. So I can do plane/AABB (or sphere) intersects with groups of objects against that volume (and discard them from drawing).

The occluder box is normally rendered ‘as usual’, as there's no depth buffer involved, I just take the 8 corners of the AABB in worldspace, to construct the planes.
I'm basically looking for a way to ‘push’ the volume further so the occluder's volume is not part of what's rejected, which I believe is now the case, because there's volume of the occluder itself, included (if that makes sense 🙂)

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Now i'm even more confused : )
It's it all on CPU, but then you also say occluder boxes are rendered.

Do you try to cull what's behind the box, e.g. other buildings?
Or do you try to cull what's inside the box, e.g. interiors of the building?

I ask becasue assuming it's the former, plane tests from a single box would not help in this case (top down view):

Neither the blue nor the orange occluder boxes can cull the red building behind them, because they occlude only parts of it.
Only if we can merge the occlusion of both boxes the red box can be culled.
The usual way to do this is rasterizing the occluder boxes, either on GPU and then using occlusion queries, or on CPU with z spans for example.

You would need to explain better, as ther are so many forms of ‘occlusion culling’ with varying culling efficiency vs. implementation complexity.

cozzie said:
I'm basically looking for a way to ‘push’ the volume further so the occluder's volume is not part of what's rejected, which I believe is now the case, because there's volume of the occluder itself, included (if that makes sense 🙂)

I guess you mean this:

The red bounding box of the house can't be used as an occluder, we actually want the blue box?

That's a hard problem ofc., often leading to making occluder geometry manually.

As mentioned when you were implementing this, you can't do anything to optimize the near plane as things stand. You first need the interior volume and not the exterior AABB. If you try to optimize using the exterior AABB it will simply introduce false positives, near plane must remain at the furthest point of the AABB until you get the correct data (and you are still going to have false positives). Second, once you have the interior volume via hand crafted AABB/OBB or something that generates it, you can only pull the near plane towards the camera based on the ‘furthest’ point of the visible silhouette edges. Anything which pulls the near plane closer will again introduce false possitives.

Basically, at this time, unless you've fixed it, you are working with bad data and the old rule: “bad data in == bad data out” is in effect. So, trying to optimize this further is just likely to exaccerbate the current errors. An no, having just reduced the size of the AABB isn't gonna work, as mentioned it was just a stop gap to make it kinda look more correct. :P So, once again, stop optimizing it till you get the data fixed, then you might not care enough to bother because it ends up being a fairly trivial gain.

Advertisement