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]
It’s called ‘normal’ like you have it. Hope that helps.
EDIT: Oh, and you can look at this for assigning vertex normals:
(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]
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.
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.