Is it possible to use face normals as vertex normals in procedurally generated meshes?
Hi All,
I have a problem with getting the normals right on a procedurally generated mesh in my project. I will attempt to clarify the steps I am following:
I have a 3dCAD model (.ifc file) of a building that i parse using an external library (xBIM) and obtain the vertice of the mesh and the triangle indices array (mesh. vertices and mesh. triangles)
Let's say that I have a wall with 6 faces (cuboid). When I parse the triangulation of this wall, I obtain 8 vertices and the 3 triangle vertices per triangle per face (i.e 2 triangles per face * 6 faces = 12 triangles. 3 vertices per triangle and hence 12*3 = 36 indices)
I use these as the arrays as mesh.vertices ( Vector3 , length 8) and mesh.triangles (int[], length36)
At this point I get the mesh right in Unity (the geomertry is correctly replicated), but the shading is bad and the edges of the shape are not visible.
Unfortunately, the library I am using gives the face normals instead of the vertex normals. Which means that per geometry (of 6 faces) I get a normal array of 6 members.
How do I use these normals to assign the normals to vertices so as to have a correctly displayed mesh in Unity?
Currently I am using the triangles array to compile an elaborate vertices array (using the 8 vertex points in an ordered manner of 36 points to define the 6 vertices that define each of the 6 faces of the cuboid), something similar to the what is done here .
Therfore, my vertices array is now 36 * Vector3 members long. In an attempt to assign normals to these vertices, I used the face normal I obtained and then assigned the same normal to all the vertices that are deining that face. For e.g, vertices 0,1,2,1,0,3 define the 2 triangles of the front face of the cuboid. I used the face normal obtained for this face and assigned that as the normal vector for each of the vertex.
Anyway, I get a strange result and the front faces of the geometries are culled.
The issue is the same even if I use mesh.RecalculateNormals() method instead of assigning the normals at all to the mesh.
Is there something I am missing/ doing wrong in assigning the normals/vertices that the mesh is incorrectly rendered? Btw, I also tried reversing the order of mesh.trianglesa array, but the result was same.
Please help. I apologize for the verbose question, but I hope it explains my problem.
The mesh hhighlighted is invisible but the geometry is alright when viewed from the opposite side.
The front faces of these cuboid (wall) geometries are culled.
The part of code I am using to assign the mesh data is as follows. The vertices and triangles arrays are parsed from an XML file:
GO.AddComponent<MeshFilter>();
GO.AddComponent<MeshRenderer>();
Mesh mesh = GO.GetComponent<MeshFilter>().mesh;
mesh.Clear();
Vector3[] mod_Verts = new Vector3[meshTriangles.Count];
//meshtriangles.count is 36 // meshtriangles is the list of indices used as mesh.triangles
int[] mod_Triangles = new int [meshTriangles.Count];
for (int x = 0; x < mod_Verts.Length; ++x)
{
mod_Verts[x] = meshVertices[meshTriangles[x]]; // extends vertices array to define vertices
for each face
Debug.Log(GO.name + "_"+ x + "_" + mod_Verts[x] + " | " + " Vert_No: " +
meshTriangles[x]);
mod_Triangles[x] = x;
}
mesh.vertices = mod_Verts;
mesh.triangles = mod_Triangles;
mesh.RecalculateBounds();
//mesh.normals = meshnormals.ToArray();
mesh.RecalculateNormals();
Many thanks in Advance, Ani
Ok, After investigating, I found out that the winding order of the vertices per face is not consistent. I am working on checking in set of 3's the vertices and deter$$anonymous$$e if the winding order is wrong and rectify it. In the mean time, if anybody has already worked out a solution to the same, pls do dhare and advise!
Thanks, Ani
I would like to ask you one thing. I wonder if you have imported the geometry information using the xbim library in Unity 3D.
Answer by dmitriy-untilov · Feb 01, 2018 at 04:31 PM
You can try to swap Y and Z coordinate of each vertex, because coordinate systems in CAD and Unity are differ.