@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,410 @@
|
|
|
1
|
+
export const noiseDefinition = /*glsl*/ `
|
|
2
|
+
import { random, random2, random3, randomUnit } from "@/random";
|
|
3
|
+
import { triangleWave, dot2 } from "@/utils";
|
|
4
|
+
import { rotate, axisAngle } from "@/geometry";
|
|
5
|
+
import { PI } from "@/constants";
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
valueNoise, perlinNoise, worleyNoise, voroNoise, gaboroNoise,
|
|
9
|
+
octaveNoise1D, octaveNoise2D, octaveNoise3D
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
float valueNoise(float p, float scale, float seed) {
|
|
13
|
+
p *= scale;
|
|
14
|
+
|
|
15
|
+
float pi = floor(p);
|
|
16
|
+
float pf = fract(p);
|
|
17
|
+
|
|
18
|
+
float sf = smoothstep(0.0, 1.0, pf);
|
|
19
|
+
|
|
20
|
+
return mix(random(pi, seed), random(pi + 1.0, seed), sf);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
float valueNoise(vec2 p, float scale, float seed) {
|
|
24
|
+
p *= scale;
|
|
25
|
+
|
|
26
|
+
vec2 pi = floor(p);
|
|
27
|
+
vec2 pf = fract(p);
|
|
28
|
+
|
|
29
|
+
vec2 sf = smoothstep(0.0, 1.0, pf);
|
|
30
|
+
vec2 o = vec2(1, 0);
|
|
31
|
+
|
|
32
|
+
return mix(
|
|
33
|
+
mix(random(pi, seed), random(pi + o.xy, seed), sf.x),
|
|
34
|
+
mix(random(pi + o.yx, seed), random(pi + o.xx, seed), sf.x),
|
|
35
|
+
sf.y
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
float valueNoise(vec3 p, float scale, float seed) {
|
|
40
|
+
p *= scale;
|
|
41
|
+
|
|
42
|
+
vec3 pi = floor(p);
|
|
43
|
+
vec3 pf = fract(p);
|
|
44
|
+
|
|
45
|
+
vec3 sf = smoothstep(0.0, 1.0, pf);
|
|
46
|
+
vec2 o = vec2(1, 0);
|
|
47
|
+
|
|
48
|
+
return mix(
|
|
49
|
+
mix(
|
|
50
|
+
mix(random(pi, seed), random(pi + o.xyy, seed), sf.x),
|
|
51
|
+
mix(random(pi + o.yxy, seed), random(pi + o.xxy, seed), sf.x),
|
|
52
|
+
sf.y
|
|
53
|
+
),
|
|
54
|
+
mix(
|
|
55
|
+
mix(random(pi + o.yyx, seed), random(pi + o.xyx, seed), sf.x),
|
|
56
|
+
mix(random(pi + o.yxx, seed), random(pi + o.xxx, seed), sf.x),
|
|
57
|
+
sf.y
|
|
58
|
+
),
|
|
59
|
+
sf.z
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
float perlinNoise(float p, float scale, float seed) {
|
|
65
|
+
p *= scale;
|
|
66
|
+
|
|
67
|
+
float pi = floor(p);
|
|
68
|
+
float pf = fract(p);
|
|
69
|
+
|
|
70
|
+
float sf = smoothstep(0.0, 1.0, pf);
|
|
71
|
+
|
|
72
|
+
float signed = mix(random(pi, seed)*pf, random(pi + 1.0, seed)*(pf - 1.0), sf);
|
|
73
|
+
|
|
74
|
+
// Signed is in range [-1/2, 1/2], map to [0, 1]
|
|
75
|
+
return 0.5 + signed;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
float perlinNoise(vec2 p, float scale, float seed) {
|
|
79
|
+
p *= scale;
|
|
80
|
+
|
|
81
|
+
vec2 pi = floor(p);
|
|
82
|
+
vec2 pf = fract(p);
|
|
83
|
+
|
|
84
|
+
vec2 sf = smoothstep(0.0, 1.0, pf);
|
|
85
|
+
vec2 o = vec2(1, 0);
|
|
86
|
+
|
|
87
|
+
float signed = mix(
|
|
88
|
+
mix(dot(randomUnit(pi, seed), pf), dot(randomUnit(pi + o.xy, seed), pf - o.xy), sf.x),
|
|
89
|
+
mix(dot(randomUnit(pi + o.yx, seed), pf - o.yx), dot(randomUnit(pi + o.xx, seed), pf - o.xx), sf.x),
|
|
90
|
+
sf.y
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
// Signed is in range [-sqrt(2)/2, sqrt(2)/2], map to [0, 1]
|
|
94
|
+
return 0.5 + 0.70710678118654752*signed;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
float perlinNoise(vec3 p, float scale, float seed) {
|
|
98
|
+
p *= scale;
|
|
99
|
+
|
|
100
|
+
vec3 pi = floor(p);
|
|
101
|
+
vec3 pf = fract(p);
|
|
102
|
+
|
|
103
|
+
vec3 sf = smoothstep(0.0, 1.0, pf);
|
|
104
|
+
vec2 o = vec2(1, 0);
|
|
105
|
+
|
|
106
|
+
float signed = mix(
|
|
107
|
+
mix(
|
|
108
|
+
mix(dot(randomUnit(pi, seed), pf), dot(randomUnit(pi + o.xyy, seed), pf - o.xyy), sf.x),
|
|
109
|
+
mix(dot(randomUnit(pi + o.yxy, seed), pf - o.yxy), dot(randomUnit(pi + o.xxy, seed), pf - o.xxy), sf.x),
|
|
110
|
+
sf.y
|
|
111
|
+
),
|
|
112
|
+
mix(
|
|
113
|
+
mix(dot(randomUnit(pi + o.yyx, seed), pf - o.yyx), dot(randomUnit(pi + o.xyx, seed), pf - o.xyx), sf.x),
|
|
114
|
+
mix(dot(randomUnit(pi + o.yxx, seed), pf - o.yxx), dot(randomUnit(pi + o.xxx, seed), pf - o.xxx), sf.x),
|
|
115
|
+
sf.y
|
|
116
|
+
),
|
|
117
|
+
sf.z
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
// Signed is in range [-sqrt(3/4), sqrt(3/4)], map to [0, 1]
|
|
121
|
+
return 0.5 + 0.57735026918962576*signed;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
float worleyNoise(float p, float scale, float seed) {
|
|
125
|
+
p *= scale;
|
|
126
|
+
|
|
127
|
+
float pi = floor(p);
|
|
128
|
+
float pf = fract(p);
|
|
129
|
+
|
|
130
|
+
float minDist = 1e9;
|
|
131
|
+
|
|
132
|
+
for (int index = -1; index <= 1; index++) {
|
|
133
|
+
float fi = float(index);
|
|
134
|
+
float centerToPosition = fi + random(pi + fi, seed) - pf;
|
|
135
|
+
|
|
136
|
+
minDist = min(minDist, abs(centerToPosition));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return minDist;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
float worleyNoise(vec2 p, float scale, float seed) {
|
|
143
|
+
p *= scale;
|
|
144
|
+
|
|
145
|
+
vec2 pi = floor(p);
|
|
146
|
+
vec2 pf = fract(p);
|
|
147
|
+
|
|
148
|
+
float minDist2 = 1e9;
|
|
149
|
+
|
|
150
|
+
for (int row = -1; row <= 1; row++) {
|
|
151
|
+
for (int col = -1; col <= 1; col++) {
|
|
152
|
+
vec2 index = vec2(col, row);
|
|
153
|
+
|
|
154
|
+
vec2 centerToPosition = index + random2(pi + index, seed) - pf;
|
|
155
|
+
float dist2 = dot2(centerToPosition);
|
|
156
|
+
|
|
157
|
+
minDist2 = min(minDist2, dist2);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return sqrt(minDist2);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
float worleyNoise(vec3 p, float scale, float seed) {
|
|
165
|
+
p *= scale;
|
|
166
|
+
|
|
167
|
+
vec3 pi = floor(p);
|
|
168
|
+
vec3 pf = fract(p);
|
|
169
|
+
|
|
170
|
+
float minDist2 = 1e9;
|
|
171
|
+
|
|
172
|
+
for (int row = -1; row <= 1; row++) {
|
|
173
|
+
for (int col = -1; col <= 1; col++) {
|
|
174
|
+
for (int slice = -1; slice <= 1; slice++) {
|
|
175
|
+
vec3 index = vec3(col, row, slice);
|
|
176
|
+
|
|
177
|
+
vec3 centerToPosition = index + random3(pi + index, seed) - pf;
|
|
178
|
+
float dist2 = dot2(centerToPosition);
|
|
179
|
+
|
|
180
|
+
minDist2 = min(minDist2, dist2);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return sqrt(minDist2);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Adapted version of https://iquilezles.org/articles/voronoise/
|
|
189
|
+
float voroNoise(vec2 p, float scale, float disorder, float smoothness, float seed) {
|
|
190
|
+
p *= scale;
|
|
191
|
+
|
|
192
|
+
vec2 pi = floor(p);
|
|
193
|
+
vec2 pf = fract(p);
|
|
194
|
+
|
|
195
|
+
float s = 1.0;
|
|
196
|
+
int kernel = 2;
|
|
197
|
+
|
|
198
|
+
float power = 64.0 - 63.0*pow(smoothness, 0.1);
|
|
199
|
+
|
|
200
|
+
float sum = 0.0;
|
|
201
|
+
float weightSum = 0.0;
|
|
202
|
+
|
|
203
|
+
for (int row = -kernel; row <= kernel; row++) {
|
|
204
|
+
for (int col = -kernel; col <= kernel; col++) {
|
|
205
|
+
vec2 index = vec2(col, row);
|
|
206
|
+
|
|
207
|
+
// xy is cell center, z is value
|
|
208
|
+
vec3 data = random3(pi + index, seed);
|
|
209
|
+
|
|
210
|
+
vec2 centerToPosition = index + data.xy*disorder - pf;
|
|
211
|
+
|
|
212
|
+
float dist2 = dot2(centerToPosition);
|
|
213
|
+
|
|
214
|
+
float weight = pow(smoothstep(1.0, 0.0, sqrt(0.5*dist2)), power );
|
|
215
|
+
|
|
216
|
+
sum += weight*data.z;
|
|
217
|
+
weightSum += weight;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return sum / weightSum;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
float gaboroNoise(vec2 p, float level, float scale, float radius, float freq, float hatchAmount, float hatchAngle, float seed) {
|
|
225
|
+
p *= scale;
|
|
226
|
+
|
|
227
|
+
vec2 pi = floor(p);
|
|
228
|
+
float exponent = 1. / (radius*radius);
|
|
229
|
+
|
|
230
|
+
float valueSum = 0., weightSum = 0.;
|
|
231
|
+
for (int i = -1; i <= 1; i++) {
|
|
232
|
+
for (int j = -1; j <= 1; j++) {
|
|
233
|
+
vec2 cellIndex = pi + vec2(i, j);
|
|
234
|
+
vec2 cellCenter = cellIndex + random2(cellIndex, seed);
|
|
235
|
+
|
|
236
|
+
float se = random(cellCenter, seed);
|
|
237
|
+
|
|
238
|
+
vec2 diff = p - cellCenter;
|
|
239
|
+
float rotation = PI*random(se);
|
|
240
|
+
|
|
241
|
+
float weight = exp(-exponent*dot(diff, diff));
|
|
242
|
+
|
|
243
|
+
vec2 texturePosition = diff*freq;
|
|
244
|
+
|
|
245
|
+
float value = max(triangleWave(texturePosition, rotation), hatchAmount*triangleWave(texturePosition, rotation + hatchAngle));
|
|
246
|
+
|
|
247
|
+
weightSum += weight;
|
|
248
|
+
valueSum += weight*value;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
level = mix(level, sqrt(level), hatchAmount);
|
|
253
|
+
|
|
254
|
+
return smoothstep(0.05, -0.05, valueSum / weightSum - level);
|
|
255
|
+
//return valueSum / weightSum;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
float idwNoise(float p, float power, float scale, float seed, int window) {
|
|
259
|
+
p *= scale;
|
|
260
|
+
|
|
261
|
+
float pi = floor(p);
|
|
262
|
+
|
|
263
|
+
float sum = 0.0;
|
|
264
|
+
float weightSum = 0.0;
|
|
265
|
+
float powerCoeff = -power;
|
|
266
|
+
|
|
267
|
+
for (int i = -window; i <= window; i++) {
|
|
268
|
+
float cellCorner = pi + i;
|
|
269
|
+
float value = random(cellCorner, seed);
|
|
270
|
+
|
|
271
|
+
float cellPosition = cellCorner + random(cellCorner, seed);
|
|
272
|
+
|
|
273
|
+
float w = pow(abs(p - cellPosition), powerCoeff);
|
|
274
|
+
|
|
275
|
+
if (isinf(w)) return value;
|
|
276
|
+
|
|
277
|
+
sum += w*value;
|
|
278
|
+
weightSum += w;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return sum / weightSum;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
float idwNoise(vec2 p, float power, float scale, float seed, int window) {
|
|
285
|
+
p *= scale;
|
|
286
|
+
|
|
287
|
+
vec2 pi = floor(p);
|
|
288
|
+
|
|
289
|
+
float sum = 0.0;
|
|
290
|
+
float weightSum = 0.0;
|
|
291
|
+
float powerCoeff = -0.5*power;
|
|
292
|
+
|
|
293
|
+
for (int i = -window; i <= window; i++) {
|
|
294
|
+
for (int j = -window; j <= window; j++) {
|
|
295
|
+
vec2 cellCorner = pi + vec2(i, j);
|
|
296
|
+
float value = random(cellCorner, seed);
|
|
297
|
+
|
|
298
|
+
vec2 cellPosition = cellCorner + random2(cellCorner, seed);
|
|
299
|
+
|
|
300
|
+
float w = pow(dot2(p - cellPosition), powerCoeff);
|
|
301
|
+
|
|
302
|
+
if (isinf(w)) return value;
|
|
303
|
+
|
|
304
|
+
sum += w*value;
|
|
305
|
+
weightSum += w;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return sum / weightSum;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
float idwNoise(vec3 p, float power, float scale, float seed, int window) {
|
|
313
|
+
p *= scale;
|
|
314
|
+
|
|
315
|
+
vec3 pi = floor(p);
|
|
316
|
+
|
|
317
|
+
float sum = 0.0;
|
|
318
|
+
float weightSum = 0.0;
|
|
319
|
+
float powerCoeff = -0.5*power;
|
|
320
|
+
|
|
321
|
+
for (int i = -window; i <= window; i++) {
|
|
322
|
+
for (int j = -window; j <= window; j++) {
|
|
323
|
+
for (int k = -window; k <= window; k++) {
|
|
324
|
+
vec3 cellCorner = pi + vec3(i, j, k);
|
|
325
|
+
float value = random(cellCorner, seed);
|
|
326
|
+
|
|
327
|
+
vec3 cellPosition = cellCorner + random3(cellCorner, seed);
|
|
328
|
+
|
|
329
|
+
float w = pow(dot2(p - cellPosition), powerCoeff);
|
|
330
|
+
|
|
331
|
+
if (isinf(w)) return value;
|
|
332
|
+
|
|
333
|
+
sum += w*value;
|
|
334
|
+
weightSum += w;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
return sum / weightSum;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
float standardizeOctaveNoise(float value, int octaves) {
|
|
343
|
+
float norm = clamp((float(octaves) - 1.0)/9.0, 0.0, 1.0);
|
|
344
|
+
float l = 0.25*pow(norm, 0.125);
|
|
345
|
+
return (value - l)/(1.0 - 2.0*l);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
float octaveNoise1D(float p, float scale, int octaves, float falloff, float lacunarity, float seed, float noise(float, float)) {
|
|
349
|
+
p *= scale;
|
|
350
|
+
|
|
351
|
+
float sum = 0.0;
|
|
352
|
+
float amplitude = 1.0;
|
|
353
|
+
float amplitudeSum = 0.0;
|
|
354
|
+
|
|
355
|
+
for (int i = 0; i < octaves; i++) {
|
|
356
|
+
float value = noise(p, seed + float(i));
|
|
357
|
+
sum += amplitude*value;
|
|
358
|
+
amplitudeSum += amplitude;
|
|
359
|
+
|
|
360
|
+
p = lacunarity*p + PI;
|
|
361
|
+
amplitude *= falloff;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// return standardizeOctaveNoise(sum / amplitudeSum, octaves);
|
|
365
|
+
return sum / amplitudeSum;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
float octaveNoise2D(vec2 p, float scale, int octaves, float falloff, float lacunarity, float seed, float noise(vec2, float)) {
|
|
369
|
+
p *= scale;
|
|
370
|
+
|
|
371
|
+
float sum = 0.0;
|
|
372
|
+
float amplitude = 1.0;
|
|
373
|
+
float amplitudeSum = 0.0;
|
|
374
|
+
|
|
375
|
+
for (int i = 0; i < octaves; i++) {
|
|
376
|
+
float value = noise(p, seed + float(i));
|
|
377
|
+
sum += amplitude*value;
|
|
378
|
+
amplitudeSum += amplitude;
|
|
379
|
+
|
|
380
|
+
p = rotate(lacunarity*p, 1.2);
|
|
381
|
+
amplitude *= falloff;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// return standardizeOctaveNoise(sum / amplitudeSum, octaves);
|
|
385
|
+
return sum / amplitudeSum;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
float octaveNoise3D(vec3 p, float scale, int octaves, float falloff, float lacunarity, float seed, float noise(vec3, float)) {
|
|
389
|
+
p *= scale;
|
|
390
|
+
|
|
391
|
+
float sum = 0.0;
|
|
392
|
+
float amplitude = 1.0;
|
|
393
|
+
float amplitudeSum = 0.0;
|
|
394
|
+
|
|
395
|
+
vec3 axis = vec3(0.5092382307155079, -0.23643203568934296, 0.8275121249127003);
|
|
396
|
+
|
|
397
|
+
for (int i = 0; i < octaves; i++) {
|
|
398
|
+
float value = noise(p, seed + float(i));
|
|
399
|
+
sum += amplitude*value;
|
|
400
|
+
amplitudeSum += amplitude;
|
|
401
|
+
|
|
402
|
+
p = axisAngle(lacunarity*p, axis, 1.2);
|
|
403
|
+
amplitude *= falloff;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// return standardizeOctaveNoise(sum / amplitudeSum, octaves);
|
|
407
|
+
return sum / amplitudeSum;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const randomDefinition = "\nimport { TWO_PI, PI } from \"@/constants\";\n\nexport { \n random, random2, random3,\n randomGauss,\n randomUnit\n };\n\nuint hash(uint value) {\n value ^= value >> 16;\n value *= 569420461u;\n value ^= value >> 15;\n value *= 3545902487u;\n value ^= value >> 15;\n return value;\n}\n\nuint hash(uvec2 v) {\n return hash(v.x ^ hash(v.y));\n}\n\nuint hash(uvec3 v) {\n return hash(v.x ^ hash(v.y ^ hash(v.z)));\n}\n\nuint hash(uvec4 v) {\n return hash(v.x ^ hash(v.y ^ hash(v.z ^ hash(v.w))));\n}\n\nuint hash(uvec4 v, uint u) {\n return hash(v.x ^ hash(v.y ^ hash(v.z ^ hash(v.w ^ hash(u)))));\n}\n\nfloat hashToFloat(uint u) {\n uint mant = 8388607u;\n uint one = 1065353216u;\n\n u &= mant;\n u |= one;\n\n float f = uintBitsToFloat(u);\n return f - 1.0;\n}\n\nfloat random(float p) {\n return hashToFloat(hash(floatBitsToUint(p)));\n}\n\nfloat random(vec2 p) {\n return hashToFloat(hash(floatBitsToUint(p)));\n}\n\nfloat random(vec3 p) {\n return hashToFloat(hash(floatBitsToUint(p)));\n}\n\nfloat random(vec4 p) {\n return hashToFloat(hash(floatBitsToUint(p)));\n}\n\nfloat random(float p, float seed) {\n return random(vec2(p, seed));\n}\n\nfloat random(vec2 p, float seed) {\n return random(vec3(p, seed));\n}\n\nfloat random(vec3 p, float seed) {\n return random(vec4(p, seed));\n}\n\nfloat random(vec4 p, float seed) {\n return hashToFloat(hash(floatBitsToUint(p), floatBitsToUint(seed)));\n}\n\nvec2 random2(float p, float seed) {\n return vec2(random(vec3(p, seed, 0), random(vec3(p, seed, 1))));\n}\n\nvec2 random2(float p) {\n return random2(p, 0.);\n}\n\nvec2 random2(vec2 p, float seed) {\n return vec2(random(vec4(p, seed, 0)), random(vec4(p, seed, 1)));\n}\n\nvec2 random2(vec2 p) {\n return random2(p, 0.0);\n}\n\nvec2 random2(vec3 p, float seed) {\n return vec2(random(vec4(p, seed), 0.), random(vec4(p, seed), 1.));\n}\n\nvec2 random2(vec3 p) {\n return random2(p, 0.0);\n}\n\nvec3 random3(float p, float seed) {\n return vec3(\n random(vec3(p, seed, 0)), \n random(vec3(p, seed, 1)), \n random(vec3(p, seed, 2))\n );\n}\n\nvec3 random3(float p) {\n return random3(p, 0.0);\n}\n\nvec3 random3(vec2 p, float seed) {\n return vec3(random(vec4(p, seed, 0)), random(vec4(p, seed, 1)), random(vec4(p, seed, 2)));\n}\n\nvec3 random3(vec2 p) {\n return random3(p, 0.0);\n}\n\nvec3 random3(vec3 p, float seed) {\n return vec3(random(vec4(p, seed), 0.0), random(vec4(p, seed), 1.0), random(vec4(p, seed), 2.0));\n}\n\nfloat randomGaussian(vec3 p, float seed) {\n float u1 = random(vec4(p, 1), seed);\n float u2 = random(vec4(p, 2), seed);\n return sqrt(-2.0 * log(u1)) * cos(TWO_PI * u2);\n}\n\nvec2 randomUnit(vec2 p, float seed) {\n float direction = TWO_PI*random(p, seed);\n return vec2(cos(direction), sin(direction));\n}\n\nvec3 randomUnit(vec3 p, float seed) {\n return normalize(vec3(\n randomGaussian(p, seed),\n randomGaussian(p, random(seed, 1.)),\n randomGaussian(p, random(seed, 2.))\n ));\n}\n\n\n\n";
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
export const randomDefinition = /*glsl*/ `
|
|
2
|
+
import { TWO_PI, PI } from "@/constants";
|
|
3
|
+
|
|
4
|
+
export {
|
|
5
|
+
random, random2, random3,
|
|
6
|
+
randomGauss,
|
|
7
|
+
randomUnit
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
uint hash(uint value) {
|
|
11
|
+
value ^= value >> 16;
|
|
12
|
+
value *= 569420461u;
|
|
13
|
+
value ^= value >> 15;
|
|
14
|
+
value *= 3545902487u;
|
|
15
|
+
value ^= value >> 15;
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
uint hash(uvec2 v) {
|
|
20
|
+
return hash(v.x ^ hash(v.y));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
uint hash(uvec3 v) {
|
|
24
|
+
return hash(v.x ^ hash(v.y ^ hash(v.z)));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
uint hash(uvec4 v) {
|
|
28
|
+
return hash(v.x ^ hash(v.y ^ hash(v.z ^ hash(v.w))));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
uint hash(uvec4 v, uint u) {
|
|
32
|
+
return hash(v.x ^ hash(v.y ^ hash(v.z ^ hash(v.w ^ hash(u)))));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
float hashToFloat(uint u) {
|
|
36
|
+
uint mant = 8388607u;
|
|
37
|
+
uint one = 1065353216u;
|
|
38
|
+
|
|
39
|
+
u &= mant;
|
|
40
|
+
u |= one;
|
|
41
|
+
|
|
42
|
+
float f = uintBitsToFloat(u);
|
|
43
|
+
return f - 1.0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
float random(float p) {
|
|
47
|
+
return hashToFloat(hash(floatBitsToUint(p)));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
float random(vec2 p) {
|
|
51
|
+
return hashToFloat(hash(floatBitsToUint(p)));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
float random(vec3 p) {
|
|
55
|
+
return hashToFloat(hash(floatBitsToUint(p)));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
float random(vec4 p) {
|
|
59
|
+
return hashToFloat(hash(floatBitsToUint(p)));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
float random(float p, float seed) {
|
|
63
|
+
return random(vec2(p, seed));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
float random(vec2 p, float seed) {
|
|
67
|
+
return random(vec3(p, seed));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
float random(vec3 p, float seed) {
|
|
71
|
+
return random(vec4(p, seed));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
float random(vec4 p, float seed) {
|
|
75
|
+
return hashToFloat(hash(floatBitsToUint(p), floatBitsToUint(seed)));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
vec2 random2(float p, float seed) {
|
|
79
|
+
return vec2(random(vec3(p, seed, 0), random(vec3(p, seed, 1))));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
vec2 random2(float p) {
|
|
83
|
+
return random2(p, 0.);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
vec2 random2(vec2 p, float seed) {
|
|
87
|
+
return vec2(random(vec4(p, seed, 0)), random(vec4(p, seed, 1)));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
vec2 random2(vec2 p) {
|
|
91
|
+
return random2(p, 0.0);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
vec2 random2(vec3 p, float seed) {
|
|
95
|
+
return vec2(random(vec4(p, seed), 0.), random(vec4(p, seed), 1.));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
vec2 random2(vec3 p) {
|
|
99
|
+
return random2(p, 0.0);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
vec3 random3(float p, float seed) {
|
|
103
|
+
return vec3(
|
|
104
|
+
random(vec3(p, seed, 0)),
|
|
105
|
+
random(vec3(p, seed, 1)),
|
|
106
|
+
random(vec3(p, seed, 2))
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
vec3 random3(float p) {
|
|
111
|
+
return random3(p, 0.0);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
vec3 random3(vec2 p, float seed) {
|
|
115
|
+
return vec3(random(vec4(p, seed, 0)), random(vec4(p, seed, 1)), random(vec4(p, seed, 2)));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
vec3 random3(vec2 p) {
|
|
119
|
+
return random3(p, 0.0);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
vec3 random3(vec3 p, float seed) {
|
|
123
|
+
return vec3(random(vec4(p, seed), 0.0), random(vec4(p, seed), 1.0), random(vec4(p, seed), 2.0));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
float randomGaussian(vec3 p, float seed) {
|
|
127
|
+
float u1 = random(vec4(p, 1), seed);
|
|
128
|
+
float u2 = random(vec4(p, 2), seed);
|
|
129
|
+
return sqrt(-2.0 * log(u1)) * cos(TWO_PI * u2);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
vec2 randomUnit(vec2 p, float seed) {
|
|
133
|
+
float direction = TWO_PI*random(p, seed);
|
|
134
|
+
return vec2(cos(direction), sin(direction));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
vec3 randomUnit(vec3 p, float seed) {
|
|
138
|
+
return normalize(vec3(
|
|
139
|
+
randomGaussian(p, seed),
|
|
140
|
+
randomGaussian(p, random(seed, 1.)),
|
|
141
|
+
randomGaussian(p, random(seed, 2.))
|
|
142
|
+
));
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const rayMarchingDefinition = "\n\nexport {\n rayMarch,\n Ray, RayMarchResult\n}\n\nstruct Ray {\n vec3 origin;\n vec3 direction;\n};\n\nstruct RayMarchResult {\n vec3 position;\n vec3 partialPosition;\n float minimumDistance;\n bool hit;\n};\n\nRayMarchResult rayMarch(Ray ray, float minThreshold, float maxThreshold, int partialIterations, float maxIterations, float sdf(vec3)) {\n vec3 position;\n float t = 0.0;\n\n vec3 origin = ray.origin;\n vec3 direction = ray.direction;\n \n vec3 partialPosition;\n float minimumDistance = 1e20;\n bool hit = false;\n\n int n = int(maxIterations) + 1;\n for (int i = 0; i <= n; i++) {\n position = origin + direction*t;\n float d = sdf(position);\n\n if (i == partialIterations) partialPosition = position;\n\n t += d*min(1.0, maxIterations - float(i));\n minimumDistance = min(minimumDistance, d);\n\n if (abs(d) < minThreshold) {\n hit = true;\n break;\n } \n \n if (d > maxThreshold) {\n break;\n }\n }\n \n return RayMarchResult(position, partialPosition, minimumDistance, hit);\n}\n\n";
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export const rayMarchingDefinition = /*glsl*/ `
|
|
2
|
+
|
|
3
|
+
export {
|
|
4
|
+
rayMarch,
|
|
5
|
+
Ray, RayMarchResult
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
struct Ray {
|
|
9
|
+
vec3 origin;
|
|
10
|
+
vec3 direction;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
struct RayMarchResult {
|
|
14
|
+
vec3 position;
|
|
15
|
+
vec3 partialPosition;
|
|
16
|
+
float minimumDistance;
|
|
17
|
+
bool hit;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
RayMarchResult rayMarch(Ray ray, float minThreshold, float maxThreshold, int partialIterations, float maxIterations, float sdf(vec3)) {
|
|
21
|
+
vec3 position;
|
|
22
|
+
float t = 0.0;
|
|
23
|
+
|
|
24
|
+
vec3 origin = ray.origin;
|
|
25
|
+
vec3 direction = ray.direction;
|
|
26
|
+
|
|
27
|
+
vec3 partialPosition;
|
|
28
|
+
float minimumDistance = 1e20;
|
|
29
|
+
bool hit = false;
|
|
30
|
+
|
|
31
|
+
int n = int(maxIterations) + 1;
|
|
32
|
+
for (int i = 0; i <= n; i++) {
|
|
33
|
+
position = origin + direction*t;
|
|
34
|
+
float d = sdf(position);
|
|
35
|
+
|
|
36
|
+
if (i == partialIterations) partialPosition = position;
|
|
37
|
+
|
|
38
|
+
t += d*min(1.0, maxIterations - float(i));
|
|
39
|
+
minimumDistance = min(minimumDistance, d);
|
|
40
|
+
|
|
41
|
+
if (abs(d) < minThreshold) {
|
|
42
|
+
hit = true;
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (d > maxThreshold) {
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return RayMarchResult(position, partialPosition, minimumDistance, hit);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const sdfDefinition = "\n\nimport { barycentric, transformToZAxis, rotate } from \"@/geometry\";\nimport { lerp, signed, dot2 } from \"@/utils\";\nimport { PI } from \"@/constants\";\n\nexport {\n sphere, box, rectangularCylinder, \n discoBall, donut, boxFrame,\n triangleSDFSquared, meshSDF, regularPolygon,\n polygon, lineSegment\n}\n\nfloat sphere(vec3 p, vec3 center, float radius) {\n return length(p - center) - radius;\n}\n\nfloat box(vec3 p, vec3 center, vec3 direction, vec3 size) {\n p = transformToZAxis(p, center, direction, 0.0);\n p = abs(p) - size/2.0;\n\n // First part gives distance inside box, second part outside\n return min(max(max(p.x, p.y), p.z), 0.0) + length(max(p, vec3(0)));\n}\n\nfloat rectangularCylinder(vec3 p, vec3 center, vec3 direction, vec2 size, float height, bool offsetCenter, float rotation) {\n if (offsetCenter) center += 0.5*height*normalize(direction);\n p = transformToZAxis(p, center, direction, rotation);\n return box(p, vec3(0), vec3(0, 0, 1), vec3(size, height));\n}\n\nfloat discoBall(vec3 p, vec3 center, float radius, float n, float o) {\n p -= center;\n float phi = -PI + 2.0*PI*(round(lerp(atan(p.y, p.x), -PI, PI)*n)/n + o);\n float theta = PI*(round(lerp(acos(p.z/length(p)), 0.0, PI)*n)/n + o);\n\n vec3 bp = vec3(sin(theta)*cos(phi), sin(theta)*sin(phi), cos(theta));\n\n return dot(bp, p - radius*bp);\n}\n\nfloat discoBall(vec3 p, vec3 center, float radius, float n) {\n return discoBall(p, center, radius, n, 0.0);\n}\n\nfloat regularPolygon(vec2 p, float radius, float n) {\n float theta = PI*signed((floor(lerp(atan(p.y, p.x), -PI, PI)*n) + .5)/n);\n vec2 pp = vec2(cos(theta), sin(theta));\n return dot(pp, p - radius*pp);\n}\n\nfloat polygon(vec2 p, sampler2D vertices, int startIndex, int endIndex, int total) {\n float nf = float(total);\n float sf = float(startIndex);\n float ef = float(endIndex);\n float minDistSquared = 1e9;\n float textureStep = 1.0 / nf;\n float winding = 0.0; // >0 \u2192 inside for CCW, <0 \u2192 inside for CW\n\n vec2 start = texture(vertices, vec2((sf + 0.5) * textureStep, 0.5)).xy;\n\n for (float i = sf + 1.0; i <= ef; i++) {\n float idx = mod(i + 0.5, nf); \n vec2 end = texture(vertices, vec2(idx * textureStep, 0.5)).xy;\n\n // Distance to segment (start to end)\n vec2 seg = end - start;\n vec2 rel = p - start;\n float t = clamp(dot(rel, seg) / dot(seg, seg), 0.0, 1.0);\n float d2 = dot2(rel - seg*t);\n minDistSquared = min(minDistSquared, d2);\n\n // Portion for finding out if point is inside polygon\n // Equivalent to classic point-in-polygon test:\n // Does segment cross horizontal ray to the right of p?\n bool aboveA = start.y > p.y;\n bool aboveB = end.y > p.y;\n // Sign: +1 when edge crosses in one direction, -1 in the opposite\n if (aboveA != aboveB) {\n float xCross = (end.x - start.x) * (p.y - start.y) / (end.y - start.y) + start.x;\n if (xCross > p.x) {\n winding += aboveB ? -1.0 : 1.0;\n }\n }\n\n start = end;\n }\n\n float signValue = (winding == 0.0 ? 1.0 : -1.0);\n return signValue * sqrt(minDistSquared);\n}\n\n\nfloat donut(vec3 p, vec3 center, vec3 direction, float innerRadius, float outerRadius, float rotation, float sections, float sides) {\n p = transformToZAxis(p, center, direction, 0.0);\n\n vec3 xy = normalize(vec3(p.xy, 0));\n float angle = mod(atan(xy.y, xy.x), 2.*PI);\n\n angle = 2.*PI*round(sections*angle/(2.*PI))/sections;\n innerRadius *= sqrt(PI/(sections*tan(PI/sections)));\n outerRadius *= sqrt(PI/(sides*tan(PI/sides)));\n return regularPolygon(rotate(vec2(dot(p, vec3(cos(angle), sin(angle), 0)) - innerRadius, p.z), rotation + 0.25*PI), outerRadius, sides);\n}\n\nfloat boxFrame(vec3 p, vec3 center, vec3 direction, vec3 size, float thickness) {\n float dBox = box(p, center, direction, size);\n\n p = transformToZAxis(p, center, direction, 0.0);\n\n vec3 o = 2.0*vec3(thickness, thickness, -1e9);\n float dX = box(p, vec3(0), vec3(1, 0, 0), size.yzx - o);\n float dY = box(p, vec3(0), vec3(0, 1, 0), size.zxy - o);\n float dZ = box(p, vec3(0), vec3(0, 0, 1), size.xyz - o);\n\n float dInner = min(dX, min(dY, dZ));\n return max(dBox, -dInner);\n}\n\n// x is distance squared, y indicates which side of triangle p is on \n// (relative to normal: positive if p is above, negative if below)\nvec2 triangleSDFSquared(vec3 p, vec3 a, vec3 b, vec3 c) {\n vec3 ab = b - a;\n vec3 ca = a - c;\n vec3 bc = c - b;\n\n vec3 ap = p - a;\n vec3 bp = p - b;\n vec3 cp = p - c;\n\n vec3 normal = normalize(cross(ab, -ca)); // Negate to make cross(ab, ac), follows right-hand rule assuming abc is CCW\n \n bool isInsideTriangle = all(greaterThan(barycentric(p, a, b, c), vec3(0)));\n bool isInsideXYProjection = abs(normal.z) > 1e-5 && all(greaterThan(barycentric(p.xy, a.xy, b.xy, c.xy), vec3(0)));\n\n float distSquared;\n bool isAboveXYProjection;\n\n // If p is above XY projection, then dist = dot(ap, normal) > 0 when normal points upwards\n // and dist < 0 when it points downwards. sign(normal.z)*dist > 0.0 then tells us if p is above \n if (isInsideTriangle) {\n float dist = dot(ap, normal);\n distSquared = dist*dist;\n isAboveXYProjection = isInsideXYProjection && sign(normal.z)*dist > 0.0;\n } else {\n distSquared = min(min(\n dot2(ap - ab*clamp(dot(ap, ab) / dot2(ab), 0.0, 1.0)),\n dot2(bp - bc*clamp(dot(bp, bc) / dot2(bc), 0.0, 1.0))),\n dot2(cp - ca*clamp(dot(cp, ca) / dot2(ca), 0.0, 1.0))\n );\n isAboveXYProjection = isInsideXYProjection && sign(normal.z)*dot(ap, normal) > 0.0;\n }\n\n return vec2(distSquared, isAboveXYProjection ? -1.0 : 1.0);\n}\n\nfloat lineSegment(vec2 p, vec2 a, vec2 b, float o) {\n vec2 ap = p - a;\n vec2 ab = b - a;\n \n float t = clamp(dot(ap, ab)/dot(ab, ab), 0.0, 1.0);\n\n return length(ap - ab*t) - o;\n}\n\nfloat lineSegment(vec2 p, vec2 a, vec2 b) {\n return lineSegment(p, a, b, 0.0);\n}\n\nfloat lineSegment(vec3 p, vec2 a, vec2 b, float o) {\n vec3 ap = p - a;\n vec3 ab = b - a;\n \n float t = clamp(dot(ap, ab)/dot(ab, ab), 0.0, 1.0);\n\n return length(ap - ab*t) - o;\n}\n\nfloat lineSegment(vec3 p, vec2 a, vec2 b) {\n return lineSegment(p, a, b, 0.0);\n}\n\n";
|