I’m creating a tile based puzzle game, hopefully with up to 256x256(65536 individual squares) tiles, eventually modeled and animated as 3d cubes.
Using procedurally generated individual geoms, nodes and nodepaths like in the procedural-cube sample I can get around 64x64 tiles before I become cpu limited. I get around 15 fps with a fairly powerful computer and without having any kind of game logic, which should be fairly cpu intensive.
How should I be constructing the game world model so that I can have many instances of a model with individual characteristics and still have good performance?
I’m thinking that’s going to be pretty tough as far as performance goes.
I was working on a system recently that had 7^3 animated spheres arrayed in 3 dimensions. Whenever the spheres were all in the screen space things got slow rather quickly. I think you’re coming up against performance constraints. If you run nodepath.flattenStrong() on your cubes you can save some performance but then you won’t be able to individually manipulate them as much.
if it’s about performance. first thing to do is run pstats.
in your case i’m pretty sure you have an extremly high geom-count. which is bad. cause your gpu prefers a few big bunches of geoms over thousands of small ones. and even 4000 cubes can bring down a high-end gpu to a grinding halt.(while it would be able to render 4 million cubes at ease if they would come in a few big bunches).
luckily panda offers many ways to solve this problem. if your tiles are static then flattenStrong() might be the joker. if your tiles contain rigid but moving parts you might prefer the rigidBodyCombiner.if all this fails, panda 1.7.0 which is about to be released very soon introduces support for hardware-instancing which would allow you to do even crazier things.
but flattenStrong and rigidBodyCombiner should do a nice job already.
in any case. have a look at the pstats video tutorial in the documentation section. and give it a run for your application. you’ll immediately see what’s slow and where you need to optimize. feel free to post pstats output here on the forum and ask for detailed advice.
Thanks for the information, people will be working on the puzzle in certain areas, so possibly one technique would be to break the world into discreet chunks, flatten those chunks into static pieces then just rebuild the piece that gets changed?
64x64 = 4096 geoms, so if you have all of them in view, your GPU will most likely choke.
Rather than flattening, you could change your geometry-generating code to generate every tile as primitive into a single Geom, rather than having one Geom per tile.
Alternatively, create one tile and use hardware instancing to duplicate it a few hundred times.
as long as you dont rebuild it every frame it’s totaly fine to rebuild and flatten parts of it again.
rdb, Can I apply individual textures and colors to the primitives if I put everything into one geom?
I can apply individual vertex colors when I build the vertex data, there wouldn’t be a way to change the colors after it’s all put together would there? If I save the vertex data can I just change the original values?
Ouch, that’s gonna be tricky. You could indeed try to use flattening the RigidBodyCombiner to flatten parts that have the same texture together.
Okay breaking up the world into chunks and running flattenStrong on it works(back up to 55+fps, thanks!) but running flattenStrong takes forever, building the initial geometry goes from 1-2 seconds to 20-30 seconds, any ideas about that?
You could construct the final geometry by hand yourself, I guess, with the use of the GeomVertexWriter, instead of creating lots of little pieces and flattening them all together. I’m not sure if this would be faster, though, since you’d be doing a low-level iteration in Python. It might be faster. Ideally, you could do this iteration in a C++ module, and call it from Python.
Or, you could come up with a caching mechanism: flatten the geometry once, then save it to disk and reload it in the future. That may help, depending on your application.
Thanks for all the information, I’ve actually got it to the point where it’s fine for development, I’m going to work on the game logic more before I do any further optimization. I’m sure I’ll revisit this thread in the future though.