-
-
Notifications
You must be signed in to change notification settings - Fork 21.2k
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
Add inverted normals when flipped model scale #53642
base: master
Are you sure you want to change the base?
Conversation
This may have a performance cost for complex meshes, so it should probably only be done if Ensure Correct Normals is enabled in the SpatialMaterial. |
Can you confirm that this fix works when cull mode is set to cull front or cull back and not just cull disabled? |
I don't think we need such a property. The goal is to have something that works automatically, without requiring the user to adjust the material by hand if they flip the MeshInstance3D node. |
Might just be me, but I think I can still see the seam. Imo the material still behaves differently on the two sides. You will probably need to also flip some other properties like tangents and bitangents. |
I was writing a long answer for this, but I reached the conclusion that three different answers are reasonable here.
glFrontFace has the advantage that the shader doesn't need to change as it sees the correct value for glFrontFace. But it has the disadvantage of not allowing a single MultiMeshInstance to contain both types of meshes as a state change would be necessary.
Here's a strong argument in favor of fixing negative scale: these combinations are likely supported and specified in glTF 2.0. For this reason, fixing this issue might be necessary to make sure that glTF files with negative scale work. Here is a testcase for negative scale: For reference, here is the glTF issue where negative scale is brought up: In fact, donmccurdy makes a good comment here summarizing the issue with the multimesh usecase ( |
Oh, I omitted an important point and part of my explanation. This PR must be changed to wrap the determinant with code += "#if defined(DO_SIDE_CHECK)"
code += " if (determinant(mat3(WORLD_MATRIX)) < 0.0) {";
code += " NORMAL = -NORMAL;";
code += " }";
code += "#endif" Also, your code has a mistake that it was added inside the "triplanar" case. That is wrong: it should be done regardless of triplanar. So, let's step back a bit and understand why the normal needs to be flipped in the first place. Well, the answer is actually, quite simply, that it does not need to be flipped. In fact, this whole PR is trying to undo a normal flip which happens in the fragment program. So why does it need that macro check? It's because that Godot's scene shader does the following in the fragment
Let's go back and see which cases are currently broken in MeshInstance:
So yeah, we only want to be fixing So I would suggest actually adding it inside of the current |
There were some unfinished review comments. Can this be updated? It's great! |
Solves #29317
When the user scales a 3d model by -1, the model lighting gets messed, thanks to @lyuma I could solve this problem!
In the image examples below, its a multimeshinstance with half side of the kart flipped to another!
PS: Must be cherrypicked for 3.x
Before:
After: