@matboks/utilities 0.0.1
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/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/dist/geometry/aabb.d.ts +40 -0
- package/dist/geometry/aabb.js +143 -0
- package/dist/geometry/cut-polygon.d.ts +7 -0
- package/dist/geometry/cut-polygon.js +116 -0
- package/dist/geometry/hollowgon.d.ts +24 -0
- package/dist/geometry/hollowgon.js +156 -0
- package/dist/geometry/index.d.ts +13 -0
- package/dist/geometry/index.js +14 -0
- package/dist/geometry/line.d.ts +10 -0
- package/dist/geometry/line.js +26 -0
- package/dist/geometry/polygon-operations.d.ts +31 -0
- package/dist/geometry/polygon-operations.js +159 -0
- package/dist/geometry/polygon.d.ts +55 -0
- package/dist/geometry/polygon.js +353 -0
- package/dist/geometry/polyline.d.ts +23 -0
- package/dist/geometry/polyline.js +100 -0
- package/dist/geometry/ray.d.ts +6 -0
- package/dist/geometry/ray.js +6 -0
- package/dist/geometry/ray3.d.ts +7 -0
- package/dist/geometry/ray3.js +10 -0
- package/dist/geometry/segment.d.ts +16 -0
- package/dist/geometry/segment.js +50 -0
- package/dist/geometry/shared.d.ts +5 -0
- package/dist/geometry/shared.js +60 -0
- package/dist/geometry/transformations.d.ts +7 -0
- package/dist/geometry/transformations.js +28 -0
- package/dist/geometry/vec2.d.ts +71 -0
- package/dist/geometry/vec2.js +225 -0
- package/dist/geometry/vec3.d.ts +102 -0
- package/dist/geometry/vec3.js +256 -0
- package/dist/geometry/vec4.d.ts +71 -0
- package/dist/geometry/vec4.js +238 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +11 -0
- package/dist/math/clamp.d.ts +1 -0
- package/dist/math/clamp.js +5 -0
- package/dist/math/fract.d.ts +1 -0
- package/dist/math/fract.js +3 -0
- package/dist/math/index.d.ts +8 -0
- package/dist/math/index.js +8 -0
- package/dist/math/mix.d.ts +1 -0
- package/dist/math/mix.js +3 -0
- package/dist/math/mod.d.ts +1 -0
- package/dist/math/mod.js +5 -0
- package/dist/math/signed.d.ts +1 -0
- package/dist/math/signed.js +3 -0
- package/dist/math/smoothstep.d.ts +3 -0
- package/dist/math/smoothstep.js +24 -0
- package/dist/math/split-into-int-and-fract.d.ts +1 -0
- package/dist/math/split-into-int-and-fract.js +5 -0
- package/dist/math/units.d.ts +2 -0
- package/dist/math/units.js +6 -0
- package/dist/noise/idw.d.ts +11 -0
- package/dist/noise/idw.js +10 -0
- package/dist/noise/index.d.ts +6 -0
- package/dist/noise/index.js +6 -0
- package/dist/noise/perlin.d.ts +5 -0
- package/dist/noise/perlin.js +29 -0
- package/dist/noise/random.d.ts +13 -0
- package/dist/noise/random.js +39 -0
- package/dist/noise/value.d.ts +4 -0
- package/dist/noise/value.js +20 -0
- package/dist/noise/voronoise.d.ts +10 -0
- package/dist/noise/voronoise.js +26 -0
- package/dist/noise/worley.d.ts +4 -0
- package/dist/noise/worley.js +39 -0
- package/dist/shader-modules/index.d.ts +2 -0
- package/dist/shader-modules/index.js +2 -0
- package/dist/shader-modules/library.d.ts +2 -0
- package/dist/shader-modules/library.js +36 -0
- package/dist/shader-modules/modules/camera.d.ts +1 -0
- package/dist/shader-modules/modules/camera.js +43 -0
- package/dist/shader-modules/modules/color/blend.d.ts +1 -0
- package/dist/shader-modules/modules/color/blend.js +108 -0
- package/dist/shader-modules/modules/color/index.d.ts +1 -0
- package/dist/shader-modules/modules/color/index.js +135 -0
- package/dist/shader-modules/modules/constants.d.ts +1 -0
- package/dist/shader-modules/modules/constants.js +14 -0
- package/dist/shader-modules/modules/geometry.d.ts +1 -0
- package/dist/shader-modules/modules/geometry.js +110 -0
- package/dist/shader-modules/modules/math.d.ts +1 -0
- package/dist/shader-modules/modules/math.js +19 -0
- package/dist/shader-modules/modules/noise.d.ts +1 -0
- package/dist/shader-modules/modules/noise.js +410 -0
- package/dist/shader-modules/modules/random.d.ts +1 -0
- package/dist/shader-modules/modules/random.js +147 -0
- package/dist/shader-modules/modules/ray-marching.d.ts +1 -0
- package/dist/shader-modules/modules/ray-marching.js +54 -0
- package/dist/shader-modules/modules/sdf/index.d.ts +1 -0
- package/dist/shader-modules/modules/sdf/index.js +183 -0
- package/dist/shader-modules/modules/sdf/operations.d.ts +1 -0
- package/dist/shader-modules/modules/sdf/operations.js +77 -0
- package/dist/shader-modules/modules/utils.d.ts +1 -0
- package/dist/shader-modules/modules/utils.js +115 -0
- package/dist/shader-modules/registry.d.ts +2 -0
- package/dist/shader-modules/registry.js +7 -0
- package/dist/shader-modules/shaders.d.ts +1 -0
- package/dist/shader-modules/shaders.js +109 -0
- package/dist/shader-renderer/helpers.d.ts +10 -0
- package/dist/shader-renderer/helpers.js +19 -0
- package/dist/shader-renderer/index.d.ts +2 -0
- package/dist/shader-renderer/index.js +2 -0
- package/dist/shader-renderer/pixel-shader.d.ts +32 -0
- package/dist/shader-renderer/pixel-shader.js +172 -0
- package/dist/shader-renderer/pixel-vertex-shader.d.ts +1 -0
- package/dist/shader-renderer/pixel-vertex-shader.js +14 -0
- package/dist/shader-renderer/texture.d.ts +28 -0
- package/dist/shader-renderer/texture.js +97 -0
- package/dist/shader-renderer/types.d.ts +17 -0
- package/dist/shader-renderer/types.js +4 -0
- package/dist/shader-renderer/uniform.d.ts +16 -0
- package/dist/shader-renderer/uniform.js +134 -0
- package/dist/tilings/delaunay.d.ts +11 -0
- package/dist/tilings/delaunay.js +28 -0
- package/dist/tilings/grid.d.ts +5 -0
- package/dist/tilings/grid.js +29 -0
- package/dist/tilings/hexagononal.d.ts +4 -0
- package/dist/tilings/hexagononal.js +40 -0
- package/dist/tilings/index.d.ts +12 -0
- package/dist/tilings/index.js +12 -0
- package/dist/tilings/line.d.ts +5 -0
- package/dist/tilings/line.js +19 -0
- package/dist/tilings/mediterranean.d.ts +3 -0
- package/dist/tilings/mediterranean.js +49 -0
- package/dist/tilings/pythagorean.d.ts +3 -0
- package/dist/tilings/pythagorean.js +40 -0
- package/dist/tilings/random-cuts.d.ts +6 -0
- package/dist/tilings/random-cuts.js +16 -0
- package/dist/tilings/recursive-cuts.d.ts +5 -0
- package/dist/tilings/recursive-cuts.js +11 -0
- package/dist/tilings/rhombille.d.ts +3 -0
- package/dist/tilings/rhombille.js +16 -0
- package/dist/tilings/rightangled-triangle.d.ts +3 -0
- package/dist/tilings/rightangled-triangle.js +29 -0
- package/dist/tilings/triangle.d.ts +3 -0
- package/dist/tilings/triangle.js +17 -0
- package/dist/tilings/voronoi.d.ts +11 -0
- package/dist/tilings/voronoi.js +29 -0
- package/dist/tilings/weaving.d.ts +1 -0
- package/dist/tilings/weaving.js +8 -0
- package/dist/transforms/camera/camera.d.ts +32 -0
- package/dist/transforms/camera/camera.js +60 -0
- package/dist/transforms/camera/index.d.ts +3 -0
- package/dist/transforms/camera/index.js +3 -0
- package/dist/transforms/camera/orthographic.d.ts +15 -0
- package/dist/transforms/camera/orthographic.js +31 -0
- package/dist/transforms/camera/perspective.d.ts +16 -0
- package/dist/transforms/camera/perspective.js +40 -0
- package/dist/transforms/index.d.ts +2 -0
- package/dist/transforms/index.js +2 -0
- package/dist/transforms/normalize-transform.d.ts +12 -0
- package/dist/transforms/normalize-transform.js +20 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.js +1 -0
- package/dist/utilities/create-frame.d.ts +2 -0
- package/dist/utilities/create-frame.js +6 -0
- package/dist/utilities/ensure-array.d.ts +1 -0
- package/dist/utilities/ensure-array.js +3 -0
- package/dist/utilities/idw-interpolator.d.ts +9 -0
- package/dist/utilities/idw-interpolator.js +18 -0
- package/dist/utilities/index.d.ts +8 -0
- package/dist/utilities/index.js +8 -0
- package/dist/utilities/marching-squares.d.ts +51 -0
- package/dist/utilities/marching-squares.js +177 -0
- package/dist/utilities/point-sampler.d.ts +12 -0
- package/dist/utilities/point-sampler.js +24 -0
- package/dist/utilities/poisson/grid.d.ts +21 -0
- package/dist/utilities/poisson/grid.js +51 -0
- package/dist/utilities/poisson/poissonnier.d.ts +50 -0
- package/dist/utilities/poisson/poissonnier.js +118 -0
- package/dist/utilities/resolution.d.ts +10 -0
- package/dist/utilities/resolution.js +14 -0
- package/dist/utilities/rng.d.ts +13 -0
- package/dist/utilities/rng.js +80 -0
- package/package.json +28 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function fract(value: number): number;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function mix(start: number, end: number, t: number): number;
|
package/dist/math/mix.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function mod(value: number, modulo: number): number;
|
package/dist/math/mod.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function signed(value: number): number;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export function smoothstep(value, lower = 0, upper = 1) {
|
|
2
|
+
value = (value - lower) / (upper - lower);
|
|
3
|
+
if (value < 0)
|
|
4
|
+
return 0;
|
|
5
|
+
if (value > 1)
|
|
6
|
+
return 1;
|
|
7
|
+
return value * value * (3 - 2 * value);
|
|
8
|
+
}
|
|
9
|
+
export function smoothsteps(value, steps, flatness) {
|
|
10
|
+
if (value < 0)
|
|
11
|
+
return 0;
|
|
12
|
+
if (value >= 1)
|
|
13
|
+
return 1;
|
|
14
|
+
if (flatness === 1) {
|
|
15
|
+
return Math.floor(value * (steps + 1)) / steps;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
const l = (1 - flatness / (steps + 1)) / steps;
|
|
19
|
+
const v = value / l;
|
|
20
|
+
const vi = Math.floor(v);
|
|
21
|
+
const vf = v - vi;
|
|
22
|
+
return (vi + smoothstep(vf, flatness, 1)) / steps;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function splitIntoIntAndFract(value: number): number[];
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { AABB } from "../geometry/aabb.js";
|
|
2
|
+
import { Vec2 } from "../geometry/vec2.js";
|
|
3
|
+
import { RNG } from "../utilities/index.js";
|
|
4
|
+
export type CreateIDWNoiseOptions = {
|
|
5
|
+
numPoints: number;
|
|
6
|
+
extent: AABB;
|
|
7
|
+
rng: RNG;
|
|
8
|
+
heightFunction: (position: Vec2, index: number) => number;
|
|
9
|
+
power?: number;
|
|
10
|
+
};
|
|
11
|
+
export declare function createIDWNoise(options: CreateIDWNoiseOptions): (v: Vec2, power?: number) => number;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createIDWInterpolator } from "../utilities/idw-interpolator.js";
|
|
2
|
+
import { Poissonnier } from "../utilities/index.js";
|
|
3
|
+
export function createIDWNoise(options) {
|
|
4
|
+
const { numPoints, extent, rng, heightFunction, power = 2 } = options;
|
|
5
|
+
const data = Poissonnier
|
|
6
|
+
.generateFixedSizeSample({ extent, sampleSize: numPoints, rng })
|
|
7
|
+
.sort((a, b) => a.y - b.y)
|
|
8
|
+
.map((position, i) => ({ position, value: heightFunction(position, i) }));
|
|
9
|
+
return createIDWInterpolator({ data, power });
|
|
10
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Vec2 } from "../geometry/vec2.js";
|
|
2
|
+
import { Vec3 } from "../geometry/vec3.js";
|
|
3
|
+
export declare function perlinNoise1D(p: number, scale: number, seed?: number): number;
|
|
4
|
+
export declare function perlinNoise2D(p: Vec2, scale: number, seed?: number): number;
|
|
5
|
+
export declare function perlinNoise3D(p: Vec3, scale: number, seed?: number): number;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Vec2, vec2 } from "../geometry/vec2.js";
|
|
2
|
+
import { vec3, Vec3 } from "../geometry/vec3.js";
|
|
3
|
+
import { mix } from "../math/mix.js";
|
|
4
|
+
import { signed } from "../math/signed.js";
|
|
5
|
+
import { smoothstep } from "../math/smoothstep.js";
|
|
6
|
+
import { random1D, randomUnit2D, randomUnit3D } from "./random.js";
|
|
7
|
+
const NORMALIZE_1D = 2;
|
|
8
|
+
const NORMALIZE_2D = Math.sqrt(2);
|
|
9
|
+
const NORMALIZE_3D = Math.sqrt(4 / 3);
|
|
10
|
+
export function perlinNoise1D(p, scale, seed = 0) {
|
|
11
|
+
p *= scale;
|
|
12
|
+
const pi = Math.floor(p);
|
|
13
|
+
const pf = p - pi;
|
|
14
|
+
const sf = smoothstep(pf);
|
|
15
|
+
const signedValue = mix(signed(random1D(pi, seed)) * pf, signed(random1D(pi + 1, seed)) * (pf - 1), sf);
|
|
16
|
+
return 0.5 + 0.5 * signedValue * NORMALIZE_1D;
|
|
17
|
+
}
|
|
18
|
+
export function perlinNoise2D(p, scale, seed = 0) {
|
|
19
|
+
const [pi, pf] = p.clone().times(scale).splitIntoIntAndFract();
|
|
20
|
+
const sf = Vec2.smoothstep(pf);
|
|
21
|
+
const signedValue = mix(mix(randomUnit2D(pi, seed).dot(pf), randomUnit2D(Vec2.add(pi, vec2(1, 0)), seed).dot(Vec2.subtract(pf, vec2(1, 0))), sf.x), mix(randomUnit2D(Vec2.add(pi, vec2(0, 1)), seed).dot(Vec2.subtract(pf, vec2(0, 1))), randomUnit2D(Vec2.add(pi, vec2(1, 1)), seed).dot(Vec2.subtract(pf, vec2(1, 1))), sf.x), sf.y);
|
|
22
|
+
return 0.5 + 0.5 * signedValue * NORMALIZE_2D;
|
|
23
|
+
}
|
|
24
|
+
export function perlinNoise3D(p, scale, seed = 0) {
|
|
25
|
+
const [pi, pf] = p.clone().times(scale).splitIntoIntAndFract();
|
|
26
|
+
const sf = Vec3.smoothstep(pf);
|
|
27
|
+
const signedValue = mix(mix(mix(randomUnit3D(pi, seed).dot(pf), randomUnit3D(Vec3.add(pi, vec3(1, 0, 0)), seed).dot(Vec3.subtract(pf, vec3(1, 0, 0))), sf.x), mix(randomUnit3D(Vec3.add(pi, vec3(0, 1, 0)), seed).dot(Vec3.subtract(pf, vec3(0, 1, 0))), randomUnit3D(Vec3.add(pi, vec3(1, 1, 0)), seed).dot(Vec3.subtract(pf, vec3(1, 1, 0))), sf.x), sf.y), mix(mix(randomUnit3D(Vec3.add(pi, vec3(0, 0, 1)), seed).dot(Vec3.subtract(pf, vec3(0, 0, 1))), randomUnit3D(Vec3.add(pi, vec3(1, 0, 1)), seed).dot(Vec3.subtract(pf, vec3(1, 0, 1))), sf.x), mix(randomUnit3D(Vec3.add(pi, vec3(0, 1, 1)), seed).dot(Vec3.subtract(pf, vec3(0, 1, 1))), randomUnit3D(Vec3.add(pi, vec3(1, 1, 1)), seed).dot(Vec3.subtract(pf, vec3(1, 1, 1))), sf.x), sf.y), sf.z);
|
|
28
|
+
return 0.5 + 0.5 * signedValue * NORMALIZE_3D;
|
|
29
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Vec2 } from "../geometry/vec2.js";
|
|
2
|
+
import { Vec3 } from "../geometry/vec3.js";
|
|
3
|
+
import { Vec4 } from "../geometry/vec4.js";
|
|
4
|
+
export declare function random1D(p: number, seed?: number): number;
|
|
5
|
+
export declare function random2D(p: Vec2, seed?: number): number;
|
|
6
|
+
export declare function random3D(p: Vec3, seed?: number): number;
|
|
7
|
+
export declare function random4D(p: Vec4, seed?: number): number;
|
|
8
|
+
export declare function randomVec2(p: Vec2, seed?: number): Vec2;
|
|
9
|
+
export declare function randomVec3(p: Vec3, seed?: number): Vec3;
|
|
10
|
+
export declare function randomUnit2D(p: Vec2, seed?: number): Vec2;
|
|
11
|
+
export declare function randomGaussian2D(p: Vec2, seed?: number): number;
|
|
12
|
+
export declare function randomGaussian3D(p: Vec3, seed?: number): number;
|
|
13
|
+
export declare function randomUnit3D(p: Vec3, seed?: number): Vec3;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { vec2, Vec2 } from "../geometry/vec2.js";
|
|
2
|
+
import { vec3 } from "../geometry/vec3.js";
|
|
3
|
+
import { vec4 } from "../geometry/vec4.js";
|
|
4
|
+
import { hash } from "../utilities/rng.js";
|
|
5
|
+
const NOISE_MULT = 1831565813.761235;
|
|
6
|
+
export function random1D(p, seed = 0) {
|
|
7
|
+
return hash(NOISE_MULT * p, seed) / 4294967296;
|
|
8
|
+
}
|
|
9
|
+
export function random2D(p, seed = 0) {
|
|
10
|
+
return hash(NOISE_MULT * p.x ^ hash(NOISE_MULT * p.y, seed), seed) / 4294967296;
|
|
11
|
+
}
|
|
12
|
+
export function random3D(p, seed = 0) {
|
|
13
|
+
return hash(NOISE_MULT * p.x ^ hash(NOISE_MULT * p.y ^ hash(NOISE_MULT * p.z, seed), seed), seed) / 4294967296;
|
|
14
|
+
}
|
|
15
|
+
export function random4D(p, seed = 0) {
|
|
16
|
+
return hash(NOISE_MULT * p.x ^ hash(NOISE_MULT * p.y ^ hash(NOISE_MULT * p.z ^ hash(NOISE_MULT * p.w, seed), seed), seed), seed) / 4294967296;
|
|
17
|
+
}
|
|
18
|
+
export function randomVec2(p, seed = 0) {
|
|
19
|
+
return vec2(random3D(vec3(p.x, p.y, 1), seed), random3D(vec3(p.x, p.y, 2), seed));
|
|
20
|
+
}
|
|
21
|
+
export function randomVec3(p, seed = 0) {
|
|
22
|
+
return vec3(random4D(vec4(p, 1), seed), random4D(vec4(p, 2), seed), random4D(vec4(p, 3), seed));
|
|
23
|
+
}
|
|
24
|
+
export function randomUnit2D(p, seed = 0) {
|
|
25
|
+
return Vec2.fromPolar(1, 2 * Math.PI * random2D(p, seed));
|
|
26
|
+
}
|
|
27
|
+
export function randomGaussian2D(p, seed = 0) {
|
|
28
|
+
const u1 = random3D(p.toVec3(1), seed);
|
|
29
|
+
const u2 = random3D(p.toVec3(2), seed);
|
|
30
|
+
return Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
|
|
31
|
+
}
|
|
32
|
+
export function randomGaussian3D(p, seed = 0) {
|
|
33
|
+
const u1 = random4D(vec4(p, 1), seed);
|
|
34
|
+
const u2 = random4D(vec4(p, 2), seed);
|
|
35
|
+
return Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
|
|
36
|
+
}
|
|
37
|
+
export function randomUnit3D(p, seed = 0) {
|
|
38
|
+
return vec3(randomGaussian3D(p, seed), randomGaussian3D(p, hash(seed, 1)), randomGaussian3D(p, hash(seed, 2))).normalize();
|
|
39
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Vec2, Vec3 } from "../geometry/index.js";
|
|
2
|
+
export declare function valueNoise1D(p: number, scale: number, seed?: number): number;
|
|
3
|
+
export declare function valueNoise2D(p: Vec2, scale: number, seed?: number): number;
|
|
4
|
+
export declare function valueNoise3D(p: Vec3, scale: number, seed?: number): number;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { vec2, Vec2, Vec3, vec3 } from "../geometry/index.js";
|
|
2
|
+
import { smoothstep, mix } from "../math/index.js";
|
|
3
|
+
import { random1D, random2D, random3D } from "./random.js";
|
|
4
|
+
export function valueNoise1D(p, scale, seed = 0) {
|
|
5
|
+
p *= scale;
|
|
6
|
+
const pi = Math.floor(p);
|
|
7
|
+
const pf = p - pi;
|
|
8
|
+
const sf = smoothstep(pf);
|
|
9
|
+
return mix(random1D(pi, seed), random1D(pi + 1, seed), sf);
|
|
10
|
+
}
|
|
11
|
+
export function valueNoise2D(p, scale, seed = 0) {
|
|
12
|
+
const [pi, pf] = p.clone().times(scale).splitIntoIntAndFract();
|
|
13
|
+
const sf = Vec2.smoothstep(pf);
|
|
14
|
+
return mix(mix(random2D(pi, seed), random2D(Vec2.add(pi, vec2(1, 0)), seed), sf.x), mix(random2D(Vec2.add(pi, vec2(0, 1)), seed), random2D(Vec2.add(pi, vec2(1, 1)), seed), sf.x), sf.y);
|
|
15
|
+
}
|
|
16
|
+
export function valueNoise3D(p, scale, seed = 0) {
|
|
17
|
+
const [pi, pf] = p.clone().times(scale).splitIntoIntAndFract();
|
|
18
|
+
const sf = Vec3.smoothstep(pf);
|
|
19
|
+
return mix(mix(mix(random3D(pi, seed), random3D(Vec3.add(pi, vec3(1, 0, 0)), seed), sf.x), mix(random3D(Vec3.add(pi, vec3(0, 1, 0)), seed), random3D(Vec3.add(pi, vec3(1, 1, 0)), seed), sf.x), sf.y), mix(mix(random3D(Vec3.add(pi, vec3(0, 0, 1)), seed), random3D(Vec3.add(pi, vec3(1, 0, 1)), seed), sf.x), mix(random3D(Vec3.add(pi, vec3(0, 1, 1)), seed), random3D(Vec3.add(pi, vec3(1, 1, 1)), seed), sf.x), sf.y), sf.z);
|
|
20
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Vec2 } from "../geometry/vec2.js";
|
|
2
|
+
type VoronoiseOptions = {
|
|
3
|
+
p: Vec2;
|
|
4
|
+
scale: number;
|
|
5
|
+
disorder?: number;
|
|
6
|
+
smoothness?: number;
|
|
7
|
+
seed?: number;
|
|
8
|
+
};
|
|
9
|
+
export declare function voronoise2D(options: VoronoiseOptions): number | undefined;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { vec2, Vec2 } from "../geometry/vec2.js";
|
|
2
|
+
import { smoothstep } from "../math/smoothstep.js";
|
|
3
|
+
import { random2D, randomVec2 } from "./random.js";
|
|
4
|
+
const { pow, sqrt } = Math;
|
|
5
|
+
export function voronoise2D(options) {
|
|
6
|
+
const { p, scale, disorder = 1, smoothness = 1, seed } = options;
|
|
7
|
+
const [pi, pf] = p.clone().times(scale).splitIntoIntAndFract();
|
|
8
|
+
const power = 64.0 - 63.0 * pow(smoothness, 0.1);
|
|
9
|
+
let sum = 0;
|
|
10
|
+
let weightSum = 0;
|
|
11
|
+
const kernel = 2;
|
|
12
|
+
for (let row = -kernel; row <= kernel; row++) {
|
|
13
|
+
for (let column = -kernel; column <= kernel; column++) {
|
|
14
|
+
const index = vec2(column, row);
|
|
15
|
+
const corner = Vec2.add(pi, index);
|
|
16
|
+
const position = randomVec2(corner, seed).times(disorder);
|
|
17
|
+
const value = random2D(corner, seed);
|
|
18
|
+
const centerToPosition = Vec2.add(index, position).minus(pf);
|
|
19
|
+
const distSquared = centerToPosition.lengthSquared();
|
|
20
|
+
const weight = pow(smoothstep(sqrt(0.5 * distSquared), 1, 0), power);
|
|
21
|
+
sum += weight * value;
|
|
22
|
+
weightSum += weight;
|
|
23
|
+
}
|
|
24
|
+
return sum / weightSum;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Vec2, Vec3 } from "../geometry/index.js";
|
|
2
|
+
export declare function worleyNoise1D(p: number, scale: number, seed?: number): number;
|
|
3
|
+
export declare function worleyNoise2D(p: Vec2, scale: number, seed?: number): number;
|
|
4
|
+
export declare function worleyNoise3D(p: Vec3, scale: number, seed?: number): number;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Vec2, vec2, vec3, Vec3 } from "../geometry/index.js";
|
|
2
|
+
import { splitIntoIntAndFract } from "../math/split-into-int-and-fract.js";
|
|
3
|
+
import { random1D, randomVec2, randomVec3 } from "./index.js";
|
|
4
|
+
const { min, sqrt, abs } = Math;
|
|
5
|
+
export function worleyNoise1D(p, scale, seed = 0) {
|
|
6
|
+
const [pi, pf] = splitIntoIntAndFract(scale * p);
|
|
7
|
+
let minDist = Infinity;
|
|
8
|
+
for (let index = -1; index <= 1; index++) {
|
|
9
|
+
const centerToPosition = index + random1D(pi + index, seed) - pf;
|
|
10
|
+
minDist = min(minDist, abs(centerToPosition));
|
|
11
|
+
}
|
|
12
|
+
return minDist;
|
|
13
|
+
}
|
|
14
|
+
export function worleyNoise2D(p, scale, seed = 0) {
|
|
15
|
+
const [pi, pf] = p.clone().times(scale).splitIntoIntAndFract();
|
|
16
|
+
let minDistSquared = Infinity;
|
|
17
|
+
for (let row = -1; row <= 1; row++) {
|
|
18
|
+
for (let column = -1; column <= 1; column++) {
|
|
19
|
+
const index = vec2(column, row);
|
|
20
|
+
const centerToPosition = index.plus(randomVec2(Vec2.add(pi, index), seed)).minus(pf);
|
|
21
|
+
minDistSquared = min(minDistSquared, centerToPosition.lengthSquared());
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return sqrt(minDistSquared);
|
|
25
|
+
}
|
|
26
|
+
export function worleyNoise3D(p, scale, seed = 0) {
|
|
27
|
+
const [pi, pf] = p.clone().times(scale).splitIntoIntAndFract();
|
|
28
|
+
let minDistSquared = Infinity;
|
|
29
|
+
for (let row = -1; row <= 1; row++) {
|
|
30
|
+
for (let column = -1; column <= 1; column++) {
|
|
31
|
+
for (let slice = -1; slice <= 1; slice++) {
|
|
32
|
+
const index = vec3(column, row, slice);
|
|
33
|
+
const centerToPosition = index.plus(randomVec3(Vec3.add(pi, index), seed)).minus(pf);
|
|
34
|
+
minDistSquared = min(minDistSquared, centerToPosition.lengthSquared());
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return sqrt(minDistSquared);
|
|
39
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { GLSLLibrary } from "glsl-modules";
|
|
2
|
+
import { geometryDefinition } from "./modules/geometry.js";
|
|
3
|
+
import { sdfDefinition } from "./modules/sdf/index.js";
|
|
4
|
+
import { operationsDefinition } from "./modules/sdf/operations.js";
|
|
5
|
+
import { arrowFunctionsPlugin, functionAsArgumentPlugin } from "glsl-modules/plugins";
|
|
6
|
+
import { rayMarchingDefinition } from "./modules/ray-marching.js";
|
|
7
|
+
import { cameraDefinition } from "./modules/camera.js";
|
|
8
|
+
import { utilsDefinition } from "./modules/utils.js";
|
|
9
|
+
import { constantsDefinition } from "./modules/constants.js";
|
|
10
|
+
import { noiseDefinition } from "./modules/noise.js";
|
|
11
|
+
import { randomDefinition } from "./modules/random.js";
|
|
12
|
+
import { colorDefinition } from "./modules/color/index.js";
|
|
13
|
+
import { blendDefinition } from "./modules/color/blend.js";
|
|
14
|
+
import { mathDefinition } from "./modules/math.js";
|
|
15
|
+
export const glslkitLibrary = new GLSLLibrary({
|
|
16
|
+
name: "glslkit",
|
|
17
|
+
definition: {
|
|
18
|
+
"color": {
|
|
19
|
+
"@index": colorDefinition,
|
|
20
|
+
"blend": blendDefinition
|
|
21
|
+
},
|
|
22
|
+
"geometry": geometryDefinition,
|
|
23
|
+
"math": mathDefinition,
|
|
24
|
+
"sdf": {
|
|
25
|
+
"@index": sdfDefinition,
|
|
26
|
+
"operations": operationsDefinition
|
|
27
|
+
},
|
|
28
|
+
"ray-marching": rayMarchingDefinition,
|
|
29
|
+
"camera": cameraDefinition,
|
|
30
|
+
"utils": utilsDefinition,
|
|
31
|
+
"constants": constantsDefinition,
|
|
32
|
+
"random": randomDefinition,
|
|
33
|
+
"noise": noiseDefinition,
|
|
34
|
+
},
|
|
35
|
+
plugins: [arrowFunctionsPlugin(), functionAsArgumentPlugin()]
|
|
36
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const cameraDefinition = "\n\nimport { create2DBasisVectors } from \"@/geometry\";\nimport { Ray } from \"@/ray-marching\";\nexport { \n orthographicCamera,\n perspectiveCamera\n}\n\nRay orthographicCamera(vec2 uv, vec3 cameraPosition, vec3 lookAt, float viewport, float aspectRatio, float rotation) {\n vec3 normal = normalize(lookAt - cameraPosition);\n\n mat2x3 basis = create2DBasisVectors(normal, rotation);\n\n // The basis forms a RHS system, but uv coordinates from NDC are left-handed. \n // To make rendered image as expected, the j vector is flipped\n basis[1] = -basis[1];\n\n vec2 offset = (uv - 0.5) * viewport * vec2(max(aspectRatio, 1.0), max(1.0 / aspectRatio, 1.0));\n\n vec3 origin = cameraPosition + basis*offset;\n\n return Ray(origin, normal);\n}\n\nRay perspectiveCamera(vec2 uv, vec3 cameraPosition, vec3 lookAt, float fov, float aspectRatio, float rotation) {\n vec3 normal = normalize(lookAt - cameraPosition);\n\n mat2x3 basis = create2DBasisVectors(normal, rotation);\n\n // The basis forms a RHS system, but uv coordinates from NDC are left-handed. \n // To make rendered image as expected, the j vector is flipped\n basis[1] = -basis[1];\n\n\n vec2 offset = 2.0 * (uv - 0.5) * tan(0.5*fov) * vec2(max(aspectRatio, 1.0), max(1.0 / aspectRatio, 1.0));\n\n vec3 direction = normalize(normal + basis*offset);\n\n return Ray(cameraPosition, direction);\n}\n\n";
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export const cameraDefinition = /*glsl*/ `
|
|
2
|
+
|
|
3
|
+
import { create2DBasisVectors } from "@/geometry";
|
|
4
|
+
import { Ray } from "@/ray-marching";
|
|
5
|
+
export {
|
|
6
|
+
orthographicCamera,
|
|
7
|
+
perspectiveCamera
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
Ray orthographicCamera(vec2 uv, vec3 cameraPosition, vec3 lookAt, float viewport, float aspectRatio, float rotation) {
|
|
11
|
+
vec3 normal = normalize(lookAt - cameraPosition);
|
|
12
|
+
|
|
13
|
+
mat2x3 basis = create2DBasisVectors(normal, rotation);
|
|
14
|
+
|
|
15
|
+
// The basis forms a RHS system, but uv coordinates from NDC are left-handed.
|
|
16
|
+
// To make rendered image as expected, the j vector is flipped
|
|
17
|
+
basis[1] = -basis[1];
|
|
18
|
+
|
|
19
|
+
vec2 offset = (uv - 0.5) * viewport * vec2(max(aspectRatio, 1.0), max(1.0 / aspectRatio, 1.0));
|
|
20
|
+
|
|
21
|
+
vec3 origin = cameraPosition + basis*offset;
|
|
22
|
+
|
|
23
|
+
return Ray(origin, normal);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
Ray perspectiveCamera(vec2 uv, vec3 cameraPosition, vec3 lookAt, float fov, float aspectRatio, float rotation) {
|
|
27
|
+
vec3 normal = normalize(lookAt - cameraPosition);
|
|
28
|
+
|
|
29
|
+
mat2x3 basis = create2DBasisVectors(normal, rotation);
|
|
30
|
+
|
|
31
|
+
// The basis forms a RHS system, but uv coordinates from NDC are left-handed.
|
|
32
|
+
// To make rendered image as expected, the j vector is flipped
|
|
33
|
+
basis[1] = -basis[1];
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
vec2 offset = 2.0 * (uv - 0.5) * tan(0.5*fov) * vec2(max(aspectRatio, 1.0), max(1.0 / aspectRatio, 1.0));
|
|
37
|
+
|
|
38
|
+
vec3 direction = normalize(normal + basis*offset);
|
|
39
|
+
|
|
40
|
+
return Ray(cameraPosition, direction);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const blendDefinition = "\n\nexport {\n multiply, screen, overlay, hardLight, softLight, colorDodge, linearDodge, divide, colorBurn, linearBurn, vividLight, linearLight, subtract, difference, darken, lighten, blendById\n}\n\nvec3 multiply(vec3 a, vec3 b) {\n return a*b;\n}\n\nvec3 screen(vec3 a, vec3 b) {\n return 1.0 - (1.0 - a)*(1.0 - b);\n}\n\nvec3 overlay(vec3 a, vec3 b) {\n return mix(2.0*a*b, 1.0 - 2.0*(1.0 - a)*(1.0 - b), step(0.5, a));\n}\n\nvec3 hardLight(vec3 a, vec3 b) {\n return mix(2.0*a*b, 1.0 - 2.0*(1.0 - a)*(1.0 - b), step(0.5, b));\n}\n\nvec3 softLight(vec3 a, vec3 b) {\n return (1.0 - 2.0*b)*a*a + 2.0*b*a;\n}\n\nvec3 colorDodge(vec3 a, vec3 b) {\n return min(a / (1.0 - b), 1.0);\n}\n\nvec3 linearDodge(vec3 a, vec3 b) {\n return min(a + b, 1.0);\n}\n\nvec3 divide(vec3 a, vec3 b) {\n return min(a / b, 1.0);\n}\n\nvec3 colorBurn(vec3 a, vec3 b) {\n return clamp(1.0 - (1.0 - a) / b, 0.0, 1.0);\n}\n\nvec3 linearBurn(vec3 a, vec3 b) {\n return clamp(a + b - 1.0, 0.0, 1.0);\n}\n\nvec3 vividLight(vec3 a, vec3 b) {\n return mix(colorBurn(a, b), colorDodge(a, b), step(0.5, b));\n}\n\nvec3 linearLight(vec3 a, vec3 b) {\n return clamp(a + 2.0*b - 1.0, 0.0, 1.0);\n}\n\nvec3 subtract(vec3 a, vec3 b) {\n return clamp(a - b, 0.0, 1.0);\n}\n\nvec3 difference(vec3 a, vec3 b) {\n return abs(b - a);\n}\n\nvec3 darken(vec3 a, vec3 b) {\n return min(a, b);\n}\n\nvec3 lighten(vec3 a, vec3 b) {\n return max(a, b);\n}\n\nvec3 blendById(vec3 a, vec3 b, int id) {\n id = max(0, min(id, 15));\n if (id == 0) {\n return multiply(a, b);\n } else if (id == 1) {\n return screen(a, b);\n } else if (id == 2) {\n return overlay(a, b);\n } else if (id == 3) {\n return hardLight(a, b);\n } else if (id == 4) {\n return softLight(a, b);\n } else if (id == 5) {\n return colorDodge(a, b);\n } else if (id == 6) {\n return linearDodge(a, b);\n } else if (id == 7) {\n return divide(a, b);\n } else if (id == 8) {\n return colorBurn(a, b);\n } else if (id == 9) {\n return linearBurn(a, b);\n } else if (id == 10) {\n return vividLight(a, b);\n } else if (id == 11) {\n return linearLight(a, b);\n } else if (id == 12) {\n return subtract(a, b);\n } else if (id == 13) {\n return difference(a, b);\n } else if (id == 14) {\n return darken(a, b);\n } else if (id == 15) {\n return lighten(a, b);\n }\n}\n\n";
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
export const blendDefinition = /*glsl*/ `
|
|
2
|
+
|
|
3
|
+
export {
|
|
4
|
+
multiply, screen, overlay, hardLight, softLight, colorDodge, linearDodge, divide, colorBurn, linearBurn, vividLight, linearLight, subtract, difference, darken, lighten, blendById
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
vec3 multiply(vec3 a, vec3 b) {
|
|
8
|
+
return a*b;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
vec3 screen(vec3 a, vec3 b) {
|
|
12
|
+
return 1.0 - (1.0 - a)*(1.0 - b);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
vec3 overlay(vec3 a, vec3 b) {
|
|
16
|
+
return mix(2.0*a*b, 1.0 - 2.0*(1.0 - a)*(1.0 - b), step(0.5, a));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
vec3 hardLight(vec3 a, vec3 b) {
|
|
20
|
+
return mix(2.0*a*b, 1.0 - 2.0*(1.0 - a)*(1.0 - b), step(0.5, b));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
vec3 softLight(vec3 a, vec3 b) {
|
|
24
|
+
return (1.0 - 2.0*b)*a*a + 2.0*b*a;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
vec3 colorDodge(vec3 a, vec3 b) {
|
|
28
|
+
return min(a / (1.0 - b), 1.0);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
vec3 linearDodge(vec3 a, vec3 b) {
|
|
32
|
+
return min(a + b, 1.0);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
vec3 divide(vec3 a, vec3 b) {
|
|
36
|
+
return min(a / b, 1.0);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
vec3 colorBurn(vec3 a, vec3 b) {
|
|
40
|
+
return clamp(1.0 - (1.0 - a) / b, 0.0, 1.0);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
vec3 linearBurn(vec3 a, vec3 b) {
|
|
44
|
+
return clamp(a + b - 1.0, 0.0, 1.0);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
vec3 vividLight(vec3 a, vec3 b) {
|
|
48
|
+
return mix(colorBurn(a, b), colorDodge(a, b), step(0.5, b));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
vec3 linearLight(vec3 a, vec3 b) {
|
|
52
|
+
return clamp(a + 2.0*b - 1.0, 0.0, 1.0);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
vec3 subtract(vec3 a, vec3 b) {
|
|
56
|
+
return clamp(a - b, 0.0, 1.0);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
vec3 difference(vec3 a, vec3 b) {
|
|
60
|
+
return abs(b - a);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
vec3 darken(vec3 a, vec3 b) {
|
|
64
|
+
return min(a, b);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
vec3 lighten(vec3 a, vec3 b) {
|
|
68
|
+
return max(a, b);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
vec3 blendById(vec3 a, vec3 b, int id) {
|
|
72
|
+
id = max(0, min(id, 15));
|
|
73
|
+
if (id == 0) {
|
|
74
|
+
return multiply(a, b);
|
|
75
|
+
} else if (id == 1) {
|
|
76
|
+
return screen(a, b);
|
|
77
|
+
} else if (id == 2) {
|
|
78
|
+
return overlay(a, b);
|
|
79
|
+
} else if (id == 3) {
|
|
80
|
+
return hardLight(a, b);
|
|
81
|
+
} else if (id == 4) {
|
|
82
|
+
return softLight(a, b);
|
|
83
|
+
} else if (id == 5) {
|
|
84
|
+
return colorDodge(a, b);
|
|
85
|
+
} else if (id == 6) {
|
|
86
|
+
return linearDodge(a, b);
|
|
87
|
+
} else if (id == 7) {
|
|
88
|
+
return divide(a, b);
|
|
89
|
+
} else if (id == 8) {
|
|
90
|
+
return colorBurn(a, b);
|
|
91
|
+
} else if (id == 9) {
|
|
92
|
+
return linearBurn(a, b);
|
|
93
|
+
} else if (id == 10) {
|
|
94
|
+
return vividLight(a, b);
|
|
95
|
+
} else if (id == 11) {
|
|
96
|
+
return linearLight(a, b);
|
|
97
|
+
} else if (id == 12) {
|
|
98
|
+
return subtract(a, b);
|
|
99
|
+
} else if (id == 13) {
|
|
100
|
+
return difference(a, b);
|
|
101
|
+
} else if (id == 14) {
|
|
102
|
+
return darken(a, b);
|
|
103
|
+
} else if (id == 15) {
|
|
104
|
+
return lighten(a, b);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const colorDefinition = "\n\nexport {\n hslToRgb, rgbToHsl, shiftRgbInHsl,\n hsvToRgb, rgbToHsv\n}\n\nvec3 hslToRgb(vec3 hsl) {\n float h = mod(hsl.r, 360.0);\n float s = clamp(hsl.g, 0.0, 1.0);\n float l = clamp(hsl.b, 0.0, 1.0);\n\n float c = s*(1.0 - abs(2.0*l - 1.0));\n float x = c*(1.0 - abs(mod(h / 60.0, 2.0) - 1.0));\n float m = l - c / 2.0;\n \n float r = 0.0;\n float g = 0.0;\n float b = 0.0;\n\n if (h < 60.0) {\n r = c;\n g = x;\n } else if (h < 120.0) {\n r = x;\n g = c;\n } else if (h < 180.0) {\n g = c;\n b = x;\n } else if (h < 240.0) {\n g = x;\n b = c;\n } else if (h < 300.0) {\n r = x;\n b = c;\n } else {\n r = c;\n b = x;\n }\n return vec3(r, g, b) + m;\n}\n\nvec3 hslToRgb(float h, float s, float l) {\n return hslToRgb(vec3(h, s, l));\n}\n\nvec3 rgbToHsl(vec3 rgb) {\n float r = rgb.r;\n float g = rgb.g;\n float b = rgb.b;\n\n float cMax = max(r, max(g, b));\n float cMin = min(r, min(g, b));\n float delta = cMax - cMin;\n\n float h;\n\n if (delta == 0.0) {\n h = 0.0;\n } else if (r == cMax) {\n h = mod((g - b)/delta, 6.0);\n } else if (g == cMax) {\n h = (b - r)/delta + 2.0;\n } else if (b == cMax) {\n h = (r - g)/delta + 4.0;\n } \n h *= 60.0;\n\th = mod(h, 360.0);\n\n float l = (cMax + cMin)/2.0;\n\n float s = 0.0;\n if (delta > 0.0) {\n s = delta/(1.0 - abs(2.0*l - 1.0));\n }\n\n return vec3(h, s, l);\n}\n\nvec3 rgbToHsl(float r, float g, float b) {\n return rgbToHsl(vec3(r, g, b));\n}\n\nvec3 shiftRgbInHsl(vec3 rgb, vec3 shift) {\n if (shift.z > 0.0) {\n rgb = mix(rgb, vec3(1.0), shift.z);\n } else {\n rgb = mix(rgb, vec3(0.0), -shift.z);\n }\n\n vec3 hsl = rgbToHsl(rgb);\n\n hsl.x += shift.x;\n\n float sShift = shift.y;\n if (sShift > 0.0) {\n hsl.y = (1.0 - sShift)*hsl.y + sShift;\n } else {\n hsl.y = (1.0 + sShift)*hsl.y;\n }\n\n vec3 res = hslToRgb(hsl);\n\n return res;\n}\n\nvec3 rgbToHsv(vec3 c)\n{\n vec4 K = vec4(0.0, -1.0/3.0, 2.0/3.0, -1.0);\n vec4 p = mix(vec4(c.bg, K.wz),\n vec4(c.gb, K.xy),\n step(c.b, c.g));\n vec4 q = mix(vec4(p.xyw, c.r),\n vec4(c.r, p.yzx),\n step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 1.0e-10;\n\n return vec3(\n abs(q.z + (q.w - q.y) / (6.0 * d + e)),\n d / (q.x + e), \n q.x \n );\n}\n\nvec3 hsv2Rgb(vec3 c)\n{\n vec4 K = vec4(1.0, 2.0/3.0, 1.0/3.0, 3.0);\n vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n\n return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n}\n\n";
|