godotengine / godot

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

Normal maps are distorted on flat surfaces #84145

Open Crazymonkay opened 11 months ago

Crazymonkay commented 11 months ago

Godot version

v4.1.2.stable.mono.official [399c9dc39]

System information

Godot v4.1.2.stable.mono - Windows 10.0.19045 - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 1070 (NVIDIA; 31.0.15.3713) - Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz (8 Threads)

Issue description

Normal maps baked in Blender or Substance Painter appear distorted when rendered in Godot, for example this cube: Godot_v4 1 2-stable_mono_win64_l6nws2GYrq

I am ignoring banding and compression artifacts. Compare this to the same cube with the same normal map viewed in Blender with no warping: blender_Wer2EC8XgU

Also viewed in Unity, again with no warping: Unity_ERDId4rOsL

I have checked the following things to try and ensure that it is not my model or baking workflow that is producing this issue:

  1. The mesh is triangulated using the Triangulate modifier, and Apply Modifiers is checked when exporting.
  2. The normal map follows OpenGL style (it wouldn't appear correct in Blender or Unity otherwise).
  3. Exporting tangents has no effect.
  4. I have not found any import options in Godot for the normal map texture or model that have any effect.

Steps to reproduce

  1. Download the attached zip archive. This contains a Godot project in the Normal Map Issue folder, as well as a Cube.blend source file.
  2. Open the Godot project within the Normal Map Issue folder, and open Cubes.tscn. This scene contains cubes imported from glTF and OBJ.
  3. Observe that both cubes distort the specular highlight.
  4. Optionally open the Cube.blend file and observe there are no distortions to reflections or highlights.

Minimal reproduction project

Normal Map Issue.zip

clayjohn commented 11 months ago

It seems that you are using per-vertex normals in Godot which is leading to the distortion. Here is a comparison using your MRP with a BoxMesh added in between the gltf and .obj using the "normal buffer" viewport mode.

image

Looking at your normalmap it looks like you have baked in the reverse of the normal into the tangent map to somehow undo the per-vertex normals, is that correct?

Screenshot from 2023-10-29 17-09-36

The end result gets close to having proper flat-shaded normals, but is skewed. Likely from using different tangents

image

Crazymonkay commented 11 months ago

It seems that you are using per-vertex normals in Godot which is leading to the distortion. Here is a comparison using your MRP with a BoxMesh added in between the gltf and .obj using the "normal buffer" viewport mode.

Looking at your normalmap it looks like you have baked in the reverse of the normal into the tangent map to somehow undo the per-vertex normals, is that correct?

The end result gets close to having proper flat-shaded normals, but is skewed. Likely from using different tangents

Yes, the low-poly cube I am using for this is entirely "smooth" with no sharp/split edges. I tend to model things this way because split edges produce their own artifacts. Using a cube like the one you showed, with a baked normal map notice the creases along the edges: Godot_v4 1 2-stable_mono_win64_KVF7dQK8c7