@thi.ng/shader-ast-stdlib 0.16.30 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2024-03-01T15:22:50Z
3
+ - **Last updated**: 2024-03-06T08:50:42Z
4
4
  - **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
5
5
 
6
6
  All notable changes to this project will be documented in this file.
@@ -9,6 +9,23 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
9
9
  **Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
10
10
  and/or version bumps of transitive dependencies.
11
11
 
12
+ ## [0.17.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/shader-ast-stdlib@0.17.0) (2024-03-06)
13
+
14
+ #### 🚀 Features
15
+
16
+ - add fbmNoiseVec34() ([40ea58d](https://github.com/thi-ng/umbrella/commit/40ea58d))
17
+ - add cosineGradient() ([7a20ae9](https://github.com/thi-ng/umbrella/commit/7a20ae9))
18
+ - update cossin(), sincos(), add opt. scale factor arg ([e3e8979](https://github.com/thi-ng/umbrella/commit/e3e8979))
19
+ - add normal2() ([f6d6e33](https://github.com/thi-ng/umbrella/commit/f6d6e33))
20
+
21
+ #### 🩹 Bug fixes
22
+
23
+ - update generics for clamp01(), clamp11() and various fitXX() fns ([41d2882](https://github.com/thi-ng/umbrella/commit/41d2882))
24
+
25
+ #### ♻️ Refactoring
26
+
27
+ - simplify callsites of addSelf/mulSelf etc. ([efa1f8d](https://github.com/thi-ng/umbrella/commit/efa1f8d))
28
+
12
29
  ### [0.16.28](https://github.com/thi-ng/umbrella/tree/@thi.ng/shader-ast-stdlib@0.16.28) (2024-02-22)
13
30
 
14
31
  #### ♻️ Refactoring
package/README.md CHANGED
@@ -51,7 +51,7 @@
51
51
 
52
52
  Function collection for modular GPGPU / shader programming with [@thi.ng/shader-ast](https://github.com/thi-ng/umbrella/tree/develop/packages/shader-ast).
53
53
 
54
- A growing collection (currently ~225) of useful functions & higher order
54
+ A growing collection (currently ~230) of useful functions & higher order
55
55
  constructs (incl. meta programming approaches) for GPU / shader programming,
56
56
  acting as optional standard library for
57
57
  [@thi.ng/shader-ast](https://github.com/thi-ng/umbrella/tree/develop/packages/shader-ast)
@@ -109,7 +109,7 @@ For Node.js REPL:
109
109
  const shaderAstStdlib = await import("@thi.ng/shader-ast-stdlib");
110
110
  ```
111
111
 
112
- Package sizes (brotli'd, pre-treeshake): ESM: 13.36 KB
112
+ Package sizes (brotli'd, pre-treeshake): ESM: 13.67 KB
113
113
 
114
114
  ## Dependencies
115
115
 
@@ -328,15 +328,20 @@ several other HOFs from this library to drastically simplify user code.
328
328
 
329
329
  ## API
330
330
 
331
- TODO. For now, please see doc strings in source for details...
331
+ [Generated API docs](https://docs.thi.ng/umbrella/shader-ast-stdlib/)
332
332
 
333
333
  ### Color
334
334
 
335
335
  [/src/color](https://github.com/thi-ng/umbrella/tree/develop/packages/shader-ast-stdlib/src/color/)
336
336
 
337
+ - `ACESFilm` (tone mapping)
338
+ - `cosineGradient`
339
+ - `levelAdjustGamma` / `levelAdjustGammaRGB`
340
+ - `levelAdjustMid` / `levelAdjustMidRGB`
341
+ - `luminanceRGB`
342
+ - `midLevelGamma` / `midLevelGammaRGB`
337
343
  - `toLinear`
338
344
  - `toSRGB`
339
- - `luminanceRGB`
340
345
  - `decodeRGBE`
341
346
 
342
347
  ### Porter-Duff alpha blending
@@ -359,6 +364,10 @@ for reference.
359
364
  - `blendXor`
360
365
  - `blendPlus`
361
366
 
367
+ Related:
368
+
369
+ - `premultiplyAlpha` / `postmultiplyAlpha`
370
+
362
371
  ### Fog
363
372
 
364
373
  [/src/fog](https://github.com/thi-ng/umbrella/tree/develop/packages/shader-ast-stdlib/src/fog/)
@@ -440,6 +449,7 @@ for reference.
440
449
 
441
450
  [/src/noise](https://github.com/thi-ng/umbrella/tree/develop/packages/shader-ast-stdlib/src/noise/)
442
451
 
452
+ - `fbmNoiseVec34`
443
453
  - `hash2` / `hash3`
444
454
  - `hash11` / `hash12` / `hash13`
445
455
  - `hash21` / `hash22` / `hash23`
@@ -447,6 +457,7 @@ for reference.
447
457
  - `hash41` / `hash42` / `hash43` / `hash44`
448
458
  - `permute` / `permute3` / `permute4`
449
459
  - `snoise2`
460
+ - `snoise3` / `snoiseVec32` / `snoiseVec3`
450
461
  - `voronoise2`
451
462
  - `worley2` / `worleyDist` / `worleyDistManhattan`
452
463
 
@@ -517,6 +528,7 @@ for reference.
517
528
 
518
529
  - `indexToCoord` / `coordToIndex`
519
530
  - `indexToUV` / `uvToIndex`
531
+ - `normal2`
520
532
  - `readIndex1` / `readIndex2` / `readIndex3` / `readIndex4`
521
533
 
522
534
  ### Visualization
@@ -0,0 +1,28 @@
1
+ import { type FloatTerm, type Vec3Term } from "@thi.ng/shader-ast";
2
+ /**
3
+ * Inline function. Computes the unclamped cosine-based color gradient value:
4
+ * `a+b*cos(2π*(c*t+d))`, where `a`..`d` are the gradient coefficients and `t`
5
+ * the gradient position in the [0,1] interval.
6
+ *
7
+ * @remarks
8
+ * Based on technique by Inigo Quilez
9
+ *
10
+ * References:
11
+ * - https://iquilezles.org/articles/palettes/
12
+ * - https://github.com/thi-ng/umbrella/tree/develop/packages/color#cosine-gradients
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * import { cosineGradient, COSINE_GRADIENTS } from "@thi.ng/shader-ast-stdlib";
17
+ *
18
+ * const rgb = cosineGradient(...COSINE_GRADIENTS["rainbow1"], 0.8)
19
+ * ```
20
+ *
21
+ * @param a
22
+ * @param b
23
+ * @param c
24
+ * @param d
25
+ * @param t
26
+ */
27
+ export declare const cosineGradient: (a: Vec3Term, b: Vec3Term, c: Vec3Term, d: Vec3Term, t: FloatTerm) => import("@thi.ng/shader-ast").Op2<"vec3">;
28
+ //# sourceMappingURL=cosine-gradient.d.ts.map
@@ -0,0 +1,10 @@
1
+ import {
2
+ TAU,
3
+ add,
4
+ cos,
5
+ mul
6
+ } from "@thi.ng/shader-ast";
7
+ const cosineGradient = (a, b, c, d, t) => add(a, mul(b, cos(mul(TAU, add(mul(c, t), d)))));
8
+ export {
9
+ cosineGradient
10
+ };
package/color/levels.js CHANGED
@@ -38,16 +38,7 @@ const levelAdjustGamma = defn(
38
38
  (x, gamma, input, output) => [
39
39
  ret(
40
40
  fit01(
41
- pow(
42
- fitClamped(
43
- x,
44
- $x(input),
45
- $y(input),
46
- FLOAT0,
47
- FLOAT1
48
- ),
49
- gamma
50
- ),
41
+ pow(fitClamped(x, $x(input), $y(input), FLOAT0, FLOAT1), gamma),
51
42
  $x(output),
52
43
  $y(output)
53
44
  )
package/fog/exp2.js CHANGED
@@ -1,12 +1,11 @@
1
1
  import { F } from "@thi.ng/shader-ast/api/types";
2
- import { assign } from "@thi.ng/shader-ast/ast/assign";
3
2
  import { defn, ret } from "@thi.ng/shader-ast/ast/function";
4
3
  import { FLOAT1 } from "@thi.ng/shader-ast/ast/lit";
5
- import { mul, sub } from "@thi.ng/shader-ast/ast/ops";
4
+ import { mul, mulSelf, sub } from "@thi.ng/shader-ast/ast/ops";
6
5
  import { exp2 } from "@thi.ng/shader-ast/builtin/math";
7
6
  import { clamp01 } from "../math/clamp.js";
8
7
  const fogExp2 = defn(F, "fogExp2", [F, F], (dist, density) => [
9
- assign(density, mul(density, dist)),
8
+ mulSelf(density, dist),
10
9
  ret(sub(FLOAT1, clamp01(exp2(mul(mul(density, density), -Math.LOG2E)))))
11
10
  ]);
12
11
  export {
package/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from "./api.js";
2
2
  export * from "./color/aces-film.js";
3
+ export * from "./color/cosine-gradient.js";
3
4
  export * from "./color/levels.js";
4
5
  export * from "./color/linear-srgb.js";
5
6
  export * from "./color/luminance.js";
@@ -35,6 +36,7 @@ export * from "./matrix/mvp.js";
35
36
  export * from "./matrix/normal.js";
36
37
  export * from "./matrix/rotation.js";
37
38
  export * from "./noise/curl3.js";
39
+ export * from "./noise/fbm.js";
38
40
  export * from "./noise/hash.js";
39
41
  export * from "./noise/permute.js";
40
42
  export * from "./noise/simplex2.js";
@@ -76,6 +78,7 @@ export * from "./sdf/union.js";
76
78
  export * from "./tex/blur.js";
77
79
  export * from "./tex/index-coord.js";
78
80
  export * from "./tex/index-uv.js";
81
+ export * from "./tex/normal.js";
79
82
  export * from "./tex/read-index.js";
80
83
  export * from "./viz/function.js";
81
84
  //# sourceMappingURL=index.d.ts.map
package/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from "./api.js";
2
2
  export * from "./color/aces-film.js";
3
+ export * from "./color/cosine-gradient.js";
3
4
  export * from "./color/levels.js";
4
5
  export * from "./color/linear-srgb.js";
5
6
  export * from "./color/luminance.js";
@@ -35,6 +36,7 @@ export * from "./matrix/mvp.js";
35
36
  export * from "./matrix/normal.js";
36
37
  export * from "./matrix/rotation.js";
37
38
  export * from "./noise/curl3.js";
39
+ export * from "./noise/fbm.js";
38
40
  export * from "./noise/hash.js";
39
41
  export * from "./noise/permute.js";
40
42
  export * from "./noise/simplex2.js";
@@ -76,5 +78,6 @@ export * from "./sdf/union.js";
76
78
  export * from "./tex/blur.js";
77
79
  export * from "./tex/index-coord.js";
78
80
  export * from "./tex/index-uv.js";
81
+ export * from "./tex/normal.js";
79
82
  export * from "./tex/read-index.js";
80
83
  export * from "./viz/function.js";
package/math/additive.js CHANGED
@@ -1,10 +1,16 @@
1
1
  import { F } from "@thi.ng/shader-ast/api/types";
2
- import { assign } from "@thi.ng/shader-ast/ast/assign";
3
2
  import { forLoop } from "@thi.ng/shader-ast/ast/controlflow";
4
3
  import { defn, ret } from "@thi.ng/shader-ast/ast/function";
5
4
  import { gensym } from "@thi.ng/shader-ast/ast/idgen";
6
5
  import { FLOAT0, FLOAT05, float } from "@thi.ng/shader-ast/ast/lit";
7
- import { add, inc, lt, mul } from "@thi.ng/shader-ast/ast/ops";
6
+ import {
7
+ add,
8
+ addSelf,
9
+ inc,
10
+ lt,
11
+ mul,
12
+ mulSelf
13
+ } from "@thi.ng/shader-ast/ast/ops";
8
14
  import { sym } from "@thi.ng/shader-ast/ast/sym";
9
15
  const additive = (type, fn, oct = 4, name = gensym("additive_")) => defn(F, name, [[type], [type], F], (pos, shift, decay) => {
10
16
  let n;
@@ -17,15 +23,12 @@ const additive = (type, fn, oct = 4, name = gensym("additive_")) => defn(F, name
17
23
  (i) => lt(i, float(oct)),
18
24
  inc,
19
25
  (i) => [
20
- assign(
26
+ addSelf(
21
27
  n,
22
- add(
23
- n,
24
- mul(amp, fn(add(pos, mul(i, shift))))
25
- )
28
+ mul(amp, fn(add(pos, mul(i, shift))))
26
29
  ),
27
- assign(amp, mul(amp, decay)),
28
- assign(pos, mul(pos, 2))
30
+ mulSelf(amp, decay),
31
+ mulSelf(pos, 2)
29
32
  ]
30
33
  ),
31
34
  ret(n)
@@ -5,7 +5,7 @@ import type { Vec2Term } from "@thi.ng/shader-ast";
5
5
  *
6
6
  * @param v -
7
7
  */
8
- export declare const cartesian2: (v: Vec2Term) => import("@thi.ng/shader-ast").Op2<"vec2">;
8
+ export declare const cartesian2: (v: Vec2Term) => import("@thi.ng/shader-ast").Lit<"vec2"> | import("@thi.ng/shader-ast").Op2<"vec2">;
9
9
  /**
10
10
  * Converts 3D polar/spherical vector `v`, i.e. `[r,θ,ϕ]` (angles in
11
11
  * radians) to cartesian coordinates. See {@link polar3} for reverse
package/math/cartesian.js CHANGED
@@ -5,7 +5,7 @@ import { mul } from "@thi.ng/shader-ast/ast/ops";
5
5
  import { $x, $y, $z } from "@thi.ng/shader-ast/ast/swizzle";
6
6
  import { sym } from "@thi.ng/shader-ast/ast/sym";
7
7
  import { cossin } from "./sincos.js";
8
- const cartesian2 = (v) => mul(cossin($y(v)), $x(v));
8
+ const cartesian2 = (v) => cossin($y(v), $x(v));
9
9
  const cartesian3 = defn(V3, "cartesian3", [V3], (v) => {
10
10
  let r;
11
11
  let t;
package/math/clamp.d.ts CHANGED
@@ -1,14 +1,14 @@
1
- import type { PrimTerm, Term, TermType } from "@thi.ng/shader-ast";
1
+ import type { Prim, Term } from "@thi.ng/shader-ast";
2
2
  /**
3
3
  * Inline function, expands to equivalent of `clamp(x, 0, 1)`.
4
4
  *
5
5
  * @param x -
6
6
  */
7
- export declare const clamp01: <T extends PrimTerm>(x: T) => Term<TermType<T>>;
7
+ export declare const clamp01: <T extends Prim>(x: Term<T>) => Term<T>;
8
8
  /**
9
9
  * Inline function, expands to equivalent of `clamp(x, -1, 1)`.
10
10
  *
11
11
  * @param x -
12
12
  */
13
- export declare const clamp11: <T extends PrimTerm>(x: T) => Term<TermType<T>>;
13
+ export declare const clamp11: <T extends Prim>(x: Term<T>) => Term<T>;
14
14
  //# sourceMappingURL=clamp.d.ts.map
package/math/fit.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { PrimTerm, Term, TermType } from "@thi.ng/shader-ast";
1
+ import type { Prim, PrimTerm, Term, TermType } from "@thi.ng/shader-ast";
2
2
  /**
3
3
  * Returns normalized value of `x` WRT to interval [a,b]. Returns 0, if
4
4
  * `a` equals `b`.
@@ -16,9 +16,8 @@ export declare const fitNorm1: import("@thi.ng/shader-ast").TaggedFn3<"float", "
16
16
  * @param x
17
17
  * @param a
18
18
  * @param b
19
- * @returns
20
19
  */
21
- export declare const fitNorm: <T extends PrimTerm>(x: T, a: T, b: T) => Term<TermType<T>>;
20
+ export declare const fitNorm: <T extends Prim>(x: Term<T>, a: Term<T>, b: Term<T>) => import("@thi.ng/shader-ast").Op2<T>;
22
21
  /**
23
22
  * Fits value `x` from closed interval [a,b] to closed interval [c,d]. No
24
23
  * clamping performed.
@@ -29,7 +28,7 @@ export declare const fitNorm: <T extends PrimTerm>(x: T, a: T, b: T) => Term<Ter
29
28
  * @param c -
30
29
  * @param d -
31
30
  */
32
- export declare const fit: <T extends PrimTerm>(x: T, a: T, b: T, c: T, d: T) => Term<TermType<T>>;
31
+ export declare const fit: <T extends Prim>(x: Term<T>, a: Term<T>, b: Term<T>, c: Term<T>, d: Term<T>) => import("@thi.ng/shader-ast").FnCall<T>;
33
32
  /**
34
33
  * Same as {@link fit}, but first clamps `x` to closed [a,b] interval.
35
34
  *
@@ -39,7 +38,7 @@ export declare const fit: <T extends PrimTerm>(x: T, a: T, b: T, c: T, d: T) =>
39
38
  * @param c -
40
39
  * @param d -
41
40
  */
42
- export declare const fitClamped: <T extends PrimTerm>(x: T, a: T, b: T, c: T, d: T) => Term<TermType<T>>;
41
+ export declare const fitClamped: <T extends Prim>(x: Term<T>, a: Term<T>, b: Term<T>, c: Term<T>, d: Term<T>) => import("@thi.ng/shader-ast").FnCall<T>;
43
42
  /**
44
43
  * Inline function. Fits value `a` in [0..1] interval to new interval
45
44
  * [b..c]. No clamping performed. Same as `mix(b, c, a)`
@@ -48,7 +47,7 @@ export declare const fitClamped: <T extends PrimTerm>(x: T, a: T, b: T, c: T, d:
48
47
  * @param b -
49
48
  * @param c -
50
49
  */
51
- export declare const fit01: <T extends PrimTerm>(a: T, b: T, c: T) => Term<TermType<T>>;
50
+ export declare const fit01: <T extends Prim>(a: Term<T>, b: Term<T>, c: Term<T>) => Term<T>;
52
51
  /**
53
52
  * Inline function. Fits value `x` in [-1..+1] interval to [0..1]
54
53
  * interval. No clamping performed.
package/math/sincos.d.ts CHANGED
@@ -1,14 +1,16 @@
1
1
  import type { FloatTerm } from "@thi.ng/shader-ast";
2
2
  /**
3
- * Inline function. Returns vec2(sin(x), cos(x)).
3
+ * Inline function. Returns vec2(sin(x), cos(x)), optionally scaled by `r`
4
4
  *
5
5
  * @param x -
6
+ * @param r -
6
7
  */
7
- export declare const sincos: (x: FloatTerm) => import("@thi.ng/shader-ast").Lit<"vec2">;
8
+ export declare const sincos: (x: FloatTerm, r?: FloatTerm | number) => import("@thi.ng/shader-ast").Lit<"vec2"> | import("@thi.ng/shader-ast").Op2<"vec2">;
8
9
  /**
9
- * Inline function. Returns vec2(cos(x), sin(x)).
10
+ * Inline function. Returns vec2(cos(x), sin(x)), optionally scaled by `r`.
10
11
  *
11
12
  * @param x -
13
+ * @param r -
12
14
  */
13
- export declare const cossin: (x: FloatTerm) => import("@thi.ng/shader-ast").Lit<"vec2">;
15
+ export declare const cossin: (x: FloatTerm, r?: FloatTerm | number) => import("@thi.ng/shader-ast").Lit<"vec2"> | import("@thi.ng/shader-ast").Op2<"vec2">;
14
16
  //# sourceMappingURL=sincos.d.ts.map
package/math/sincos.js CHANGED
@@ -1,7 +1,14 @@
1
1
  import { vec2 } from "@thi.ng/shader-ast/ast/lit";
2
+ import { mul } from "@thi.ng/shader-ast/ast/ops";
2
3
  import { cos, sin } from "@thi.ng/shader-ast/builtin/math";
3
- const sincos = (x) => vec2(sin(x), cos(x));
4
- const cossin = (x) => vec2(cos(x), sin(x));
4
+ const sincos = (x, r) => {
5
+ const res = vec2(sin(x), cos(x));
6
+ return r != void 0 ? mul(res, r) : res;
7
+ };
8
+ const cossin = (x, r) => {
9
+ const res = vec2(cos(x), sin(x));
10
+ return r != void 0 ? mul(res, r) : res;
11
+ };
5
12
  export {
6
13
  cossin,
7
14
  sincos
package/noise/fbm.d.ts ADDED
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Higher order function to compute 3D texture-based FBM noise for given number
3
+ * of octaves and decay factor (default: 1/octaves). Returns a 2-arg shader
4
+ * function, taking a sampler3D and vec3 position and which returns summed noise
5
+ * value as vec4.
6
+ *
7
+ * @remarks
8
+ * Not compatible with WebGL 1.0 (texture type not natively supported).
9
+ *
10
+ * The texture should be configured to use linear filtering and texture repeat
11
+ * mode.
12
+ *
13
+ * Using thi.ng/webgl (for example), the 3D noise texture can be initialized as
14
+ * follows:
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import { repeatedly } from "@thi.ng/transducers";
19
+ * import {
20
+ * defTexture,
21
+ * TextureFilter, TextureFormat, TextureRepeat, TextureTarget
22
+ * } from "@thi.ng/webgl";
23
+ *
24
+ * // (GL context creation omitted here)
25
+ *
26
+ * const noiseTex = defTexture(gl, {
27
+ * width: 32,
28
+ * height: 32,
29
+ * depth: 32,
30
+ * target: TextureTarget.TEXTURE_3D,
31
+ * format: TextureFormat.RGB,
32
+ * filter: TextureFilter.LINEAR,
33
+ * wrap: TextureRepeat.REPEAT,
34
+ * image: new Uint8Array(
35
+ * repeatedly(() => Math.random() * 255.5, 32 * 32 * 32 * 3)
36
+ * )
37
+ * });
38
+ * ```
39
+ *
40
+ * @param octaves
41
+ * @param decay
42
+ */
43
+ export declare const fbmNoiseVec34: (octaves: number, decay?: number) => import("@thi.ng/shader-ast").TaggedFn2<"sampler3D", "vec3", "vec4">;
44
+ //# sourceMappingURL=fbm.d.ts.map
package/noise/fbm.js ADDED
@@ -0,0 +1,35 @@
1
+ import { S3D, V3, V4 } from "@thi.ng/shader-ast/api/types";
2
+ import { forLoop } from "@thi.ng/shader-ast/ast/controlflow";
3
+ import { defn, ret } from "@thi.ng/shader-ast/ast/function";
4
+ import { FLOAT05, UINT0, uint, vec4 } from "@thi.ng/shader-ast/ast/lit";
5
+ import {
6
+ addSelf,
7
+ div,
8
+ inc,
9
+ lt,
10
+ mul,
11
+ mulSelf
12
+ } from "@thi.ng/shader-ast/ast/ops";
13
+ import { sym } from "@thi.ng/shader-ast/ast/sym";
14
+ import { texture } from "@thi.ng/shader-ast/builtin/texture";
15
+ const fbmNoiseVec34 = (octaves, decay = 1 / octaves) => defn(V4, null, [S3D, V3], (tex, p) => {
16
+ let res;
17
+ let amp;
18
+ return [
19
+ res = sym(vec4()),
20
+ amp = sym(FLOAT05),
21
+ forLoop(
22
+ sym(UINT0),
23
+ (i) => lt(i, uint(octaves)),
24
+ inc,
25
+ () => [
26
+ addSelf(res, mul(texture(tex, div(p, amp)), amp)),
27
+ mulSelf(amp, decay)
28
+ ]
29
+ ),
30
+ ret(res)
31
+ ];
32
+ });
33
+ export {
34
+ fbmNoiseVec34
35
+ };
package/noise/hash.js CHANGED
@@ -1,8 +1,7 @@
1
1
  import { F, V2, V3, V4 } from "@thi.ng/shader-ast/api/types";
2
- import { assign } from "@thi.ng/shader-ast/ast/assign";
3
2
  import { defn, ret } from "@thi.ng/shader-ast/ast/function";
4
3
  import { mat2, vec2, vec3, vec4 } from "@thi.ng/shader-ast/ast/lit";
5
- import { add, mul } from "@thi.ng/shader-ast/ast/ops";
4
+ import { add, addSelf, mul, mulSelf } from "@thi.ng/shader-ast/ast/ops";
6
5
  import { $, $x, $y, $z } from "@thi.ng/shader-ast/ast/swizzle";
7
6
  import { sym } from "@thi.ng/shader-ast/ast/sym";
8
7
  import { dot, fract, sin } from "@thi.ng/shader-ast/builtin/math";
@@ -31,8 +30,8 @@ const hash11 = defn(F, "hash11", [F], (p) => {
31
30
  let x;
32
31
  return [
33
32
  x = sym(fract(mul(p, 0.1031))),
34
- assign(x, mul(x, add(x, 19.19))),
35
- assign(x, mul(x, add(x, x))),
33
+ mulSelf(x, add(x, 19.19)),
34
+ mulSelf(x, add(x, x)),
36
35
  ret(fract(x))
37
36
  ];
38
37
  });
@@ -40,7 +39,7 @@ const hash12 = defn(F, "hash12", [V2], (p) => {
40
39
  let x;
41
40
  return [
42
41
  x = sym(fract(mul($(p, "xyx"), 0.1031))),
43
- assign(x, add(x, dot(x, add($(x, "yzx"), 19.19)))),
42
+ addSelf(x, dot(x, add($(x, "yzx"), 19.19))),
44
43
  ret(fract(mul(add($x(x), $y(x)), $z(x))))
45
44
  ];
46
45
  });
@@ -48,7 +47,7 @@ const hash13 = defn(F, "hash13", [V3], (p) => {
48
47
  let x;
49
48
  return [
50
49
  x = sym(fract(mul($(p, "xyx"), 0.1031))),
51
- assign(x, add(x, dot(x, add($(x, "yzx"), 19.19)))),
50
+ addSelf(x, dot(x, add($(x, "yzx"), 19.19))),
52
51
  ret(fract(mul(add($x(x), $y(x)), $z(x))))
53
52
  ];
54
53
  });
@@ -56,7 +55,7 @@ const hash21 = defn(V2, "hash21", [F], (p) => {
56
55
  let x;
57
56
  return [
58
57
  x = sym(fract(mul(vec3(p), H))),
59
- assign(x, add(x, dot(x, add($(x, "yzx"), 19.19)))),
58
+ addSelf(x, dot(x, add($(x, "yzx"), 19.19))),
60
59
  ret(fract(mul(add($(x, "xx"), $(x, "yz")), $(x, "zy"))))
61
60
  ];
62
61
  });
@@ -64,7 +63,7 @@ const hash22 = defn(V2, "hash22", [V2], (p) => {
64
63
  let x;
65
64
  return [
66
65
  x = sym(fract(mul($(p, "xyx"), H))),
67
- assign(x, add(x, dot(x, add($(x, "yzx"), 19.19)))),
66
+ addSelf(x, dot(x, add($(x, "yzx"), 19.19))),
68
67
  ret(fract(mul(add($(x, "xx"), $(x, "yz")), $(x, "zy"))))
69
68
  ];
70
69
  });
@@ -72,7 +71,7 @@ const hash23 = defn(V2, "hash23", [V3], (p) => {
72
71
  let x;
73
72
  return [
74
73
  x = sym(fract(mul(p, H))),
75
- assign(x, add(x, dot(x, add($(x, "yzx"), 19.19)))),
74
+ addSelf(x, dot(x, add($(x, "yzx"), 19.19))),
76
75
  ret(fract(mul(add($(x, "xx"), $(x, "yz")), $(x, "zy"))))
77
76
  ];
78
77
  });
@@ -80,7 +79,7 @@ const hash31 = defn(V3, "hash31", [F], (p) => {
80
79
  let x;
81
80
  return [
82
81
  x = sym(fract(mul(p, H))),
83
- assign(x, add(x, dot(x, add($(x, "yzx"), 19.19)))),
82
+ addSelf(x, dot(x, add($(x, "yzx"), 19.19))),
84
83
  ret(fract(mul(add($(x, "xxy"), $(x, "yzz")), $(x, "zyx"))))
85
84
  ];
86
85
  });
@@ -88,7 +87,7 @@ const hash32 = defn(V3, "hash32", [V2], (p) => {
88
87
  let x;
89
88
  return [
90
89
  x = sym(fract(mul($(p, "xyx"), H))),
91
- assign(x, add(x, dot(x, add($(x, "yzx"), 19.19)))),
90
+ addSelf(x, dot(x, add($(x, "yzx"), 19.19))),
92
91
  ret(fract(mul(add($(x, "xxy"), $(x, "yzz")), $(x, "zyx"))))
93
92
  ];
94
93
  });
@@ -96,7 +95,7 @@ const hash33 = defn(V3, "hash33", [V3], (p) => {
96
95
  let x;
97
96
  return [
98
97
  x = sym(fract(mul(p, H))),
99
- assign(x, add(x, dot(x, add($(x, "yzx"), 19.19)))),
98
+ addSelf(x, dot(x, add($(x, "yzx"), 19.19))),
100
99
  ret(fract(mul(add($(x, "xxy"), $(x, "yzz")), $(x, "zyx"))))
101
100
  ];
102
101
  });
@@ -104,7 +103,7 @@ const hash41 = defn(V4, "hash41", [F], (p) => {
104
103
  let x;
105
104
  return [
106
105
  x = sym(fract(mul(p, H4))),
107
- assign(x, add(x, dot(x, add($(x, "wzxy"), 19.19)))),
106
+ addSelf(x, dot(x, add($(x, "wzxy"), 19.19))),
108
107
  ret(fract(mul(add($(x, "xxyz"), $(x, "yzzw")), $(x, "zywx"))))
109
108
  ];
110
109
  });
@@ -112,7 +111,7 @@ const hash42 = defn(V4, "hash42", [V2], (p) => {
112
111
  let x;
113
112
  return [
114
113
  x = sym(fract(mul($(p, "xyxy"), H4))),
115
- assign(x, add(x, dot(x, add($(x, "wzxy"), 19.19)))),
114
+ addSelf(x, dot(x, add($(x, "wzxy"), 19.19))),
116
115
  ret(fract(mul(add($(x, "xxyz"), $(x, "yzzw")), $(x, "zywx"))))
117
116
  ];
118
117
  });
@@ -120,7 +119,7 @@ const hash43 = defn(V4, "hash43", [V3], (p) => {
120
119
  let x;
121
120
  return [
122
121
  x = sym(fract(mul($(p, "xyzx"), H4))),
123
- assign(x, add(x, dot(x, add($(x, "wzxy"), 19.19)))),
122
+ addSelf(x, dot(x, add($(x, "wzxy"), 19.19))),
124
123
  ret(fract(mul(add($(x, "xxyz"), $(x, "yzzw")), $(x, "zywx"))))
125
124
  ];
126
125
  });
@@ -128,7 +127,7 @@ const hash44 = defn(V4, "hash44", [V4], (p) => {
128
127
  let x;
129
128
  return [
130
129
  x = sym(fract(mul(p, H4))),
131
- assign(x, add(x, dot(x, add($(x, "wzxy"), 19.19)))),
130
+ addSelf(x, dot(x, add($(x, "wzxy"), 19.19))),
132
131
  ret(fract(mul(add($(x, "xxyz"), $(x, "yzzw")), $(x, "zywx"))))
133
132
  ];
134
133
  });
package/noise/simplex2.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  vec3,
12
12
  vec4
13
13
  } from "@thi.ng/shader-ast/ast/lit";
14
- import { add, gt, mul, sub } from "@thi.ng/shader-ast/ast/ops";
14
+ import { add, gt, mul, mulSelf, sub } from "@thi.ng/shader-ast/ast/ops";
15
15
  import { $, $x, $xy, $y } from "@thi.ng/shader-ast/ast/swizzle";
16
16
  import { sym } from "@thi.ng/shader-ast/ast/sym";
17
17
  import {
@@ -68,20 +68,17 @@ const snoise2 = defn(F, "snoise2", [V2], (v) => {
68
68
  VEC3_0
69
69
  )
70
70
  ),
71
- assign(m, mul(m, m)),
72
- assign(m, mul(m, m)),
71
+ mulSelf(m, m),
72
+ mulSelf(m, m),
73
73
  x = sym(sub(mul(2, fract(mul(p, $(C, "www")))), FLOAT1)),
74
74
  h = sym(sub(abs(x), FLOAT05)),
75
75
  ox = sym(floor(add(x, FLOAT05))),
76
76
  a0 = sym(sub(x, ox)),
77
- assign(
77
+ mulSelf(
78
78
  m,
79
- mul(
80
- m,
81
- sub(
82
- 1.79284291400159,
83
- mul(0.85373472095314, add(mul(a0, a0), mul(h, h)))
84
- )
79
+ sub(
80
+ 1.79284291400159,
81
+ mul(0.85373472095314, add(mul(a0, a0), mul(h, h)))
85
82
  )
86
83
  ),
87
84
  g = sym(vec3(add(mul($x(a0), $x(x0)), mul($x(h), $y(x0))))),
package/noise/simplex3.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  vec3,
12
12
  vec4
13
13
  } from "@thi.ng/shader-ast/ast/lit";
14
- import { add, mul, neg, sub } from "@thi.ng/shader-ast/ast/ops";
14
+ import { add, mul, mulSelf, neg, sub } from "@thi.ng/shader-ast/ast/ops";
15
15
  import { $, $w, $x, $xy, $y, $z } from "@thi.ng/shader-ast/ast/swizzle";
16
16
  import { sym } from "@thi.ng/shader-ast/ast/sym";
17
17
  import {
@@ -119,10 +119,10 @@ const snoise3 = defn(F, "snoise3", [V3], (v) => {
119
119
  )
120
120
  )
121
121
  ),
122
- assign(p0, mul(p0, $x(norm))),
123
- assign(p1, mul(p1, $y(norm))),
124
- assign(p2, mul(p2, $z(norm))),
125
- assign(p3, mul(p3, $w(norm))),
122
+ mulSelf(p0, $x(norm)),
123
+ mulSelf(p1, $y(norm)),
124
+ mulSelf(p2, $z(norm)),
125
+ mulSelf(p3, $w(norm)),
126
126
  m = sym(
127
127
  max(
128
128
  vec4(),
@@ -132,7 +132,7 @@ const snoise3 = defn(F, "snoise3", [V3], (v) => {
132
132
  )
133
133
  )
134
134
  ),
135
- assign(m, mul(m, m)),
135
+ mulSelf(m, m),
136
136
  ret(
137
137
  mul(
138
138
  42,
package/noise/voronoi2.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import { F, V2 } from "@thi.ng/shader-ast/api/types";
2
- import { assign } from "@thi.ng/shader-ast/ast/assign";
3
2
  import { forLoop } from "@thi.ng/shader-ast/ast/controlflow";
4
3
  import { defn, ret } from "@thi.ng/shader-ast/ast/function";
5
4
  import {
@@ -10,7 +9,15 @@ import {
10
9
  vec2,
11
10
  vec3
12
11
  } from "@thi.ng/shader-ast/ast/lit";
13
- import { add, div, inc, lte, madd, mul, sub } from "@thi.ng/shader-ast/ast/ops";
12
+ import {
13
+ add,
14
+ addSelf,
15
+ div,
16
+ inc,
17
+ lte,
18
+ mul,
19
+ sub
20
+ } from "@thi.ng/shader-ast/ast/ops";
14
21
  import { $xy, $z } from "@thi.ng/shader-ast/ast/swizzle";
15
22
  import { sym } from "@thi.ng/shader-ast/ast/sym";
16
23
  import {
@@ -62,8 +69,8 @@ const voronoise2 = defn(F, "voronoise2", [V2, F, F], (x, u, v) => {
62
69
  k
63
70
  )
64
71
  ),
65
- assign(va, madd(w, $z(o), va)),
66
- assign(wt, add(wt, w))
72
+ addSelf(va, mul(w, $z(o))),
73
+ addSelf(wt, w)
67
74
  ]
68
75
  )
69
76
  ]
package/noise/worley2.js CHANGED
@@ -63,8 +63,8 @@ const worley2 = (distFn, name = gensym("worley2_")) => defn(V2, name, [V2, F], (
63
63
  d3 = sym($dist(-1.5)),
64
64
  d1a = sym(min(d1, d2)),
65
65
  assign(d2, min(max(d1, d2), d3)),
66
- assign(d1, min(d1a, d2)),
67
- assign(d2, max(d1a, d2)),
66
+ assign(d1, min(d2, d1a)),
67
+ assign(d2, max(d2, d1a)),
68
68
  assign($xy(d1), ternary(lt($x(d1), $y(d1)), $xy(d1), $(d1, "yx"))),
69
69
  assign(
70
70
  $(d1, "xz"),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/shader-ast-stdlib",
3
- "version": "0.16.30",
3
+ "version": "0.17.0",
4
4
  "description": "Function collection for modular GPGPU / shader programming with @thi.ng/shader-ast",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "dependencies": {
41
41
  "@thi.ng/api": "^8.9.27",
42
- "@thi.ng/shader-ast": "^0.13.15"
42
+ "@thi.ng/shader-ast": "^0.14.0"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@microsoft/api-extractor": "^7.40.1",
@@ -107,6 +107,9 @@
107
107
  "./color/aces-film": {
108
108
  "default": "./color/aces-film.js"
109
109
  },
110
+ "./color/cosine-gradient": {
111
+ "default": "./color/cosine-gradient.js"
112
+ },
110
113
  "./color/levels": {
111
114
  "default": "./color/levels.js"
112
115
  },
@@ -215,6 +218,9 @@
215
218
  "./noise/curl3": {
216
219
  "default": "./noise/curl3.js"
217
220
  },
221
+ "./noise/fbm": {
222
+ "default": "./noise/fbm.js"
223
+ },
218
224
  "./noise/hash": {
219
225
  "default": "./noise/hash.js"
220
226
  },
@@ -338,6 +344,9 @@
338
344
  "./tex/index-uv": {
339
345
  "default": "./tex/index-uv.js"
340
346
  },
347
+ "./tex/normal": {
348
+ "default": "./tex/normal.js"
349
+ },
341
350
  "./tex/read-index": {
342
351
  "default": "./tex/read-index.js"
343
352
  },
@@ -354,5 +363,5 @@
354
363
  ],
355
364
  "year": 2019
356
365
  },
357
- "gitHead": "d660ae8fd1bf64d919b4334f19509f1f539d70f6\n"
366
+ "gitHead": "f6bb0e172c5dcb574b961f5155a50040d5569685\n"
358
367
  }
package/raymarch/ao.js CHANGED
@@ -1,10 +1,17 @@
1
1
  import { F, V3 } from "@thi.ng/shader-ast/api/types";
2
- import { assign } from "@thi.ng/shader-ast/ast/assign";
3
2
  import { forLoop } from "@thi.ng/shader-ast/ast/controlflow";
4
3
  import { defn, ret } from "@thi.ng/shader-ast/ast/function";
5
4
  import { gensym } from "@thi.ng/shader-ast/ast/idgen";
6
5
  import { FLOAT0, FLOAT05, FLOAT1, float } from "@thi.ng/shader-ast/ast/lit";
7
- import { add, inc, lte, mul, sub } from "@thi.ng/shader-ast/ast/ops";
6
+ import {
7
+ add,
8
+ addSelf,
9
+ inc,
10
+ lte,
11
+ mul,
12
+ mulSelf,
13
+ sub
14
+ } from "@thi.ng/shader-ast/ast/ops";
8
15
  import { $x } from "@thi.ng/shader-ast/ast/swizzle";
9
16
  import { sym } from "@thi.ng/shader-ast/ast/sym";
10
17
  import { clamp01 } from "../math/clamp.js";
@@ -21,11 +28,8 @@ const raymarchAO = (scene, numSamples = 5, name = gensym("raymarchAO_")) => defn
21
28
  inc,
22
29
  (i) => [
23
30
  d0 = sym(mul(i, 1 / numSamples)),
24
- assign(
25
- r,
26
- add(r, mul(w, sub(d0, $x(scene(add(p, mul(n, d0)))))))
27
- ),
28
- assign(w, mul(w, FLOAT05))
31
+ addSelf(r, mul(w, sub(d0, $x(scene(add(p, mul(n, d0))))))),
32
+ mulSelf(w, FLOAT05)
29
33
  ]
30
34
  ),
31
35
  ret(sub(FLOAT1, clamp01(r)))
package/sdf/hex.js CHANGED
@@ -1,8 +1,7 @@
1
1
  import { F, V2 } from "@thi.ng/shader-ast/api/types";
2
- import { assign } from "@thi.ng/shader-ast/ast/assign";
3
2
  import { defn, ret } from "@thi.ng/shader-ast/ast/function";
4
3
  import { FLOAT0, vec2 } from "@thi.ng/shader-ast/ast/lit";
5
- import { mul, sub } from "@thi.ng/shader-ast/ast/ops";
4
+ import { mul, subSelf } from "@thi.ng/shader-ast/ast/ops";
6
5
  import { $x, $y } from "@thi.ng/shader-ast/ast/swizzle";
7
6
  import { sym } from "@thi.ng/shader-ast/ast/sym";
8
7
  import {
@@ -20,8 +19,8 @@ const sdfHexagon2 = defn(F, "sdfHexagon2", [V2, F], (p, r) => {
20
19
  // sin/cos @ 60deg
21
20
  k = sym(vec2(-0.8660254037844386, 0.5)),
22
21
  q = sym(abs(p)),
23
- assign(q, sub(q, mul(k, mul(2, min(dot(k, q), FLOAT0))))),
24
- assign(q, sub(q, vec2(clamp($x(q), mul(r, -TAN30), mul(r, TAN30)), r))),
22
+ subSelf(q, mul(k, mul(2, min(dot(k, q), FLOAT0)))),
23
+ subSelf(q, vec2(clamp($x(q), mul(r, -TAN30), mul(r, TAN30)), r)),
25
24
  ret(mul(length(q), sign($y(q))))
26
25
  ];
27
26
  });
package/sdf/polygon.js CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  import { $x, $y } from "@thi.ng/shader-ast/ast/swizzle";
20
20
  import { sym } from "@thi.ng/shader-ast/ast/sym";
21
21
  import { _any, all } from "@thi.ng/shader-ast/builtin/bvec";
22
- import { dot, min, sqrt } from "@thi.ng/shader-ast/builtin/math";
22
+ import { dot, minSelf, sqrt } from "@thi.ng/shader-ast/builtin/math";
23
23
  import { clamp01 } from "../math/clamp.js";
24
24
  const sdfPolygon2 = (N) => defn(
25
25
  F,
@@ -48,7 +48,7 @@ const sdfPolygon2 = (N) => defn(
48
48
  b = sym(
49
49
  sub(w, mul(e, clamp01(div(dot(w, e), dot(e, e)))))
50
50
  ),
51
- assign(d, min(d, dot(b, b))),
51
+ minSelf(d, dot(b, b)),
52
52
  c = sym(
53
53
  bvec3(
54
54
  gte($y(p), $y(pi)),
@@ -14,7 +14,7 @@ const sdfRepeatPolar2 = defn(V2, "sdfRepeatPolar2", [V2, F], (p, n) => {
14
14
  angle = sym(div(TAU, n)),
15
15
  angle2 = sym(mul(angle, FLOAT05)),
16
16
  a = sym(sub(mod(add(angle2, atan($y(p), $x(p))), angle), angle2)),
17
- ret(mul(cossin(a), length(p)))
17
+ ret(cossin(a, length(p)))
18
18
  ];
19
19
  });
20
20
  export {
package/tex/blur.js CHANGED
@@ -1,16 +1,12 @@
1
1
  import { S2D, V2, V4 } from "@thi.ng/shader-ast/api/types";
2
- import { assign } from "@thi.ng/shader-ast/ast/assign";
3
2
  import { defn, ret } from "@thi.ng/shader-ast/ast/function";
4
3
  import { vec2 } from "@thi.ng/shader-ast/ast/lit";
5
- import { add, div, mul, sub } from "@thi.ng/shader-ast/ast/ops";
4
+ import { add, addSelf, div, mul, sub } from "@thi.ng/shader-ast/ast/ops";
6
5
  import { sym } from "@thi.ng/shader-ast/ast/sym";
7
6
  import { texture } from "@thi.ng/shader-ast/builtin/texture";
8
- const singlePass = (col, tex, uv, off, k) => assign(
7
+ const singlePass = (col, tex, uv, off, k) => addSelf(
9
8
  col,
10
- add(
11
- col,
12
- mul(add(texture(tex, add(uv, off)), texture(tex, sub(uv, off))), k)
13
- )
9
+ mul(add(texture(tex, add(uv, off)), texture(tex, sub(uv, off))), k)
14
10
  );
15
11
  const blur5 = defn(
16
12
  V4,
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Computes the surface normal from a grayscale texture at given `uv` position
3
+ * and using given `step` to define the half-distances between the 4 neighbor
4
+ * lookups (north/south/east/west). The `z` value is used as the normal's Z
5
+ * component (prior to normalization). `eps` is being added to all components to
6
+ * avoid zero-vectors.
7
+ *
8
+ * @remarks
9
+ * The function only uses the X (red) component of the texture.
10
+ *
11
+ * @param tex
12
+ * @param uv
13
+ * @param step
14
+ * @param z
15
+ * @param eps
16
+ */
17
+ export declare const normal2: import("@thi.ng/shader-ast").TaggedFn5<"sampler2D", "vec2", "vec2", "float", "float", "vec3">;
18
+ //# sourceMappingURL=normal.d.ts.map
package/tex/normal.js ADDED
@@ -0,0 +1,33 @@
1
+ import { F, S2D, V2, V3 } from "@thi.ng/shader-ast/api/types";
2
+ import { defn, ret } from "@thi.ng/shader-ast/ast/function";
3
+ import { vec2, vec3 } from "@thi.ng/shader-ast/ast/lit";
4
+ import { add, sub } from "@thi.ng/shader-ast/ast/ops";
5
+ import { sym } from "@thi.ng/shader-ast/ast/sym";
6
+ import { $x, $y } from "@thi.ng/shader-ast/ast/swizzle";
7
+ import { normalize } from "@thi.ng/shader-ast/builtin/math";
8
+ import { texture } from "@thi.ng/shader-ast/builtin/texture";
9
+ const sample1 = (tex, uv, unit) => sub($x(texture(tex, sub(uv, unit))), $x(texture(tex, add(uv, unit))));
10
+ const normal2 = defn(
11
+ V3,
12
+ null,
13
+ [S2D, V2, V2, F, F],
14
+ (tex, uv, step, z, eps) => {
15
+ let sx;
16
+ let sy;
17
+ return [
18
+ sx = sym(vec2($x(step), 0)),
19
+ sy = sym(vec2(0, $y(step))),
20
+ ret(
21
+ normalize(
22
+ add(
23
+ vec3(sample1(tex, uv, sx), sample1(tex, uv, sy), z),
24
+ eps
25
+ )
26
+ )
27
+ )
28
+ ];
29
+ }
30
+ );
31
+ export {
32
+ normal2
33
+ };
package/viz/function.js CHANGED
@@ -12,6 +12,7 @@ import {
12
12
  } from "@thi.ng/shader-ast/ast/lit";
13
13
  import {
14
14
  add,
15
+ addSelf,
15
16
  div,
16
17
  gt,
17
18
  inc,
@@ -40,12 +41,12 @@ const functionSampler = (fn, map, opts = {}) => {
40
41
  forLoop(
41
42
  sym(float(-radius)),
42
43
  (x) => lte(x, float(radius)),
43
- (x) => assign(x, add(x, invStep)),
44
+ (x) => addSelf(x, invStep),
44
45
  (x) => [
45
46
  forLoop(
46
47
  sym(float(-radius)),
47
48
  (y) => lte(y, float(radius)),
48
- (y) => assign(y, add(y, invStep)),
49
+ (y) => addSelf(y, invStep),
49
50
  (y) => [
50
51
  inc(total),
51
52
  assign(q, map(add(frag, vec2(x, y)), res)),