@thi.ng/shader-ast-stdlib
Version:
Function collection for modular GPGPU / shader programming with @thi.ng/shader-ast
116 lines (115 loc) • 2.95 kB
JavaScript
import { F, V2 } from "@thi.ng/shader-ast/api/types";
import { assign } from "@thi.ng/shader-ast/ast/assign";
import { ifThen } from "@thi.ng/shader-ast/ast/controlflow";
import { defn, ret } from "@thi.ng/shader-ast/ast/function";
import {
FLOAT0,
FLOAT1,
FLOAT2,
float,
vec2
} from "@thi.ng/shader-ast/ast/lit";
import {
add,
div,
gte,
lt,
madd,
mul,
neg,
sub
} from "@thi.ng/shader-ast/ast/ops";
import { $x, $y } from "@thi.ng/shader-ast/ast/swizzle";
import { sym } from "@thi.ng/shader-ast/ast/sym";
import {
abs,
acos,
cos,
dot,
powf,
sign,
sin,
sqrt
} from "@thi.ng/shader-ast/builtin/math";
import { clamp01 } from "../math/clamp.js";
import { cross2 } from "../math/cross2.js";
const sdfQuadratic2 = defn(
F,
"sdfQuadratic2",
[V2, V2, V2, V2],
(pos, A, B, C) => {
let a, b, c, d;
let kk, kx, ky, kz;
let p, q, p3, q2, h;
let m, n, t, v, z;
let res, sgn;
let x, y, uv;
return [
a = sym(sub(B, A)),
b = sym(add(madd(B, -2, A), C)),
c = sym(mul(a, FLOAT2)),
d = sym(sub(A, pos)),
kk = sym(div(FLOAT1, dot(b, b))),
kx = sym(mul(kk, dot(a, b))),
ky = sym(mul(kk, div(madd(FLOAT2, dot(a, a), dot(d, b)), 3))),
kz = sym(mul(kk, dot(d, a))),
res = sym(FLOAT0),
sgn = sym(FLOAT0),
p = sym(sub(ky, mul(kx, kx))),
q = sym(madd(sub(mul(mul(FLOAT2, kx), kx), mul(3, ky)), kx, kz)),
p3 = sym(mul(mul(p, p), p)),
q2 = sym(mul(q, q)),
h = sym(madd(p3, 4, q2)),
ifThen(
gte(h, FLOAT0),
[
assign(h, sqrt(h)),
x = sym(div(sub(vec2(h, neg(h)), q), FLOAT2)),
uv = sym(mul(sign(x), powf(abs(x), float(1 / 3)))),
t = sym(clamp01(sub(add($x(uv), $y(uv)), kx))),
assign(x, madd(madd(b, t, c), t, d)),
assign(res, dot(x, x)),
assign(sgn, cross2(madd(b, mul(t, FLOAT2), c), x))
],
[
z = sym(sqrt(neg(p))),
v = sym(
div(acos(div(q, mul(mul(p, z), FLOAT2))), float(3))
),
m = sym(cos(v)),
n = sym(mul(sin(v), Math.sqrt(3))),
uv = sym(
clamp01(
sub(mul(vec2(add(m, m), sub(neg(n), m)), z), kx)
)
),
x = sym(madd(madd(b, $x(uv), c), $x(uv), d)),
y = sym(madd(madd(b, $y(uv), c), $y(uv), d)),
assign(m, dot(x, x)),
assign(n, dot(y, y)),
ifThen(
lt(m, n),
[
assign(res, m),
assign(
sgn,
cross2(madd(b, mul($x(uv), FLOAT2), c), x)
)
],
[
assign(res, n),
assign(
sgn,
cross2(madd(b, mul($y(uv), FLOAT2), c), y)
)
]
)
]
),
ret(mul(sign(sgn), sqrt(res)))
];
}
);
export {
sdfQuadratic2
};