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?


1 Answer 1


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.

enter image description here

  • 1
    $\begingroup$ So much trouble, and you fixed it with one well positioned node :D Great, thanks! $\endgroup$ Commented Feb 18 at 9:05
  • $\begingroup$ 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). $\endgroup$ Commented Feb 18 at 9:19
  • $\begingroup$ mmm... in fact, if used as normal, it seems there is still an issue... : ( ... something about back facing $\endgroup$
    – lemon
    Commented Feb 18 at 9:30
  • 1
    $\begingroup$ 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). $\endgroup$
    – lemon
    Commented Feb 18 at 10:01
  • 1
    $\begingroup$ 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. $\endgroup$
    – lemon
    Commented Feb 18 at 11:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .