How to reproduce Blender's smooth shading?

Thanks to help of shmuel I made a setup for interpolating a normal in geonodes. Ideally, it would reproduce Blender's smooth shading exactly. So I reproduced the setup in the Shading nodes. In order to access the vertex positions and values, I capture them in geonodes on face domain:

For this to work properly I triangulate first:

Now, the main shading tree is straight-forward, just read the attribute, offload the actual calculations to another tree "Smooth Shading", and use the result:

"Smooth Shading" tree is based on barycentric coordinates:

The "Triangle Area" tree:

This all works very well for most purposes, but isn't perfect, the Mix node is there to easily switch between the two and see the difference:

It's very subtle and not visible when actually used as a normal. And yet there is a difference and it's not some kind of super-subtle difference I got here:

It's more, my approach is a linear interpolation, but here's I think a quadratic interpolation? Which would mean I need to consider also further vertices? Just a guess... You can see it if you pass the normal through Vector Math: Wrap to generate lines. In linear interpolation they are straight, but as seen on the top of the head, the Blender's interpolation smooths the lines:

So what algorithm do you propose to reproduce the smooth shading exactly?

The issue is inside "Smooth shading" node group.

It calculates 3 surfaces from a given point and takes the weighted average of the normals relatively to the whole surface (the sum of the 3).

But this weighted average of 3 normalized vectors is not normalized itself.

Simplified case:

n1 = (1, 0) and n2 = (0, 1)

s1 = 0.5 and s2 = O.5 (s total = 1)

will result in 0.5 * n1 + 0.5 * n2 = (0.5, 0.5) which has not a length of 1.

• So much trouble, and you fixed it with one well positioned node :D Great, thanks! Commented Feb 18 at 9:05
• It also explains why I didn't see a difference when testing it as an actual normal in the shader - I thought it's just because it's a subtle difference, but instead it's because the normals are normalized by the shader (or otherwise their magnitude doesn't matter in the calculations). Commented Feb 18 at 9:19
• mmm... in fact, if used as normal, it seems there is still an issue... : ( ... something about back facing Commented Feb 18 at 9:30
• face corners are not "doubled" per face depending on front/back facing, or am I wrong? Another way to say that is "back facing is just a point of view... so impossible to know that in gn" (except calculating from the cam, of course). Commented Feb 18 at 10:01
• Well in fact, I placed it here just because it was more simple... without taking any other consideration into account. But thanks for the precisions. Commented Feb 18 at 11:47