@thi.ng/shader-ast
Version:
DSL to define shader code in TypeScript and cross-compile to GLSL, JS and other targets
159 lines (158 loc) • 3.66 kB
JavaScript
import { isBoolean } from "@thi.ng/checks/is-boolean";
import { isNumber } from "@thi.ng/checks/is-number";
import {
B,
F,
I,
M2,
M3,
M4,
U,
V2,
V3,
V4
} from "../api/types.js";
import { isVec } from "./checks.js";
const lit = (type, val, info) => type === val.type && info === val.info ? val : {
tag: "lit",
type,
info,
val
};
const bool = (x) => lit(B, isNumber(x) ? !!x : x);
const float = (x) => lit(F, isBoolean(x) ? x & 1 : x);
const int = (x) => lit(I, isBoolean(x) ? x & 1 : isNumber(x) ? x | 0 : x);
const uint = (x) => lit(U, isBoolean(x) ? x & 1 : isNumber(x) ? x >>> 0 : x);
const __wrap = (type, ctor) => (x) => isNumber(x) ? ctor(x) : x !== void 0 && !isVec(x) && x.type !== type ? ctor(x) : x;
const wrapFloat = __wrap(F, float);
const wrapInt = __wrap(I, int);
const wrapUint = __wrap(U, uint);
const wrapBool = __wrap(B, bool);
const TRUE = bool(true);
const FALSE = bool(false);
const FLOAT0 = float(0);
const FLOAT1 = float(1);
const FLOAT2 = float(2);
const FLOAT05 = float(0.5);
const INT0 = int(0);
const INT1 = int(1);
const UINT0 = uint(0);
const UINT1 = uint(1);
const PI = float(Math.PI);
const TAU = float(Math.PI * 2);
const HALF_PI = float(Math.PI / 2);
const SQRT2 = float(Math.SQRT2);
const PHI = float((1 + Math.sqrt(5)) / 2);
const $gvec = (wrap, init) => (xs) => [xs[0] === void 0 ? init : wrap(xs[0]), ...xs.slice(1).map(wrap)];
const $vec = $gvec(wrapFloat, FLOAT0);
const $ivec = $gvec(wrapInt, INT0);
const $uvec = $gvec(wrapUint, UINT0);
const $bvec = $gvec(wrapBool, FALSE);
const $vinfo = (v, info = "") => v[0] + info.substring(1);
const $info = (xs, info) => isVec(xs[0]) ? $vinfo(xs[0].type, info[xs.length]) : info[xs.length];
const $gvec2 = (type, ctor, xs) => lit(type, xs = ctor(xs), $info(xs, ["n", "n"]));
const $gvec3 = (type, ctor, xs) => lit(type, xs = ctor(xs), $info(xs, ["n", "n", "vn"]));
const $gvec4 = (type, ctor, xs) => lit(
type,
xs = ctor(xs),
xs.length === 2 ? isVec(xs[1]) ? xs[0].type[0] + xs[1].type[0] : "vn" : $info(xs, ["n", "n", void 0, "vnn"])
);
const $gmat = (type, info, xs) => lit(type, xs = $vec(xs), info[xs.length]);
function vec2(...xs) {
return $gvec2(V2, $vec, xs);
}
function vec3(...xs) {
return $gvec3(V3, $vec, xs);
}
function vec4(...xs) {
return $gvec4(V4, $vec, xs);
}
function ivec2(...xs) {
return $gvec2("ivec2", $ivec, xs);
}
function ivec3(...xs) {
return $gvec3("ivec3", $ivec, xs);
}
function ivec4(...xs) {
return $gvec4("ivec4", $ivec, xs);
}
function uvec2(...xs) {
return $gvec2("uvec2", $uvec, xs);
}
function uvec3(...xs) {
return $gvec3("uvec3", $uvec, xs);
}
function uvec4(...xs) {
return $gvec4("uvec4", $uvec, xs);
}
function bvec2(...xs) {
return $gvec2("bvec2", $bvec, xs);
}
function bvec3(...xs) {
return $gvec3("bvec3", $bvec, xs);
}
function bvec4(...xs) {
return $gvec4("bvec4", $bvec, xs);
}
function mat2(...xs) {
return $gmat(M2, ["n", "n", "vv"], xs);
}
function mat3(...xs) {
return $gmat(M3, ["n", "n", void 0, "vvv"], xs);
}
function mat4(...xs) {
return $gmat(M4, ["n", "n", void 0, void 0, "vvvv"], xs);
}
const VEC2_0 = vec2(0);
const VEC2_1 = vec2(1);
const VEC2_2 = vec2(2);
const VEC3_0 = vec3(0);
const VEC3_1 = vec3(1);
const VEC3_2 = vec3(2);
export {
FALSE,
FLOAT0,
FLOAT05,
FLOAT1,
FLOAT2,
HALF_PI,
INT0,
INT1,
PHI,
PI,
SQRT2,
TAU,
TRUE,
UINT0,
UINT1,
VEC2_0,
VEC2_1,
VEC2_2,
VEC3_0,
VEC3_1,
VEC3_2,
bool,
bvec2,
bvec3,
bvec4,
float,
int,
ivec2,
ivec3,
ivec4,
lit,
mat2,
mat3,
mat4,
uint,
uvec2,
uvec3,
uvec4,
vec2,
vec3,
vec4,
wrapBool,
wrapFloat,
wrapInt,
wrapUint
};