Suppose I have two upper and lower curved ropes in a geometry node, I would like to achieve a zigzag rope in that section.

Ideally, I would like to learn the points of the upper curve and the points of the lower curve, I would like to create a curve that alternates back and forth, but it won't work.

Expected result of zig-zag curve


I have added the information in an addendum. The curves used are pre-created at the node.

Current geometry nodes

Solution 1 (ALEX)


ALEX's excellent answer gave me the answer. I will share the blender file with you.

Animation of tweaking nodes

Full node tree

Solution 2 (StefLAncien)

StefLAncien provided a great geomery node that also takes UV textures into account.

I want to realize a bridge zigzag rope with geometry nodes

There are several answers to the question of UV texture development for curves, but this one is clear and straightforward.

My goal is to output it in FBX in the end, though, By changing the setting here from Vector to 2D Vector, the UVs are expanded and output in FBX without any problem.

enter image description here

enter image description here


2 Answers 2


You could actually do this with a single curve

enter image description here

enter image description here

Basically, you'd need to offset every two points of the curve. You can do that by using the index node in a math modulo node value of two.

You can then offset a duplicate of the original curve by the same amount to make the top curve.

For the points at intersections, simply use instance on points on the zigzag curve

You can see I also made it so the curves react to radius and twist in edit mode for more control (the cross product of the curve tangent and normal will offset the curve based on the tilt and direction)

enter image description here

You can also use two separated curves if needed with a different method

enter image description here

Here, you can sample the points position of the first curve, and transfer this position to the second curve. Like the first method, use the index node a math modulo node with a value of two so you only move one out of two points of the curve

This method only works if the two curves go in the same direction as it samples the points position based on the curve's factor

enter image description here

  • $\begingroup$ Thanks! I don't understand the logic, but it seems to work. I will try to implement it as soon as I get home. $\endgroup$
    – mml
    Commented Mar 16 at 7:56
  • $\begingroup$ Dear. I have a follow-up question on this script. If you don't mind. Is it possible to control the upper and lower curves separately? This node seems to be based on a single curve. $\endgroup$
    – mml
    Commented Mar 17 at 0:11
  • $\begingroup$ I have added additional information to the question. $\endgroup$
    – mml
    Commented Mar 17 at 0:37
  • $\begingroup$ @mml Hey, I just posted a second method with two curves input. Hope that helps $\endgroup$
    – Alex
    Commented Mar 17 at 2:06
  • $\begingroup$ Thank you! Works really great no problems! I will share the blender file later for community contribution (^o^) $\endgroup$
    – mml
    Commented Mar 17 at 3:45

(Using Blender 3.6.8)

(NB: documentation to be continued...)


To connect two independent curves, roughly parallel and in the same direction, with a third one in a zigzag pattern, keeping the ability to edit original curves while adding some thickness and texture to all three.

Final results


The upper and lower curves are kept without Geometry, nor Bevel, nor Modifier to not prematurely convert these into meshes. To make meshes from these, a dedicated GeometryNodes Modifier is added to Single Vertex meshes, to thicken and to define UV Map for shading.
To make the connecting zigzag mesh, cylinders are instanced because it could be tricky for a curve with sharp bends to adjust normals, these controlling achieved thickness.

GeometryNodes modifiers

Zigzag rope

GN Zigzag rope overview

1. User defined input parameters are:
1.1. Lower rope: target curve with the prescribed number of knots.
1.2. Upper rope: target curve with the prescribed number of knots plus one.
1.3. Knots: number of knots.
1.4. Radius: radius of the bars connecting curves.
2. The _Zigzag_curve node group is building the curve connecting upper and lower knots.
3. The _Zigzag_bars node group is creating the bars.
4. The material Rope Bump is defined in the Shading Editor.

GN Zigzag - Curve node group

1. Let $N \ge 2$ be the number of knots on the lower rope. A Bezier Segment of $2N+1$ control points is initialized. The index $n$ of those control points is varying between 0 and $2N$.
2. Control points with odd indexes are put on the lower rope; those with even indexes are put on the upper rope. Index parity is computed by a Modulo 2 Math node.
3. Knots are evenly spaced along ropes using the Factor parameter varying between 0 and 1. So the factor increment between two adjacent knots is $\Delta f = \frac{1}{N-1}$.
4. Let $n=2i+1$ be the index of an odd control point. The value of $i$ is recovered as the integer part of $\frac{n}{2}$. $i$ varies between 0 (for $n=1$) to $N-1$ (for $n=2N-1$). So the factor value $f = i \Delta f$ varies between 0 and 1. $f$ is input in a Sample Curve node to recover the associated position along the lower curve. This vector is transferred to the zigzag curve node of index $n$ using a Set Position node. NB1: Using a Float Curve node, the value of $i \Delta f$ can be adjusted before the Sample Curve node to make uneven the knots distribution. NB2: Instead of sampling by factor, the control points position can be directly transferred if the lower curve has exactly $N$ control points, by replacing the Sample Curve node with a Sample Index node.
5. Let $n=2i$ be the index of an even control point. The value of $i$ is recovered as $\frac{n}{2}$. $i$ varies between 0 (for $n=0$) to $N$ (for $n=2N$). Knots along the upper curve are shifted by half $\Delta f$. So the factor of these is computed as $f = (i-\frac{1}{2}) \Delta f$, varying between $-\frac{1}{2} \Delta f$ (for $i=0$) to $1 + \frac{1}{2} \Delta f$ (for $i=N$). $f$ is limited to the range 0 to 1 by activating the Clamp property of the Multiply Math node. Thus for $n=0$, $f=0$ while for $n=2N$, $f=1$. As a consequence, the end points of the zigzag curve and of the upper curve are at the same positions. The position vector is transferred from the upper curve to the zigzag curve as at step 4.

GN Zigzag - Bars node group

1. Bars are created as instances of a Cylinder:
1.1. By default, it is aligned with Z axis, and its origin is at mid-length.
1.2. Its Radius is controlled to the user defined value. Its Depth (i.e. length) is set to 1, so it can be easily scaled along its axis.
1.3. The visual quality of the rope procedural texture is a function of the mesh resolution. Here, 65 vertices are distributed in the axial direction, i.e. 64 Side Segments. 36 Vertices are distributed in the tangential direction, i.e. 12 per strand for a three strands rope.
1.4. By default, its UV Map is such that $U$ is in the tangential direction while $V$ is in the axial direction. Because the reverse convention is used for ropes, a Separate XYZ node followed by a Combine XYZ node are used to swap $U$ (i.e $X$) and $V$ (i.e. $Y$).
1.5. The thread pitch is controlled by scaling $U$, $V$ varying between 0 and 1 for one turn around the cylinder. By trial and error, a scaling factor of 16 was adjusted for the present demonstration. NB: This factor could be added to the user defined input parameters.
1.6. The modified UV Map is stored as a named attribute with type set to 2D Vector and domain set to Face Corner.
2. The curve output by the _Zigzag_curve node group is converted to a mesh made of $2N$ edges by a Curve to Mesh node. Then points are put at the middle of these edges using a Mesh to Points node set in Edges domain. Finally, a cylinder with origin at mid-length is instanced on these points with custom rotation and scaling.
3. An instance scaling factor is the length of the segment connecting two adjacent curve points. This value is computed from the vector between end points of the associated edge, which position is recovered through an Edge Vertices node. So the scaling factor is captured as an attribute in the Edge domain. It is combined with ones on X and Y directions to scale the cylinder only in Z direction.
4. An instance rotation vector is such that the cylinder Z axis is aligned with the vector between end points of an edge. As at step 3, this value computed by an Align Euler to Vector node is captured in the Edge domain.

Upper and lower ropes

GN thicken

1. .
2. .
3. .
4. .
5. .
6. .
7. .
8. .
9. .


Shading nodes

1. .
2. .
3. .
4. .
5. .
6. .
7. .
8. .
9. .


  • $\begingroup$ Thanks! I was able to check it out! Great UV node! This makes it more perfect! (^o^) $\endgroup$
    – mml
    Commented Mar 18 at 11:18

You must log in to answer this question.

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