Was node culled/occluded

Is there a way to detect if a target node in the scene is completely occluded by other nodes (and hence would have been effectively culled during rendering)?

My use case is around generating a 2D image of a 3D scene and retrieving the projected 2D vertices of particular objects in the scene. I use usual renderFrame and screenshot methods. To retrieve the 2D coordinates, I first get the 3d vertices of my target node with GeomVertexReader and use cam.getRelativePoint, followed by camLens.project and resolution adjustment to get the 2d values. All works as expected.

I can detect if my target node is out of bounds of the window/view due to camera positioning from the None value returned by camLens.project. However, I am not able to detect if the node is completely or partially occluded - the projected 2d values are indeed valid, so this is not useful.

I see there are some callback utilities (e.g. CallbackNode) - not sure whether it should be set at scene root or at target node. More importantly, want to know if there is any handy property that would show whether a node was rendered or not in the scene.


I believe that the cull callback of CallbackNode is only called if the related node (or more exactly its bounding volume) is at least partially visible; however you don’t have any indication on how much visible it is.

If you want to check if an object is occluded by another object, you can use the Occlusion Culling system (also called Polygon Occluder Culling) provided by Panda3D, see Polygon Occluder Culling — Panda3D Manual but I’m not 100% sure it supports the cull callback of CallbackNode.

Another possibility is to directly use OpenGL occlusion queries to check if an object is visible of occluded, and by what amount. But, if I’m not wrong, the Python binding are not available, so you have to use the C++ API to use them.

A third possibility is to use a shader which has an attribute that contains a unique identifier for each object, the shader will write that value to an attached texture using imageStore(). Then you can either use a compute shader to accumulate the number of points for each ID, or retrieve the texture and do a simple search and accumulate on the CPU.

1 Like