Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LightmapGI: Some meshes become completely unlit or black when baking lightmaps #73124

Closed
Tracked by #56033
BlockyDK opened this issue Feb 11, 2023 · 23 comments · Fixed by #81951
Closed
Tracked by #56033

LightmapGI: Some meshes become completely unlit or black when baking lightmaps #73124

BlockyDK opened this issue Feb 11, 2023 · 23 comments · Fixed by #81951

Comments

@BlockyDK
Copy link

BlockyDK commented Feb 11, 2023

Godot version

Godot 4 RC1

System information

Windows 10, GeForce 3070

Issue description

When baking lightmaps, some meshes will occasionally show as completely unlit. Sometimes they will bake properly, and sometimes they will not, but I have not been able to find any sort of pattern to it. None of the LightmapGI settings I have tried, nor settings on the meshes themselves, have had any effect. All of the meshes in this scene were imported with Light Baking set to Static Lightmaps and they have their Global Illumination mode set to Static. They are all instances and share the exact settings, but some of them become completely black after baking. On occasion, they will bake correctly even if I have not changed any settings.

Godot_RC1_LightmapRandomlyUnlitMeshes_01

Steps to reproduce

  1. Create a scene where all the static meshes are imported with Light Baking set to Static Lightmaps and their Global Illumination mode is set to Static.
  2. Place a directional light in that scene with shadows enabled and the Bake Mode set to Static.
  3. Add a LightmapGI and Bake the Lightmaps for the scene.

Minimal reproduction project

RC1_LightmapGI_UnlitMeshes.zip

@mikatomik
Copy link

I am still getting this in 4.0 stable. I have found something interesting, though. If I open up the inherited scene and go to one of the black meshes and manually re-UV unwrap layer two, it will bake the next time I try to bake. However, a different instance of the mesh that was displaying before will then go black at random. I'm definitely too dumb to understand what's going on but thought maybe that could be a clue for the smart brains.

@clayjohn
Copy link
Member

Now that you mention it, I have seen a similar issue that was caused by not having UV2s for the meshes. Typically reimporting with GI mode set to static + lightmaps has been enough. With the MRP, I reimported the mesh and tried baking again and the pillars were properly included in the bake.

@BlockyDK
Copy link
Author

BlockyDK commented Mar 16, 2023

Just to add to clayjohn's comment, back when I encountered this in RC1, reimporting would sometimes fix it, and sometimes wouldn't. And even if it did fix it, they would sometimes break in a later bake. At all times I could view the uv2 on the mesh, even when it was not baking correctly. What makes it strange is that the way the scene was set up, all the meshes are instances of the same source, so it is strange that some would bake and others would not.

@mikatomik
Copy link

mikatomik commented Mar 17, 2023

What makes it strange is that the way the scene was set up, all the meshes are instances of the same source, so it is strange that some would bake and others would not.

Yep same here. All of the wall meshes are identical, duplicated in blender and brought in through the blendfile.

image

Also, there are a lot of strange artifacts on some of the pieces.
image

And I'm getting these error messages that I'm not quite sure how to decipher. But I do know baking seemed to work properly until these little puppies showed up.
image

@mikatomik
Copy link

Apologies for blowing up this thread, and also for the picture of the screen. I don't have an internet connection at the moment. But something else that may be of interest. As I add more and more geometry to the scene, LightmapGI seems to start doing strange things. Here, you can see what looks like the UV outline of the plane... on the ground mesh?

image

This appears after I bake the light map, and toggles when I toggle visibility of the light map. And I think the artifacts in my above post might be just this, coordinates being projected onto incorrect objects which might be what's causing unlit meshes.

@Calinou
Copy link
Member

Calinou commented Mar 19, 2023

The debug gizmos should have shadow casting disabled to prevent this (I don't think this is done yet), but the property is ignored by the GPU lightmapper: #56870

@lw64
Copy link

lw64 commented Mar 22, 2023

I am not sure if it is related, but I have the same issue, some objects don't receive light, sometimes even only from certain lights, but not all. The environment lights the objects a bit up though. Also some objects are getting light, but there are really strange artifacts, like some parts of the mesh are glowing, as if there would be emission. And when enabling to bake also direct lighting, the artifacts like grey lines appear. After using a different lightmap scale than 1 it disappeared though. Another thing I discovered was that when baking the light, after it has finished, for a very short moment the correct lighting is visible, but then it disappears again and the wrong lighting remains.

I hope these information are useful for debugging. Maybe some of it is not related though.

Also this is blocking my project currently. Is there a workaround available?

@Calinou
Copy link
Member

Calinou commented Mar 23, 2023

I am not sure if it is related, but I have the same issue, some objects don't receive light, sometimes even only from certain lights, but not all.

Which rendering method are you using? While Forward+ has no limit on the number of lights per surface, Mobile is limited to 8 real-time lights per mesh surface. If you have more lights on a surface, the light may appear to flicker in and out depending on camera position for certain lights. To prevent this, you must bake static light by setting the light's bake mode to Static to prevent the light from disappearing if there are more than 8 lights on a given surface.

Another thing I discovered was that when baking the light, after it has finished, for a very short moment the correct lighting is visible, but then it disappears again and the wrong lighting remains.

This is most likely #71585.

Also this is blocking my project currently. Is there a workaround available?

Not that I know of, outside of baking lightmaps in Blender and using a custom shader to display them on materials (which is possible but tedious).

@mikatomik
Copy link

mikatomik commented Mar 23, 2023

Also this is blocking my project currently. Is there a workaround available?

My issues happened while using Forward+. Inexplicably, it fixed itself after several reimports of the scene, deleting the unwrap cache, and tweaking the"Lightmap Texel Size" at the import dock.

I do not know if those things directly fixed it, are even related, or if simply reimporting 100 times somehow fixed it, but that's how I got mine to bake properly. It kind of seems like chance.

I'm not a brain to pick for these things, and I have no idea how light baking works, but it really feels like a UV issue as sometimes I can see the outline of an objects UV layout on a completely separate object, like in my image above where you can see the plane's UV on the floor.

Also, if you are getting black artifacts with reflection probes, that went away when I unchecked "directional" in the LightmapGI bake settings.

@marius-se
Copy link
Contributor

Not that I know of, outside of baking lightmaps in Blender and using a custom shader to display them on materials (which is possible but tedious).

@Calinou I tried to find some resources online on how to do this, but I wasn't really successful. Can you recommend some keywords or even articles explaining how to do this? I think I need to make Blender output a UV2 map and somehow tell Godot to use the UV2 map... is that correct? 😄

@Calinou
Copy link
Member

Calinou commented Mar 27, 2023

I wonder if this issue is related to threaded culling or rendering.

Can you reproduce this if you increase the Rendering > Limits > Spatial Indexer > Threaded Cull Minimum Instances advanced project setting to 65536?

Also try increasing Rendering > Limits > Forward Renderer > Threaded Render Minimum Instances to 65536 if that doesn't resolve it.

@Calinou I tried to find some resources online on how to do this, but I wasn't really successful. Can you recommend some keywords or even articles explaining how to do this? I think I need to make Blender output a UV2 map and somehow tell Godot to use the UV2 map... is that correct? smile

It's been a long time since I've seen someone attempt using external lightmaps in Godot – last time I've seen it was in Godot 3.1, back when Godot used a different lightmapper with a different API. So I wouldn't know how to do it now, as I've never attempted it myself.

Godot should be able to import existing UV2 from a glTF scene without regenerating it. In this case, make sure the GI mode is set to Static and not Static Lightmaps in the Import dock (as I believe Static Lightmaps will overwrite existing UV2 – though I'm not 100% sure, so try both).

Note that OBJ does not support storing UV2, so you can't use that format even if you import it as a 3D scene in Godot (rather than a mesh).

@marius-se
Copy link
Contributor

I see, do I still need to add a LightmapGI to my scene?

@Calinou
Copy link
Member

Calinou commented Mar 27, 2023

I see, do I still need to add a LightmapGI to my scene?

It might be possible to create a LightmapGI node and add a new LightmapGIData to it, then load a lightmap Texture2DArray1 in the Light Texture property. I believe it must be a texture atlas, even if it only has 1 layer:

image

If that doesn't work, you'll need to forego LightmapGI and use a custom shader on your MeshInstance3Ds to use the lightmap texture sampled in UV2.

Footnotes

  1. Select the lightmap texture in the FileSystem dock, go to the Import dock and change its import mode from Texture2D to Texture2DArray.

@marius-se
Copy link
Contributor

I'll give that a try, many thanks!

@Racktash
Copy link

I'm seeing the seemingly random (suspect it's not, of course) black textures on lightmap bakes for some of my levels too.

I don't have sufficient knowledge to properly debug the lightmapping code, but I have some data that may be useful to somebody who is more knowledgeable.

I built a custom 4.1 master engine build (only difference being I enabled DEBUG_BSP_TREE to get a bsp.txt debug file). I had a level that was getting the "all black" bug which fixed itself when I copied every single node and pasted it into a new hierarchy without changing anything else.

I have the bsp.txt debug for the broken and fixed version of this map (again: the only difference is my copy and paste hack), and perhaps this contains a hint as to what's going on. bsp.txt files attached.

broken-bsp.txt
working-bsp.txt

Interestingly, the working BSP is missing some of the planes listed in the broken one.

@Racktash
Copy link

Spent another few hours trying to dig deeper and at least figure out what separates "working" and "not working" instances.

I found I was able to make one of my meshes work by moving it in the node tree (like, just changing the order – the parent remained the same) and rebaking. I could then move it back to its original position, bake again, and it'd be broken again (see screenshots).

I think this suggests that node order may have something to do with this while it is broken.

position1-bad
position2-good

I thought at first the meshes were not being found or were being filtered out by _find_meshes_and_lights – but so far as I've been able to see, the meshes that are not getting baked properly are detected and added to the found_meshes vector.

As ever, hopefully some of this data lights a bulb above somebody's head. For me, I remain baffled. :)

@Calinou
Copy link
Member

Calinou commented Sep 18, 2023

I can confirm this on 4.2.dev 221884e (Linux, NVIDIA 535.104.05).

This is what it looks like with the Static bake mode on lights:

Screenshot_20230918_235627

When using the Dynamic bake mode on lights then rebaking lightmaps, the real-time portion of the light is still visible on the black objects:

Screenshot_20230919_000928

This still occurs if all lights in the scene have their bake mode set to Disabled and lightmaps are baked again:

image

The same goes if you remove all light nodes then bake lightmaps again.

Testing project: test_dm6.zip

@Calinou Calinou changed the title LightmapGI: Some meshes become completely unlit when baking Lightmaps LightmapGI: Some meshes become completely unlit or black when baking lightmaps Sep 18, 2023
@jeffhube
Copy link

jeffhube commented Sep 19, 2023

I can also confirm on 4.2 dev 4 (Windows 11, AMD).

I have two scenes with different arrangements of hundreds of identical 1x1 PlaneMesh. Both scenes will only successfully bake lighting for the first 784 meshes in the scene. All the others are black except for any real-time lighting. If I decrease the lightmap size hint from the default of 7x7, then it will successfully bake lighting for more meshes.

image

@jeffhube
Copy link

I noticed that in my case, the lightmapper packs 7*7=49 meshes into each slice. One scene has 864 meshes, resulting in 18 slices. However, 16 slices * 7 * 7 = 784, which is exactly the number of meshes that are rendering correctly as I mentioned above.

Are we hitting some sort of limit at 16 lightmap slices?

@Racktash
Copy link

Racktash commented Sep 19, 2023

I noticed that in my case, the lightmapper packs 7*7=49 meshes into each slice. One scene has 864 meshes, resulting in 18 slices. However, 16 slices * 7 * 7 = 784, which is exactly the number of meshes that are rendering correctly as I mentioned above.

Are we hitting some sort of limit at 16 lightmap slices?

I didn't find the actual cause in my investigation, but I did recompile the lightmapper code with the debug definition in place. This spits out the generated bitmaps of the various stages of lightmap generation. I then printed the coordinates of each of my objects and matched the coordinates on the bitmaps and found the objects coming out black post bake were not black on the bitmaps. I also found I was able to fix the problem by clearing out my .Godot folder (not sure which bit of it was relevant).

So I never proved anything, but I was coming under the impression it was some filesystem / caching issue which would explain why when I imported the example project and baked I had zero problems – it's not a limits issue, it's a local project issue.

@jeffhube
Copy link

I did some more investigation and the issue seems to be that when there are more than 16 lightmap slices, it messes up some exposure normalization calculation in the shader which causes the meshes to be black.

Inside scene_forward_clustered.glsl, there is a line which samples the lightmap texture and then multiples it by the exposure normalization.

ambient_light += textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw, 0.0).rgb * lightmaps.data[idx].exposure_normalization;

If you remove the last part, * lightmaps.data[idx].exposure_normalization, then the meshes are no longer black.


In my scene, the lightmaps.data array contains only one populated element, which has an exposure_normalization of 1. All others have a value of 0.
image

So whenever idx is not 0, * lightmaps.data[idx].exposure_normalization effectively multiplies the lightmap by 0, turning it black.

idx is calculated as

uint idx = instances.data[instance_index].gi_offset >> 20;

gi_offset partially comes from here: (render_forward_clustered.cpp)

inst->gi_offset_cache = inst->lightmap_slice_index << 16;
inst->gi_offset_cache |= lightmap_cull_index;

So if I have a mesh that uses slice # 17 of the lightmap (index 16), then gi_offset is 16 << 16 = 1048576, and idx is 1048576 >> 20 = 1. Since idx is 1, exposure_normalization is 0, and so the mesh is black.

So at least in my scene, any mesh using the first 16 lightmap slices renders fine, and any others will appear black because the lightmap is multiplied by a 0 exposure_normalization.


As far as fixing this goes, I'm not clear on whether lightmaps.data is missing additional elements, whether the packing of data into gi_offset needs to be adjusted so that more than 16 lightmap slices doesn't change the index into lightmaps.data, or whether the lightmapper needs to be capped at 16 slices.

@bitsawer
Copy link
Member

I wonder if the exposure normalization from CameraAttributes is not always updated correctly, see #74139. I think the exposure normalization was added in #63751

I fixed a somewhat similar bug in VoxelGI: #81067, but there the effect was less noticeable (exposure was just reset to normal level).

@marius-se
Copy link
Contributor

Nice, thank you! 🙏🏼

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants