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

CSGCylinder3D has incorrect normals compared to the CylinderMesh primitive #49800

Closed
Calinou opened this issue Jun 21, 2021 · 4 comments · Fixed by #59039
Closed

CSGCylinder3D has incorrect normals compared to the CylinderMesh primitive #49800

Calinou opened this issue Jun 21, 2021 · 4 comments · Fixed by #59039

Comments

@Calinou
Copy link
Member

Calinou commented Jun 21, 2021

See also #19143.

Godot version

4.0.dev (6d98f84), 3.3.2

System information

Fedora 34, GeForce GTX 1080 (NVIDIA 465.31)

Issue description

CSGCylinder3D has incorrect normals compared to the CylinderMesh primitive.

CSGTorus3D also has unexpected normals compared to a torus exported from Blender (due to a sharp line in the middle), but it's not as bad.

Top: CSG nodes (torus, box, sphere, cylinder) or meshes (Suzannes, sharp cylinder).
Bottom: MeshInstances with primitive meshes (box, sphere, smooth cyulinder) or OBJs exported from Blender (torus, Suzannes, sharp cylinder).

image

This also occurs on 3.3.2. CSGCylinder on top, MeshInstance with CylinderMesh at the bottom:

image

Steps to reproduce

  • Create a CSGCylinder node and set the number of sides to 64 to match a CylinderMesh.
  • Create a MeshInstance node, add a CylinderMesh to it.
  • Place the MeshInstance above/below the CSGCylinder and compare the lighting on both.

Minimal reproduction project

@devvoid
Copy link

devvoid commented Jul 14, 2021

CSGSphere has the same issue.

Taking a guess, this might be the CSG models not having merging vertices that share the same coordinates - you get similar errors in Blender if you use the spin modifier to make a circular object, but disable "Auto Merge". I've included an exported model in my test project to show what I mean.

From top to bottom: CSGSphere, MeshInstance sphere, UV sphere from Blender (made with the spin modifier, Auto Merge disabled).

Screenshot from 2021-07-13 23-41-58

CSGSphereNormals.zip

@unfa
Copy link

unfa commented Dec 16, 2021

I have the same issue. Here's how the shading looks after subtracting a CSG cylinder from a block:

Clipboard - December 15, 2021 11_06 PM

@unfa
Copy link

unfa commented Dec 16, 2021

I suspect this is what's going on:
The CSG cylinder's curved shell's normals point away from the whole object's origin, rather than from the center of a ring of vertices they belong to (top or bottom).

Here's an illustration of what I suspect is going on:

Screenshot_20211216_141626

Of course the normals are split on edges with the flat top and bottom faces, but I'm omitting these as they appear to be correct.

I have no idea how the code looks like, but maybe this is enough to help fix it?

@Calinou
Copy link
Member Author

Calinou commented Feb 16, 2022

I looked briefly at fixing this, but it appears the CSG shape's normals are automatically generated with no way to manually override them:

Plane p(n->faces[i].vertices[0], n->faces[i].vertices[1], n->faces[i].vertices[2]);
for (int j = 0; j < 3; j++) {
Vector3 v = n->faces[i].vertices[j];
Vector3 normal = p.normal;
if (n->faces[i].smooth && vec_map.lookup(v, normal)) {
normal.normalize();
}
if (n->faces[i].invert) {
normal = -normal;
}

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

Successfully merging a pull request may close this issue.

3 participants