# Normals are flipped

I colored normals with negative y red and here's what I get:

Any idea why some normals are flipped?

Here's simplified version of my code that add vertices, triangles, normals, etc.

I'm playing around with Godot, so axes are are the following:

• Vertical is y axis, up is positive
• Horizontal is x axis, left is positive (left in image)
• Depth is z axis, forward is positive (up in image)
public static TerrainMesh GenerateMesh(float[,] heights, Color[,] colors) {
int width = heights.GetLength(0);
int height = heights.GetLength(1);
float topLeftX = (width - 1) / 2f;
float topLeftZ = (height - 1) / 2f;

TerrainMesh mesh = new TerrainMesh(width, height);
int vertexIndex = 0;

for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
mesh.Vertices[vertexIndex] = new Vector3(topLeftX - x, heights[x, y], topLeftZ - y);
mesh.Uvs[vertexIndex] = new Vector2(x / (float)width, y / (float)height);

// rudimentary normals
if (x != 0) {
// PS! if I swap Vector3's in Cross, upper half of the map has flipped normals
Vector3 normal = mesh.Vertices[vertexIndex].Cross(mesh.Vertices[vertexIndex - 1]).Normalized();
mesh.Normals[vertexIndex] = normal;
} else if (x == 1) {
Vector3 normal = mesh.Vertices[vertexIndex - 1].Cross(mesh.Vertices[vertexIndex]).Normalized();
mesh.Normals[vertexIndex - 1] = normal;
}

if (x < width - 1 && y < height - 1) {
mesh.AddTriangle(vertexIndex, vertexIndex + width + 1, vertexIndex + width);
mesh.AddTriangle(vertexIndex + width + 1, vertexIndex, vertexIndex + 1);
}

vertexIndex += 1;
}
}

return mesh;
}

• I also get some normals artifacts in the border where normals flip. – Sir May 1 '20 at 13:12

The method of computing normals shown here is beyond "rudimentary" - it's just flat out wrong. What you're computing there in no way corresponds to a terrain normal.

It's taking two vectors from the origin to different vertices in your mesh - which don't always belong to the same mesh triangle, even - and computing a normal of the triangle they form with the origin. Naturally, when you cross the origin, this triangle - which has nothing to do with the triangles of the mesh you're drawing - flips over, resulting in the inverted normals you see for half your mesh.

Vector3 GetNormal(int x, int y, float[,] heights, float stepSize = 1.0f) {
float center = heights[x, y];

float left  = x > 0                        ? heights[x-1, y], center;
float right = x < heights.GetLength(0) - 1 ? heights[x+1, y], center;

float bottom = y > 0                        ? heights[x, y-1], center;
float top    = y < heights.GetLength(1) - 1 ? heights[x, y+1], center;

return Vector3.Normalize(new Vector3(left - right, 2 * stepSize, bottom - top)
}


The stepSize variable corresponds to how great a distance there is between adjacent cells of your heightmap grid. Smaller values will exaggerate the normals, while larger values will tend to pull the normals closer to vertical.