SoftBody3D: face normals aren't fully recalculated every frame for lighting purposes.
Godot version
v4.1.stable.official [970459615]
System information
Godot v4.1.stable - Windows 10.0.19045 - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 1660 (NVIDIA; 31.0.15.3179) - Intel(R) Core(TM) i5-9400F CPU @ 2.90GHz (6 Threads)
Issue description
When a SoftBody3D is receiving light from a DirectionalLight3D, any faces that start out fully lit by a DirectionalLight3D remain fully lit by it, as if the face remained pointing at the DirectionalLight3D light source the entire time.
Similarly, any faces of a SoftBody3D that start out without any lighting from a DirectionalLight3D are never lit by that light source, as if the face was always pointing away from the DirectionalLight3D light source.
The net result is that in a scene with a PlaneMesh-shaped SoftBody3D and a DirectionalLight3D, where the SoftBody3D has a material applied which allows both sides to render, one side of the SoftBody3D is significantly darker versus the other side, regardless of the current deformation.
Steps to reproduce
- Unzip, import and edit the attached project.
- Open
main.tscnfor editing. - Run the attached project for a few seconds.
- Notice the incorrect lighting of the
SoftBody3Dby theDirectionalLight3D. Example screenshot attached:
Minimal reproduction project
face normals aren't fully recalculated
Are they even recalculated in the first place?
The exact behavior I'm observing in the test setup attached in the original project after some deformation of a SoftBody3D can be described as follows:
- You might not notice it, but there are some relative differences in shading between adjacent faces on the same side, based on the angle between the faces. See attached screenshot for a better example.
- However, the overall brightness of a given face of the
SoftBody3Ddoes not change significantly over time (bright faces remain bright, dark faces remain dark).
The material is a standard 3D material with a solid white color, with the only change being Transparency -> Cull Mode: Disabled (and all other properties default).
Well, unless there are some extra settings needed then I think I can confirm this on my side too. I tried adding omnilight to see what happens there but it's not ok too as you can see below.
- Front plane having light
- Back plane no idea what exactly is happening
In the editor both sides are ok with omni as well as directional, only during simulation you can see the issue.
EDIT: Video of how it looks in action https://github.com/godotengine/godot/assets/33526847/664e2cb5-32b9-4081-bad1-7fe0bbda7d7d
I noticed that all else being equal, the initial rotation of the SoftBody3D node matters too. As @viksl mentions, it doesn't happen in the editor.
Running:
Editor:
Godot version: v4.1.3.stable.official [f06b6836a] System: MacBook Pro M2 Max, Sonoma 14.1.1 Reproduction project: SoftBody3D Lighting Issue Reproduction.zip This happens in all rendering modes: Forward+, Mobile and Compatibility
After upgrading from Godot 4.1.3 to 4.2.1, I noticed that the reproduction I posted above yields the expected (correct) result. See screenshot above.
I then tried it on the reproduction project of the issue's author, where it seems to work as expected too:
Thanks for testing! Closing as fixed in 4.2.