# Different values for split normals depending on face/triangle

I'm writing an exporter for an old game file format that only supports one normal per vertex. This requires creating duplicates for each vertex (or rather, loop) that has split normals. The problem I'm having is that, even when the split normals are averaged (via Mesh -> Normals -> Average -> Custom Normal), the result I get can be slightly different, causing my script to duplicate the vertex.

I made a simple test, with 2 triangles joined at vertices 0 and 2. Here's a sample code I'm using to check the values of the split normals. The current example ignores transforming from object space to world space for simplicity.

import bpy

print("start")

for  object in bpy.data.objects:

mesh = object.data
mesh.calc_loop_triangles()
mesh.calc_normals_split()

print(object.name)
print(mesh.has_custom_normals)

for triangle in mesh.loop_triangles:

for loop, vertex, normal in zip(triangle.loops, triangle.vertices, triangle.split_normals):

n = mesh.loops[loop].normal
#n = normal #triangle normal gives the same result

print(vertex, str(tuple(n)))


And the output of the script for my sample

start
Sphere
True
0 (-0.02063608169555664, 0.7257574796676636, 0.6876412034034729)
1 (-0.2683730721473694, 0.6490309834480286, 0.7118530869483948)
2 (-0.02064351737499237, 0.7257753610610962, 0.6876221299171448)
0 (-0.020633935928344727, 0.7257868647575378, 0.6876101493835449)
2 (-0.020631134510040283, 0.7257802486419678, 0.6876172423362732)
3 (0.2285022735595703, 0.7532715797424316, 0.616740345954895)


I would expect the split normal for vertices 0 and 2 to be identical, but it's not. In this case the difference is fairly minimal but, in some real-world scenarios, I've noticed bigger differences. Am I missing something? Do the values of the normals need to be somehow corrected per face/triangle?

• why don't you just use edge split modifier? Jul 26, 2022 at 13:26