godotengine / godot

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

Normalmap inverts at certain angles on mesh rotated by bone. #81446

Open jitspoe opened 1 year ago

jitspoe commented 1 year ago

Godot version

4.1.1.stable.official

System information

Windows 10, Vulkan forward +

Issue description

Under certain conditions, it's possible for the normal map to effectively invert the lighting, as seen here: revolver_normal

I tried to make some simpler repro cases in the background, but, for some reason, the issue only happens with my revolver. This was originally happening with a procedurally rotated bone using skeleton.set_bone_pose_rotation, but I tested with an animation driving the bone and the issue still happened.

My hypothesis is that the tangent and/or binormal are getting miscalculated because a cross product is attempted with 2 vectors that are the same somehow, but I could be way off.

Steps to reproduce

I attempted to recreate this using a simple skinned 6-sided cylinder mesh with a rotation animation by itself, but, alas, the issue only seems to repro with my KOOK game asset, so I've included that in the repro project:

Minimal reproduction project

test_animation_normalmap.zip

bitsawer commented 1 year ago

I can confirm this on current master too (0bca4242392992840b0b891acde6422c49712e3e). Pretty interesting, I would also guess that something goes wrong with the skinning tangent space or related calculation when a bone is rotated/scaled in a certain way. Manually rotating rr_cyl1 bone around its cylider axis in pose mode also seems to cause this bug, but if you also rotate bone's another axis a bit it seems to "fix" the issue, so there could indeed be some kind of axis issue.

jitspoe commented 1 year ago

Yeah, certainly bizarre that I couldn't seem to reproduce it with basically the same kind of mesh as well, just isolated to a 6-sided cylinder. I added like 0.01 rotation on another axis to work around it for now. Thanks for the temp fix idea.

I thought maybe it was something to do with the GLTF tangents, as I had another asset that had inverted normals and I had to shut off tangent exports and let Godot handle the tangents, but I also tried that on this asset and it didn't fix it.