UNPKG

@thi.ng/shader-ast-stdlib

Version:

Function collection for modular GPGPU / shader programming with @thi.ng/shader-ast

74 lines (73 loc) 1.98 kB
import { F, V2 } from "@thi.ng/shader-ast/api/types"; import { assign } from "@thi.ng/shader-ast/ast/assign"; import { forLoop, ifThen } from "@thi.ng/shader-ast/ast/controlflow"; import { defn, ret } from "@thi.ng/shader-ast/ast/function"; import { FLOAT0, FLOAT2, VEC2_0, VEC2_1, float, vec2 } from "@thi.ng/shader-ast/ast/lit"; import { add, addSelf, div, gt, inc, lt, lte, or, 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 { fit } from "../math/fit.js"; const functionSampler = (fn, map, opts = {}) => { const { min = 0, max = 1, radius = 1, steps = 4, area = false } = opts; return defn(F, void 0, [V2, V2], (frag, res) => { let count, total; let q; const invStep = float(2 * radius / steps); return [ q = sym(map(frag, res)), // bail out early if outside [min..max] interval ifThen(or(lt($x(q), float(min)), gt($x(q), float(max))), [ ret(FLOAT0) ]), count = sym(FLOAT0), total = sym(FLOAT0), forLoop( sym(float(-radius)), (x) => lte(x, float(radius)), (x) => addSelf(x, invStep), (x) => [ forLoop( sym(float(-radius)), (y) => lte(y, float(radius)), (y) => addSelf(y, invStep), (y) => [ inc(total), assign(q, map(add(frag, vec2(x, y)), res)), ifThen(gt(fn($x(q)), $y(q)), [inc(count)]) ] ) ] ), ...!area ? [ ifThen(gt(count, div(total, FLOAT2)), [ assign(count, sub(total, count)) ]) ] : [], ret(div(count, total)) ]; }); }; const functionDomainMapper = (amin, amax, bmin = VEC2_0, bmax = VEC2_1) => defn(V2, void 0, [V2, V2], (p, res) => [ ret(fit(div(p, res), amin, amax, bmin, bmax)) ]); export { functionDomainMapper, functionSampler };