godotengine / godot

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

lightmap visual glitches #85730

Open Enhex opened 7 months ago

Enhex commented 7 months ago

Godot version

v4.2.stable.official [46dc27791]

System information

Godot v4.2.stable - Manjaro Linux #1 SMP PREEMPT_DYNAMIC Tue Nov 28 20:37:45 UTC 2023 - X11 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 2060 SUPER (nvidia; 545.29.06) - AMD Ryzen 9 3950X 16-Core Processor (32 Threads)

Issue description

black rectangles (appeared in other places too): image image

texture bleeding? image without denoiser: image

this one seems like it uses UV1 instead of UV2. after deleting the corner prefab and creating a new instance this offset thing was fixed. image UV1: image UV2: image

light penetration? image

Steps to reproduce

don't know how. might be related to 4.1 to 4.2 upgrade?

Minimal reproduction project

tried create a new project with the same wall/floor/ground meshes but it didn't reproduce it.

DarioSamo commented 7 months ago

tried create a new project with the same wall/floor/ground meshes but it didn't reproduce it.

Sounds like it might be similar to this if you're using primitive meshes instead of OBJ imports.

We couldn't determine much but it seemed like the UV2 generation had some issues that were exposed by the half pixel offset, which in turn fixed the issues present in OBJ imports.

Are you using primitive meshes or OBJ meshes?

Enhex commented 7 months ago

the wall/floor/ceiling meshes are made in Blender and imported as .glb files. and the UV2 is manually created in Blender.

DarioSamo commented 7 months ago

the wall/floor/ceiling meshes are made in Blender and imported as .glb files. and the UV2 is manually created in Blender.

Does it get fixed if you let Godot auto-generate the UV2 instead? I'm wondering if a discrepancy has popped up between both of them.

Enhex commented 7 months ago

when i tried auto-generate it was broken. before auto-generate: image after auto-generate (had to make the mesh unique in case it matters): image

DarioSamo commented 7 months ago

when i tried auto-generate it was broken.

Did you re-bake the lighting after auto-generating the UV2s?

Enhex commented 7 months ago

didn't try originally.

after trying and using auto-generated for wall/floor/ceil meshes:

image image

floor (wall is the same black rectangle as last post): image

DarioSamo commented 7 months ago
* floor black rectangles seems to be gone

* introduced seams between meshes

* slightly improved the UV offset thing but didn't completely fix it

* unwrapped wall and floor scenes remain messed up

That's a lot of different issues so I'd try ruling them out one by one to see if we can find any actual issue caused by the lightmapper.

Let's start with the first one, as I've explained in other issues, lightmapping is pretty much the enemy of kitbashing if you push really low resolutions and it looks like those tiles on the walls are all individual meshes. It's like trying to get two blurry textures to match across two planes, it's pretty much never gonna look right. Does the issue of the first picture get alleviated if you increase the resolution (by modifying their texel size)?

As for the original issues, I think it reveals there's a discrepancy between whatever tool was used to generate the UV2 and what Godot seems to be expecting, although I'm not sure about saying who's in the right without seeing the mapping itself in numerical detail.

Enhex commented 7 months ago

this is the actual problem with the first pic in my last post (auto-unwrap): image compared to the first post (manual unwrap): image

I used Blender and it's a simple square with UV1 having an offset to align the texture I'm using.

additionally when i tried to use Ultra lightmap setting Godot freezed after running for over an hour.

Calinou commented 7 months ago

Please upload a minimal reproduction project[^1] to make this easier to troubleshoot.

[^1]: A small Godot project which reproduces the issue, with no unnecessary files included. Be sure to not include the .godot folder in the archive (but keep project.godot).

Drag and drop a ZIP archive to upload it. Do not select another field until the project is done uploading.

Note for C# users: If your issue is not Mono-specific, please upload a minimal reproduction project written in GDScript or VisualScript. This will make it easier for contributors to reproduce the issue locally as not everyone has a Mono setup available.

Enhex commented 7 months ago

here's the scene that causes trouble (too big for github upload): https://virhex.com/d/lightmap.zip

Enhex commented 6 months ago

compared to the first post (manual unwrap): image

this problem turned out to be a leftover "make unique" mesh from enabling "Editable Children" that was later disabled, so this is a bug with the revert when disabling not working.

resetting the mesh fixed it.

Enhex commented 6 months ago

disabling "use texture for bounces" fixed the black rectangles, so this feature is bugged.

perhaps it's related to the scene's size?

DarioSamo commented 6 months ago

disabling "use texture for bounces" fixed the black rectangles, so this feature is bugged.

perhaps it's related to the scene's size?

That feature isn't bugged, it's a shortcut option. Normally when computing samples the tracer can choose to grab the light data that was computed on the first light pass or compute it from scratch. Disabling is more accurate but much slower on scenes with multiple lights.

If disabling helps you out then that's for the best, but it probably indicates your lightmap resolution is too low or your UVs are too stretched if it's making a significant impact.

From the docs:

If true, a texture with the lighting information will be generated to speed up the generation of indirect lighting at the cost of some accuracy. The geometry might exhibit extra light leak artifacts when using low resolution lightmaps or UVs that stretch the lightmap significantly across surfaces. Leave use_texture_for_bounces at its default value of true if unsure.

Enhex commented 6 months ago

Just to be clear i was referring to this kind of black rectangles: eb2f1a0b-c346-446b-bba3-1d10265116e3 (this one is roughly 0.96mx0.12m)

having big black rectangles randomly appear at well lit places isn't "some accuracy" tradeoff, something is wrong, or perhaps you can explain why they appear if it's a known side effect? perhaps the texture is being sampled at wrong coordinates?

not sure what lightmap resolution refers to. max_texture_size is set to 16384. the generated .exr file is 1024x12288. it does contain black margins where nothing was rendered in each 1024x1024 block, perhaps that's what's being sampled?

all UVs in this scene are 1x1 and 1x3 so streched UVs doesn't seem likely to be the problem.

EDIT: I can't reproduce the black rectangles anymore, perhaps they were related to the unique mesh with wrong UV offsets.

DarioSamo commented 6 months ago

Sorry, I mistakenly edited your comment instead of replying. Will reply in a bit.

DarioSamo commented 6 months ago

perhaps the texture is being sampled at wrong coordinates?

That's what I mean by the fact the flag isn't bugged. The flag itself enables the behavior of the tracer to take this shortcut and sample the texture. If for whatever reason the texture sampling itself is wrong, that error will carry over. That's why I said the feature itself isn't broken, it's just carrying over the error from another step.

However it sounds like it was unrelated if you can't reproduce it, so I think I'm still with the theory that the coordinates are at fault in one of the iterations you've tested of this.

Enhex commented 4 months ago

here's a minimal reproducible case: lightmap_demo.zip image

looking at the generated lightmap it seems like pixels at the edges are shifted, possibly mismatching their UV coordinates? image

lander-vr commented 1 month ago

I imported a cube from Blender with the same dimensions (1m), and imported it with a texel size of 0.2 (same as the project settings) and this is the difference between the two: image

Lightmap size hint of the primitive mesh: image

Lightmap size hint of my imported cube: image

Since they are the same scale, I'd expect to see the same value here.

Changing the texel scale parameter in the lightmapper to add a bit more resolution entirely resolves the issue though: image

There seems to be a discrepancy between the "texel size" in the project settings and the "lightmap texel size" in the import window. It looks like the lightmaps of the primitive meshes are generated at the expected resolution: A texel size of 0.2 unites per texels means you get 5x5 texels on a 1x1m surface, which lines up with what we're seeing in the scene. I'm not sure why this scale is so different for imported meshes.

lander-vr commented 1 month ago

Changing the texel size in project settings (the one for primitive meshes) to 0.05, and regenerating the UV2s of the primitive box, gives a texel density that seems to match up exactly with the imported model. image

However, the artifacts in the corners and on the edges reappeared. Kinda seems like this might be happening: https://github.com/godotengine/godot/issues/69126#issuecomment-1734730220 .

Enhex commented 1 month ago

the linked comment seems to suggest it's texture bleeding due to wrong UVs.

while it's probably not the problem as the generated UVs include padding, I will mention the following just to be safe: correct padding size may also depend on stuff like texture filtering that causes neighboring pixels to also be sampled.

higher resolution will make the texture bleeding smaller and/or less likely to happen, but it's still there and there's still a bug.

also the shifted lightmap pixels are still a possible source for problems, possibly making the UV coordinate problem worse.

lander-vr commented 1 month ago

the linked comment seems to suggest it's texture bleeding due to wrong UVs.

The reason I'm inclined to believe this is a UV issue is because I can't really spot any substantial difference in the bake results between the imported cubes and primitive cubes: (primitive cubes) image (imported cubes) image

I think the shifted pixels you're seeing are from the dilation step (and/or maybe the blendseams step). We see the same effect on the lightmaps of the imported cube and those don't show any artifacts, so I'm not entirely convinced that that's the (or an) issue.

higher resolution will make the texture bleeding smaller and/or less likely to happen, but it's still there and there's still a bug.

This isn't the case, when using texel scaling in the lightmapper node the artifacts do go away, but when increasing the texel size for primitive meshes in the project settings and regenerating their uv2 the artifacts stay, despite being at a higher resolution. So for example, generating the uvs with a density of 0.1 and texel scaling of 1 in the lightmapper has the artifacts, but generating them with a density of 0.2 and texel scaling of 2, giving us the same texel density in the end, does not. image

Does look like the issue is insufficient padding between islands. The normal EXRs reveal that the primitive cubes only have 1 pixel of padding between the islands: image

Compared to two pixels for imported cubes: image

I'm guessing when using texel_scale it does not change any padding, so when baking with a texel scale of 2, the primitive islands do have 2 pixels of padding, getting rid of the bleeding.

I don't know why there is a pixel missing in one corner in each island, this could be giving that shifted pixel impression too once dilation has happened and filled that pixel in.

I'm not entirely sure why this padding is so tight on both though. I'd expect the denoiser to cause leakage with islands this tightly packed too, which you can see in the leakage/padding example in https://github.com/godotengine/godot/pull/91601#issue-2279700017

Calinou commented 1 month ago

For reference, UV2 on primitive meshes was added in https://github.com/godotengine/godot/pull/67975.

cc @BastiaanOlij

Enhex commented 1 month ago

I don't know why there is a pixel missing in one corner in each island

maybe off by 1 error in some loop?

lander-vr commented 1 month ago

The editor (current dev build v4.3.beta.custom_build [8e2141eac] ) is freezing up for me when I try to bake after changing the lightmap padding on the primitive to anything other than 2 (i.e. 3 or 4). The freeze happens on determining optimal atlas size, there seems to be something funky going on here with the uv2 generation.