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