gururise / RigidBody3D-Stress-Test

RigidBody3D Stress Test for Godot 3.x
MIT License
11 stars 2 forks source link

Performance optimization ideas #2

Open pwab opened 4 years ago

pwab commented 4 years ago

I ran your project on this system:

Windows x64 
Intel Core i/-7700 @ 3.6GHz
Nvidia GeForce GTX 1050 Ti
16 GB RAM

After draining every bit using anything written below I got this:

Cubes: 1600
Max_FPS: 2321 
Min_FPS: 31
Avg_FPS: 538

I tried your list of possible perfomance improvements:

Use the Bullet Physics Engine (default). The Godot Physics Engine is significantly slower.

It is. As far as I know it won't get any performance updates in the future because Bullet is and will be the standard engine for 3D physics.

Drop Physics Framerate from the default 60 fps.

30 works fine for me - even if the tower is collapsing in a different way. Below that you're getting a lot of wrong movement and the cubes seem to behave more like a liquid. I changed it back to 50 to get comparable results.

Export as executable without Debug symbols.

Worked but did not have a massive effect. I guess this boosts the GDScript performance a lot but not the physics system. I got a min_fps of 24 in editor and 30 when exported in DEBUG and 40 when exported as RELEASE.

Disable shadows and/or directional lighting.

I removed the directional light and I got a few more fps.

You can play around with rendering quality/lighting and try GLES2. I haven't noticed much difference.

Same here. Switched everything graphics related to zero but did't noticed anything. I'm still not sure if switching rendering/threads/thread_model has an effect.

There are a few things that could be considered too:


I tracked my performance with the following addtion:

onready var fps : int = int(Performance.get_monitor(Performance.TIME_FPS))
onready var fps_min : int = 9999
onready var fps_max : int = 0
onready var fps_sum : int = 0
onready var fps_average : float = 0.0
onready var frames : int = -20  # need to wait a bit before starting to track the fps

#...

func _process(delta):
    timer += delta
    if timer > TIMER_LIMIT:
        frames += 1
        timer = 0.0
        #OS.set_window_title(title + " | fps: " + str(Engine.get_frames_per_second()))
        fps = int(Performance.get_monitor(Performance.TIME_FPS))
        if frames > 0:
            if fps < fps_min:
                fps_min = fps
            if fps > fps_max:
                fps_max = fps
            fps_sum += fps
            fps_average = fps_sum / frames
            fpsLabel.text = "fps: " + str(fps) + " // " + "min: " + str(fps_min) + " // " + "max: " + str(fps_max) + " // " + "avg: " + str(fps_average)

Last result

result

gururise commented 4 years ago

Thanks for the feedback. I just tagged the v1.0 release, which swaps out the individual MeshInstances for a single MultiMeshInstance. Performance appears significantly improved on my system; however, there is now code (gdscript) that must update the per-instance transforms of all CollisionShapes on every physics frame.

Perhaps you could run the new version and see how the results compare to what you got above.

Furthermore, the code updating the transforms could be optimized further, some ideas include:

gururise commented 4 years ago

I just created a csharp branch, where performance critical code that updates the multimesh transforms was re-written in c#.

Norrox commented 3 years ago

it's a little strange, if i increase the "physics jitter fix" in the settings i get better performance (i have it at 400 in the picture below). the whole tower with 4k cubes can come down without super low fps, ( i added physics material to, friction 0.9 and bounce 0.4 ) the lagging starts awhile after the tower has collapsed. Skärmbild 2021-07-22 234430