Custom voxel-like generated mesh dosen't have good normals.

Quick note before starting: I didn’t use Unity Answers because the tool bar wasn’t there.

I’ve generated a custom voxel-like (blocky) mesh, the mesh way good but It was black. I searched on the Internet for the solution and I found this: mesh.RecalculateNormals();

Here’s the problem: The mesh look shiny and totally not blocky. (Almost like pure gold)

I’ve also tried to set all normals to Vector3.zero but It didn’t work as expected.

Taking the vertices list and setting it into the normals vector3 list sound like a good idea, it looks good from far away but looks weird from a close point of view.

What should I do?


3145544--238867--VoxelGold.png
3145544--238868--VoxelZero.png
3145544--238869--VoxelVertexFar.png
3145544--238870--VoxelVertexNear.png

Your voxel mesh is probably too good. Vertices can only store one normal at a time, and if your mesh is using a single vertex for each corner (as it appears to be) then it can only assign one normal for that corner when you really need 3.

Basically each face needs to not share vertices with another face unless those faces are coplanar. For something like a simple cube you need 24 vertices, 4 for each face shared between each two coplanar triangles, where as what you’re doing would just be constructing 8, one for each corner, and sharing them for all of the faces.

Once you do that RecalculateNormals() should work.

The alternative is a custom shader that doesn’t use vertex normals, but that’s likely going to be more difficult than duplicating vertices if you’re not intimately familiar with shaders.

I’m a begginer with mesh and all the stuff, that’s why I don’t really know where I need to start and what I need to do… Could I get more information? Or maybe some usefull links if you don’t have time?

There are a ton of easily found voxel mesh tutorials out there you can look at. While not exactly what you’re doing, should get you the information you need.

1 Like

Here’s some example what I found.

filter.mesh.Clear();
filter.mesh.vertices = meshData.vertices.ToArray();
filter.mesh.triangles = meshData.triangles.ToArray();
MeshUtility.Optimize(cMesh);
cMesh.RecalculateNormals();
mesh.Optimize();
mesh.RecalculateNormals();

But NOTHING work, they are all the same.
I’ve search everywere I could, and also on every single voxel that this website has: https://unitycoder.com/blog/2012/10/18/voxel-resources-engines-for-unity/

Why do my normals look like a random mess?

3145929--238929--RandomVoxelNormals.png

Recalculate is probably not what you want. It will “soften” everything, if you’re more familiar with the art side…

You want to set the normals. Think about each block as a set of planes, not a box…

I don’t fully understand what you’re telling me to do, Is place 4 normal at each corner in the direction of the plane?

3146745--239027--NotNormal.jpg

Ya. Thinking about this more Optimize might be your real culprit… try doing RecalculateNormals without Optimize.

This give the result of the first picture and the normals look like the picture named RandomVoxelNormal.png

EDIT: Nevermind, I found a nice technique that auto-flat shade any mesh.

Vector3[] oldVerts = mesh.vertices;
         int[] triangles = mesh.triangles;
         Vector3[] vertices = new Vector3[triangles.Length];
         for (int i = 0; i < triangles.Length; i++) {
             vertices[i] = oldVerts[triangles[i]];
             triangles[i] = i;
         }
         mesh.vertices = vertices;
         mesh.triangles = triangles;
         mesh.RecalculateBounds();
         mesh.RecalculateNormals();