Hermite-style Spline Mesh Blending in Unreal Blueprints

As I’ve been exploring more Blueprints inside of Unreal, I have been putting together a physics-based ‘soapbox racer’ where the track is primarily generated from splines. One of the challenges I encountered when dealing with the spline roll is easing or blending multiple meshes across a distance smoothly. Using the built-in ‘Ease’ mode was enough for a quick prototype, but it did not provide the the smoothness needed for the fast-paced racing.

In researching different ways to handle this, I came across Hermite Polynomials, as described here.

Why Hermite?

Experimenting with the different Ease modes made me realize I was not going to get the result I wanted. Each had its own quirks with factors that can change, e.g. how close the spline nodes are to each other, the directions and lengths of their tangents. The major issue I wanted to solve was smoothness, ensuring that the transitions between different spline nodes prevented ‘v’ shapes from forming in the track, as these can unsettle the cars and, in some cases, stop them completely.

These images show the existing functions: Linear, Ease in Out, Circular in Out, Sinusoidal in Out, and Expo in Out. I avoided the ‘In’ or ‘Out’ options for these because the ‘in Out’ versions provided a better starting point, with the best being Ease in Out because of its additional Blend Factor. However, even with this additional value, when the track rolls to a high angle, or there are multiple spline indices close to each other, the results often varied greatly. Rather than fight the system, I decided to research additional options.

Linear

Expo in Out

Ease in Out (blend factor: 2.0)

Circular in Out

Sinusoidal

Hermite

This led me to Hermite Polynomials.

I have several known values:

  • The number of spline points

  • The spline indices

  • A 0-1 Alpha value, which is:

    • The mesh length, and in the cases where the meshes are repeating multiple times between each spline point, the stretched mesh length

    • The length of a spline between two indices

      • The current spline index is multiplied by the stretched mesh length, then divided by the current spline length.

  • The rotation at the current and next spline points (RollA, RollB), the previous point (PrevRoll), and the point after the next point (NextRoll)

  • The slope at the spline points (mA, mB)

    • These values provide us with an estimation of where the slope was and where it will be, and they’re calculated by:

      • (RollB - PrevRoll) / 2 = mA

      • (NextRoll - RollA) / 2 = mB

With these 5 values (Alpha, RollA, RollB, mA, mB), we have what we need for the function.

The values need to be computed twice: once for ‘Set Start Roll’ and once for ‘Set End Roll’. To do this, we combine the Alpha Start or End value respectively, along with RollA, RollB, mA, and mB into the Hermite function. This is where the real math begins.

Alpha (α) represents how far along a segment we are from 0 to 1. We need to stash several values:

  • A2 = Alpha x Alpha (This is Alpha squared, α²)

  • A3 = A2 x Alpha (This is Alpha cubed, α³)

  • Two_A2 = 2 x A2 (This is 2α²)

  • Three_A2 = 3 x A2 (This is 3α²)

Next, we need to build the four blending weights called Hermite basis functions:

  • h00 = 2α³ - 3α² + 1 (This weighs how much Roll A contributes)

  • h10 = α³ - 2α² + α (This weighs how much mA contributes)

  • h01 = -2α³ + 3α² (This weighs how much RollB contributes)

  • h11 = α³ - α² — This weighs how much mB contributes

Put another way:

  • At Alpha = 0, h00 = 1 and the others = 0, so the output is exactly RollA

  • At Alpha = 1, h01 = 1 and the others = 0, so the output is exactly RollB

  • The h10 and h11 weights are shaped so the slope of the curve at A matches mA, and the slope at B matches mB

Next, we multiply each weight by its value:

  • Term0 = h00 * RollA

  • Term1 = h10 * mA

  • Term2 = h01 * RollB

  • Term3 = h11 * mB

Finally, we add these together to get the resulting roll value

  • Term0 + Term1 + Term2 + Term3

    • or

  • Roll(α) = h00*RollA + h10*mA + h01*RollB + h11*mB

This provides the standard cubic Hermite interpolation, giving a smooth value at any point along the spline segment and a smoother mesh.

Previous
Previous

Environment Shader & Tooling

Next
Next

RGBA Mask Shader Node