Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect shader normal calculation in godot 4 compared to godot 3 #79647

Closed
FireCatMagic opened this issue Jul 19, 2023 · 3 comments
Closed

Comments

@FireCatMagic
Copy link

Godot version

Godot v4.1.1.rc1 and 3.5.2.stable

System information

Godot v4.1.1.rc1 - Windows 10.0.19045 - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 750 Ti (NVIDIA; 31.0.15.3179) - 12th Gen Intel(R) Core(TM) i5-12400F (12 Threads) - Windows 10.0.19045 - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 750 Ti (NVIDIA; 31.0.15.3179) - 12th Gen Intel(R) Core(TM) i5-12400F (12 Threads)

Issue description

Godot 3

image

Godot 4

image

If you did not notice, the positive Z facing direction is broken on the Godot 4 version.
image
It's correctly calculated in the godot 3 version
image

These are both the exact same scene using the exact same shader.

The z facing normal is controlled by these two lines, which (obviously) breaks it when removed:
image

The shader in godot 4:
image

The exact same shader in godot 3:
image

The expected behavior is that this shader will function the same in godot 3 and 4.

Steps to reproduce

Open the projects, and observe the shaders and how they are the same in both

Minimal reproduction project

I've included both projects below.
NormalsGD4.zip
NormalsGD3.zip

@bitsawer
Copy link
Member

bitsawer commented Jul 19, 2023

Instead of using floating point equality comparison, use an epsilon, like this:

if (abs(NORMAL.y) < 0.0001) {

seems to fix the issue.

You should generally avoid comparing floating points using == / != operators. It can be safe in some situations, but in practice it's often not. Especially depending on how you import or generate the mesh, the mesh import pipeline might add some inaccuracies if it recalculates normals or other data.

abs

@AThousandShips
Copy link
Member

Once #77239 is merged you'll be able to use is_equal_approx/is_zero_approx as well

@Calinou
Copy link
Member

Calinou commented Jul 19, 2023

This is not a bug (but caused by floating-point precision errors), as described above. It might happen to work in Godot 3, but it's not guaranteed that it will keep working there correctly forever. This is why you want to use approximate comparisons instead of exact comparisons.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants