Description
Godot version
4.0.alpha14
System information
Windows 11, Intel i7-10750H, Nvidia RTX 2060 Laptop (511.65), Vulkan
Issue description
Godot takes a lot of time to import a scene with big meshes. To better understand the problem I've been doing some tests with the new "Colorful Curtains" (without Base Scene) from the new Intel's Sponza scene. The scene has twelve 4K textures and several meshes that add up to a total of 1.059.862 vertices, and while Blender only takes ~7 seconds, Godot takes ~1 minute and 3 seconds to import. I've spent some time investigating the causes with a profiler and I've found that from that import:
- ~50 seconds are spent on LOD generation
- ~13 seconds are spent on Texture import
So I'd say the main issue is with LOD generation. Two observations:
- Using meshoptimizer, we start with a target of 12 indices (last LOD with 4 triangles), and multiply this number by two until we reach 75% of total indices. This works well for small meshes, but in this case a single mesh can have up to ~100.000 vertices and ~600.000 indices, generating 12 LODs. Most meshes in this scene generate around 10 LODs per mesh. This process takes 17 seconds of the total time.
- For each LOD, Godot performs a "normal reconstruction" where between 16 and 64 rays are casted from the face of each new triangle over the original mesh, so new triangles can preserve an aproximation of the original direction in their normals. This reconstruction takes a very long time because it requires in my test scene to cast a total of 10.739.327 individual rays using Embree. This process takes 33 seconds of the total time.
Some possible changes I can think of to make it faster:
- Make "Number of LODs" a mesh import setting, so we could have a default of 4 or 6 and let the user decide the total number. I think that's what Unreal 4 and Unity do.
- Make the initial target of 12 indices and/or the target index multiply step (2 right now) dependant on the total number of indices, so both smaller and larger meshes have similar number of LODs.
- Right now we start from smallest index target to largest and the original mesh is always used as a base when a new LOD is created. So instead start with the largest index target and use the previous LOD as the base for each new one. I remember reading this is more efficient but has slightly worse results, can't recall where.
- Use
meshopt_simplifySloppy
, which seems to be x6.6 more performant, and test if it has big perceptible differences and wether it's worth changing or not. - Explore other ways to do the "normal reconstruction" or reduce the number of rays per triangle.
I explained the issue a bit over Rocket.chat a few days ago, but I'd like some discussion on this before I attempt a fix (if I'm capable).
Steps to reproduce
Download "Colorful Curtains" or any scene from the new Intel Sponza. Move GLTF scene to project folder and see it takes a very long time to import.
Minimal reproduction project
No response