2
$\begingroup$

I want to color closed curves with a gradient along their length, to make it easier to see where they cross over each other. I found how to do this for an open curve using the spline parameter in Geometry Nodes; for example, as done below:

https://www.reddit.com/r/blender/comments/15it19x/how_to_make_gradient_material_which_will_follow_a/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button

But this solution fails to work for a closed curve, because the spline parameter "backtracks" in some sense, so that the gradient repeats itself in the opposite direction at the ends. enter image description here

The above example is of a custom curve created entirely using Geometry Nodes, but I was able to recreate the issue for a much less complicated example, where I started with a BezierCircle and then used the following Geometry Nodes and Shader setup.

enter image description here

enter image description here

$\endgroup$
1

1 Answer 1

2
$\begingroup$

Yes, in your simplified example, the "curve_position" attribute is being stored only on the curve control points (and if this is a Bezier Circle, that means only four control points with values 0, 0.25, 0.5, and 0.75). The "Curve to Mesh" node interpolates these values onto the mesh, so the "curve_position" attribute grows from 0 up to 0.75 and then back down to 0 as you move along the curve. But, even if you fixed this (say by resampling the curve at a high resolution) to calculate proper "curve_position" values on all the vertices of the created mesh, the shader would still try to interpolate between the "last" vertices of the mesh and the "first" vertices (which is what's happening in your first screenshot, I think).

I think the best solution, as unsatisfying as it is, is to double up the start and end vertices of your curve. If your handles are "Auto" or something, switch them to some other mode, like V > Aligned:

enter image description here

and then shut off cyclic (AltC):

enter image description here

Pick one of the endpoints and split it with Y but leave it in position with Esc. Here, the highlighted control point has actually been split from the existing curve -- if you grabbed it, it would be a single point moving free from the rest of the curve:

enter image description here

With that extra control point still selected, Shift-select the other endpoint:

enter image description here

and hit F to connect them with a segment:

enter image description here

Now, you can toggle cyclic back on with AltC, and the interpolation will occur on the zero-length segment you created.

enter image description here

This works because the duplicate control points can be assigned curve_offset=0 and curve_offset=1 respectively, and the zero length segment created between them will hide the interpolation from 1 back down to 0.

As an alternative, as per @MarkusVonBroady's comment, this modification can be implemented in a fairly simple geonodes network directly on the cyclic curve without having to edit it:

enter image description here

Here, the "Set Handle Type" ensures the handles aren't in "Auto" mode, which will cause deformation of the curve when its cyclic nature is broken, and then the "Trim Curve" node has the effect of breaking the curve's cyclic nature while keeping the final endpoint at the same location as the start. The rest of the network just stores the "curve_position" as in your original geonodes network, but the stored position will now be 0 at the start of the curve and 1 at the end. Your material can stay as-is:

enter image description here

and the final result is similar to the above:

enter image description here

There is one issue with this approach -- the mesh will technically be disconnected where the curve is broken, and using "Merge by Distance" will reintroduce the original issue at the merge point.

If this is a problem, I guess you'll need to figure out how the linked duplicate can be applied to your situation.

$\endgroup$
3
  • 2
    $\begingroup$ In Geonodes there's a simple way to achieve that: "trim curve" with default parameters. It's not ideal, as you end up with an unnecessary seam, so now you need to e.g. override normals. In my answer under the linked duplicate I tackle the problem at its heart: resolving 0/1 factor ambiguity in a cyclic curve. $\endgroup$ Commented Nov 15 at 11:00
  • $\begingroup$ Thanks for pointing out the "Trim Curve" technique -- that's very clever. Honestly, I couldn't make heads or tails out of the answers in the marked duplicate, but maybe the OP will have better luck. $\endgroup$ Commented Nov 15 at 21:14
  • 1
    $\begingroup$ Unfortunately, while this solution works for the simplified example, I don't think it works for the more complicated one, because I need a Resample Curve node to increase the number of control points. (This is needed because I am using the spline parameter to set the position of points along the curve.) I am going to give the solutions in the other post a go, and hopefully that will work. Thank you regardless! $\endgroup$ Commented Nov 16 at 1:49

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.