Skip to content

Commit

Permalink
feat(shader-ast-stdlib): add more functions
Browse files Browse the repository at this point in the history
- toLinear() / toSRGB()
- luminanceRGB()
- cartesian2/3() / polar2/3()
- perpendicularCW/CCW()
- sincos() / cossin()
- rotation matrix factories for mat2/3/4
  • Loading branch information
postspectacular committed Jul 6, 2019
1 parent ac179a3 commit 4b6e4fe
Show file tree
Hide file tree
Showing 8 changed files with 284 additions and 1 deletion.
24 changes: 24 additions & 0 deletions packages/shader-ast-stdlib/src/color/linear-srgb.ts
@@ -0,0 +1,24 @@
import {
float,
FloatTerm,
pow,
Prim,
Term,
vec2,
vec3,
vec4
} from "@thi.ng/shader-ast";

const GAMMA = float(2.2);
const INV_GAMMA = float(1 / 2.2);

const $ = <T extends Prim>(t: Term<T>, x: FloatTerm): Term<T> => <any>{
float: x,
vec2: vec2(x),
vec3: vec3(x),
vec4: vec4(x, x, x, 1)
}[t.type];

export const toLinear = <T extends Prim>(x: Term<T>) => pow(x, $(x, GAMMA));

export const toSRGB = <T extends Prim>(x: Term<T>) => pow(x, $(x, INV_GAMMA));
9 changes: 9 additions & 0 deletions packages/shader-ast-stdlib/src/color/luminance.ts
@@ -0,0 +1,9 @@
import { dot, vec3, Vec3Term } from "@thi.ng/shader-ast";

/**
* Inline function. Computes luminance of given RGB color
*
* @param rgb
*/
export const luminanceRGB = (rgb: Vec3Term) =>
dot(rgb, vec3(0.299, 0.587, 0.114));
7 changes: 7 additions & 0 deletions packages/shader-ast-stdlib/src/index.ts
@@ -1,5 +1,8 @@
export * from "./api";

export * from "./color/linear-srgb";
export * from "./color/luminance";

export * from "./fog/exp";
export * from "./fog/exp2";
export * from "./fog/linear";
Expand All @@ -8,6 +11,7 @@ export * from "./lighting/lambert";
export * from "./lighting/trilight";

export * from "./math/additive";
export * from "./math/cartesian";
export * from "./math/clamp";
export * from "./math/cross2";
export * from "./math/dist-chebyshev";
Expand All @@ -17,10 +21,13 @@ export * from "./math/magsq";
export * from "./math/maxcomp";
export * from "./math/mincomp";
export * from "./math/orthogonal";
export * from "./math/polar";
export * from "./math/sincos";

export * from "./matrix/lookat";
export * from "./matrix/mvp";
export * from "./matrix/normal";
export * from "./matrix/rotation";

export * from "./noise/hash";
export * from "./noise/permute";
Expand Down
41 changes: 41 additions & 0 deletions packages/shader-ast-stdlib/src/math/cartesian.ts
@@ -0,0 +1,41 @@
import {
$x,
$y,
$z,
defn,
FloatSym,
mul,
ret,
sym,
vec2,
Vec2Sym,
Vec2Term,
vec3
} from "@thi.ng/shader-ast";
import { cossin } from "./sincos";

/**
* Converts 2D polar vector `v` to cartesian coordinates. See `polar2()`
* for reverse operation.
*
* @param v
*/
export const cartesian2 = (v: Vec2Term) => mul(cossin($y(v)), vec2($x(v)));

/**
* Converts 3D polar vector `v` to cartesian coordinates. See `polar3()`
* for reverse operation.
*
* @param v
*/
export const cartesian3 = defn("vec3", "cartesian3", [["vec3"]], (v) => {
let r: FloatSym;
let t: Vec2Sym;
let p: Vec2Sym;
return [
(r = sym($x(v))),
(t = sym(cossin($y(v)))),
(p = sym(cossin($z(v)))),
ret(vec3(mul(mul(r, $x(t)), $x(p))))
];
});
20 changes: 19 additions & 1 deletion packages/shader-ast-stdlib/src/math/orthogonal.ts
Expand Up @@ -8,15 +8,33 @@ import {
neg,
ret,
ternary,
vec2,
Vec2Term,
vec3
} from "@thi.ng/shader-ast";

/**
* Inline function. Returns counter-clockwise perpendicular vector
* (assuming Y-up). [-y, x]
*
* @param v
*/
export const perpendicularCCW = (v: Vec2Term) => vec2(neg($y(v)), $x(v));

/**
* Inline function. Returns clockwise perpendicular vector (assuming
* Y-up). [y,-x]
*
* @param v
*/
export const perpendicularCW = (v: Vec2Term) => vec2($y(v), neg($x(v)));

/**
* Returns an orthogonal vector to `v`.
*
* http://lolengine.net/blog/2013/09/21/picking-orthogonal-vector-combing-coconuts
*/
export const orthogonal = defn("vec3", "orthogonal", [["vec3"]], (v) => [
export const orthogonal3 = defn("vec3", "orthogonal3", [["vec3"]], (v) => [
ret(
ternary(
gt(abs($x(v)), abs($z(v))),
Expand Down
40 changes: 40 additions & 0 deletions packages/shader-ast-stdlib/src/math/polar.ts
@@ -0,0 +1,40 @@
import {
$x,
$y,
$z,
asin,
atan,
defn,
div,
FloatSym,
length,
ret,
sym,
vec2,
vec3
} from "@thi.ng/shader-ast";

/**
* Converts 2D cartesian vector `v` to polar coordinates, i.e. `[r,θ]`
* (angle in radians). See `cartesian2()` for reverse operation.
*
* @param v
*/
export const polar2 = defn("vec2", "polar2", [["vec2"]], (v) => [
ret(vec2(length(v), atan(div($y(v), $x(v)))))
]);

/**
* Converts 3D cartesian vector `v` to spherical coordinates, i.e.
* `[r,θ,ϕ]` (angles in radians). See `cartesian3()` for reverse
* operation.
*
* @param v
*/
export const polar3 = defn("vec3", "polar3", [["vec3"]], (v) => {
let r: FloatSym;
return [
(r = sym(length(v))),
ret(vec3(r, asin(div($z(v), r)), atan(div($y(v), $x(v)))))
];
});
20 changes: 20 additions & 0 deletions packages/shader-ast-stdlib/src/math/sincos.ts
@@ -0,0 +1,20 @@
import {
cos,
FloatTerm,
sin,
vec2
} from "@thi.ng/shader-ast";

/**
* Inline function. Returns vec2(sin(x), cos(x)).
*
* @param x
*/
export const sincos = (x: FloatTerm) => vec2(sin(x), cos(x));

/**
* Inline function. Returns vec2(cos(x), sin(x)).
*
* @param x
*/
export const cossin = (x: FloatTerm) => vec2(cos(x), sin(x));
124 changes: 124 additions & 0 deletions packages/shader-ast-stdlib/src/matrix/rotation.ts
@@ -0,0 +1,124 @@
import {
$x,
$y,
defn,
mat2,
mat3,
mat4,
neg,
ret,
sym,
Vec2Term
} from "@thi.ng/shader-ast";
import { perpendicularCCW } from "../math/orthogonal";
import { cossin } from "../math/sincos";

export const rotation2 = defn("mat2", "rotation2", [["float"]], (theta) => {
let cs: Vec2Term;
return [(cs = sym(cossin(theta))), ret(mat2(cs, perpendicularCCW(cs)))];
});

export const rotationX3 = defn("mat3", "rotationX3", [["float"]], (theta) => {
let cs: Vec2Term;
return [
(cs = sym(cossin(theta))),
ret(mat3(1, 0, 0, 0, $x(cs), $y(cs), 0, neg($y(cs)), $x(cs)))
];
});

export const rotationY3 = defn("mat3", "rotationY3", [["float"]], (theta) => {
let cs: Vec2Term;
return [
(cs = sym(cossin(theta))),
ret(mat3($x(cs), 0, neg($y(cs)), 0, 1, 0, $y(cs), 0, $x(cs)))
];
});

export const rotationZ3 = defn("mat3", "rotationZ3", [["float"]], (theta) => {
let cs: Vec2Term;
return [
(cs = sym(cossin(theta))),
ret(mat3($x(cs), $y(cs), 0, neg($y(cs)), $x(cs), 0, 0, 0, 1))
];
});

export const rotationX4 = defn("mat3", "rotationX4", [["float"]], (theta) => {
let cs: Vec2Term;
return [
(cs = sym(cossin(theta))),
ret(
mat4(
1,
0,
0,
0,
0,
$x(cs),
$y(cs),
0,
0,
neg($y(cs)),
$x(cs),
0,
0,
0,
0,
1
)
)
];
});

export const rotationY4 = defn("mat3", "rotationY4", [["float"]], (theta) => {
let cs: Vec2Term;
return [
(cs = sym(cossin(theta))),
ret(
mat4(
$x(cs),
0,
neg($y(cs)),
0,
0,
1,
0,
0,
$y(cs),
0,
$x(cs),
0,
0,
0,
0,
1
)
)
];
});

export const rotationZ4 = defn("mat4", "rotationZ4", [["float"]], (theta) => {
let cs: Vec2Term;
return [
(cs = sym(cossin(theta))),
ret(
mat4(
$x(cs),
$y(cs),
0,
0,
neg($y(cs)),
$x(cs),
0,
0,
0,
0,
1,
0,
0,
0,
0,
1
)
)
];
});

0 comments on commit 4b6e4fe

Please sign in to comment.