 # How to calculate vertex normal

I need to set the vertex normals on a mesh. I have a procedrally generated terrain and I need to set the vertex normals after the mesh is displaced so that it does not look flat. Can anyone point me to a formula or anything like that to do it? I know the vertex normal has to be a vector in the form vert.normal = [x,y,z]

https://www.blender.org/api/blender_python_api_2_78_release/bge.types.KX_VertexProxy.html#bge.types.KX_VertexProxy

It’s called ‘normal’ like you have it. Hope that helps.

EDIT: Oh, and you can look at this for assigning vertex normals:
https://www.blender.org/api/blender_python_api_2_78_release/bge.types.KX_MeshProxy.html#bge.types.KX_MeshProxy
(it’s in the example code)

if you are joining many meshes at the seams, it’s helpful to use a kd tree,

you get each faces normal, and then average the overlapping faces normal

that is what I did for this

If you want flat faces the normals of all vertices of a face are the same -> face normal. The face normal is the cross product of two of the edges of the face.

``````f = face
v1,v2,v3,v4 = vertices

fn = face normal
vn1, vn2, vn3, vn4 = vertex normals

fn = (v1-v2).cross(v2-v3)
``````

[remark: if you want the opposite normal - exchange the vectors]

Flat:

``````vn1 = vn2 = vn3 = vn4 = fn
``````

smooth, means the vertex normal equals the vertex normals of the adjacent vertices of connected faces.

A) identify the adjacent vertices (of different faces) f1v, f2v, f3v, …;
B) I suggest tu calculate the average middle of the face normals normals, by adding them and normalize the result:

``````f1vn, f2vn, f3vn, ... = (f1vn + f2vn +f3vn + ... ).normalized()
``````

I hope this helps

I’m having this problem as well, where I have a subdivided plane with 1600 triangles, a code that makes random vertices move randomly up and down, but the shading is flat. I need to update the normals. I already had a working code, but the shading looked a bit weird.

``````import mathutils

mesh = own.meshes #first mesh

number = mesh.numPolygons #total number of polygons

for polyID in range(0, number):

p = mesh.getPolygon(polyID)

a1 = mesh.getVertex(0, p.v1) #first vertex of polygon
b1 = a1.getXYZ()
a2 = mesh.getVertex(0, p.v2) #second vertex of polygon
b2 = a2.getXYZ()
a3 = mesh.getVertex(0, p.v3) #third vertex of polygon
b3 = a3.getXYZ()

poly_n = mathutils.geometry.normal(b1,b2,b3)

v_list = [a1, a2, a3]

for v in v_list:

v.setNormal(poly_n)
``````

But as you can see the darker areas are on vertices, not whole polygons, and I would like flat shaded type.
Sorry if I interrupted this thread but I didn’t want to start a new one if this one was on the same exact topic.

### Attachments

``````def recalc_normals(cont):
mat_id = bge.texture.materialID(own, "MA"+"Material")
for poly_id in range(mesh.numPolygons):
poly = mesh.getPolygon(poly_id)
v1 = mesh.getVertex(mat_id, poly.v1)
v2 = mesh.getVertex(mat_id, poly.v2)
v3 = mesh.getVertex(mat_id, poly.v3)
if poly.v4 == 0:
normal = mathutils.geometry.normal(v1.getXYZ(), v2.getXYZ(), v3.getXYZ())
v1.setNormal(normal)
v2.setNormal(normal)
v3.setNormal(normal)
else:
v4 = mesh.getVertex(mat_id, poly.v4)
normal = mathutils.geometry.normal(v1.getXYZ(), v2.getXYZ(), v3.getXYZ(), v4.getXYZ())
``````

Here is the correct code.

With kdtree, I use 1 mesh in a couple thousand times, and use the kdtree to get all vertex that share a x/y/z cord and then you can average faces across objects.