godotengine / godotengine/godot
Differing UV2 generation for primitives and imported meshes causes LightmapGI inconsistencies
- Dominant language
- C++
- Stars
- 117k
- Forks
- 26.8k
- PR merge metrics
- PR metrics pending
Description
### Tested versions
- Reproducible in: 4.0.stable onwards
### System information
Godot v4.5.1.stable - Windows 10 (build 19045)
### Issue description
I'm unclear whether this is intended behaviour as its existed in some form since 4.0, but the lightmap LightmapGI generates for a 1x1m PlaneMesh is not the same as the lightmap it generates for an imported 1x1m plane made in Blender and they are aligned on the meshes differently.
This issue is related and possibly intertwined with another issue I just opened: https://github.com/godotengine/godot/issues/112768. It strikes me that either there will probably need to be two different fixes for 112768 for primitives and imported meshes or this issue needs to be resolved at the same time, so the generated lightmaps and their alignment across the meshes is the same.
The following is a comparison in 4.5.1. As with the other issue, Denoiser and Use Bicubic Filter are both off to get as 'raw' a result as possible and I'm reimporting the .exr as Lossless in Compatibility so you can see the issue more clearly but the problem is unchanged across renderers. Texel size is the default 0.2 for both. So firstly the issue of the lightmaps not being symmetrical when they should be (see https://github.com/godotengine/godot/issues/112768 concerning PlaneMesh) is also true for the imported mesh. The imported mesh lightmap actually looks like it would be symmetrical were it not misaligned, in this case the expected centre has been shifted down and right (+X, +Z) and the texels no longer align with the edges of the mesh. However the lightmap for the imported mesh is also completely different.
The lightmaps that are being generated for a PlaneMesh and an imported mesh are different but how they are being applied on to the meshes is also different. There's the obvious thing that the texels are aligned differently to the edges but it would appear for the imported mesh the lightmap is also being rotated 90 degrees clockwise (which explains the different direction of shift when applied to mesh) as the shift is in the same direction in the actual lightmap file. It's also worth nothing that the generated Lightmap Size Hint is different - the PlaneMesh has 7x7, whereas the imported mesh has 6x6.
Going back to 4.0 it seems lightmaps have always generated differently for primitives compared to imported meshes. It appears the texels have always been aligned with the edges on primitive meshes and not on imported meshes. It is unclear whether the rotation of the lightmap was occurring in this example as the centre of the light is correctly aligned here as https://github.com/godotengine/godot/issues/112768 only became a problem from 4.1.2 onwards.
Moving the light to the right to check and the lightmap of the imported mesh is indeed being rotated 90 degrees clockwise in 4.0. This is because the lightmap in the file is 'facing' a different direction (upwards in this case, instead of to the right) and needs to be corrected. So the rotation has always been present.
Unless there is a technical reason that I am not aware of I would expect the lightmap to be identical (or at the very least much more similar) across primitives and imported meshes if they have the same texel density. Please note I have so far only tested this with a plane so I don't know for sure whether it applies to other primitives.
### Steps to reproduce
Open the MRP. Toggle the visibility of the MeshInstance3D to see the difference in the lightmaps between it and the imported 1mPlane. If you want to see the texels clearly, in Compatibility select test1.exr and reimport it in Compress Mode Lossless.
### Minimal reproduction project (MRP)
[LightmapGI_plane_tests.zip](https://github.com/user-attachments/files/23555670/LightmapGI_plane_tests.zip)
Contributor guide
Research direction
Start with the attached LightmapGI_plane_tests.zip and reproduce the comparison between the PlaneMesh and imported 1m plane, including the generated Lightmap Size Hint and lightmap orientation. Read the LightmapGI, primitive mesh, and imported mesh paths involved in UV2 generation, then compare the generated lightmaps and their alignment at the same texel density. Done means the intended behavior is established and the discrepancy is corrected or clearly documented.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- computer-graphics, game-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100