How to calculate mesh normals?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By izhvnter

Hello guys,
I’ve been trying to get the normals to work for a while but still can’t get it right.

here is the code i wrote:

var a: = Vector3(1, 1, 0)
var b: = Vector3(0, 1, 0)
var c: = Vector3(0, 0, 0)
var d: = Vector3(1, 0, 0)

var e: = Vector3(0, 1, 1)
var f: = Vector3(1, 1, 1)
var g: = Vector3(1, 0, 1)
var h: = Vector3(0, 0, 1)

var arr: = []; arr.resize(Mesh.ARRAY_MAX)

var verts: = PoolVector3Array()
var uvs: = PoolVector2Array()
var normals: = PoolVector3Array()
var indices: = PoolIntArray()
verts += create_verts(a, b, c, d)
uvs += create_uvs()
normals += create_normals(a, b, c, d)
indices += create_indices(0, 1, 2, 3)
verts += create_verts(e, f, g, h)
uvs += create_uvs()
normals += create_normals(e, f, g, h)
indices += create_indices(4, 5, 6, 7)
verts += create_verts(f, a, d, g)
uvs += create_uvs()
normals += create_normals(f, a, d, g)
indices += create_indices(8, 9, 10, 11)
verts += create_verts(b, e, h, c)
uvs += create_uvs()
normals += create_normals(b, e, h, c)
indices += create_indices(12, 13, 14, 15)
verts += create_verts(b, a, f, e)
uvs += create_uvs()
normals += create_normals(b, a, f, e)
indices += create_indices(16, 17, 18, 19)
verts += create_verts(d, c, h, g)
uvs += create_uvs()
normals += create_normals(d, c, h, g)
indices += create_indices(20, 21, 22, 23)

arr[Mesh.ARRAY_VERTEX] = verts
arr[Mesh.ARRAY_TEX_UV] = uvs
arr[Mesh.ARRAY_NORMAL] = normals
arr[Mesh.ARRAY_INDEX] = indices

get_mesh().add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arr)

and here are the functions i made to help me:

func create_verts(v1: Vector3, v2: Vector3, v3: Vector3, v4: Vector3) -> PoolVector3Array:
return PoolVector3Array([v1, v2, v3, v4])

func create_uvs() -> PoolVector2Array:
	return PoolVector2Array([Vector2(0, 1), Vector2(1, 1), Vector2(1, 0), Vector2(0, 0)])

func create_normals(v1: Vector3, v2: Vector3, v3: Vector3, v4: Vector3) -> PoolVector3Array:
	return PoolVector3Array([((v2 - v1).cross(v3 - v1) + (v4 - v3).cross(v1 - v3)).normalized()])

func create_indices(v1: int, v2: int, v3: int, v4: int) -> PoolIntArray:
	return PoolIntArray([v1, v2, v3, v3, v4, v1])

the cube is displayed without applying the normals.

i have also tried just adding the vertices instead of trying to calculate the normal by using the cross product and this happened

:bust_in_silhouette: Reply From: izhvnter

I have already fixed the problem, if you have the same problem too here’s what i did:
before i was trying to calculate the normal of each triangle in each side of the cube until i realized the normals are per vertex and not per face.
this is how it looks now:

#assuming it's one side of the cube we're dealing with:
#since it's a cube it's obvious what normal it is for each side
#one side of the cube is made of 4 vertices so pass it 4 times
#using front vector assuming we're dealing with the front side of the cube
var normals = PoolVector3Array([Vector3.FRONT, Vector3.FRONT, Vector3.FRONT, Vector3.FRONT])