Hi!
I would like to use the spline function to write a ramp shader, however
this function only takes points at equal distance. Then it restrict a
lot the flexibility of my ramp shader.
If there a cheap way to re-parametrize the spline function, and
consequently to interpolate points that are not at equal distance?
So far I've used a second spline to reparametrize the first one.
let's say I want to interpolate the points "spl_y[]".
y = spline(x, spl_y)
Now I want to give the x value of my points to interpolate, I have a
second spline "spl_x[]".
assuming X is "spl_x" reparametrized, I get:
X = reparam(spl_x)
x' = spline(x, X)
y = spline(x', spl_y)
This is working, however my fonction reparam is prettry slow. it does a
stupid search in an array for every single pixel to shade.
first question, is there a way to precompute a table at the first
execution of the shader, then there is no need to compute it again?
Second question, is there a better way to re-parametrized a spline?
here is my function to reparametrize a spline:
// *******************************************************************
/**
* Inverses the spline. We give the result and we get the input
* parameter
* a == spline(i, spl)
* i == invSpline(spl, a, prev, step)
* @param spl spline
* @param a the result from the spline function
* @param prev the previous value or 0. it is used to speed up the search
* @param step how precise do we inverse the spline
*
*/
float invSpline(uniform float spl[];
uniform float a;
uniform float prev;
uniform float step)
{
uniform float j = prev;
while(j<1 && spline(j, spl) < a) {
j += step;
}
return j;
}
// *******************************************************************
/**
* Reparametrizes a spline
*
* @param spl spline to reparametrize
* @param spl_n spline's size
* @param X the resulting spline reparametrized. its size must be bigger
* @param X_n X's size
*/
void reparam(uniform float spl[];
uniform float spl_n;
output uniform float X[];
uniform float X_n) {
uniform float i;
uniform float prev=0;
uniform float step = 1/(X_n*10);
// the first and last point are the same
X[i] = spl[0];
X[X_n-1] = spl[spl_n-1];
for(i=0; i<X_n-2; i+=1) {
uniform float grad = i/(X_n-3);
// we search where in spl the spline is equal to grad
prev = invSpline(spl, grad, prev, step);
X[i+1] = prev;
}
}
Thanks!