@thi.ng/shader-ast-stdlib
Version:
Function collection for modular GPGPU / shader programming with @thi.ng/shader-ast
320 lines (319 loc) • 7.06 kB
JavaScript
import { F } from "@thi.ng/shader-ast/api/types";
import { ifThen, ternary } from "@thi.ng/shader-ast/ast/controlflow";
import { defn, ret } from "@thi.ng/shader-ast/ast/function";
import {
FLOAT0,
FLOAT05,
FLOAT1,
FLOAT2,
HALF_PI,
PI,
TAU,
float
} from "@thi.ng/shader-ast/ast/lit";
import {
add,
div,
eq,
gte,
lt,
lte,
madd,
mul,
neg,
reciprocal,
sub
} from "@thi.ng/shader-ast/ast/ops";
import { cos, exp2, pow, sin, sqrt } from "@thi.ng/shader-ast/builtin/math";
const defEasing = (body) => defn(F, null, [F], body);
const easeInSine = defEasing((x) => [
ret(sub(FLOAT1, cos(mul(x, HALF_PI))))
]);
const easeOutSine = defEasing((x) => [ret(sin(mul(x, HALF_PI)))]);
const easeInOutSine = defEasing((x) => [
ret(div(neg(sub(cos(mul(PI, x)), FLOAT1)), FLOAT2))
]);
const __easeIn = (k) => (x) => [ret(pow(x, k))];
const __easeOut = (k) => (x) => [ret(sub(FLOAT1, pow(sub(FLOAT1, x), k)))];
const __easeInOut = (a, b) => (x) => [
ret(
ternary(
lt(x, FLOAT05),
mul(a, pow(x, b)),
sub(
FLOAT1,
div(pow(madd(neg(FLOAT2), x, FLOAT2), b), FLOAT2)
)
)
)
];
const easeInQuad = defEasing(__easeIn(FLOAT2));
const easeOutQuad = defEasing(__easeOut(FLOAT2));
const easeInOutQuad = defEasing(__easeInOut(FLOAT2, FLOAT2));
const easeInCubic = defEasing(__easeIn(float(3)));
const easeOutCubic = defEasing(__easeOut(float(3)));
const easeInOutCubic = defEasing(__easeInOut(float(4), float(3)));
const easeInQuart = defEasing(__easeIn(float(4)));
const easeOutQuart = defEasing(__easeOut(float(4)));
const easeInOutQuart = defEasing(__easeInOut(float(8), float(4)));
const easeInQuint = defEasing(__easeIn(float(5)));
const easeOutQuint = defEasing(__easeOut(float(5)));
const easeInOutQuint = defEasing(__easeInOut(float(16), float(5)));
const easeInExpo = defEasing((x) => [
ret(
ternary(eq(x, FLOAT0), FLOAT0, exp2(sub(mul(float(10), x), float(10))))
)
]);
const easeOutExpo = defEasing((x) => [
ret(
ternary(
eq(x, FLOAT1),
FLOAT1,
sub(FLOAT1, exp2(mul(neg(float(10)), x)))
)
)
]);
const easeInOutExpo = defEasing((x) => [
ret(
ternary(
eq(x, FLOAT0),
FLOAT0,
ternary(
eq(x, FLOAT1),
FLOAT1,
ternary(
lt(x, FLOAT05),
div(exp2(sub(mul(float(20), x), float(10))), FLOAT2),
div(
sub(FLOAT2, exp2(madd(neg(float(20)), x, float(10)))),
FLOAT2
)
)
)
)
)
]);
const easeInCirc = defEasing((x) => [
ret(sub(FLOAT1, sqrt(sub(FLOAT1, pow(x, FLOAT2)))))
]);
const easeOutCirc = defEasing((x) => [
ret(sqrt(sub(FLOAT1, pow(sub(x, FLOAT1), FLOAT2))))
]);
const easeInOutCirc = defEasing((x) => [
ret(
ternary(
lt(x, FLOAT05),
div(
sub(FLOAT1, sqrt(sub(FLOAT1, pow(mul(FLOAT2, x), FLOAT2)))),
FLOAT2
),
div(
add(
sqrt(
sub(FLOAT1, pow(madd(neg(FLOAT2), x, FLOAT2), FLOAT2))
),
FLOAT1
),
FLOAT2
)
)
)
]);
const easeInBack = defEasing((x) => {
const c1 = 1.70158;
const c3 = c1 + 1;
return [ret(sub(mul(c3, pow(x, float(3))), mul(c1, pow(x, FLOAT2))))];
});
const easeOutBack = defEasing((x) => {
const c1 = 1.70158;
const c3 = c1 + 1;
return [
ret(
add(
madd(float(c3), pow(sub(x, FLOAT1), float(3)), FLOAT1),
mul(c1, pow(sub(x, FLOAT1), FLOAT2))
)
)
];
});
const easeInOutBack = defEasing((x) => {
const c1 = 1.70158;
const c2 = c1 * 1.525;
return [
ret(
ternary(
lt(x, FLOAT05),
div(
mul(
pow(mul(FLOAT2, x), FLOAT2),
sub(mul(mul(add(c2, FLOAT1), FLOAT2), x), c2)
),
FLOAT2
),
div(
add(
mul(
pow(sub(mul(FLOAT2, x), FLOAT2), FLOAT2),
add(
mul(
add(c2, FLOAT1),
sub(mul(x, FLOAT2), FLOAT2)
),
c2
)
),
FLOAT2
),
FLOAT2
)
)
)
];
});
const easeInElastic = defEasing((x) => [
ret(
ternary(
eq(x, FLOAT0),
FLOAT0,
ternary(
eq(x, FLOAT1),
FLOAT1,
mul(
neg(exp2(sub(mul(10, x), 10))),
sin(mul(sub(mul(x, 10), 10.75), div(TAU, 3)))
)
)
)
)
]);
const easeOutElastic = defEasing((x) => [
ret(
ternary(
lte(x, FLOAT0),
FLOAT0,
ternary(
gte(x, FLOAT1),
FLOAT1,
madd(
exp2(mul(-10, x)),
sin(mul(sub(mul(x, 10), 0.75), div(TAU, 3))),
FLOAT1
)
)
)
)
]);
const easeInOutElastic = defEasing((x) => {
const c5 = div(TAU, 4.5);
return [
ret(
ternary(
eq(x, FLOAT0),
FLOAT0,
ternary(
eq(x, FLOAT1),
FLOAT1,
ternary(
lt(x, FLOAT05),
div(
neg(
mul(
exp2(sub(mul(20, x), 10)),
sin(mul(sub(mul(20, x), 11.125), c5))
)
),
FLOAT2
),
add(
div(
mul(
exp2(madd(neg(float(20)), x, float(10))),
sin(mul(sub(mul(20, x), 11.125), c5))
),
FLOAT2
),
FLOAT1
)
)
)
)
)
];
});
const easeOutBounce = defEasing((x) => {
const n1 = 7.5625;
const d1 = float(2.75);
return [
ifThen(lt(x, reciprocal(d1)), [ret(mul(n1, pow(x, FLOAT2)))]),
ifThen(lt(x, div(FLOAT2, d1)), [
ret(
add(
mul(mul(n1, sub(x, div(1.5, d1))), sub(x, div(1.5, d1))),
0.75
)
)
]),
ifThen(lt(x, div(2.5, d1)), [
ret(
add(
mul(mul(n1, sub(x, div(2.25, d1))), sub(x, div(2.25, d1))),
0.9375
)
)
]),
ret(
add(
mul(mul(n1, sub(x, div(2.625, d1))), sub(x, div(2.625, d1))),
0.984375
)
)
];
});
const easeInBounce = defEasing((x) => [
ret(sub(FLOAT1, easeOutBounce(sub(FLOAT1, x))))
]);
const easeInOutBounce = defEasing((x) => [
ret(
ternary(
lt(x, FLOAT05),
div(
sub(FLOAT1, easeOutBounce(sub(FLOAT1, mul(FLOAT2, x)))),
FLOAT2
),
div(add(FLOAT1, easeOutBounce(sub(mul(FLOAT2, x), FLOAT1))), FLOAT2)
)
)
]);
export {
defEasing,
easeInBack,
easeInBounce,
easeInCirc,
easeInCubic,
easeInElastic,
easeInExpo,
easeInOutBack,
easeInOutBounce,
easeInOutCirc,
easeInOutCubic,
easeInOutElastic,
easeInOutExpo,
easeInOutQuad,
easeInOutQuart,
easeInOutQuint,
easeInOutSine,
easeInQuad,
easeInQuart,
easeInQuint,
easeInSine,
easeOutBack,
easeOutBounce,
easeOutCirc,
easeOutCubic,
easeOutElastic,
easeOutExpo,
easeOutQuad,
easeOutQuart,
easeOutQuint,
easeOutSine
};