I have a set of custom normal data here.

enter image description here

First one simply use the normal data in the shader.

enter image description hereenter image description here

Second one is achieved by define custom split normals of this mesh from normal data by script.(normals_split_custom_set(normals))

enter image description here

Is there anyway to make leaves look like first one without using any normal data or texture in shader?

  • $\begingroup$ Perhaps you are looking for Point to Target? $\endgroup$ Commented Mar 9 at 2:56
  • $\begingroup$ You want to get the attribute data onto an true custom normal, is that right? It's not easy. Potentially you could instance a face on every point and realize instances, using GN, then data transfer custom normals from it. Is that something you'd be interested in, or is it too much work? $\endgroup$
    – Nathan
    Commented Mar 9 at 4:49
  • $\begingroup$ Both normal->point to target and data transfer(face corner data->custom normal) manipulate split normal and get same result in second image. $\endgroup$
    – Wow
    Commented Mar 9 at 5:43
  • $\begingroup$ Hmm, one difference is the split normals get normalized after interpolation, whereas a generic attribute doesn't. To test if this causes the difference, try putting a [Vector Math:Normalize] node after the Attribute node in your first image and see what you get. $\endgroup$
    – scurest
    Commented Mar 9 at 7:48
  • $\begingroup$ Also normals_split_custom_set will misbehave if the normals you pass it are not exactly unit length (or very close), so maybe check that. $\endgroup$
    – scurest
    Commented Mar 9 at 7:49

1 Answer 1


enter image description here

The question as I'm hearing it: Suzanne has weird normals, set by an attribute created in GN. How do we turn those weird normals into actual custom normals? Maybe we have an export algorithm that can't read attributes or something like that. And, even though it'd be easier, we can't use image-based normal mapping instead. Maybe our desired rendering engine doesn't support that.

GN still doesn't have real custom normal support, so we have to use tricks. We'll just start by adding a cube (any mesh object) with a geometry nodes modifier:

enter image description here

I'm just instancing a plane, on every vertex of Suzanne, and aligning that with the "normal" attribute. I realize instances so that I can apply the modifier or convert to mesh to eliminate any future dependency problems, although I'm not sure that dependencies would actually create any problems.

After creating this object and its modifier, as mentioned, we'll apply it, then we'll transfer normals from it to our original mesh with a data transfer modifier:

enter image description here

Shown side-by-side with an unmodified copy so I can compare. We can (and should) apply the data transfer modifier after we make sure it's working correctly. Use of custom normals currently requires enabling autosmooth (soon to disappear, I understand...)

Here are the things to be careful of if using this technique:

  1. As scurest pointed out in comments, a normal, custom normal, or whatever, gets renormalized implicitly, while a GN attribute does not. It doesn't matter that the attribute might already be normalized, because interpolation between different values along the face can take two normalized inputs and still give unnormalized output. (Worst case: halfway between 1,0,0 and -1,0,0 lies 0,0,0.) This can mean minor differences in your output between your attributes and your custom normal, and there is no way to tell Blender to not bother normalizing a custom normal. But, especially with the mesh and normals you're showing, this should be a tiny, tiny effect.

  2. I'm transferring custom normals here, but not really split custom normals. Because I'm transferring from faces, all face-corners of a particular vertex get the same custom normal. For the mesh that you're showing in your pic, it looks like this is fine: you appear to have custom normals, but no split custom normals (which show up as hard creases, like the sharp edge of a cube.) I am not sure that there is any kind of workaround to get true, split normals from a GN attribute, because "best matching normal" may not map to the correct face-corner in cases of extreme difference, topology is not possible without edge splitting the input mesh, and other transfer methods just give us vertex normals, not face-corner normals.


You must log in to answer this question.

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