318 lines
7.1 KiB
GLSL
318 lines
7.1 KiB
GLSL
// these are shaping functions taken from various places of https://flong.com
|
|
|
|
// Polynominal shaping
|
|
|
|
float blinn_wyvill_cos_approx(float x) {
|
|
float x2 = x*x;
|
|
float x4 = x2*x2;
|
|
float x6 = x4*x2;
|
|
|
|
float fa = ( 4.0/9.0);
|
|
float fb = (17.0/9.0);
|
|
float fc = (22.0/9.0);
|
|
|
|
return fa*x6 - fb*x4 + fc*x2;
|
|
}
|
|
|
|
// TODO: factor out clamping
|
|
float double_cubic_seat(float x, vec2 ab) {
|
|
float epsilon = 0.00001;
|
|
float min_param_a = 0.0 + epsilon;
|
|
float max_param_a = 1.0 - epsilon;
|
|
float min_param_b = 0.0;
|
|
float max_param_b = 1.0;
|
|
float a = clamp(ab.x, min_param_a, max_param_a);
|
|
float b = clamp(ab.y, min_param_b, max_param_b);
|
|
|
|
if (x <= a){
|
|
return b - b*pow(1.-x/a, 3.0);
|
|
}
|
|
return b + (1.-b)*pow((x-a)/(1.-a), 3.0);
|
|
}
|
|
|
|
float double_cubic_seat_linear_blend(float x, vec2 ab) {
|
|
float epsilon = 0.00001;
|
|
float min_param_a = 0.0 + epsilon;
|
|
float max_param_a = 1.0 - epsilon;
|
|
float min_param_b = 0.0;
|
|
float max_param_b = 1.0;
|
|
float a = clamp(ab.x, min_param_a, max_param_a);
|
|
float b = clamp(ab.y, min_param_b, max_param_b);
|
|
b = 1.0 - b;
|
|
|
|
if (x<=a){
|
|
return b*x + (1.-b)*a*(1.-pow(1.-x/a, 3.));
|
|
}
|
|
return b*x + (1.-b)*(a + (1.-a)*pow((x-a)/(1.-a), 3.));
|
|
}
|
|
|
|
float double_odd_polynomial_seat(float x, float a, float b, float n) {
|
|
float epsilon = 0.00001;
|
|
float min_param_a = 0.0 + epsilon;
|
|
float max_param_a = 1.0 - epsilon;
|
|
float min_param_b = 0.0;
|
|
float max_param_b = 1.0;
|
|
a = clamp(a, min_param_a, max_param_a);
|
|
b = clamp(b, min_param_b, max_param_b);
|
|
|
|
float p = 2.*n + 1.;
|
|
if (x <= a){
|
|
return b - b*pow(1.-x/a, p);
|
|
}
|
|
return b + (1.-b)*pow((x-a)/(1.-a), p);
|
|
}
|
|
|
|
float double_poly_sigmoid(float x, float a, float b, float n) {
|
|
if(mod(n, 2.) == 0.) {
|
|
if(x <= 0.5) {
|
|
return pow(2.0*x, n)/2.0;
|
|
}
|
|
return 1.0 - pow(2.*(x-1.), n)/2.0;
|
|
} else {
|
|
if (x<=0.5){
|
|
return pow(2.0*x, n)/2.0;
|
|
}
|
|
return 1.0 + pow(2.0*(x-1.), n)/2.0;
|
|
}
|
|
}
|
|
|
|
float quad_through_point(float x, vec2 ab) {
|
|
float epsilon = 0.00001;
|
|
float min_param_a = 0.0 + epsilon;
|
|
float max_param_a = 1.0 - epsilon;
|
|
float min_param_b = 0.0;
|
|
float max_param_b = 1.0;
|
|
float a = clamp(ab.x, min_param_a, max_param_a);
|
|
float b = clamp(ab.y, min_param_b, max_param_b);
|
|
|
|
float A = (1.-b)/(1.-a) - (b/a);
|
|
float B = (A*(a*a)-b)/a;
|
|
float y = A*(x*x) - B*(x);
|
|
y = clamp(0., 1., y);
|
|
|
|
return y;
|
|
}
|
|
|
|
// exponential shaping
|
|
|
|
float exp_easing(float x, float a) {
|
|
float e = 0.00001;
|
|
a = clamp(a, 0.+e, 1.-e);
|
|
|
|
if (a < 0.5) {
|
|
a = 2.0*(a);
|
|
return pow(x, a);
|
|
}
|
|
a = 2.*(a-.5);
|
|
return pow(x, 1./(1.-a));
|
|
}
|
|
|
|
float double_exp_seat(float x, float a) {
|
|
float e = 0.00001;
|
|
a = clamp(a, .0+e, 1.-e);
|
|
|
|
if (x<=0.5) {
|
|
return pow(2.*x, 1.-a)/2.0;
|
|
}
|
|
return 1. - pow(2.*(1.-x), 1.-a)/2.;
|
|
}
|
|
|
|
float double_exp_sigmoid(float x, float a) {
|
|
float e = 0.00001;
|
|
a = 1.-clamp(a, .0+e, 1.-e);
|
|
|
|
if (x<=0.5){
|
|
return pow(2.0*x, 1.0/a)/2.0;
|
|
}
|
|
return 1.0 - (pow(2.0*(1.0-x), 1.0/a))/2.0;
|
|
}
|
|
|
|
float normalized_log_sigmoid(float x, float a) {
|
|
float e = 0.0001;
|
|
a = 1./(1.-clamp(a, 0.+e, 1.-e)) - 1.;
|
|
|
|
float b = 1.0 / (1.0 + exp(a));
|
|
float c = 1.0 / (1.0 + exp(0.-a));
|
|
a = 1. / (1. + exp(0. -((x-.5)*a*2.)));
|
|
return (a-b)/(c-b);
|
|
}
|
|
|
|
// bezier shaping
|
|
|
|
float quad_bezier(float x, vec2 ab) {
|
|
float e = 0.00001;
|
|
float a = clamp(ab.x, 0., 1.);
|
|
float b = clamp(ab.y, 0., 1.);
|
|
if (a == 0.5) a += e;
|
|
|
|
float om2a = 1. - 2.*a;
|
|
float t = (sqrt(a*a + om2a*x) - a)/om2a;
|
|
return (1.-2.*b)*(t*t) + (2.*b)*t;
|
|
}
|
|
|
|
|
|
// cubic bezier begin
|
|
float slope_from_t(float t, float A, float B, float C) {
|
|
return 1.0/(3.0*A*t*t + 2.0*B*t + C);
|
|
}
|
|
|
|
float x_from_t(float t, float A, float B, float C, float D) {
|
|
return A*(t*t*t) + B*(t*t) + C*t + D;
|
|
}
|
|
|
|
float y_from_t(float t, float E, float F, float G, float H) {
|
|
return E*(t*t*t) + F*(t*t) + G*t + H;
|
|
}
|
|
|
|
float cubic_bezier(float x, vec2 a, vec2 b) {
|
|
float y0a = 0.00;
|
|
float x0a = 0.00;
|
|
float y1a = a.y;
|
|
float x1a = a.x;
|
|
float y2a = b.y;
|
|
float x2a = b.x;
|
|
float y3a = 1.00;
|
|
float x3a = 1.00;
|
|
|
|
float A = x3a - 3.*x2a + 3.*x1a - x0a;
|
|
float B = 3.*x2a - 6.*x1a + 3.*x0a;
|
|
float C = 3.*x1a - 3.*x0a;
|
|
float D = x0a;
|
|
|
|
float E = y3a - 3.*y2a + 3.*y1a - y0a;
|
|
float F = 3.*y2a - 6.*y1a + 3.*y0a;
|
|
float G = 3.*y1a - 3.*y0a;
|
|
float H = y0a;
|
|
|
|
float currentt = x;
|
|
for (int i=0; i < 5; i++){
|
|
float currentx = x_from_t(currentt, A, B, C, D);
|
|
float currentslope = slope_from_t(currentt, A, B, C);
|
|
currentt -= (currentx - x)*(currentslope);
|
|
currentt = clamp(currentt, 0., 1.);
|
|
}
|
|
|
|
float y = y_from_t(currentt, E, F, G, H);
|
|
return y;
|
|
}
|
|
// cubic bezier end
|
|
|
|
// cubic bezier through points (requires cubic bezier) begin
|
|
float b0 (float t){
|
|
return (1.-t)*(1.-t)*(1.-t);
|
|
}
|
|
float b1 (float t){
|
|
return 3.*t* (1.-t)*(1.-t);
|
|
}
|
|
float b2 (float t){
|
|
return 3.*t*t* (1.-t);
|
|
}
|
|
float b3 (float t){
|
|
return t*t*t;
|
|
}
|
|
float findx(float t, float x0, float x1, float x2, float x3) {
|
|
return x0*b0(t) + x1*b1(t) + x2*b2(t) + x3*b3(t);
|
|
}
|
|
float findy(float t, float y0, float y1, float y2, float y3) {
|
|
return y0*b0(t) + y1*b1(t) + y2*b2(t) + y3*b3(t);
|
|
}
|
|
|
|
float cubic_bezier_through(float x, vec2 a, vec2 b) {
|
|
float y = 0.;
|
|
float e = 0.00001;
|
|
float minp = 0. + e;
|
|
float maxp = 1. - e;
|
|
a = clamp(a, minp, maxp);
|
|
b = clamp(b, minp, maxp);
|
|
|
|
float x0 = 0.;
|
|
float y0 = 0.;
|
|
float x4 = a.x;
|
|
float y4 = a.y;
|
|
float x5 = b.x;
|
|
float y5 = b.y;
|
|
float x3 = 1.;
|
|
float y3 = 1.;
|
|
float x1,y1,x2,y2;
|
|
|
|
// arbitrary but reasonable
|
|
float t1 = 0.3;
|
|
float t2 = 0.7;
|
|
|
|
float b0t1 = b0(t1);
|
|
float b1t1 = b1(t1);
|
|
float b2t1 = b2(t1);
|
|
float b3t1 = b3(t1);
|
|
float b0t2 = b0(t2);
|
|
float b1t2 = b1(t2);
|
|
float b2t2 = b2(t2);
|
|
float b3t2 = b3(t2);
|
|
|
|
float ccx = x4 - x0*b0t1 - x3*b3t1;
|
|
float ccy = y4 - y0*b0t1 - y3*b3t1;
|
|
float ffx = x5 - x0*b0t2 - x3*b3t2;
|
|
float ffy = y5 - y0*b0t2 - y3*b3t2;
|
|
|
|
x2 = (ccx - (ffx*b1t1)/b1t2) / (b2t1 - (b1t1*b2t2)/b1t2);
|
|
y2 = (ccy - (ffy*b1t1)/b1t2) / (b2t1 - (b1t1*b2t2)/b1t2);
|
|
x1 = (ccx - x2*b2t1) / b1t1;
|
|
y1 = (ccy - y2*b2t1) / b1t1;
|
|
|
|
x1 = clamp(x1, minp, maxp);
|
|
x2 = clamp(x2, minp, maxp);
|
|
|
|
y = cubic_bezier(x, vec2(x1,y1), vec2(x2,y2));
|
|
return clamp(y, 0., 1.);
|
|
}
|
|
// cubic bezier through points end
|
|
|
|
// Circular shaping
|
|
|
|
float circ_ease_in (float x){
|
|
return 1. - sqrt(1. - x*x);
|
|
}
|
|
|
|
float circ_ease_out (float x){
|
|
return sqrt(1. - pow(1. - x, 2.));
|
|
}
|
|
|
|
float double_circ_seat(float x, float a) {
|
|
a = clamp(a, 0., 1.);
|
|
|
|
if (x<=a){
|
|
return sqrt(pow(a, 2.) - pow(x-a, 2.));
|
|
}
|
|
return 1. - sqrt(pow(1.-a, 2.) - pow(x-a, 2.));
|
|
}
|
|
|
|
float double_circ_sigmoid(float x, float a) {
|
|
a = clamp(a, 0., 1.);
|
|
|
|
if (x<=a){
|
|
return a - sqrt(pow(a, 2.) - pow(x, 2.));
|
|
}
|
|
return a + sqrt(pow(1.-a, 2.) - pow(x-1., 2.));
|
|
}
|
|
|
|
float double_ellip_seat(float x, vec2 ab) {
|
|
float e = 0.00001;
|
|
float a = clamp(ab.x, 0.+e, 1.+e);
|
|
float b = clamp(ab.y, 0., 1.);
|
|
|
|
if (x<=a){
|
|
return (b/a) * sqrt(pow(a, 2.) - pow(x-a, 2.));
|
|
}
|
|
return 1.-((1.-b)/(1.-a))*sqrt(pow(1.-a, 2.)-pow(x-a,2.));
|
|
}
|
|
|
|
float double_ellip_sigmoid(float x, vec2 ab) {
|
|
float e = 0.00001;
|
|
float a = clamp(ab.x, 0.+e, 1.+e);
|
|
float b = clamp(ab.y, 0., 1.);
|
|
|
|
if (x<=a){
|
|
return b * (1. - (sqrt(pow(a, 2.) - pow(x, 2.))/a));
|
|
}
|
|
return b+((1.-b)/(1.-a))*sqrt(pow(1.-a,2.)-pow(x-1.,2.));
|
|
}
|