@takram/three-geospatial 0.0.1-alpha.5 → 0.0.1-alpha.7

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.
Files changed (47) hide show
  1. package/build/index.cjs +1 -43
  2. package/build/index.cjs.map +1 -1
  3. package/build/index.js +403 -787
  4. package/build/index.js.map +1 -1
  5. package/build/r3f.js +2 -2
  6. package/build/shaders.cjs +397 -0
  7. package/build/shaders.cjs.map +1 -0
  8. package/build/shaders.js +408 -0
  9. package/build/shaders.js.map +1 -0
  10. package/package.json +7 -3
  11. package/src/DataLoader.ts +1 -0
  12. package/src/STBNLoader.ts +21 -0
  13. package/src/Texture3DLoader.ts +81 -0
  14. package/src/bufferGeometry.ts +2 -2
  15. package/src/constants.ts +6 -0
  16. package/src/defineShorthand.ts +68 -0
  17. package/src/index.ts +5 -10
  18. package/src/math.ts +36 -1
  19. package/src/r3f/index.ts +1 -0
  20. package/src/r3f/types.ts +63 -0
  21. package/src/resolveIncludes.test.ts +21 -0
  22. package/src/resolveIncludes.ts +22 -0
  23. package/src/shaders/cascadedShadowMaps.glsl +79 -0
  24. package/src/shaders/depth.glsl +3 -1
  25. package/src/shaders/generators.glsl +9 -0
  26. package/src/shaders/index.ts +19 -0
  27. package/src/shaders/math.glsl +92 -0
  28. package/src/shaders/poissonDisk.glsl +23 -0
  29. package/src/shaders/raySphereIntersection.glsl +134 -0
  30. package/src/shaders/turbo.glsl +9 -0
  31. package/src/typedArrayParsers.ts +19 -8
  32. package/src/types.ts +5 -51
  33. package/src/unrollLoops.ts +23 -0
  34. package/types/DataLoader.d.ts +4 -4
  35. package/types/STBNLoader.d.ts +1 -0
  36. package/types/Texture3DLoader.d.ts +5 -0
  37. package/types/TypedArrayLoader.d.ts +3 -3
  38. package/types/constants.d.ts +4 -0
  39. package/types/defineShorthand.d.ts +16 -0
  40. package/types/index.d.ts +5 -3
  41. package/types/math.d.ts +4 -1
  42. package/types/r3f/index.d.ts +1 -0
  43. package/types/r3f/types.d.ts +21 -0
  44. package/types/resolveIncludes.d.ts +5 -0
  45. package/types/shaders/index.d.ts +9 -0
  46. package/types/types.d.ts +5 -20
  47. package/types/unrollLoops.d.ts +1 -0
@@ -0,0 +1,408 @@
1
+ const n = `// Reference: https://github.com/mrdoob/three.js/blob/r171/examples/jsm/csm/CSMShader.js
2
+
3
+ #ifndef SHADOW_CASCADE_COUNT
4
+ #error "SHADOW_CASCADE_COUNT macro must be defined."
5
+ #endif // SHADOW_CASCADE_COUNT
6
+
7
+ int getCascadeIndex(
8
+ const mat4 viewMatrix,
9
+ const vec3 worldPosition,
10
+ const vec2 intervals[SHADOW_CASCADE_COUNT],
11
+ const float near,
12
+ const float far
13
+ ) {
14
+ vec4 viewPosition = viewMatrix * vec4(worldPosition, 1.0);
15
+ float depth = viewZToOrthographicDepth(viewPosition.z, near, far);
16
+ vec2 interval;
17
+ #pragma unroll_loop_start
18
+ for (int i = 0; i < 4; ++i) {
19
+ #if UNROLLED_LOOP_INDEX < SHADOW_CASCADE_COUNT
20
+ interval = intervals[i];
21
+ if (depth >= interval.x && depth < interval.y) {
22
+ return UNROLLED_LOOP_INDEX;
23
+ }
24
+ #endif // UNROLLED_LOOP_INDEX < SHADOW_CASCADE_COUNT
25
+ }
26
+ #pragma unroll_loop_end
27
+ return SHADOW_CASCADE_COUNT - 1;
28
+ }
29
+
30
+ int getFadedCascadeIndex(
31
+ const mat4 viewMatrix,
32
+ const vec3 worldPosition,
33
+ const vec2 intervals[SHADOW_CASCADE_COUNT],
34
+ const float near,
35
+ const float far,
36
+ const float jitter
37
+ ) {
38
+ vec4 viewPosition = viewMatrix * vec4(worldPosition, 1.0);
39
+ float depth = viewZToOrthographicDepth(viewPosition.z, near, far);
40
+
41
+ vec2 interval;
42
+ float intervalCenter;
43
+ float closestEdge;
44
+ float margin;
45
+ int nextIndex = -1;
46
+ int prevIndex = -1;
47
+ float alpha;
48
+
49
+ #pragma unroll_loop_start
50
+ for (int i = 0; i < 4; ++i) {
51
+ #if UNROLLED_LOOP_INDEX < SHADOW_CASCADE_COUNT
52
+ interval = intervals[i];
53
+ intervalCenter = (interval.x + interval.y) * 0.5;
54
+ closestEdge = depth < intervalCenter ? interval.x : interval.y;
55
+ margin = closestEdge * closestEdge * 0.5;
56
+ interval += margin * vec2(-0.5, 0.5);
57
+
58
+ #if UNROLLED_LOOP_INDEX < SHADOW_CASCADE_COUNT - 1
59
+ if (depth >= interval.x && depth < interval.y) {
60
+ prevIndex = nextIndex;
61
+ nextIndex = UNROLLED_LOOP_INDEX;
62
+ alpha = saturate(min(depth - interval.x, interval.y - depth) / margin);
63
+ }
64
+ #else // UNROLLED_LOOP_INDEX < SHADOW_CASCADE_COUNT - 1
65
+ // Don't fade out the last cascade.
66
+ if (depth >= interval.x) {
67
+ prevIndex = nextIndex;
68
+ nextIndex = UNROLLED_LOOP_INDEX;
69
+ alpha = saturate((depth - interval.x) / margin);
70
+ }
71
+ #endif // UNROLLED_LOOP_INDEX < SHADOW_CASCADE_COUNT - 1
72
+ #endif // UNROLLED_LOOP_INDEX < SHADOW_CASCADE_COUNT
73
+ }
74
+ #pragma unroll_loop_end
75
+
76
+ return jitter <= alpha
77
+ ? nextIndex
78
+ : prevIndex;
79
+ }
80
+ `, e = `// cSpell:words logdepthbuf
81
+
82
+ float reverseLogDepth(const float depth, const float near, const float far) {
83
+ #ifdef USE_LOGDEPTHBUF
84
+ float d = pow(2.0, depth * log2(far + 1.0)) - 1.0;
85
+ float a = far / (far - near);
86
+ float b = far * near / (near - far);
87
+ return a + b / d;
88
+ #else // USE_LOGDEPTHBUF
89
+ return depth;
90
+ #endif // USE_LOGDEPTHBUF
91
+ }
92
+
93
+ float linearizeDepth(const float depth, const float near, const float far) {
94
+ float ndc = depth * 2.0 - 1.0;
95
+ return 2.0 * near * far / (far + near - ndc * (far - near));
96
+ }
97
+ `, t = `float checker(const vec2 uv, const vec2 repeats) {
98
+ vec2 c = floor(repeats * uv);
99
+ float result = mod(c.x + c.y, 2.0);
100
+ return sign(result);
101
+ }
102
+
103
+ float checker(const vec2 uv, const float repeats) {
104
+ return checker(uv, vec2(repeats));
105
+ }
106
+ `, c = `#if !defined(saturate)
107
+ #define saturate(a) clamp(a, 0.0, 1.0)
108
+ #endif // !defined(saturate)
109
+
110
+ float remap(const float x, const float min1, const float max1, const float min2, const float max2) {
111
+ return min2 + (x - min1) / (max1 - min1) * (max2 - min2);
112
+ }
113
+
114
+ vec2 remap(const vec2 x, const vec2 min1, const vec2 max1, const vec2 min2, const vec2 max2) {
115
+ return min2 + (x - min1) / (max1 - min1) * (max2 - min2);
116
+ }
117
+
118
+ vec3 remap(const vec3 x, const vec3 min1, const vec3 max1, const vec3 min2, const vec3 max2) {
119
+ return min2 + (x - min1) / (max1 - min1) * (max2 - min2);
120
+ }
121
+
122
+ vec4 remap(const vec4 x, const vec4 min1, const vec4 max1, const vec4 min2, const vec4 max2) {
123
+ return min2 + (x - min1) / (max1 - min1) * (max2 - min2);
124
+ }
125
+
126
+ float remapClamped(
127
+ const float x,
128
+ const float min1,
129
+ const float max1,
130
+ const float min2,
131
+ const float max2
132
+ ) {
133
+ return clamp(min2 + (x - min1) / (max1 - min1) * (max2 - min2), min2, max2);
134
+ }
135
+
136
+ vec2 remapClamped(
137
+ const vec2 x,
138
+ const vec2 min1,
139
+ const vec2 max1,
140
+ const vec2 min2,
141
+ const vec2 max2
142
+ ) {
143
+ return clamp(min2 + (x - min1) / (max1 - min1) * (max2 - min2), min2, max2);
144
+ }
145
+
146
+ vec3 remapClamped(
147
+ const vec3 x,
148
+ const vec3 min1,
149
+ const vec3 max1,
150
+ const vec3 min2,
151
+ const vec3 max2
152
+ ) {
153
+ return clamp(min2 + (x - min1) / (max1 - min1) * (max2 - min2), min2, max2);
154
+ }
155
+
156
+ vec4 remapClamped(
157
+ const vec4 x,
158
+ const vec4 min1,
159
+ const vec4 max1,
160
+ const vec4 min2,
161
+ const vec4 max2
162
+ ) {
163
+ return clamp(min2 + (x - min1) / (max1 - min1) * (max2 - min2), min2, max2);
164
+ }
165
+
166
+ // Implicitly remap to 0 and 1
167
+ float remap(const float x, const float min1, const float max1) {
168
+ return (x - min1) / (max1 - min1);
169
+ }
170
+
171
+ vec2 remap(const vec2 x, const vec2 min1, const vec2 max1) {
172
+ return (x - min1) / (max1 - min1);
173
+ }
174
+
175
+ vec3 remap(const vec3 x, const vec3 min1, const vec3 max1) {
176
+ return (x - min1) / (max1 - min1);
177
+ }
178
+
179
+ vec4 remap(const vec4 x, const vec4 min1, const vec4 max1) {
180
+ return (x - min1) / (max1 - min1);
181
+ }
182
+
183
+ float remapClamped(const float x, const float min1, const float max1) {
184
+ return saturate((x - min1) / (max1 - min1));
185
+ }
186
+
187
+ vec2 remapClamped(const vec2 x, const vec2 min1, const vec2 max1) {
188
+ return saturate((x - min1) / (max1 - min1));
189
+ }
190
+
191
+ vec3 remapClamped(const vec3 x, const vec3 min1, const vec3 max1) {
192
+ return saturate((x - min1) / (max1 - min1));
193
+ }
194
+
195
+ vec4 remapClamped(const vec4 x, const vec4 min1, const vec4 max1) {
196
+ return saturate((x - min1) / (max1 - min1));
197
+ }
198
+ `, i = `// Reference: https://jcgt.org/published/0003/02/01/paper.pdf
199
+
200
+ vec2 signNotZero(vec2 v) {
201
+ return vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0);
202
+ }
203
+
204
+ vec2 packNormalToVec2(vec3 v) {
205
+ vec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z)));
206
+ return v.z <= 0.0
207
+ ? (1.0 - abs(p.yx)) * signNotZero(p)
208
+ : p;
209
+ }
210
+
211
+ vec3 unpackVec2ToNormal(vec2 e) {
212
+ vec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));
213
+ if (v.z < 0.0) {
214
+ v.xy = (1.0 - abs(v.yx)) * signNotZero(v.xy);
215
+ }
216
+ return normalize(v);
217
+ }
218
+ `, o = `// TODO: Maybe switch to Vogel disk with IGN:
219
+ // https://www.gamedev.net/tutorials/programming/graphics/contact-hardening-soft-shadows-made-fast-r4906/
220
+ // Taken from: https://developer.download.nvidia.com/whitepapers/2008/PCSS_Integration.pdf
221
+ const vec2 poissonDisk[16] = vec2[16](
222
+ vec2(-0.94201624, -0.39906216),
223
+ vec2(0.94558609, -0.76890725),
224
+ vec2(-0.094184101, -0.9293887),
225
+ vec2(0.34495938, 0.2938776),
226
+ vec2(-0.91588581, 0.45771432),
227
+ vec2(-0.81544232, -0.87912464),
228
+ vec2(-0.38277543, 0.27676845),
229
+ vec2(0.97484398, 0.75648379),
230
+ vec2(0.44323325, -0.97511554),
231
+ vec2(0.53742981, -0.4737342),
232
+ vec2(-0.26496911, -0.41893023),
233
+ vec2(0.79197514, 0.19090188),
234
+ vec2(-0.2418884, 0.99706507),
235
+ vec2(-0.81409955, 0.9143759),
236
+ vec2(0.19984126, 0.78641367),
237
+ vec2(0.14383161, -0.1410079)
238
+ );
239
+
240
+ #define POISSON_DISK_COUNT (16)
241
+ `, r = `float raySphereFirstIntersection(
242
+ const vec3 origin,
243
+ const vec3 direction,
244
+ const vec3 center,
245
+ const float radius
246
+ ) {
247
+ vec3 a = origin - center;
248
+ float b = 2.0 * dot(direction, a);
249
+ float c = dot(a, a) - radius * radius;
250
+ float discriminant = b * b - 4.0 * c;
251
+ return discriminant < 0.0
252
+ ? -1.0
253
+ : (-b - sqrt(discriminant)) * 0.5;
254
+ }
255
+
256
+ float raySphereFirstIntersection(const vec3 origin, const vec3 direction, const float radius) {
257
+ return raySphereFirstIntersection(origin, direction, vec3(0.0), radius);
258
+ }
259
+
260
+ vec4 raySphereFirstIntersection(
261
+ const vec3 origin,
262
+ const vec3 direction,
263
+ const vec3 center,
264
+ const vec4 radius
265
+ ) {
266
+ vec3 a = origin - center;
267
+ float b = 2.0 * dot(direction, a);
268
+ vec4 c = dot(a, a) - radius * radius;
269
+ vec4 discriminant = b * b - 4.0 * c;
270
+ vec4 mask = step(discriminant, vec4(0.0));
271
+ return mix((-b - sqrt(max(vec4(0.0), discriminant))) * 0.5, vec4(-1.0), mask);
272
+ }
273
+
274
+ vec4 raySphereFirstIntersection(const vec3 origin, const vec3 direction, const vec4 radius) {
275
+ return raySphereFirstIntersection(origin, direction, vec3(0.0), radius);
276
+ }
277
+
278
+ float raySphereSecondIntersection(
279
+ const vec3 origin,
280
+ const vec3 direction,
281
+ const vec3 center,
282
+ const float radius
283
+ ) {
284
+ vec3 a = origin - center;
285
+ float b = 2.0 * dot(direction, a);
286
+ float c = dot(a, a) - radius * radius;
287
+ float discriminant = b * b - 4.0 * c;
288
+ return discriminant < 0.0
289
+ ? -1.0
290
+ : (-b + sqrt(discriminant)) * 0.5;
291
+ }
292
+
293
+ float raySphereSecondIntersection(const vec3 origin, const vec3 direction, const float radius) {
294
+ return raySphereSecondIntersection(origin, direction, vec3(0.0), radius);
295
+ }
296
+
297
+ vec4 raySphereSecondIntersection(
298
+ const vec3 origin,
299
+ const vec3 direction,
300
+ const vec3 center,
301
+ const vec4 radius
302
+ ) {
303
+ vec3 a = origin - center;
304
+ float b = 2.0 * dot(direction, a);
305
+ vec4 c = dot(a, a) - radius * radius;
306
+ vec4 discriminant = b * b - 4.0 * c;
307
+ vec4 mask = step(discriminant, vec4(0.0));
308
+ return mix((-b + sqrt(max(vec4(0.0), discriminant))) * 0.5, vec4(-1.0), mask);
309
+ }
310
+
311
+ vec4 raySphereSecondIntersection(const vec3 origin, const vec3 direction, const vec4 radius) {
312
+ return raySphereSecondIntersection(origin, direction, vec3(0.0), radius);
313
+ }
314
+
315
+ void raySphereIntersections(
316
+ const vec3 origin,
317
+ const vec3 direction,
318
+ const vec3 center,
319
+ const float radius,
320
+ out float intersection1,
321
+ out float intersection2
322
+ ) {
323
+ vec3 a = origin - center;
324
+ float b = 2.0 * dot(direction, a);
325
+ float c = dot(a, a) - radius * radius;
326
+ float discriminant = b * b - 4.0 * c;
327
+ if (discriminant < 0.0) {
328
+ intersection1 = -1.0;
329
+ intersection2 = -1.0;
330
+ return;
331
+ } else {
332
+ float Q = sqrt(discriminant);
333
+ intersection1 = (-b - Q) * 0.5;
334
+ intersection2 = (-b + Q) * 0.5;
335
+ }
336
+ }
337
+
338
+ void raySphereIntersections(
339
+ const vec3 origin,
340
+ const vec3 direction,
341
+ const float radius,
342
+ out float intersection1,
343
+ out float intersection2
344
+ ) {
345
+ raySphereIntersections(origin, direction, vec3(0.0), radius, intersection1, intersection2);
346
+ }
347
+
348
+ void raySphereIntersections(
349
+ const vec3 origin,
350
+ const vec3 direction,
351
+ const vec3 center,
352
+ const vec4 radius,
353
+ out vec4 intersection1,
354
+ out vec4 intersection2
355
+ ) {
356
+ vec3 a = origin - center;
357
+ float b = 2.0 * dot(direction, a);
358
+ vec4 c = dot(a, a) - radius * radius;
359
+ vec4 discriminant = b * b - 4.0 * c;
360
+ vec4 mask = step(discriminant, vec4(0.0));
361
+ vec4 Q = sqrt(max(vec4(0.0), discriminant));
362
+ intersection1 = mix((-b - Q) * 0.5, vec4(-1.0), mask);
363
+ intersection2 = mix((-b + Q) * 0.5, vec4(-1.0), mask);
364
+ }
365
+
366
+ void raySphereIntersections(
367
+ const vec3 origin,
368
+ const vec3 direction,
369
+ const vec4 radius,
370
+ out vec4 intersection1,
371
+ out vec4 intersection2
372
+ ) {
373
+ raySphereIntersections(origin, direction, vec3(0.0), radius, intersection1, intersection2);
374
+ }
375
+ `, a = `vec3 screenToView(
376
+ const vec2 uv,
377
+ const float depth,
378
+ const float viewZ,
379
+ const mat4 projectionMatrix,
380
+ const mat4 inverseProjectionMatrix
381
+ ) {
382
+ vec4 clip = vec4(vec3(uv, depth) * 2.0 - 1.0, 1.0);
383
+ float clipW = projectionMatrix[2][3] * viewZ + projectionMatrix[3][3];
384
+ clip *= clipW;
385
+ return (inverseProjectionMatrix * clip).xyz;
386
+ }
387
+ `, s = `// A fifth-order polynomial approximation of Turbo color map.
388
+ // See: https://observablehq.com/@mbostock/turbo
389
+ // prettier-ignore
390
+ vec3 turbo(const float x) {
391
+ float r = 0.1357 + x * (4.5974 - x * (42.3277 - x * (130.5887 - x * (150.5666 - x * 58.1375))));
392
+ float g = 0.0914 + x * (2.1856 + x * (4.8052 - x * (14.0195 - x * (4.2109 + x * 2.7747))));
393
+ float b = 0.1067 + x * (12.5925 - x * (60.1097 - x * (109.0745 - x * (88.5066 - x * 26.8183))));
394
+ return vec3(r, g, b);
395
+ }
396
+ `, v = n, m = e, d = t, l = c, x = i, p = o, f = r, u = a, h = s;
397
+ export {
398
+ v as cascadedShadowMaps,
399
+ m as depth,
400
+ d as generators,
401
+ l as math,
402
+ x as packing,
403
+ p as poissonDisk,
404
+ f as raySphereIntersection,
405
+ u as transform,
406
+ h as turbo
407
+ };
408
+ //# sourceMappingURL=shaders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shaders.js","sources":["../src/shaders/cascadedShadowMaps.glsl?raw","../src/shaders/depth.glsl?raw","../src/shaders/generators.glsl?raw","../src/shaders/math.glsl?raw","../src/shaders/packing.glsl?raw","../src/shaders/poissonDisk.glsl?raw","../src/shaders/raySphereIntersection.glsl?raw","../src/shaders/transform.glsl?raw","../src/shaders/turbo.glsl?raw","../src/shaders/index.ts"],"sourcesContent":null,"names":["_cascadedShadowMaps","_depth","_generators","_math","_packing","_poissonDisk","_raySphereIntersection","_transform","_turbo","cascadedShadowMaps","depth","generators","math","packing","poissonDisk","raySphereIntersection","transform","turbo"],"mappings":"AAAA,MAAeA,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GCAAC,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GCAAC,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GCAAC,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GCAAC,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GCAAC,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GCAAC,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GCAAC,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GCAAC,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GCUFC,IAA6BT,GAC7BU,IAAgBT,GAChBU,IAAqBT,GACrBU,IAAeT,GACfU,IAAkBT,GAClBU,IAAsBT,GACtBU,IAAgCT,GAChCU,IAAoBT,GACpBU,IAAgBT;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@takram/three-geospatial",
3
- "version": "0.0.1-alpha.5",
3
+ "version": "0.0.1-alpha.7",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {
@@ -13,6 +13,11 @@
13
13
  "import": "./build/r3f.js",
14
14
  "require": "./build/r3f.cjs",
15
15
  "types": "./types/r3f/index.d.ts"
16
+ },
17
+ "./shaders": {
18
+ "import": "./build/shaders.js",
19
+ "require": "./build/shaders.cjs",
20
+ "types": "./types/shaders/index.d.ts"
16
21
  }
17
22
  },
18
23
  "main": "./build/index.cjs",
@@ -26,10 +31,9 @@
26
31
  "README.md"
27
32
  ],
28
33
  "dependencies": {
29
- "lodash-es": "^4.17.21",
30
34
  "react-merge-refs": "^2.1.1",
31
35
  "tiny-invariant": "^1.3.3",
32
- "type-fest": "^4.32.0"
36
+ "type-fest": "^4.33.0"
33
37
  },
34
38
  "peerDependencies": {
35
39
  "@react-three/fiber": ">=8.17.10",
package/src/DataLoader.ts CHANGED
@@ -25,6 +25,7 @@ import {
25
25
  } from './typedArrayParsers'
26
26
  import { type Callable } from './types'
27
27
 
28
+ // TODO: Move to types
28
29
  type ParameterProperties<T> = {
29
30
  [K in WritableKeysOf<T> as T[K] extends Callable ? never : K]: T[K]
30
31
  }
@@ -0,0 +1,21 @@
1
+ import { NearestFilter, RedFormat, RepeatWrapping } from 'three'
2
+
3
+ import {
4
+ STBN_TEXTURE_DEPTH,
5
+ STBN_TEXTURE_HEIGHT,
6
+ STBN_TEXTURE_WIDTH
7
+ } from './constants'
8
+ import { createData3DTextureLoaderClass } from './DataLoader'
9
+ import { parseUint8Array } from './typedArrayParsers'
10
+
11
+ export const STBNLoader = createData3DTextureLoaderClass(parseUint8Array, {
12
+ format: RedFormat,
13
+ minFilter: NearestFilter,
14
+ magFilter: NearestFilter,
15
+ wrapS: RepeatWrapping,
16
+ wrapT: RepeatWrapping,
17
+ wrapR: RepeatWrapping,
18
+ width: STBN_TEXTURE_WIDTH,
19
+ height: STBN_TEXTURE_HEIGHT,
20
+ depth: STBN_TEXTURE_DEPTH
21
+ })
@@ -0,0 +1,81 @@
1
+ import {
2
+ Data3DTexture,
3
+ ImageLoader,
4
+ LinearFilter,
5
+ Loader,
6
+ RepeatWrapping
7
+ } from 'three'
8
+
9
+ export class Texture3DLoader extends Loader<Data3DTexture> {
10
+ override load(
11
+ url: string,
12
+ onLoad: (data: Data3DTexture) => void,
13
+ onProgress?: (event: ProgressEvent) => void,
14
+ onError?: (error: unknown) => void
15
+ ): void {
16
+ const loader = new ImageLoader(this.manager)
17
+ loader.setRequestHeader(this.requestHeader)
18
+ loader.setPath(this.path)
19
+ loader.setWithCredentials(this.withCredentials)
20
+ loader.load(
21
+ url,
22
+ image => {
23
+ const canvas = document.createElement('canvas')
24
+ const context = canvas.getContext('2d')
25
+ if (context == null) {
26
+ onError?.(new Error('Could not obtain canvas context.'))
27
+ return
28
+ }
29
+
30
+ // Assume cubic 3D texture.
31
+ const { width, height } = image
32
+ const size = Math.min(width, height)
33
+ canvas.width = width
34
+ canvas.height = height
35
+ context.drawImage(image, 0, 0)
36
+ const imageData = context.getImageData(0, 0, width, height).data
37
+ let data: Uint8Array
38
+
39
+ if (width < height) {
40
+ data = new Uint8Array(imageData.buffer)
41
+ } else {
42
+ data = new Uint8Array(imageData.length)
43
+ const sizeSq = size ** 2
44
+ for (let z = 0; z < size; ++z) {
45
+ for (let y = 0; y < size; ++y) {
46
+ for (let x = 0; x < size; ++x) {
47
+ const src = (x + z * size + y * sizeSq) * 4
48
+ const dest = (x + y * size + z * sizeSq) * 4
49
+ data[dest + 0] = imageData[src + 0]
50
+ data[dest + 1] = imageData[src + 1]
51
+ data[dest + 2] = imageData[src + 2]
52
+ data[dest + 3] = imageData[src + 3]
53
+ }
54
+ }
55
+ }
56
+ }
57
+
58
+ const texture = new Data3DTexture(data, size, size, size)
59
+ texture.minFilter = LinearFilter
60
+ texture.magFilter = LinearFilter
61
+ texture.wrapS = RepeatWrapping
62
+ texture.wrapR = RepeatWrapping
63
+ texture.wrapT = RepeatWrapping
64
+ texture.needsUpdate = true
65
+
66
+ try {
67
+ onLoad(texture)
68
+ } catch (error) {
69
+ if (onError != null) {
70
+ onError(error)
71
+ } else {
72
+ console.error(error)
73
+ }
74
+ this.manager.itemError(url)
75
+ }
76
+ },
77
+ onProgress,
78
+ onError
79
+ )
80
+ }
81
+ }
@@ -1,4 +1,3 @@
1
- import { pick } from 'lodash-es'
2
1
  import { Box3, BufferAttribute, BufferGeometry, Sphere, Vector3 } from 'three'
3
2
 
4
3
  export type BufferGeometryLike = Pick<
@@ -9,8 +8,9 @@ export type BufferGeometryLike = Pick<
9
8
  export function toBufferGeometryLike(
10
9
  geometry: BufferGeometry
11
10
  ): [BufferGeometryLike, ArrayBuffer[]] {
11
+ const { attributes, index, boundingBox, boundingSphere } = geometry
12
12
  return [
13
- pick(geometry, ['attributes', 'index', 'boundingBox', 'boundingSphere']),
13
+ { attributes, index, boundingBox, boundingSphere },
14
14
  [
15
15
  ...Object.values(geometry.attributes).map(
16
16
  attribute => attribute.array.buffer
@@ -0,0 +1,6 @@
1
+ export const STBN_TEXTURE_WIDTH = 128
2
+ export const STBN_TEXTURE_HEIGHT = 128
3
+ export const STBN_TEXTURE_DEPTH = 64
4
+
5
+ export const DEFAULT_STBN_URL =
6
+ 'https://media.githubusercontent.com/media/takram-design-engineering/three-geospatial/9627216cc50057994c98a2118f3c4a23765d43b9/packages/core/assets/stbn.bin'
@@ -0,0 +1,68 @@
1
+ import { type Uniform } from 'three'
2
+
3
+ // TODO: Make mutable value types (e.g. vectors, matrices) read-only.
4
+
5
+ // Maps argument of type [T1, K1[], T2, K2[], ...] to:
6
+ // { [K in K1]: T1[K],
7
+ // [K in K2]: T2[K], ... }
8
+ export type PropertyShorthand<Args extends readonly unknown[]> =
9
+ Args extends readonly [infer T, infer K, ...infer Rest]
10
+ ? K extends readonly string[]
11
+ ? K[number] extends keyof T
12
+ ? Rest extends readonly unknown[]
13
+ ? { [P in K[number]]: T[P] } & PropertyShorthand<Rest>
14
+ : { [P in K[number]]: T[P] }
15
+ : never // K must be keyof T
16
+ : never // K must be an array
17
+ : {} // Termination
18
+
19
+ export function definePropertyShorthand<T, Args extends readonly unknown[]>(
20
+ destination: T,
21
+ ...sourceKeysArgs: [...Args]
22
+ ): T & PropertyShorthand<Args> {
23
+ const descriptors: PropertyDescriptorMap = {}
24
+ for (let i = 0; i < sourceKeysArgs.length; i += 2) {
25
+ const source = sourceKeysArgs[i]
26
+ const keys = sourceKeysArgs[i + 1] as ReadonlyArray<keyof typeof source>
27
+ for (const key of keys) {
28
+ descriptors[key] = {
29
+ enumerable: true,
30
+ get: () => source[key],
31
+ set: (value: any) => {
32
+ source[key] = value
33
+ }
34
+ }
35
+ }
36
+ }
37
+ Object.defineProperties(destination, descriptors)
38
+ return destination as T & PropertyShorthand<Args>
39
+ }
40
+
41
+ // The argument of defineUniformShorthand can also be variadic, but I can't
42
+ // think of any practical use cases for it.
43
+
44
+ export type UniformShorthand<
45
+ T extends { uniforms: Record<K, Uniform> },
46
+ K extends keyof T['uniforms']
47
+ > = {
48
+ [P in K]: T['uniforms'][P] extends Uniform<infer U> ? U : never
49
+ }
50
+
51
+ export function defineUniformShorthand<
52
+ T,
53
+ S extends { uniforms: Record<K, Uniform> },
54
+ K extends keyof S['uniforms']
55
+ >(destination: T, source: S, keys: readonly K[]): T & UniformShorthand<S, K> {
56
+ const descriptors: PropertyDescriptorMap = {}
57
+ for (const key of keys) {
58
+ descriptors[key] = {
59
+ enumerable: true,
60
+ get: () => source.uniforms[key].value,
61
+ set: (value: S['uniforms'][K]) => {
62
+ source.uniforms[key].value = value
63
+ }
64
+ }
65
+ }
66
+ Object.defineProperties(destination, descriptors)
67
+ return destination as T & UniformShorthand<S, K>
68
+ }
package/src/index.ts CHANGED
@@ -1,26 +1,21 @@
1
- /// <reference types="vite-plugin-glsl/ext" />
2
-
3
- import depth from './shaders/depth.glsl'
4
- import packing from './shaders/packing.glsl'
5
- import transform from './shaders/transform.glsl'
6
-
7
- export const depthShader: string = depth
8
- export const packingShader: string = packing
9
- export const transformShader: string = transform
10
-
11
1
  export * from './ArrayBufferLoader'
12
2
  export * from './assertions'
13
3
  export * from './bufferGeometry'
4
+ export * from './constants'
14
5
  export * from './DataLoader'
6
+ export * from './defineShorthand'
15
7
  export * from './Ellipsoid'
16
8
  export * from './EllipsoidGeometry'
17
9
  export * from './Geodetic'
18
10
  export * from './math'
19
11
  export * from './PointOfView'
20
12
  export * from './Rectangle'
13
+ export * from './resolveIncludes'
14
+ export * from './STBNLoader'
21
15
  export * from './TileCoordinate'
22
16
  export * from './TilingScheme'
23
17
  export * from './typedArray'
24
18
  export * from './TypedArrayLoader'
25
19
  export * from './typedArrayParsers'
26
20
  export * from './types'
21
+ export * from './unrollLoops'