godotengine / godot

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

High texel density in large scenes crashes lightmap baking #95204

Open jcostello opened 1 month ago

jcostello commented 1 month ago

Tested versions

v4.3.rc.custom_build [4359c28fe]

System information

Ubuntu 22.04

Issue description

Supersedes https://github.com/godotengine/godot/issues/86416

As I talked with @clayjohn in todays Render Meeting, baking lightmaps in large scenes with high texel density still crash the lightamap bake (This is after the fix of cowdata 64bits)

Steps to reproduce

1) Download TPSDemo 2) Reimport the next scenes with texel density 0.1 (default) in the import tab

3) Remove VoxelGI (Game wont run because you have to remove references in code to VoxelGI) 4) Add a LightmapGI 5) Add new camera Attribute to LightmapGI 6) Set LightmapGI quality to low 7) Set LightmapGI texel_scale to 1.5 (or 2 to be sure) 8) Bake LightmapGI

It will crash

Minimal reproduction project (MRP)

TPSDemo

Calinou commented 1 month ago

I don't get a crash here on https://github.com/godotengine/godot/commit/eabeafd8c3d3fb346853eb1c590ae54b8aa4cd14, but I get this instead:

  Too many pixels for Image. Maximum is 16777216x16777216 = 268435456pixels.
  ./core/io/image.cpp:2772 - Condition "dsize == 0" is true.
  ./core/io/image.cpp:2772 - Condition "dsize == 0" is true.
  ./core/io/image.cpp:2772 - Condition "dsize == 0" is true.
  ./core/io/image.cpp:2772 - Condition "dsize == 0" is true.
  ./core/io/image.cpp:2772 - Condition "dsize == 0" is true.
  ./core/io/image.cpp:2772 - Condition "dsize == 0" is true.
  ./core/io/image.cpp:2772 - Condition "dsize == 0" is true.
  ./core/io/image.cpp:2772 - Condition "dsize == 0" is true.
  ./core/io/image.cpp:2772 - Condition "dsize == 0" is true.
  ./core/io/image.cpp:2772 - Condition "dsize == 0" is true.
  ./core/io/image.cpp:2772 - Condition "dsize == 0" is true.
  ./core/io/image.cpp:2772 - Condition "dsize == 0" is true.
  ./core/io/image.cpp:2772 - Condition "dsize == 0" is true.
  ./core/io/image.cpp:2772 - Condition "dsize == 0" is true.
  ./core/io/image.cpp:2772 - Condition "dsize == 0" is true.
  ./core/io/image.cpp:2772 - Condition "dsize == 0" is true.
  ./core/io/image.cpp:2772 - Condition "dsize == 0" is true.
  ./core/io/image.cpp:2772 - Condition "dsize == 0" is true.
  ./core/io/image.cpp:2772 - Condition "dsize == 0" is true.
  ./core/io/image.cpp:2772 - Condition "dsize == 0" is true.
  ./scene/3d/lightmap_gi.cpp:1169 - Condition "err" is true. Returning: BAKE_ERROR_CANT_CREATE_IMAGE
  Image format not supported for saving as EXR. Consider saving as PNG.
  Saving EXR failed.
Done baking lightmaps in 00:01:41.
PC specifications - **CPU:** Intel Core i9-13900K - **GPU:** NVIDIA GeForce RTX 4090 - **RAM:** 64 GB (2×32 GB DDR5-5800 C30) - **SSD:** Solidigm P44 Pro 2 TB - **OS:** Linux (Fedora 40)

The issue on your system is that VRAM and RAM utilization is very high during the bake. The bake process fully utilizes my RTX 4090's 24 GB of VRAM and uses 12+ GB of system RAM on its own (excluding other apps on the system). This is bound to cause issues on systems with less (V)RAM, to the point that some kind of chunked baking system is required (so that bakes are performed in smaller chunks).

Either way, even if the bake succeeds (like in my case), the resulting OpenEXR image can't be saved due to file format limitations.

I would try to detect this kind of situation for now and clamp the effective lightmap texel size (with a warning printed).

jcostello commented 1 month ago

@Calinou thank for the resport.

So mainly there are 2 problems:

1) Baking can overpass the VRAM and crash Godot 2) Still bakes but cant be save due to OpenEXR limitations

IMO this issues have to be solved. We have to take into consideration that this is happening in a demo scene that is not even that big as a level of a game can be.

1) Baking should happen in chunks to better use of VRAM. 2) If the resulting texture is bigger than the limit of the EXR file, we should split it in another layer or file.