Terrain performance problem.

Hello. I would like post an issue and ask a question regarding performance.

Yesterday I was trying to display a simple terrain mesh but I’ve hit a serious performance issue. I used GeoMipTerrain class to generate the terrain:

from direct.showbase.ShowBase import ShowBase
from panda3d.core import *



class MyApp(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        terrain = GeoMipTerrain("mySimpleTerrain")
        terrain.setHeightfield("loco_hm.png")
        #terrain.setBruteforce(True)
        terrain.getRoot().reparentTo(render)
        terrain.getRoot().setSz(60)
        terrain.generate()
        light = DirectionalLight("Light1")
        light_np = render.attachNewNode(light)
        light_np.lookAt(0,0,-10)
        render.setLight(light_np)

app = MyApp()
app.run()

The problem is that after running this example my CPU usage went from 20% to 70% meaning that the whole core was eaten by python. Is this normal? I’ve got Intel Core 2 DUO @2.66ghz with 4gb of ram. The GPU is Nvidia Geforce 8600. For certain this is not GPU issue, since the GPU-z shows that the GPU load is 1%.

Anybody has any clues about how to improve performance of this? Maybe different terrain algorithm?

Thanks for help in advice.

It’s perfectly normal for Panda to take up all the unused resources and there’s nothing to worry about. If you really don’t want that to happen add something like this at top of your script:

from panda3d.core import loadPrcFileData
loadPrcFileData('','client-sleep 0.01')

The CPU usage should drop to ~5% with a script and system like that (unless that’s a 16k heightmap, but it should drop anyway).

Is it a good idea to do it? No, unless you have something important running on that core at the same time.

A client-sleep value of 10 ms does negatively affect performance; if you’re going to do that, then even a value of 1 or 2 ms would be sufficient without it affecting framerate.

Ah, yes, sorry, that should be

from panda3d.core import loadPrcFileData
loadPrcFileData('','client-sleep 0.001')

Thanks.
Unfortunately the loadPrcFileData routing didn’t helped too much.

Well… The terrain mesh is 512x512, that yields max 250k (a lot less if the mesh uses indexing) verts… Yes that’s some but the GPU is still almost idle while I get not satisfactory framerate, which depends of how many of the terrain actual mesh is inside the view frustum.

You could check it for yourself if you want, the heightmap file is this:
https://dl.dropboxusercontent.com/u/40322040/loco_hm.png

Any more ideas here?

For one, the heightmap is not of a power-of-two-plus-one size. Rescale to either 257x257 or 513x513.

Secondly, try increasing the block size of the GeoMipTerrain.

If you’re in need of an alternative to GeoMipTerrain then I happen to have something at hand… be it half finished.

It uses a ~3k triangles mesh with a random-cellular pattern (not quads cut in half), the mesh is deformed in a shader based on a heightmap, then the heightmap (+ some details) is used in a fragment shader to generate normals for the mesh. For now it uses one color texture for the whole terrain, but it still looks not bad and it runs at 300-600fps on my system (Core2@1.86GHz, 2GB ram, Radeon 3800 series) :wink:

The screen shows the terrain with a 1024x1024 color map, 512x512 height and detail map:

Source (zip, ~3MB):
sendspace.com/file/golz6w