In my sandbox game, I have lots of meshes/blocks to render. This causes massive lag when I have generated some terrain and my question is how to minimize this lag. I need to be able to remove and place blocks so I can’t use flatten_strong. How does Minecraft handle so many meshes at once?
Expanding a little on the above, I strongly suspect that the way that Minecraft handles some many meshes is that it doesn’t–it just gives the illusion that it does.
I don’t know for certain, but I imagine that in Minecraft each region of the terrain (i.e. excluding creatures and the like) is a single mesh (or perhaps a few meshes). When a block is removed or added, the relevant mesh is updated.
Does this mean that all my meshes are updated too often and it is the reason I get so much lag? Is there a way to control when the meshes are updated and only make the relevant meshes update when I want to? How do implement this?
It’s more likely, I think, that you simply have too many meshes.
You see, a major limiter for modern graphics cards, as I understand it, is not the polygon count–as we know, that ceiling is quite high these days. Instead, it’s the batch count: the number of separate “chunks” that the card can handle at once.
Thus, given the same number of polygons, it may sometimes be better to have those polygons be held in a smaller number of meshes than to have them spread across many meshes. That said, this isn’t a hard-and-fast rule–sometimes it better to aid culling by breaking things up, or to find a balance between the two.
From what I gather, it’s generally best to have no more than a few hundred individual meshes.
As I understand it, I need to reduce the number of meshes somehow. Can I do this by having all blocks of an in-game chunk reparented to the NodePath of that chunk for instance? I have also seen samples using some culling functionality, is that relevant?
When you call flatten_strong, it combines all the primitives into one. Initially, you had to design your work based on the modification of the primitive. At the moment, there is no simple solution other than this.
Indeed; for a game in the vein of Minecraft direct manipulation of the mesh-data might be better–more effective and quicker to run–than use of “flattenStrong”.
I think that there have been a few threads on the forum dealing with such issues, even specifically with Minecraft-like projects. Serega linked to one above, and searching might turn up more. These might provide further information for the implementation of your project.
I have now tried putting all NodePaths in a chunk under one NodePath, so that I get one NodePath per chunk, and called flatten_strong. But the texture wraps in a very weird way. How do I prevent this? What happens with textures when you call flatten_strong?
I have a pattern of using flatten_strong in python. I don’t think C++ will be any different.
from panda3d.core import NodePath
from direct.showbase.ShowBase import ShowBase
all_node = NodePath('all')
for i in range(0, 20):
for j in range(0, 20):
model = loader.load_model("box")
model.set_pos(i, j, 0)
app = MyApp()
Sorry if I wasn’t clear enough. Just like your code below I have a NodePath (all) which I am reparenting some nodes to (box). Then I call flatten_strong on all_node and reparent it to render. This reduces lag significantly. The only problem is that every “box” needs to have a unique texture which flatten_strong seems to merge into one texture.
This is without flatten_strong (As I want it to look, but not performing that well):
I’m guessing that it’s the cube-map that’s the problem: Having been flattened, the models no longer have distinct positions, rotations, etc. Everything has a position and rotation of zero, with its vertices providing the actual location of the object.
Without distinct positions and/or rotations per model, the cube-map code might be becoming confused–hence the single patch of grass spread oddly over one location, and the radial pattern on the ground.