Frustrum / occlusion culling


I would like to ask, are you implementing for large scenes with many entities any kind of culling for hidden objects?

Firstly frustrum culling for objects not in the camera window and secondly anything regarding occlusion culling, objects hidden by other objects?


Frustum Culling is already available, and is a simple tick on a camera.

Currently there is no culling API’s and it is very a case specific.
There are many options that could work here, and many things could be implemented.

For outdoors some depth based occlusion to check if something os fully behind something else could work.
For indoors there are many techniques, one of them is sectors+portals, which actually you can do yourself by making 2 level graph of rooms (boundingbox of a room) and all entities within that room.
Then you have to make portals between sectors and know the state of a portal (open/close) and position, so that you know which connected rooms has to be visible or hidden.

Or toy might go another options which there is vast variety of.

So because there are many different occlusion techniques and they all are case specific, we haven’t implemented any particular. We might implement better interface that will help altering culling states of things, and allow to access culling state from scripts, so that you can prevent some costly logic if it is not needed when entity is not seen.

Thank you Max, that was a comprehensive reply.

Looking forward as well for the script culling idea.

Best regards,

Hi @max,

Would a single FBX/json with 3 meshes consider the separate meshes for frustum culling?


  • BJörn


If you inspect the Model asset in Playcanvas editor, you can see how many meshInstances it consist of. Each pc.MeshInstance is individually frustum culled by default by the camera unless you explicitly specify them as _..cull=false by code. (see documentation)

You may perform your own manual frustum(/whatever) culling algorithm or avoid it altogether (instead of relying on Playcanvas engine’s default approach) by setting the meshInstance to _.cull=true;_.visible=false to flag visibility OFF or _.cull=false;_.visible=true to flag visibility ON (you normally do this with a layer.onPreCull hook if doing your own frustum culling, or you may simply alter visibilities whenever required depending on your game’s situation). This isn’t obvious from the documentation though, unless you observe the source code though: . From there, you are able to retrieve the camera’s frustum planes as well from the camera object reference, and translate it to any needed coordinate spaces if needed depending on how you handle culling.

From what i remembered (i might be wrong…) , Playcanvas’ default culling approach uses bounding spheres culling (which is simpler, with just 1 dot product per plane, compared to actual AABB check, though not necessarily very accruate either, without adopting plane masking) My favourite culling approach that I use (if needed) is conservative box+plane masking approach as described in : , but again, it largely depends on the needs/structure of your app. Sometimes, not having any culling calculations might simply be the best.

1 Like

Hi Max. How could I work out the depth based occlusion in playcanvas. I understand the concept but I have no idea of how to set it up. Thanks

You probably would need to read up online on publications on that topic.