# What is the math for the B-spline interpolation of a color ramp with two color stops?

I often use a color ramp with only two color stops as a way to modify the output of a texture parameter as in this example. I would like to be able to do something similar in a node group where the positions of the two color stops are input parameters. Such a group might look like this There is a solution for a linear color ramp in this answer.

A similar solution would work for the other interpolation types, provided I knew the interpolation equation.

What is the equation for b-spline?

• Hi Marty. Does it need to specifically be B-Spline or would something more akin to Ease be useful? (I don’t know the maths for b-spline but a generic ‘ease’ should be feasible without much difficulty) – Rich Sedman Sep 10 '18 at 15:39
• Hi Rich. Ease would definitely be useful. – Marty Fouts Sep 10 '18 at 22:38

Implementing B-Spline is quite a bit beyond my maths capabilities but a simple 'ease' is certainly feasible. To achieve this you can calculate the 'influence' of each of the control points and combine these to produce the overall influence. Varying the parameters controls the shape of the curve.

I've created a Desmos example which can be accessed here : https://www.desmos.com/calculator/orfi1cybkc and is as shown in the following image : Breaking this down a bit, we start with two points along the x-axis defined as p1 and p2 along with associated values v1 and v2 so each point is defined as (p,v). These can be adjusted and positioned as desired.

To determine the 'height' (y) at each point along the x-axis we need to determine the relative influence of each point. For this we first determine the distance as d = abs(x - p) for each 'point' (p1, p2).

The variables w and E (exponent) control the shape of the curve. w is present to avoid divide by zero errors by ensuring there is always a small offset from zero, while E controls how the influence of each point drops off over distance. Each influence is determined with :

i = 1 / (w + pow(d,E))


Once we have the 'influence' of each point (i1, i2) we can combine them with :

y = (v1*i1 + v2*i2) / (i1 + i2)


To build the nodes I opted to use the Dynamic Maths Expression add-on developed for this answer which can be downloaded from here. The add-on allows you to simply type an equation and the corresponding nodes are automatically built within a node group hidden behind the node. This allows complicated expressions to be very easily constructed.

For instance, for the 'influence' calculation I used the following equation :

Influence=1/(w+Distance**Exponent)


This produces the following node : Within the node are the following generated nodes to implement the specified expression : Similar can be done with 'Distance' and 'Output' as shown in the following (all wrapped within a Group for convenience) : This node group can now be used to produce the required 'easing' curve as demonstrated with this example : Using an exponent of 1.0 will produce a straight line : Exponents greater than 1.0 will produce increasing curve :

Exponents less than 1.0 will produce the opposite curve :

Two blend files are included - one that requires the Dynamic Expression add-on and one that does not require the Dynamic Expression add-on (the 'internal' node groups have been transferred into standard node groups) :

Using Dynamic Expression add-on : Stand-alone (without Dynamic Expression add-on) : EDIT Note : Rather than using multiple Dynamic Expression nodes within the group you can actually combine the maths into a single expression (by substitution) and use this in a single Dynamic Expression node :

Output=((1/(0.001+abs(x-Point1)**Exponent))*Value1+(1/(0.001+abs(x-Point2)**Exponent))*Value2)/((1/(0.001+abs(x-Point1)**Exponent))+(1/(0.001+abs(x-Point2)**Exponent))) This avoids the complexity of the additional level of node groups but will be slightly less efficient (due to the 'influence' needing to be effectively calculated twice for each 'point'). Note also that the add-on creates the node with the input variables in the order they are presented in the equation and this results in 'x', 'Point1', 'Exponent', 'Value1', etc. - rather than a more intuitive sequence. Being able to specify the order of the input sockets would be a useful addition to the add-on.

• My most important take-away from this is the debugging potential for other situations (OSL) in your 'obvious' way of visualizing the function .. which I'd never thought of. – Robin Betts Sep 12 '18 at 8:32
• @RobinBetts Yes - it is very useful to be able to visualise the output. I was inspired to this way from another answer (which I can't find to give credit) which used a displacement to achieve a similar result. – Rich Sedman Sep 12 '18 at 11:33