Recently, I have been working on a little Infinite Terrain demo that explains how to take full advantage of Panda3D’s terrain capabilities. In the process I have been adding various features to Panda3D that would make it easier for me, including many improvements to the Shader Generator. (On a sidenote, I didn’t end up needing any shaders for the terrain.)
Last Monday, I added trees to the terrain. As this is an infinite terrain demo, I needed to add quite an amount of trees. But I found that (even with Panda3D’s flattening capabilities) my GPU quickly let me down after a few thousand trees. So, I realized I needed to add geometry instancing support to Panda3D.
And so I did. It turned out to be quite trivial to implement and only took me an hour or two. The results are quite pleasing! I have managed to render over 100000 trees (and a huge terrain) at the same time at a reasonable framerate! Here’s a screenshot of what it looks like right now:

Of course, that WIP scene could use a lot of improvement, but you get my point. And with some proper culling and LOD, I could push the amount of trees even higher.
But doesn’t Panda3D already support instancing?
Currently, Panda3D supports instancing of animated models. That is entirely unrelated to geometry instancing. The existing instancing system only exists to improve performance if you have a lot of animated models, by reducing the amount of vertex displacements that are done by Panda3D’s animation system. Geometry instancing, on the other hand, exists to greatly reduce the amount of data that is passed to the video card. Whether the model is animated or not is irrelevant with the new instancing system.
How does it work?
Before yesterday, if you wanted to create multiple instances of a model, you’d either load the model multiple times or use copyTo. I’ve seen that many people use instanceTo in this case, but that will have no positive effect on performance for static models. The geometry will still be passed many times to the GPU, which is a slow process.
With the new system, you keep just a single copy of the model and call setInstanceCount(n) on it. This means that it will still be passed to the GPU only once, but it will be rendered n times.
You might be wondering, how do I give each node different parameters or a different position? Well, that can be done in the shader. You can access the instance ID in the shader and calculate the position, color, etc. based on that, or simply use a different model projection matrix from an array of transform matrices that you pass to the shader. This allows you to do basically anything. You can send a single sphere to the GPU, passing a 3D texture with a displacement map in each layer, and set the instance count to 1024. That will result in 1024 unique rocks using just one batch call and a very limited amount of uploaded geometry.
This leaves the question of whether this will actually work without use of shaders. The answer is no, I’m afraid. There is an OpenGL extension that allows you to use geometry instancing with the fixed-function pipeline, but very few video cards support it. Because it would be quite complicated to implement that, I decided not to do it.
Note that this is only supported in OpenGL so far. Maybe someone will add support for this to Panda’s DirectX side someday.




What’s that thundering sound I hear? It’s the sound of the future coming!
Comment by drwr — December 22, 2009 @ 11:52 am
Really good job, rdb. And I agree, no need to bother with the FF pipeline in this case.
Comment by gogg — December 22, 2009 @ 11:59 am
RSS did not appear to update.
Comment by treeform — December 22, 2009 @ 4:07 pm
Is it just me, or are the trees missing in the reflection? Anyway, looks great. I think I’ll wait for this to be released before doing anymore on my terrain thing.
Comment by Craig — December 22, 2009 @ 4:31 pm
whooohoooo ! At last!
very good job indeed !
Just have to wait for the 1.7 now !
Comment by SylHar — December 23, 2009 @ 5:48 am
Very cool. I’m with Craig though- why are the trees absent in the reflection?
Comment by mavasher — January 1, 2010 @ 1:44 pm
Ah, they are indeed missing. Nothing special, just something I overlooked in my code, I applied an incorrect draw mask to the trees.
Comment by rdb — January 1, 2010 @ 2:41 pm
damn, how picky you are guys for some tree missing?!
I was so astonished watching the scene that never happen to notice that!
just wonder how much have to wait for 1.7 issue, hope is close to be released
Comment by fabius — January 2, 2010 @ 5:11 am
I didn’t think it was a problem. More I was just interested in if they were truly missing.
Comment by mavasher — January 3, 2010 @ 10:11 am
good…that’s going to be interesting…
Comment by LBarret — January 4, 2010 @ 1:13 pm
That’s can be very VERY handy… Is the shader for placing/scaling/modifiying trees available somewhere or is it some kind of secret of the gods ?
Comment by Tallmystcarpet — February 8, 2010 @ 2:22 pm
I will distribute the code once I have cleaned it up and got it working properly.
The shader is really easy though. It just requires texture prefetch in vertex shader. It does not even use a geometry shader.
I don’t have time to do that anytime soon, I’m afraid.
Comment by rdb — February 10, 2010 @ 6:25 am
Any chance we can have a peek at the source? I’m very interested!
Comment by deganderson — May 20, 2010 @ 7:25 pm
I tried installing Pirates Of the carribean online. I had to install the panda3d (p3d setup) when i agreed to every term and conditions nothing happened it didnt come to my desktop. I tried installing it a million times. What do I do?
Comment by JL — October 2, 2010 @ 4:20 pm
Hmm it seems like your blog ate my first comment (it was super long) so I guess I’ll just sum it up what I submitted and say, I’m thoroughly enjoying your blog.
I too am an aspiring blog blogger but I’m still new to the whole thing. Do you have any helpful hints for first-time blog writers? I’d really appreciate
it.
Comment by how to lower high cholesterol — December 2, 2012 @ 6:16 am
I am in fact happy to read this web site posts which consists of lots of useful facts, thanks for providing such statistics.
Comment by Stephaine Gallamore — January 1, 2013 @ 3:32 am
Great job on Make this week! Thoroughly enjoyed it from afar (online). Having worked conferences in the past, I know it’s a true (and massive) labor of love. Just say’n, it matters. It was beyond encouraging for where I’m at in ministry and business and life. So thankful for God blessing y’all.
Comment by Senaida Liepins — January 1, 2013 @ 7:10 am
That is a really good tip especially to those new to the blogosphere. Short but very precise info… Thank you for sharing this one. A must read post!
Comment by buy used cars bedfordshire — February 5, 2013 @ 3:15 pm
I am typically to running a blog and i really appreciate your content. The article has really peaks my interest. I’m going to bookmark your site and keep checking for brand spanking new information.
Comment by http://www.thelittleghoststore.com/ — March 13, 2013 @ 4:45 pm
Note: that the sources origin of this fund is from my father coffee and cocoa merchant business and I’ve the deposit paperwork which my late father issued to me prior to his death which sure the fund is 100% threat absolutely free.
Comment by mygirlfund — May 6, 2013 @ 9:18 pm
First of all I would like to say wonderful blog! I had a quick
question that I’d like to ask if you don’t mind.
I was curious to find out how you center yourself and clear your thoughts prior to
writing. I’ve had difficulty clearing my thoughts in getting my thoughts out. I do enjoy writing but it just seems like the first 10 to 15 minutes tend to be lost simply just trying to figure out how to begin. Any ideas or tips? Appreciate it!
Comment by babycenter.com — May 13, 2013 @ 12:08 am