UNPKG

@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
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 };