geomipterrain update

Hey,

Came across a strange issue for a few days and haven’t been able to pinpoint the cause exactly. Basically a change in the terrain’s configs making .update() being a necessary call is making the app spend an awful amount of time on the terrain update task.

this is the relevant code to which was switched to.

       #self.setBruteforce(True)
       
       self.setBlockSize(32)
       self.setNearFar(30, 60)
       self.setFocalPoint(base.camera)
       self.setAutoFlatten(GeoMipTerrain.AFMStrong)
       self.generate()
       #self.getRoot().flattenStrong()
       self.terrainParentNP = scene.attachNewNode('terrain_root')
       self.getRoot().reparentTo(self.terrainParentNP)
       
       self.getRoot().setPos(x, y, z)
       self.scaleZ = 2
       self.getRoot().setSz(self.scaleZ)
       self.getRoot().setTexScale(TextureStage.getDefault(), 32, 32)       
       self.getRoot().setTexture(RESOURCES['ground'])
       self.terrainParentNP.setCollideMask(collisionBitmasks['P_Terrain_into'])

and the task area

    def updateTerrain(self, task):
        self.terrain.update()
        return task.cont

This is the previous one.

       self.setBruteforce(True)
       
       #self.setBlockSize(32)
       #self.setNearFar(30, 60)
       #self.setFocalPoint(base.camera)
       #self.setAutoFlatten(GeoMipTerrain.AFMStrong)
       self.generate()
       self.getRoot().flattenStrong()
       self.terrainParentNP = scene.attachNewNode('terrain_root')
       self.getRoot().reparentTo(self.terrainParentNP)
       
       self.getRoot().setPos(x, y, z)
       self.scaleZ = 2
       self.getRoot().setSz(self.scaleZ)
       self.getRoot().setTexScale(TextureStage.getDefault(), 32, 32)       
       self.getRoot().setTexture(RESOURCES['ground'])
       self.terrainParentNP.setCollideMask(collisionBitmasks['P_Terrain_into'])

On the update part, PStats is acusing that task to consume around 8ms. It’s almost all of the app time. the fps drop is from 250 to 25 according to the meter without pstats running.

without moving the camera the update call is done once or twice (as in returning a true value). Seen a bit of the update internal code as well (not that much :slight_smile: ) and there’s a few areas with loops, level calculations and flattening. Could it be doing more than it’s supposed to due to some error in that code? or something i haven’t set up .

I’m also under the impression i had it working well with update before so after so many changes and tests during the last few days i kinda got lost on what i could be doing wrong :stuck_out_tongue:.

I have also tried making sure bruteforce was false, removing scaling and textures (before or after the generate call). Reducing the nearFar didn’t increase to 60-70fps but it’s still a big drop considering using bruteforce alone.

If your terrain takes a long time generating, consider smaller block sizes, or adjusting your settings in such a way that not much terrain will have to be regenerated.
Big blocks take a long time to regenerate, but having lots of small blocks kills the GPU. It’s up to you to find the perfect balance.

Making bruteforce True will make update() only faster (except for the first call).

oops, a typo (meant “did increase to 60-70fps” :slight_smile: ).

will keep trying. In this case, this gpu doesn’t really have issues with small blocks. Just more worried bout weaker gpus.
The calls to update is what’s taking such a hit, added conditions to actually only call update when the camera moves. Tried a lot of configs so far and the update calls are still quite a pain :slight_smile:.
Got some doubts though, when does a terrain actually needs updating? asking this cause i got the impression when a terrain was bruteforced it wouldnt need any update call since the terrain wasnt being regenerated.

When a terrain is set to bruteforce, update() shouldn’t be taking any time (except if you changed some important settings or so).

If the camera has barely moved, the GeoMipTerrain will only recalculate LOD levels, and if none of the chunks’ levels changed, it won’t regenerate anything.