godotengine / godot

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

Lightmap baking creates noticeable seams on meshes #90929

Open reptofrog opened 2 months ago

reptofrog commented 2 months ago

Tested versions

v4.2.2.stable.official [15073afe3]

System information

Godot v4.2.2.stable - Fedora Linux 39 (Workstation Edition) - Wayland - Vulkan (Forward+) - integrated AMD Radeon Graphics (RADV RENOIR) () - AMD Ryzen 7 5700G with Radeon Graphics (16 Threads)

Issue description

Lightmap baking creates noticeable seams on meshes.

The seams appear with and without the denoiser.

image

Minimal reproduction project (MRP)

Lightmap Seams.zip

passivestar commented 2 months ago

Can confirm, in my experience more often than not cylinders bake with stripes

I wasn't able to get rid of them by changing any settings

image
patwork commented 2 months ago

Yep, there are some serious problems with lightmaps even in 4.3 master.

scene: ll

lightmap: ll2

https://github.com/godotengine/godot/issues/87815

for comparison, this is what the ligtmap looks like in a similar scene (5 planes and 2 cylinders) generated by CPU lightmapper in Godot 3.5.3

ll3

passivestar commented 1 month ago

Can confirm, in my experience more often than not cylinders bake with stripes

This is what they look like in the lightmap:

stripes

lander-vr commented 1 month ago

Aside from Passivestar's issue, which I don't think is related to this issue post and probably needs its own issue report, the these baking errors come down to poor lightmapper setups, which I think can be attributed to a lack of documentation on how to use a lightmapper. If I can find the time, I could work on a guide to add to the docs going over how to achieve clean bakes with LightmapGI, and covering some common pitfalls that arise.

The issues shown here come from a combination of a too low lightmap resolution (which could be attributed to Godots very low default texel density) and a bake that's not converged well enough (quality is set too low). This results in a very low resolution, very noisy render, which is practically impossible to denoise to a point where you get a qualitative result. You can see in this first example bake (OPs settings) how practically every neighboring pixel has a completely different color: image With this as a starting point, it is expected to get a poor end result even using denoising.

First thing I did was to increase bounces, this gives the rays more opportunities to bounce off of surfaces and hit the backs of the cylinders/sphere: image

Increasing the quality to ultra, without denoising, you can see how the overall result is much cleaner. This will give much better results from the denoiser, because instead of having to go from pure noise to a clean smooth result, it only has to work away some smaller inconsistencies. The seams are still very visible though: image

To reduce the seams, we need to increase how much detail is shown, which we do by increasing the texel density. You can see the seams practically all disappear (except the sphere but I'll get to that): image

Adding the denoiser to this gives us a qualitative clean result with no seams: image

I do think it is strange that those leaks in the corners still occur though. Luckily the denoiser is able to smooth those away, but it is reducing AO that would and should be present there. I think https://github.com/godotengine/godot/pull/81872 should've resolved that. Cc: @DarioSamo

The sphere still shows a bad seam, and this comes down to the UV2 unwrap: image

Spheres would be more appropriately unwrapped as two individual hemispheres.

As for @passivestar's issue:

Can confirm, in my experience more often than not cylinders bake with stripes

I wasn't able to get rid of them by changing any settings

image

This one is strange, because it looks like those two lines on the right side are showing up in the middle of your lightmap and not at the borders of your UV islands. The two lines on the left side have a hard cutoff caused by the edge of the lightmap UV island, which would indicate an issue with padding or something along those lines, but those two on the right side don't seem to have that so it looks like they're just random rows of pixels in the middle of a UV island that are experiencing light leakage somehow.

patwork commented 1 month ago

I am sorry but I cannot agree with this. Of course increasing the resolution of lightmaps will improve their appearance, but the problem of light leakage at the edges remains, it's just a little sharper.

Please, compare the lightmaps from 3.x and 4.x - the ones from 3.x are clean from edge to edge, while the ones from 4.x have strange lighter borders. Denoising is not the solution as it only blurs these borders making them appear even larger at times.

All the time something is wrong with the accuracy of the calculation, perhaps the UV boundary conditions? Where are those black pixels in the corners of the faces in the lightmaps from 4.x coming from? Where do these lighter edges come from?

Is there any way to see the uv2 grid and the generated lightmap at the same time?

Unity

lander-vr commented 1 month ago

This issue isn't about light leaks at corners though, it's about seams appearing on meshes. Those are a universal thing with any lightmapper and the steps I have gone over is how you'd go about reducing those seams in other lightmappers too.

Please, compare the lightmaps from 3.x and 4.x - the ones from 3.x are clean from edge to edge, while the ones from 4.x have strange lighter borders. Denoising is not the solution as it only blurs these borders making them appear even larger at times.

I addressed those leaks and cc'd Dario because he'll likely have a better idea what's causing those since he worked on a PR to resolve that particular issue. I didn't mean to say denoising is an appropriate solution for this issue, just that in this situation it does not show up very visibly after denoising with the drawback of reducing AO that would be present in those corners.

My guess is that when UV islands are not aligned to the edges of texels, the center of a pixel (due to half-pixel offset) can be in a position that's not on the actual mesh, which would cause it to shoot out a ray that's not originating from a point where the surface of that mesh exists. This means that when you have a floorplane and simple planes as walls around it, that ray can be shot out from behind a wall (because the center of a pixel may be there), thus not intersecting with that wall, in this case returning the environment lighting. This would also explain why those leaks get severely reduced when increasing resolution.

That said, I would suggest to open an issue that specifically addresses those particular leaks, if it doesn't exist already.

Where are those black pixels in the corners of the faces in the lightmaps from 4.x coming from?

Those single pixels are in the padded areas and don't show up on meshes themselves, it's likely something to do with how the padding algorithm works but I don't really see how those would cause any issues since it's not within the lightmap UVs, except maybe when generating mipmaps.

DarioSamo commented 1 month ago

My guess is that when UV islands are not aligned to the edges of texels, the center of a pixel (due to half-pixel offset) can be in a position that's not on the actual mesh, which would cause it to shoot out a ray that's not originating from a point where the surface of that mesh exists. This means that when you have a floorplane and simple planes as walls around it, that ray can be shot out from behind a wall (because the center of a pixel may be there), thus not intersecting with that wall, in this case returning the environment lighting. This would also explain why those leaks get severely reduced when increasing resolution.

There's a suspicion that is very much the case for simple meshes that weren't imported. Here's the issue where I last suspected some meshes are being generated with the wrong UV2.

mikatomik commented 1 month ago

Dropping in to say I'm having this issue with non-cylinder meshes as well. I'm on 4.2.2 Windows.

I made a small modular kit, the meshes are manifold and normals are correct. Each piece of the kit has a crazy seam on it after baking. Maybe it's related? Here's screenshots in lighting view:

Before LightmapGI: image

After LightmapGI: image

and without Lighting view: image

Normals in Blender: image

lander-vr commented 1 month ago

@mikatomik This is a classic issue with lightmappers and modular kits. Related to #82607, and will be (mostly) resolved by https://github.com/godotengine/godot/pull/91601. @Calinou has made a proof-of-concept implementation for lightmap downsampling, which together with the denoiser-range property will give the tools needed to entirely resolve seams between modular meshes and support modular workflows.

mikatomik commented 1 month ago

@lander-vr Ah, thanks for the info. Wasn't aware that's a common issue with modular pieces. Shows what I know about the lower-level stuff. 😅 Hopefully Calinou's work will straighten this out down the line. Thanks!