godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.33k stars 21.24k forks source link

Performance drop in 3D scenes with DirectionalLight in Godot 3.6 compared to 3.5 #99468

Open sabudum opened 3 days ago

sabudum commented 3 days ago

Tested versions

System information

Linux Ubuntu 22.04, Intel Core 2 Duo 2.8 Ghz, Geforce 9500 GT 3Gb VRAM, 4 Gb RAM 800 Mhz

Issue description

Performance is considerably worse in Godot 3.6, compared to 3.5

Godot 3.5.3, with 33 FPS: Image

Same exact scene in Godot 3.6 with 27 FPS: Image

A drop of 20% in performance can be observed.

Steps to reproduce

Run a project in Godot 3.5.3, make note of the FPS Run the same project in Godot 3.6 and observe the drop in performance.

Minimal reproduction project (MRP)

The truck town demo can be used to attest the performance change. https://github.com/godotengine/godot-demo-projects/releases/download/3.5-9e68af3/3d_truck_town.zip

lawnjelly commented 2 days ago

I just wanted to look at this prior to a power cut today, but can't seem to replicate here (Mint 21.1, Intel i7-13700T integrated graphics) with truck town so far, so it may be system dependent (I'll look more when power back on).

If you could create an MRP with a fixed camera location / orientation, that would be super useful making it easier to try and work out what might be going on for you.

Your FPS figures are very low for very little in your scene, so this could be something that is sensitive on low end hardware (bottlenecks may be completely different). Your CPU is from ~2006 wiki suggests, and GPU from 2008. (That's not a complaint by the way, we do aim to have it running on as old / low end PCs as possible, so a drop in performance here is worth a look).

Some other things to try:

Also be sure to let us know / try running outside the editor. Particularly on low end, running e.g. the editor in the background can change runtime performance if something has changed in the editor. The same goes for external programs that are running, especially browsers, which can totally skew performance testing.

UPDATE: Actually no on further testing I am getting a drop in FPS in platformer 3D between 3.5.3 and 3.6 (in the editor at least), I'll see if I can pin it down.

The drop seems to be introduced between beta 4 and beta 5. I'll see if I can bisect before power is off at 9am here. 😁

lawnjelly commented 2 days ago

Bisected to #60246, this reduced my FPS from 310 to 278 in 3D platformer (GLES3), 404 to 394 in GLES2 suggesting GLES2 is less affected.

@Calinou .

(This may have been expected as there may be some changes to defaults, but leaving this here so can be investigated while I'm offline.)

It seems I did flag the need for performance testing at the time, this may also be affecting Godot 4. Also tagging @clayjohn to have a look.

clayjohn commented 2 days ago

It seems I did flag the need for performance testing at the time, this may also be affecting Godot 4. Also tagging @clayjohn to have a look.

I suspect it is an issue in Godot 4. This looks like a memory issue (both because the struct got more bloated and we are doing two additional 4 byte reads). Lighting is heavily memory op bound in Godot, so I suspect this just tips things over the edge.

Unfortunately, in Godot 4, we aren't going to take features away from users, so we have to live with the cost

lawnjelly commented 2 days ago

Hopefully @Calinou will get a look at this, I'll probably have an investigate too as to what precisely is causing the slowdown, as it seems quite significant.

For 3.x, we can probably just make this new mode optional with defines in the shader, if there's no way to ameliorate the slowdown.

lawnjelly commented 1 day ago

This looks like a memory issue (both because the struct got more bloated and we are doing two additional 4 byte reads). Lighting is heavily memory op bound in Godot, so I suspect this just tips things over the edge.

This does appear to be the case in some tests, if I remove reference to fade_from and fade_to and just use constants in the shader, e.g.:

Change:

float pssm_fade = smoothstep(fade_from, fade_to, vertex.z);

to

float pssm_fade = smoothstep(0.0, 1.0, vertex.z);

The speed goes back up. It could be the shader compiler (in my case) is eliminating fade_from and fade_to if unused.

Given that there is just one directional light with splits (I think?) I'm wondering whether these fade params could be passed in a different way. 🤔

lawnjelly commented 15 hours ago

Keeping this open, as although #99536 is merged, there is probably more work to be done in this area to fully resolve the performance regression.