I am trying to create a Geometry Nodes for hanging grass on the outside edges of planes.

After deleting the original faces, I resample the curve to add many points, then extrude along Z at a random value to create the grass effect:

enter image description here

However, I don't want the grass to go straight down, but be angled at a 45 degree angle along its normals.

The problem is, when I resampled the curve to add many points, I had to split the edges so the original points were included in the curve:

enter image description here

When I exclude the split edges node, I can first extrude along the Z, and then use that node's Top selection to size my extrusion along the normals, giving me the 45 degree angle:

enter image description here

However, when I include the split edges node, the normals aren't maintained:

enter image description here

I need both the original points in the curve, without splitting the edges to maintain the normals for the angle. I've tried both not splitting the edges and trying to incorporate the original points into the curve, and keeping the split edges in but trying to recalculate the normals with the "Set Curve Normal" node, but couldn't get either implementation to work.

My second problem is that, since I first extrude along the Z, then resize my extrusion along normals, I'm having a hard time randomizing along the angle, to get the straight hanging grass from the first image:

enter image description here

I've tried to give the same value to the Z extrusion and the Resize, with no luck:

enter image description here

  • $\begingroup$ Unfortunetaly, I just found out even in my above "good" normals nodes, I get inconsistent results when the seperate planes are too close on X and Y. If two planes are intersecting on X and Y, yet above and below on Z, the intersecting planes get inverted normals, and extrude inwards instead of outwards, while the non-intersecting planes have good normals. $\endgroup$ Nov 10, 2023 at 4:07

1 Answer 1


First delete all edges interior edges, then delete the faces in case there's faces with no adjacent faces. Now you have the shape outline.

To get the 45º offset from the $Z$ axis, you can rotate the vector $\left(0, 0, -1 \right)$ by 45º on the axis made by the edge points, but the the the edge points won't necessarily have the correct order, making some edges flipped (they all need to point to the same direction in the edge loop).

To fix the direction, after converting the split edges to curves, we can reverse the ones that have the incorrect order. To detect the curves to reverse we need to first, before splitting and converting to curve, store in each vertex the index of the following border edge in face winding order, so this process needs to be done before deleting the faces.

For each vertex, get the next edge of its face corner that has a next edge with one face neighbor, but don't simply store the edge index since further in the node tree interior edges are deleted, invalidating the indices, store instead the trailing accumulation of: $1$ if the edge has one face; $0$ otherwise. This gives an integer equal to the index of the edge if edges that don't have one face were deleted.

Now that each point has the index of its following edge, first capture the edge index before converting to curve since the conversion changes the index order, then for each spline, reverse it if its first point's stored edge index is not equal to the captured edge index.

With the correct direction, store the rotation axis made by the two points of the lines. After that the curve resampling can be done, and merge the endpoints if desired.

Now rotate the vector $\left(0, 0, -1 \right)$ along the captured axis by the desired angle to get the offset direction.


result, endpoints merged result

Full node tree:

$\small\color{DarkOrange}{|}\hspace{2pt}\color{gray}{{\tiny\text{V}}\text{ 3.4.1}}\hspace{2pt}\color{DarkOrange}{|}$

  • $\begingroup$ This is incredible, truly an expert solution! Thank you for the work, I've been trying your file and it truly works with all possible shapes. There is a slight flaw, it only works if there's at least one internal edge to delete, not with a single face. Secondly, I want the grass downwards regardless of angle, this angles the grass more along the vertical slopes. The last thing (hope you can bare with me) is I've been truly struggling to upgrade to 4.0, I copied your nodes in 3.0 but I don't have "Evaluate on Domain" or "Evaluate on Index", I have too many python scripts I can't adapt to 4.0. $\endgroup$ Nov 30, 2023 at 6:58
  • $\begingroup$ @MountainWhirl I fixed the answer, but could only downgrade to v3.4 $\endgroup$
    – Hulifier
    Nov 30, 2023 at 23:26
  • $\begingroup$ Wow! What a legend! Works perfectly with my version. $\endgroup$ Dec 1, 2023 at 1:16

You must log in to answer this question.

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