@genex-ai/cli-demo 0.6.0 → 0.6.2
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/index.js +5 -0
- package/package.json +1 -1
- package/templates/skills/genex-threejs-atmosphere-aerial-perspective/SKILL.md +30 -18
- package/templates/skills/genex-threejs-atmosphere-aerial-perspective/references/atmosphere.md +204 -20
- package/templates/skills/genex-threejs-bloom/SKILL.md +29 -18
- package/templates/skills/genex-threejs-bloom/references/bloom.md +176 -20
- package/templates/skills/genex-threejs-camera-direction/SKILL.md +38 -26
- package/templates/skills/genex-threejs-camera-direction/references/camera-rigs.md +359 -27
- package/templates/skills/genex-threejs-exposure-color-grading/SKILL.md +27 -18
- package/templates/skills/genex-threejs-exposure-color-grading/references/exposure-grading.md +196 -21
- package/templates/skills/genex-threejs-image-pipeline/SKILL.md +38 -17
- package/templates/skills/genex-threejs-image-pipeline/references/image-pipeline.md +185 -29
- package/templates/skills/genex-threejs-procedural-animation/SKILL.md +34 -21
- package/templates/skills/genex-threejs-procedural-animation/references/procedural-motion.md +353 -24
- package/templates/skills/genex-threejs-procedural-architecture/SKILL.md +36 -17
- package/templates/skills/genex-threejs-procedural-architecture/references/architecture-systems.md +500 -22
- package/templates/skills/genex-threejs-procedural-fields/SKILL.md +59 -24
- package/templates/skills/genex-threejs-procedural-fields/references/field-systems.md +222 -25
- package/templates/skills/genex-threejs-procedural-geometry/SKILL.md +34 -20
- package/templates/skills/genex-threejs-procedural-geometry/references/mesh-systems.md +192 -26
- package/templates/skills/genex-threejs-procedural-materials/SKILL.md +55 -18
- package/templates/skills/genex-threejs-procedural-materials/references/material-systems.md +189 -22
- package/templates/skills/genex-threejs-procedural-planets/SKILL.md +36 -18
- package/templates/skills/genex-threejs-procedural-planets/references/planet-systems.md +489 -21
- package/templates/skills/genex-threejs-procedural-vegetation/SKILL.md +35 -25
- package/templates/skills/genex-threejs-procedural-vegetation/references/vegetation-systems.md +304 -27
- package/templates/skills/genex-threejs-procedural-vfx/SKILL.md +26 -18
- package/templates/skills/genex-threejs-procedural-vfx/references/vfx-systems.md +208 -20
- package/templates/skills/genex-threejs-raymarched-space-effects/SKILL.md +25 -18
- package/templates/skills/genex-threejs-raymarched-space-effects/references/space-effects.md +185 -21
- package/templates/skills/genex-threejs-screen-space-ambient-occlusion/SKILL.md +23 -17
- package/templates/skills/genex-threejs-screen-space-ambient-occlusion/references/ambient-occlusion.md +430 -20
- package/templates/skills/genex-threejs-shadow-systems/SKILL.md +29 -18
- package/templates/skills/genex-threejs-shadow-systems/references/shadow-systems.md +420 -21
- package/templates/skills/genex-threejs-skill-router/SKILL.md +21 -21
- package/templates/skills/genex-threejs-spectral-ocean/SKILL.md +30 -20
- package/templates/skills/genex-threejs-spectral-ocean/references/spectral-ocean.md +462 -22
- package/templates/skills/genex-threejs-temporal-surfaces/SKILL.md +26 -17
- package/templates/skills/genex-threejs-temporal-surfaces/references/temporal-surfaces.md +198 -20
- package/templates/skills/genex-threejs-visual-validation/SKILL.md +34 -18
- package/templates/skills/genex-threejs-visual-validation/references/visual-validation.md +396 -32
- package/templates/skills/genex-threejs-volumetric-clouds/SKILL.md +33 -17
- package/templates/skills/genex-threejs-volumetric-clouds/references/volumetric-clouds.md +570 -21
- package/templates/skills/genex-threejs-water-optics/SKILL.md +33 -18
- package/templates/skills/genex-threejs-water-optics/references/water-optics.md +184 -20
|
@@ -1,30 +1,429 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Cached clipmap shadow system
|
|
2
2
|
|
|
3
|
-
Use this reference for stable shadows
|
|
3
|
+
Use this reference for stable directional shadows across a large procedural scene using committed light-space centers, texel snapping, bounded refresh budgets, cross-level blending, and targeted invalidation.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Contents
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
1. Representation and defaults
|
|
8
|
+
2. Light-space stabilization
|
|
9
|
+
3. Committed centers and containment
|
|
10
|
+
4. Sampling and cross-level blending
|
|
11
|
+
5. Cache scheduling and invalidation
|
|
12
|
+
6. Bias, defects, adaptation, and diagnostics
|
|
11
13
|
|
|
12
|
-
##
|
|
14
|
+
## 1. Identify the representation correctly
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
- Track invalidation from moving objects, time of day, or geometry edits.
|
|
17
|
-
- Keep cache memory visible in diagnostics.
|
|
16
|
+
The system is a set of concentric square shadow maps centered around
|
|
17
|
+
the camera in light space.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
It is **not** a virtual shadow map:
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
-
|
|
21
|
+
```text
|
|
22
|
+
no page table
|
|
23
|
+
no physical page cache
|
|
24
|
+
no page-granular caster submission
|
|
25
|
+
one ordinary shadow texture per level
|
|
26
|
+
```
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
Every level consumes a sampled shadow texture in the material stage. Check the
|
|
29
|
+
target device's sampled-texture limit before increasing level count.
|
|
27
30
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
## 2. Preserve the exact default envelope
|
|
32
|
+
|
|
33
|
+
Default construction:
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
first half-width 12 m
|
|
37
|
+
scale factor 2.5
|
|
38
|
+
maximum distance 2000 m
|
|
39
|
+
light margin 100 m
|
|
40
|
+
shadow near 1 m
|
|
41
|
+
shadow far cap 3000 m
|
|
42
|
+
guard band 0.15
|
|
43
|
+
cross-fade ratio 0.15
|
|
44
|
+
dynamic near levels 2
|
|
45
|
+
cached update budget 2 per frame
|
|
46
|
+
maximum cache age 64 frames
|
|
47
|
+
direction epsilon 0.002 radians
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Level count:
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
ceil(log(maxDistance / firstRadius) / log(scaleFactor)) + 1
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Each half-width is:
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
min(firstRadius * scaleFactor^level, maxDistance)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The last level is forced to `maxDistance` exactly.
|
|
63
|
+
|
|
64
|
+
Clamp adaptation controls to safe ranges:
|
|
65
|
+
|
|
66
|
+
```text
|
|
67
|
+
firstRadius >= 1
|
|
68
|
+
scaleFactor >= 1.5
|
|
69
|
+
guardBand in [0.02, 0.5]
|
|
70
|
+
blendRatio in [0.01, 0.9]
|
|
71
|
+
dynamicLevels in [0, levelCount]
|
|
72
|
+
updateBudget >= 1
|
|
73
|
+
maxCacheAge >= 0
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Per-level map sizes may differ. Missing entries use the directional light's
|
|
77
|
+
current shadow-map width.
|
|
78
|
+
|
|
79
|
+
## 3. Store committed map state
|
|
80
|
+
|
|
81
|
+
Each level owns:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
type LevelState = {
|
|
85
|
+
halfWidth: number
|
|
86
|
+
centerX: number
|
|
87
|
+
centerY: number
|
|
88
|
+
centerZ: number
|
|
89
|
+
valid: boolean
|
|
90
|
+
forceDirty: boolean
|
|
91
|
+
age: number
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The shader-facing vector stores:
|
|
96
|
+
|
|
97
|
+
```text
|
|
98
|
+
x = committed light-space center X
|
|
99
|
+
y = committed light-space center Y
|
|
100
|
+
z = sampled half-width = halfWidth * (1 - guardBand)
|
|
101
|
+
w = unused
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Publish the center from the last completed map render. Do not publish the
|
|
105
|
+
camera's desired center while a cached level waits for its budget slot.
|
|
106
|
+
|
|
107
|
+
That distinction prevents the shader containment box from drifting away from
|
|
108
|
+
the map content and causing rhythmic boundary flicker.
|
|
109
|
+
|
|
110
|
+
Before a level renders once, park it at:
|
|
111
|
+
|
|
112
|
+
```text
|
|
113
|
+
center = (1e9, 1e9)
|
|
114
|
+
sample half-width = 1e-6
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
An invalid level must never win selection.
|
|
118
|
+
|
|
119
|
+
## 4. Stabilize X/Y by the actual texel footprint
|
|
120
|
+
|
|
121
|
+
Per level:
|
|
122
|
+
|
|
123
|
+
```text
|
|
124
|
+
texelWidth =
|
|
125
|
+
(orthographicRight - orthographicLeft)
|
|
126
|
+
/ mapWidth
|
|
127
|
+
|
|
128
|
+
desiredX = round(cameraLightX / texelWidth) * texelWidth
|
|
129
|
+
desiredY = round(cameraLightY / texelWidth) * texelWidth
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
This aligns the orthographic projection to a fixed world-space texel grid.
|
|
133
|
+
|
|
134
|
+
Quantize Z more coarsely:
|
|
135
|
+
|
|
136
|
+
```text
|
|
137
|
+
zQuantum = halfWidth * 0.5
|
|
138
|
+
desiredZ = round(cameraLightZ / zQuantum) * zQuantum
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Z changes depth coverage and update cadence but does not define the projected
|
|
142
|
+
texel grid, so a coarser quantum is intentional.
|
|
143
|
+
|
|
144
|
+
Do not snap by a fraction of total level extent. At coarse levels that produces
|
|
145
|
+
tens-of-meters jumps.
|
|
146
|
+
|
|
147
|
+
## 5. Derive the light-space frame once
|
|
148
|
+
|
|
149
|
+
Each frame:
|
|
150
|
+
|
|
151
|
+
```text
|
|
152
|
+
lightDirection = normalize(light.target.position - light.position)
|
|
153
|
+
lightOrientation = lookAt(origin, lightDirection, worldUp)
|
|
154
|
+
worldToLight = inverse(lightOrientation)
|
|
155
|
+
cameraLight = worldToLight * cameraWorld
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
The direction is considered changed when:
|
|
159
|
+
|
|
160
|
+
```text
|
|
161
|
+
dot(currentDirection, lastCommittedDirection)
|
|
162
|
+
< cos(directionEpsilon)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
A direction change gives the frame enough budget to refresh all levels.
|
|
166
|
+
|
|
167
|
+
This gates a continuously moving sun into occasional coherent refreshes. If
|
|
168
|
+
the art direction requires per-frame sun motion, reduce levels or accept the
|
|
169
|
+
cost rather than allowing mismatched cached directions.
|
|
170
|
+
|
|
171
|
+
## 6. Use a two-class update policy
|
|
172
|
+
|
|
173
|
+
A level is dirty when:
|
|
174
|
+
|
|
175
|
+
```text
|
|
176
|
+
it is in the dynamic near set
|
|
177
|
+
or it has never rendered
|
|
178
|
+
or forceDirty is set
|
|
179
|
+
or snapped X/Y/Z changed
|
|
180
|
+
or cache age expired
|
|
181
|
+
or light direction changed
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Policy:
|
|
185
|
+
|
|
186
|
+
```text
|
|
187
|
+
dynamic near levels:
|
|
188
|
+
render every frame
|
|
189
|
+
do not consume cached update budget
|
|
190
|
+
|
|
191
|
+
ordinary cached levels:
|
|
192
|
+
render only while budget remains
|
|
193
|
+
|
|
194
|
+
explicitly invalidated levels:
|
|
195
|
+
bypass the cached budget
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Although invalidation may be described as “rate-limited”, `forceDirty` renders
|
|
199
|
+
without consuming or checking the ordinary budget. Preserve that exception
|
|
200
|
+
intentionally or change both behavior and documentation together.
|
|
201
|
+
|
|
202
|
+
On first update or light-direction change:
|
|
203
|
+
|
|
204
|
+
```text
|
|
205
|
+
budget = levelCount
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Otherwise:
|
|
209
|
+
|
|
210
|
+
```text
|
|
211
|
+
budget = updateBudget
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Age increments every frame and resets after render. Initial ages are staggered:
|
|
215
|
+
|
|
216
|
+
```text
|
|
217
|
+
age(level) = floor(-level * maxCacheAge / levelCount)
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
This prevents all coarse levels expiring together.
|
|
221
|
+
|
|
222
|
+
## 7. Commit camera and map atomically
|
|
223
|
+
|
|
224
|
+
When a level renders:
|
|
225
|
+
|
|
226
|
+
1. commit snapped X/Y/Z to `LevelState`;
|
|
227
|
+
2. clear `forceDirty`;
|
|
228
|
+
3. reset age;
|
|
229
|
+
4. place the light at:
|
|
230
|
+
|
|
231
|
+
```text
|
|
232
|
+
(centerX, centerY, centerZ + halfWidth + lightMargin)
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
5. transform that position back from light space;
|
|
236
|
+
6. aim the target one light-direction unit away;
|
|
237
|
+
7. force light and target matrices current;
|
|
238
|
+
8. render the shadow map immediately from that committed transform.
|
|
239
|
+
|
|
240
|
+
The level's orthographic depth range is:
|
|
241
|
+
|
|
242
|
+
```text
|
|
243
|
+
near = configuredNear
|
|
244
|
+
far = max(
|
|
245
|
+
near + 1,
|
|
246
|
+
min(configuredFarCap, lightMargin + 2 * halfWidth)
|
|
247
|
+
)
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Every cloned shadow has:
|
|
251
|
+
|
|
252
|
+
```text
|
|
253
|
+
autoUpdate = false
|
|
254
|
+
needsUpdate = false
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
The clipmap owner drives updates manually. Allowing Three.js to update the
|
|
258
|
+
clone independently can render from a transform different from the one later
|
|
259
|
+
sampled.
|
|
260
|
+
|
|
261
|
+
## 8. Cross-fade levels without divergent shadow samples
|
|
262
|
+
|
|
263
|
+
Transform `shadowPositionWorld` to the shared light-space XY plane.
|
|
264
|
+
|
|
265
|
+
For each level:
|
|
266
|
+
|
|
267
|
+
```text
|
|
268
|
+
distance = max(
|
|
269
|
+
abs(lightX - levelCenterX),
|
|
270
|
+
abs(lightY - levelCenterY)
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
fade =
|
|
274
|
+
1 - smoothstep(
|
|
275
|
+
sampledHalfWidth * (1 - blendRatio),
|
|
276
|
+
sampledHalfWidth,
|
|
277
|
+
distance
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
weight = fade * remaining
|
|
281
|
+
remaining *= 1 - fade
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Accumulate from finest to coarsest. Leftover weight resolves to unshadowed,
|
|
285
|
+
creating a smooth fade outside the outer level.
|
|
286
|
+
|
|
287
|
+
Critical GPU contract:
|
|
288
|
+
|
|
289
|
+
```text
|
|
290
|
+
sample every level's depth-comparison texture unconditionally
|
|
291
|
+
multiply the result by its weight afterward
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Do not put comparison sampling behind a per-pixel conditional. Doing so can
|
|
295
|
+
produce view-dependent flicker and undefined derivatives.
|
|
296
|
+
|
|
297
|
+
`BoundedShadowNode` still evaluates the filter function, then selects `1`
|
|
298
|
+
outside the level's projected XYZ range. This keeps the comparison sample in
|
|
299
|
+
uniform control flow while preventing out-of-bounds projection from shadowing.
|
|
300
|
+
|
|
301
|
+
## 9. Scale normal bias by texel size
|
|
302
|
+
|
|
303
|
+
Capture the original directional-light bias values before cloning.
|
|
304
|
+
|
|
305
|
+
Per level:
|
|
306
|
+
|
|
307
|
+
```text
|
|
308
|
+
texelScale = levelTexelWidth / finestTexelWidth
|
|
309
|
+
shadow.bias = baseBias
|
|
310
|
+
shadow.normalBias = baseNormalBias * texelScale
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
The implementation keeps depth bias unchanged and scales only world-space normal bias.
|
|
314
|
+
|
|
315
|
+
Inspect acne and peter-panning separately per level. A single normal bias
|
|
316
|
+
across 12 m and 2000 m levels is not coherent.
|
|
317
|
+
|
|
318
|
+
## 10. Target invalidation spatially
|
|
319
|
+
|
|
320
|
+
`invalidate()` with no bounds sets `forceDirty` on every level.
|
|
321
|
+
|
|
322
|
+
With a world-space bounding sphere:
|
|
323
|
+
|
|
324
|
+
1. transform its center to light space;
|
|
325
|
+
2. for each level compute:
|
|
326
|
+
|
|
327
|
+
```text
|
|
328
|
+
reach = halfWidth + sphereRadius
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
3. invalidate when both projected X and Y distances are below `reach`.
|
|
332
|
+
|
|
333
|
+
Use this for:
|
|
334
|
+
|
|
335
|
+
- streamed terrain arrival;
|
|
336
|
+
- regenerated buildings;
|
|
337
|
+
- moving hero casters;
|
|
338
|
+
- vegetation chunks whose deformed silhouettes matter.
|
|
339
|
+
|
|
340
|
+
Observed limitation: the test is a conservative square intersection in XY. It
|
|
341
|
+
does not test Z or the exact projected sphere-square distance. This is cheap
|
|
342
|
+
and safe but may refresh extra levels.
|
|
343
|
+
|
|
344
|
+
## 11. Attach and dispose ownership explicitly
|
|
345
|
+
|
|
346
|
+
The node attaches through:
|
|
347
|
+
|
|
348
|
+
```text
|
|
349
|
+
light.shadow.shadowNode = clipmapNode
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
Detaching removes that property only if it still points to the node.
|
|
353
|
+
|
|
354
|
+
Disposal must:
|
|
355
|
+
|
|
356
|
+
- detach from the directional light;
|
|
357
|
+
- dispose every level shadow node;
|
|
358
|
+
- dispose every cloned shadow;
|
|
359
|
+
- remove level lights and targets from their parent;
|
|
360
|
+
- invoke base disposal.
|
|
361
|
+
|
|
362
|
+
Cached shadow maps are persistent GPU resources. Treat missing disposal as a
|
|
363
|
+
real leak.
|
|
364
|
+
|
|
365
|
+
## 12. Adaptation workflow
|
|
366
|
+
|
|
367
|
+
1. Verify target Three.js WebGPU/TSL shadow-node APIs.
|
|
368
|
+
2. Start with two or three equal-resolution levels and no caching.
|
|
369
|
+
3. add X/Y texel snapping;
|
|
370
|
+
4. add guard-band selection and cross-fade;
|
|
371
|
+
5. verify unconditional comparison sampling;
|
|
372
|
+
6. separate dynamic and cached level updates;
|
|
373
|
+
7. publish committed centers only;
|
|
374
|
+
8. add cache-age staggering;
|
|
375
|
+
9. add targeted invalidation;
|
|
376
|
+
10. tune per-level map sizes and normal bias.
|
|
377
|
+
|
|
378
|
+
Do not add caching before stable selection and committed-state tracking work.
|
|
379
|
+
Caching makes a spatial mismatch persist longer.
|
|
380
|
+
|
|
381
|
+
## 13. Required diagnostics
|
|
382
|
+
|
|
383
|
+
Expose:
|
|
384
|
+
|
|
385
|
+
```text
|
|
386
|
+
level count and texture count
|
|
387
|
+
rendered half-width and sampled half-width
|
|
388
|
+
map size and world texel width per level
|
|
389
|
+
desired versus committed X/Y/Z
|
|
390
|
+
selected level and cross-fade weights
|
|
391
|
+
remaining unshadowed weight
|
|
392
|
+
dynamic/cached classification
|
|
393
|
+
dirty reason bits
|
|
394
|
+
valid/forceDirty/age
|
|
395
|
+
budget before and after updates
|
|
396
|
+
direction delta versus epsilon
|
|
397
|
+
base and scaled normal bias
|
|
398
|
+
shadow-map preview per level
|
|
399
|
+
invalidation sphere in light space
|
|
400
|
+
level render count and GPU time
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
Failure diagnosis:
|
|
404
|
+
|
|
405
|
+
```text
|
|
406
|
+
shadows crawl under slow camera motion:
|
|
407
|
+
X/Y center is not snapped to the level's texel width
|
|
408
|
+
|
|
409
|
+
level boundaries flicker every other frame:
|
|
410
|
+
desired center was published while the cached map retained its old center
|
|
411
|
+
|
|
412
|
+
shadows disappear by view angle:
|
|
413
|
+
comparison samplers were evaluated in divergent control flow
|
|
414
|
+
|
|
415
|
+
coarse moving casters freeze:
|
|
416
|
+
max age and targeted invalidation are both absent
|
|
417
|
+
|
|
418
|
+
all levels spike together:
|
|
419
|
+
cache ages were not staggered
|
|
420
|
+
|
|
421
|
+
important streamed geometry remains unshadowed:
|
|
422
|
+
explicit invalidation was incorrectly blocked by the coarse update budget
|
|
423
|
+
|
|
424
|
+
coarse levels show acne:
|
|
425
|
+
normal bias was not scaled by world texel width
|
|
426
|
+
|
|
427
|
+
memory grows after scene replacement:
|
|
428
|
+
cloned shadows, level nodes, lights, or targets were not disposed
|
|
429
|
+
```
|
|
@@ -15,27 +15,27 @@ map, execution order, and acceptance gate.
|
|
|
15
15
|
|
|
16
16
|
| Work needed | Load |
|
|
17
17
|
| --- | --- |
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
|
|
|
21
|
-
|
|
|
22
|
-
|
|
|
23
|
-
| trees,
|
|
24
|
-
| buildings,
|
|
25
|
-
| planets,
|
|
26
|
-
| sky
|
|
27
|
-
|
|
|
28
|
-
|
|
|
29
|
-
| analytic
|
|
30
|
-
| black holes, accretion disks, wormholes
|
|
31
|
-
| particles, trails, plasma, shockwaves,
|
|
32
|
-
| accumulated frost, touch
|
|
33
|
-
| cascades, clipmaps,
|
|
34
|
-
| GTAO, bent normals,
|
|
35
|
-
| HDR bloom
|
|
36
|
-
|
|
|
37
|
-
|
|
|
38
|
-
| fixed-view
|
|
18
|
+
| shot composition, chase/side/orbit rigs, camera handoffs, projection ownership, pointer look, floating origins | `$genex-threejs-camera-direction` |
|
|
19
|
+
| launch and docking timelines, procedural transform phases, springs, staging, rotating-frame alignment, debris motion | `$genex-threejs-procedural-animation` |
|
|
20
|
+
| reusable scalar/vector fields, domain warping, causal masks, procedural normals | `$genex-threejs-procedural-fields` |
|
|
21
|
+
| atlas-filtered blocks, planetary surfaces, terrain wetness, lava/emissive procedural surfaces, authored frame PBR, specular AA | `$genex-threejs-procedural-materials` |
|
|
22
|
+
| sculpted rails/frames, branch rings, semantic mesh writers, material groups | `$genex-threejs-procedural-geometry` |
|
|
23
|
+
| trees, stylized grass, branching organisms, roots, foliage, rooted wind deformation | `$genex-threejs-procedural-vegetation` |
|
|
24
|
+
| buildings, façade grammars, profiles, ornaments, modular mesh writers | `$genex-threejs-procedural-architecture` |
|
|
25
|
+
| planets, terrain, craters, biome fields, coastlines, spherical detail | `$genex-threejs-procedural-planets` |
|
|
26
|
+
| sky scattering, planetary shells, depth-based aerial perspective | `$genex-threejs-atmosphere-aerial-perspective` |
|
|
27
|
+
| weather-driven raymarched clouds and cloud shadows | `$genex-threejs-volumetric-clouds` |
|
|
28
|
+
| FFT oceans, hybrid FFT/Gerstner clear water, stylized above/below ocean optics, spectral cascades, choppy derivatives, Jacobian whitecaps | `$genex-threejs-spectral-ocean` |
|
|
29
|
+
| authored analytic waves, bounded heightfield pools, object ripples, differential-area caustics, ray-traced pool volume optics, shared normals, heuristic refraction, fallback absorption, crest foam | `$genex-threejs-water-optics` |
|
|
30
|
+
| curved-ray black holes, accretion disks, wormholes | `$genex-threejs-raymarched-space-effects` |
|
|
31
|
+
| particles, trails, plasma, shockwaves, layered event effects | `$genex-threejs-procedural-vfx` |
|
|
32
|
+
| accumulated screen frost, touch clearing, reduced blur, and refraction masks | `$genex-threejs-temporal-surfaces` |
|
|
33
|
+
| stable large-world shadows, cascades, clipmaps, cached updates | `$genex-threejs-shadow-systems` |
|
|
34
|
+
| GTAO, bent normals, bilateral reconstruction | `$genex-threejs-screen-space-ambient-occlusion` |
|
|
35
|
+
| HDR bloom and selective emission contribution | `$genex-threejs-bloom` |
|
|
36
|
+
| eye adaptation, tone mapping, LUT grading, output color | `$genex-threejs-exposure-color-grading` |
|
|
37
|
+
| shared depth/normal/velocity ownership and multi-pass ordering | `$genex-threejs-image-pipeline` |
|
|
38
|
+
| fixed-view diagnostics, seed sweeps, temporal and budget evidence | `$genex-threejs-visual-validation` |
|
|
39
39
|
| realtime multiplayer: movement sync, shared state, presence, shots/emotes, persistence | `$genex-threejs-multiplayer` |
|
|
40
40
|
|
|
41
41
|
**Multiplayer is mandatory routing:** if the game has 2+ players sharing a world, loading
|
|
@@ -5,26 +5,36 @@ description: Build large procedural oceans for Genex Three.js games. Use for FFT
|
|
|
5
5
|
|
|
6
6
|
# Genex Three.js Spectral Ocean
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
scale, directionality, and far-distance motion.
|
|
10
|
-
|
|
11
|
-
Read [references/spectral-ocean.md](references/spectral-ocean.md) for wave
|
|
12
|
-
cascades, foam, shading, and budget controls.
|
|
8
|
+
Treat an ocean as a sampled stochastic wave field with explicit frequency-space ownership. Do not approximate this target with a pile of Gerstner waves, scrolling normal maps, or unrelated foam noise.
|
|
13
9
|
|
|
14
10
|
## Build order
|
|
15
11
|
|
|
16
|
-
1. Define
|
|
17
|
-
2.
|
|
18
|
-
3.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
12
|
+
1. Define the sea-state spectrum and deterministic Gaussian seed.
|
|
13
|
+
2. Partition wavelengths into disjoint cascades.
|
|
14
|
+
3. Validate the inverse FFT independently with analytic inputs.
|
|
15
|
+
4. Generate and conjugate-pack the initial spectrum.
|
|
16
|
+
5. Evolve packed displacement and derivative fields in frequency space.
|
|
17
|
+
6. Inverse-transform every packed field with explicit inter-step barriers.
|
|
18
|
+
7. Assemble displacement, derivatives, and persistent Jacobian foam maps.
|
|
19
|
+
8. Shade from summed cascade displacement and derivatives.
|
|
20
|
+
9. Add sub-grid detail only below the resolved simulation bands.
|
|
21
|
+
10. Expose spectrum, height, slopes, Jacobian, and foam-history diagnostics.
|
|
22
|
+
|
|
23
|
+
Read [references/spectral-ocean.md](references/spectral-ocean.md) before implementing or auditing a spectral ocean.
|
|
24
|
+
|
|
25
|
+
## Non-negotiable gates
|
|
26
|
+
|
|
27
|
+
- Require a power-of-two grid and a passing FFT impulse/frequency test.
|
|
28
|
+
- Keep cascade wavenumber intervals disjoint.
|
|
29
|
+
- Derive normals from transformed derivatives, not a detached normal texture.
|
|
30
|
+
- Detect breaking from the horizontal-displacement Jacobian.
|
|
31
|
+
- Persist foam in simulation state; do not infer all foam anew per frame.
|
|
32
|
+
- Submit FFT stages with the synchronization required by the active backend.
|
|
33
|
+
- Share sun and sky parameters between the visible sky and ocean reflection.
|
|
34
|
+
- Keep a deterministic seed and fixed-camera capture for comparisons.
|
|
35
|
+
|
|
36
|
+
## Route elsewhere
|
|
37
|
+
|
|
38
|
+
- Use `$genex-threejs-water-optics` for bounded water, screen-space refraction, depth thickness, shoreline absorption, and analytic wave surfaces.
|
|
39
|
+
- Add `$genex-threejs-procedural-vfx` only when crest spray or interaction splashes are required.
|
|
40
|
+
- Add `$genex-threejs-visual-validation` for cross-seed, temporal, and GPU evidence.
|