SurfaceTool & Noise causing lag issues

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By AdmiralOwl

Hello there,

I’m currently trying some things out with SurfaceTool and the FastNoise module from Zylann for a simple terrain generation. At the moment everything is really simple and generates well, but I have big FPS drop when I test it.

Here is my code and how I am approaching this (I’m learning, it may have some weird ways to do things but let me know) : https://pastebin.com/yq7LEvyJ

If you want to try my test project by yourself: https://github.com/AdmiralOwl/SurfaceTool-FastNoise-Test-Project (If you don’t have WIN64bits you need to compile Godot yourself with Zylann’s module : GitHub - Zylann/godot_fastnoise: FastNoise library integration for Godot Engine )

Thank you for your further help, I can give more infos if needed, don’t hesitate to ask me.

Note: you know you can create local variables with var? It might work with only member variables like you have, but it’s error prone, as the state of a var you modify in a function might leak into the next function if you forget to reset it.
Also, I notice a loooooot of copy/paste, it might be possible to reduce this down to 1/4 less code (which can also help clearing things up)

Do you get a slowdown only during a second or more?
When does that happen? You could wrap your code into time checks, or use the profiler so you’ll see which part takes longer to execute (sorry cant test the project right now)

Zylann | 2018-03-21 18:55

Hi, thank you for your really good help as always Zylann.

Mmh in the profiler I get what is displayed on the image attached below.
I won’t lie, it seems pretty much way beyond my abilities to understand what the Profiler is trying to tell me, but, correct me if I’m wrong, something seems wrong in terms of physics and takes a lot of time to being computed. I tried to not generate the collisions, but same thing happens.

What do you mean by local variables? Indeed a lot of things similar as I was testing, I was afraid to get lost in the vertices but now that it’s done I could get them into arrays, it could help.

Profiler

AdmiralOwl | 2018-03-22 11:13

The profiler looks broken… or you are indeed getting frequent lag spikes.

By local variables, I mean:

var a = 42

func foo():
    print(a)
    a += 1

If you call foo twice, it will print 42, and then 43.
However:

func foo():
    var a = 42
    print(a)
    a += 1

If a local variable is used like this, it will print 42 and then 42, because a variable only exists within the scope it is defined in. “locals” are such variables, when not declared as member (outside of functions).
I find some newcomers using member variables all the time, and tbh I have difficulties explaining why locals are useful (and they are!) because, well, if you care about your script you probably don’t see a functionnal difference, it works in the end, right^^.

I might say, you want to put as member a variable that NEEDS to exist even outside of functions of the script, while a local variable only NEEDS to exist within a function, or within an if block or a forloop, like a temporary var.
Code written with this rule is easier to maintain and explain to others, because in your case, I started reading your script and saw maaaany member variables and not a single local. To me, it means “I have dozens of states that can be changed from litterally anywhere in my big script and they can also be modified from outside”, which means it’s harder to diagnose where a bug can possibly be^^

Zylann | 2018-03-22 19:33

:bust_in_silhouette: Reply From: Zylann

I notice you call surfTool.generate_normals() every time you add a few vertices: don’t do this. You only need this at the end, just before to commit the surface to the mesh. Otherwise you’ll recompute normals of the whole mesh everytime you add one triangle to it.

There might be more but i cannot test the project right now.

Thank you for your help as always, I missed this info for generate_normals(), I’ve cleaned every of these lines and now I’m only generating the normals of the whole mesh.

Sadly it doesn’t help with performance, but atleast it helps getting the code cleaner. Something still wrong.

AdmiralOwl | 2018-03-22 11:16

I tried your project in 3.0.2 by mocking FastNoise:

Generation takes a few seconds to complete but I get around 250 fps. Did you build Godot from master?

Zylann | 2018-03-22 19:57

Hi, was off for vacations for a couple of weeks, back now.
Build from Godot master, yes (3.0.2), I also get around 250 fps but it’s dropping a lot when you go around with a camera and getting a bit far of the generated meshes.

AdmiralOwl | 2018-04-04 09:54

I don’t know, tried to move around or even too far from the chunks to not see them in view, but got no lag. Did you make a debug build or a release_debug build? Also chunks don’t generate dynamically for me (in case they should?), the scene really is just a bunch of meshes that runs fine and nothing else. The only issue is a lot of errors in the console:

ERROR: RasterizerStorageGLES3::mesh_surface_get_index_array: Condition ' surface->index_array_len == 0 ' is true. returned: PoolVector<uint8_t>()
   At: drivers\gles3\rasterizer_storage_gles3.cpp:3265

Zylann | 2018-04-05 00:40