Culling distant objects from render

Hello,
Synopsis:
I’ve been working with panda for about two weeks now and I’ve got some of the basics down. However the project I am working on requires that we have a large number of objects in the word, but few on the screen. The main premise is that our character will be in a mostly dark world and will only be able to see so far past their light source. But the world will be relatively detailed once the character gets close enough to see it. (Think Pitch Black the movie when they’re walking through the darkness).
Goal:
I want to somehow culling or remove all objects(models/actors/etc.) from being rendered or considered for being rendered if they are outside a certain radius of the main character (e.g. a given node/nodePath).
I know panda handles this on its own when it comes to rendering objects only visible to the camera. When a large quantity of objects are off the screen the frame rate is much higher than when they are on the screen.
Help:
Is this something that can be accomplished by extending a class in python, or by making function calls to the panda3d API, or will I need to dig deeper into the engine to get the results I need? I think I can accomplish this by iterating through the objects and reparentTo(render) or reparentTo(hidden) if they are out of range, but I thought there might be an easier/better way to do it after the render has already removed the ones that won’t be on the screen anyway. No need to double up the work if we don’t have to.
Any help or insight will be greatly appreciated.
Thanks!
Chris

I’m not sure if I got this question 100% right. Maybe I am thinking too simple here.
But this is what I would do:

Set the camera lens far plane to the desired maximum distance for your objects. And to make the objects disappear softly you could use fog which blends to the background color at maximum distance.

This manual page tells more about camera clip planes: http://panda3d.org/manual/index.php/Lenses_and_Field_of_View

enn0x

This may be too simple but:

lens = base.camLens
lens.setFar(100)

This won’t render polygon that is further than 100 away from the camera.

i it might not render but it will still process i think (need clarification)

so sticking a clip planes at that 100 see http://panda3d.org/apiref.php?page=ClipPlaneAttrib will do the job for sure :slight_smile:

Bringing the far plane closer is absolutely the right thing to do–objects that are wholly on the other side of the far plane will be culled early, and not processed beyond examining their bounding volume.

Since objects get clipped by the far plane when they intersect it, this looks a little weird. This is why people use fog to darken things smoothly to black just at the point they reach the far plane, as enn0x suggested.

Both are classic 3-d game tricks. Ever wonder why so many games are played on worlds that seem really foggy, or really dark? It’s all just an excuse to bring the far plane real close.

David

Thank you everyone,

I stumbled upon the camera lens after I posted, and I even implemented a black fog per enn0x’s suggestion. It seems to work close to how I want it to. If we still have performance problems I’ll look more into the clip plane. It’s good to know I still have other options

Thank you again, I really appreciate the assistance.

So if an object is clipped away does that mean its just not rendered? Or does it stop processing altogether?

First of all thanks again for the help.

Second, it seems that I may have to use the clipping planes in order to get my skybox to appear correctly (it disappears because the camera lense far distance is too close for it). Unfortunately the documentation for clipPlaneAttribute is kind of sparse (for someone of my level of understanding to implement). Are there any tutorials or sample code that use it? I haven’t been able to find anything myself but I know that it doesn’t mean they doesn’t exist. I would like to put a plane that clips in front of the camera (like the lense does) however keep it directly in front of the camera based only on heading, not pitch or roll.

In addition I believe I will need to use the polyLightEffect for the skybox model, but again I can’t make heads or tails from the docs. I have pieced together that you have to call make and set the effect to the object, but I’m confused. How would I set the models ambient light to Vec4(1,1,1,1)?

self.effect=PolylightEffect.make()
self.skybox.setEffect(self.effect)

No need to use a clip plane. You can tell Panda3D to render the sky “behind” all other geometry. This way you can use a very small sky-box/dome/whatever model, just big enough to be outside the near plane. Also you might want to disable lighting for the sky.

np.setBin( 'background', 1 )
np.setDepthWrite( 0 )
np.setLightOff( )

enn0x

Enn0x,

Brilliant! As I was reading your reply I was thinking to myself “I can do that?!”. That is the perfect solution. Not to mention I can use that method for a couple other things that are fairly important to our project.

Edit: Is there a way to make it so that the object is not effected by the fog? Or is visible through the fog? As it stands if it’s past the far-lense it can’t be seen because of the fog exponential fog that is being used to soften the culling.

Thanks again! I really appreciate the suggestion, as well as the snipplet.

panda3d.org/apiref.php?page=NodePath#setFogOff

or in short:
node.setFogOff(1)
… or so… or maybe not^^ didnt try

Worked perfectly. Thanks Thomas.

Edit: Since I didn’t want the skybox to always be visible after culling (performed by the lens) I ended up doing a different type of fog on the skybox.

Thanks everyone.