-
-
Notifications
You must be signed in to change notification settings - Fork 151
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(shader-ast-stdlib): add more 2D SDF prims
- Loading branch information
1 parent
59d631a
commit 2672e75
Showing
6 changed files
with
254 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import type { FloatSym, Vec2Sym } from "@thi.ng/shader-ast"; | ||
import { ternary } from "@thi.ng/shader-ast/ast/controlflow"; | ||
import { defn, ret } from "@thi.ng/shader-ast/ast/function"; | ||
import { FLOAT0, VEC2_0 } from "@thi.ng/shader-ast/ast/lit"; | ||
import { add, gt, sub } from "@thi.ng/shader-ast/ast/ops"; | ||
import { $, $x, $xy, $y } from "@thi.ng/shader-ast/ast/swizzle"; | ||
import { sym } from "@thi.ng/shader-ast/ast/sym"; | ||
import { abs, length, max, min } from "@thi.ng/shader-ast/builtin/math"; | ||
import { maxComp2 } from "../math/maxcomp.js"; | ||
|
||
/** | ||
* Returns signed distance from `p` to centered 2D rect of `size` and corner | ||
* radii defined by given vec4 `r`. | ||
* | ||
* @remarks | ||
* Ported from original GLSL impl by Inigo Quilez: | ||
* - https://iquilezles.org/articles/distfunctions2d/ | ||
* | ||
* @param p - vec2 | ||
* @param size - vec2 | ||
* @param r - vec4 | ||
*/ | ||
export const sdfBoxRounded = defn( | ||
"float", | ||
"sdfBoxRounded", | ||
["vec2", "vec2", "vec4"], | ||
(p, size, r) => { | ||
let q: Vec2Sym, t: Vec2Sym, d: FloatSym; | ||
return [ | ||
(t = sym(ternary(gt($x(p), FLOAT0), $xy(r), $(r, "zw")))), | ||
(d = sym(ternary(gt($y(p), FLOAT0), $x(t), $y(t)))), | ||
(q = sym(add(sub(abs(p), size), d))), | ||
ret(sub(add(min(maxComp2(q), FLOAT0), length(max(q, VEC2_0))), d)), | ||
]; | ||
} | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import type { FloatSym, Vec2Sym } from "@thi.ng/shader-ast/api/syms"; | ||
import { assign } from "@thi.ng/shader-ast/ast/assign"; | ||
import { ifThen, ternary } from "@thi.ng/shader-ast/ast/controlflow"; | ||
import { defn, ret } from "@thi.ng/shader-ast/ast/function"; | ||
import { FLOAT0, FLOAT05, vec2, VEC2_0 } from "@thi.ng/shader-ast/ast/lit"; | ||
import { add, gt, madd, mul, neg, 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 { abs, length, max, min, sign } from "@thi.ng/shader-ast/builtin/math"; | ||
import { maxComp2 } from "../math/maxcomp.js"; | ||
|
||
/** | ||
* Returns signed distance from `p` to 2D cross/plus of given `size` and corner | ||
* radius `r`. | ||
* | ||
* @remarks | ||
* - `size` consist of overall width/size (in x) and thickness (in y component) | ||
* - corner radius can also be negative | ||
* | ||
* Ported from original GLSL impl by Inigo Quilez: | ||
* - https://iquilezles.org/articles/distfunctions2d/ | ||
* | ||
* @param p - | ||
* @param size - | ||
* @param r - | ||
*/ | ||
export const sdfCross2 = defn( | ||
"float", | ||
"sdfCross2", | ||
["vec2", "vec2", "float"], | ||
(p, size, r) => { | ||
let a: Vec2Sym, q: Vec2Sym, w: Vec2Sym; | ||
let k: FloatSym; | ||
return [ | ||
(a = sym(abs(p))), | ||
ifThen(gt($y(a), $x(a)), [assign(a, $(a, "yx"))]), | ||
(q = sym(sub(a, size))), | ||
(k = sym(maxComp2(q))), | ||
(w = sym( | ||
ternary(gt(k, FLOAT0), q, vec2(sub($y(size), $x(a)), neg(k))) | ||
)), | ||
ret(madd(sign(k), length(max(w, VEC2_0)), r)), | ||
]; | ||
} | ||
); | ||
|
||
/** | ||
* Returns signed distance from `p` to 2D "X-sign" of given `size` and stroke | ||
* weight `r`. | ||
* | ||
* @remarks | ||
* Ported from original GLSL impl by Inigo Quilez: | ||
* - https://iquilezles.org/articles/distfunctions2d/ | ||
* | ||
* @param p - | ||
* @param size - | ||
* @param r - | ||
*/ | ||
export const sdfRoundedX2 = defn( | ||
"float", | ||
"sdfRoundedX", | ||
["vec2", "float", "float"], | ||
(p, size, r) => { | ||
let q: Vec2Sym; | ||
return [ | ||
(q = sym(abs(p))), | ||
ret( | ||
sub( | ||
length(sub(q, mul(min(add($x(q), $y(q)), size), FLOAT05))), | ||
r | ||
) | ||
), | ||
]; | ||
} | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import type { Vec2Sym } from "@thi.ng/shader-ast/api/syms"; | ||
import { assign } from "@thi.ng/shader-ast/ast/assign"; | ||
import { defn, ret } from "@thi.ng/shader-ast/ast/function"; | ||
import { FLOAT0, vec2 } from "@thi.ng/shader-ast/ast/lit"; | ||
import { mul, 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 { | ||
abs, | ||
clamp, | ||
dot, | ||
length, | ||
min, | ||
sign, | ||
} from "@thi.ng/shader-ast/builtin/math"; | ||
|
||
/** | ||
* Returns signed distance from `p` to 2D hexagon of given radius `r`. | ||
* | ||
* @remarks | ||
* Ported from original GLSL impl by Inigo Quilez: | ||
* - https://iquilezles.org/articles/distfunctions2d/ | ||
*/ | ||
export const sdfHexagon2 = defn( | ||
"float", | ||
"sdfHexagon2", | ||
["vec2", "float"], | ||
(p, r) => { | ||
const TAN30 = 0.5773502691896257; | ||
let k: Vec2Sym, q: Vec2Sym; | ||
return [ | ||
// sin/cos @ 60deg | ||
(k = sym(vec2(-0.8660254037844386, 0.5))), | ||
(q = sym(abs(p))), | ||
assign(q, sub(q, mul(k, mul(2, min(dot(k, q), FLOAT0))))), | ||
assign( | ||
q, | ||
sub(q, vec2(clamp($x(q), mul(r, -TAN30), mul(r, TAN30)), r)) | ||
), | ||
ret(mul(length(q), sign($y(q)))), | ||
]; | ||
} | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import type { BVec3Sym, FloatSym, IntSym, Vec2Sym } from "@thi.ng/shader-ast"; | ||
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 { index } from "@thi.ng/shader-ast/ast/indexed"; | ||
import { bvec3, FLOAT1, int, INT0 } from "@thi.ng/shader-ast/ast/lit"; | ||
import { | ||
div, | ||
gt, | ||
gte, | ||
inc, | ||
lt, | ||
mul, | ||
neg, | ||
not, | ||
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 { all, _any } from "@thi.ng/shader-ast/builtin/bvec"; | ||
import { dot, min, sqrt } from "@thi.ng/shader-ast/builtin/math"; | ||
import { clamp01 } from "../math/clamp.js"; | ||
|
||
/** | ||
* Higher-order function. Returns specialized function to compute signed | ||
* distance for 2D polygons of `N` vertices. | ||
* | ||
* @remarks | ||
* Based on original GLSL impl by Inigo Quilez: | ||
* - https://iquilezles.org/articles/distfunctions2d/ | ||
* | ||
* @param N | ||
*/ | ||
export const sdfPolygon2 = (N: number) => | ||
defn( | ||
"float", | ||
`sdfPolygon2_${N}`, | ||
["vec2", ["vec2[]", "pts", { num: N }]], | ||
(p, pts) => { | ||
let d: FloatSym, s: FloatSym; | ||
let b: Vec2Sym, e: Vec2Sym, w: Vec2Sym, t: Vec2Sym; | ||
let pi: Vec2Sym, pj: Vec2Sym; | ||
let c: BVec3Sym; | ||
let j: IntSym; | ||
return [ | ||
(t = sym(sub(p, index(pts, 0)))), | ||
(d = sym(dot(t, t))), | ||
(s = sym(FLOAT1)), | ||
(j = sym(int(N - 1))), | ||
forLoop( | ||
sym(INT0), | ||
(i) => lt(i, int(N)), | ||
inc, | ||
(i) => [ | ||
(pi = sym(index(pts, i))), | ||
(pj = sym(index(pts, j))), | ||
(e = sym(sub(pj, pi))), | ||
(w = sym(sub(p, pi))), | ||
(b = sym( | ||
sub(w, mul(e, clamp01(div(dot(w, e), dot(e, e))))) | ||
)), | ||
assign(d, min(d, dot(b, b))), | ||
(c = sym( | ||
bvec3( | ||
gte($y(p), $y(pi)), | ||
lt($y(p), $y(pj)), | ||
gt(mul($x(e), $y(w)), mul($y(e), $x(w))) | ||
) | ||
)), | ||
ifThen(or(all(c), not(_any(c))), [assign(s, neg(s))]), | ||
assign(j, i), | ||
] | ||
), | ||
ret(mul(s, sqrt(d))), | ||
]; | ||
} | ||
); |