UNPKG

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