@genex-ai/cli-demo 0.6.1 → 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.
Files changed (44) hide show
  1. package/package.json +1 -1
  2. package/templates/skills/genex-threejs-atmosphere-aerial-perspective/SKILL.md +30 -18
  3. package/templates/skills/genex-threejs-atmosphere-aerial-perspective/references/atmosphere.md +204 -20
  4. package/templates/skills/genex-threejs-bloom/SKILL.md +29 -18
  5. package/templates/skills/genex-threejs-bloom/references/bloom.md +176 -20
  6. package/templates/skills/genex-threejs-camera-direction/SKILL.md +38 -26
  7. package/templates/skills/genex-threejs-camera-direction/references/camera-rigs.md +359 -27
  8. package/templates/skills/genex-threejs-exposure-color-grading/SKILL.md +27 -18
  9. package/templates/skills/genex-threejs-exposure-color-grading/references/exposure-grading.md +196 -21
  10. package/templates/skills/genex-threejs-image-pipeline/SKILL.md +38 -17
  11. package/templates/skills/genex-threejs-image-pipeline/references/image-pipeline.md +185 -29
  12. package/templates/skills/genex-threejs-procedural-animation/SKILL.md +34 -21
  13. package/templates/skills/genex-threejs-procedural-animation/references/procedural-motion.md +353 -24
  14. package/templates/skills/genex-threejs-procedural-architecture/SKILL.md +36 -17
  15. package/templates/skills/genex-threejs-procedural-architecture/references/architecture-systems.md +500 -22
  16. package/templates/skills/genex-threejs-procedural-fields/SKILL.md +59 -24
  17. package/templates/skills/genex-threejs-procedural-fields/references/field-systems.md +222 -25
  18. package/templates/skills/genex-threejs-procedural-geometry/SKILL.md +34 -20
  19. package/templates/skills/genex-threejs-procedural-geometry/references/mesh-systems.md +192 -26
  20. package/templates/skills/genex-threejs-procedural-materials/SKILL.md +55 -18
  21. package/templates/skills/genex-threejs-procedural-materials/references/material-systems.md +189 -22
  22. package/templates/skills/genex-threejs-procedural-planets/SKILL.md +36 -18
  23. package/templates/skills/genex-threejs-procedural-planets/references/planet-systems.md +489 -21
  24. package/templates/skills/genex-threejs-procedural-vegetation/SKILL.md +35 -25
  25. package/templates/skills/genex-threejs-procedural-vegetation/references/vegetation-systems.md +304 -27
  26. package/templates/skills/genex-threejs-procedural-vfx/SKILL.md +26 -18
  27. package/templates/skills/genex-threejs-procedural-vfx/references/vfx-systems.md +208 -20
  28. package/templates/skills/genex-threejs-raymarched-space-effects/SKILL.md +25 -18
  29. package/templates/skills/genex-threejs-raymarched-space-effects/references/space-effects.md +185 -21
  30. package/templates/skills/genex-threejs-screen-space-ambient-occlusion/SKILL.md +23 -17
  31. package/templates/skills/genex-threejs-screen-space-ambient-occlusion/references/ambient-occlusion.md +430 -20
  32. package/templates/skills/genex-threejs-shadow-systems/SKILL.md +29 -18
  33. package/templates/skills/genex-threejs-shadow-systems/references/shadow-systems.md +420 -21
  34. package/templates/skills/genex-threejs-skill-router/SKILL.md +21 -21
  35. package/templates/skills/genex-threejs-spectral-ocean/SKILL.md +30 -20
  36. package/templates/skills/genex-threejs-spectral-ocean/references/spectral-ocean.md +462 -22
  37. package/templates/skills/genex-threejs-temporal-surfaces/SKILL.md +26 -17
  38. package/templates/skills/genex-threejs-temporal-surfaces/references/temporal-surfaces.md +198 -20
  39. package/templates/skills/genex-threejs-visual-validation/SKILL.md +34 -18
  40. package/templates/skills/genex-threejs-visual-validation/references/visual-validation.md +396 -32
  41. package/templates/skills/genex-threejs-volumetric-clouds/SKILL.md +33 -17
  42. package/templates/skills/genex-threejs-volumetric-clouds/references/volumetric-clouds.md +570 -21
  43. package/templates/skills/genex-threejs-water-optics/SKILL.md +33 -18
  44. package/templates/skills/genex-threejs-water-optics/references/water-optics.md +184 -20
@@ -1,30 +1,579 @@
1
- # Volumetric Clouds
1
+ # Weather-shaped cloud volume and reconstruction
2
2
 
3
- Use this reference for cloud rendering in Genex games.
3
+ Use this reference for planetary or large-world volumetric clouds built from packed weather layers, generated shape and detail fields, bounded integration, temporal reconstruction, and low-cost cloud shadows.
4
4
 
5
- ## Density model
5
+ ## Contents
6
6
 
7
- - Weather map controls coverage, cloud type, and density scale.
8
- - Height profile controls base, body, and top falloff.
9
- - Detail erosion breaks up silhouettes.
10
- - Wind moves the sample domain consistently over time.
7
+ 1. Four-layer density model
8
+ 2. Packed intervals and generated field assets
9
+ 3. Weather, shape, turbulence, and detail
10
+ 4. Beauty march and lighting
11
+ 5. Temporal reconstruction
12
+ 6. Shadow system and quality presets
13
+ 7. Implementation limits, adaptation, and diagnostics
11
14
 
12
- ## Raymarching
15
+ ## 1. Preserve the four-layer vector model
13
16
 
14
- - Intersect the camera ray with a bounded cloud volume.
15
- - Use coarse steps before expensive lighting.
16
- - Early-exit when transmittance is low.
17
- - Keep step count and resolution adjustable.
17
+ Evaluate four layers in parallel as `vec4` channels. Do not collapse them into
18
+ one scalar weather field before applying per-layer altitude, profile, shape,
19
+ and detail controls.
18
20
 
19
- ## Lighting
21
+ Default active layers:
20
22
 
21
- - Use sun direction from the scene.
22
- - Add forward-scattering emphasis for bright cloud edges.
23
- - Approximate self-shadow with short secondary samples or cached maps.
24
- - Keep cloud shadows optional and low-frequency.
23
+ | Channel | Altitude | Height | Density | Shape | Detail | Coverage width | Shadow |
24
+ | --- | ---: | ---: | ---: | ---: | ---: | ---: | --- |
25
+ | R low | 750 m | 650 m | 0.2 | 1.0 | 1.0 | 0.6 | yes |
26
+ | G middle | 1000 m | 1200 m | 0.2 | 1.0 | 1.0 | 0.6 | yes |
27
+ | B high | 7500 m | 500 m | 0.003 | 0.4 | 0.0 | 0.5 | no |
28
+ | A spare | disabled | disabled | default | default | default | default | no |
25
29
 
26
- ## Temporal behavior
30
+ Each layer also owns:
27
31
 
28
- - Reprojection can reduce cost but must expose history diagnostics.
29
- - Validate camera cuts, fast turns, and pause/resume behavior.
30
- - Provide a single-frame mode for debugging.
32
+ ```ts
33
+ type Layer = {
34
+ weatherChannel: "r" | "g" | "b" | "a"
35
+ weatherExponent: number
36
+ shapeAlteringBias: number
37
+ densityProfile: {
38
+ exponentialTerm: number
39
+ exponent: number
40
+ linearTerm: number
41
+ constantTerm: number
42
+ }
43
+ }
44
+ ```
45
+
46
+ Default density profile:
47
+
48
+ ```text
49
+ profile(h) =
50
+ expTerm * exp(exponent * h)
51
+ + linearTerm * h
52
+ + constantTerm
53
+
54
+ default = 0.75 * h + 0.25
55
+ ```
56
+
57
+ The profile is not a generic bottom/top smoothstep. It is a compact
58
+ artist-authored function that can produce rising, falling, or exponential
59
+ density by layer.
60
+
61
+ ## 2. Understand the packed interval subtlety
62
+
63
+ The layer system sorts all lower/upper altitude endpoints and merges occupied
64
+ ranges. It then packs up to three intervals where the active-layer balance is
65
+ zero.
66
+
67
+ Those packed intervals are **empty gaps**, despite names such as
68
+ `minIntervalHeights` and `insideLayerIntervals`.
69
+
70
+ Beauty and shadow marches use:
71
+
72
+ ```glsl
73
+ if (height is inside any packed gap) {
74
+ skip density work;
75
+ }
76
+ ```
77
+
78
+ For the default layers, the low and middle ranges merge into one occupied band
79
+ from 750–2200 m, followed by an empty gap before the 7500–8000 m high layer.
80
+
81
+ If adapting the system:
82
+
83
+ 1. merge occupied layer ranges on CPU;
84
+ 2. pack the complementary gaps;
85
+ 3. verify the debug view labels them as skipped intervals;
86
+ 4. do not accidentally skip the occupied bands.
87
+
88
+ ## 3. Generate field assets once
89
+
90
+ Render procedural textures into repeatable targets, then sample them during
91
+ the expensive march.
92
+
93
+ ### Local weather RGBA
94
+
95
+ The procedural weather texture assigns:
96
+
97
+ ```text
98
+ R: low-cloud Worley FBM
99
+ G: middle-cloud Worley FBM
100
+ B: high-cloud anisotropic Perlin
101
+ A: auxiliary Perlin variation
102
+ ```
103
+
104
+ Low and middle fields are intentionally separated:
105
+
106
+ ```text
107
+ middle = smoothstep(1.0, 1.4, WorleyFBM(point + 0.5))
108
+ low = saturate(
109
+ smoothstep(0.8, 1.4, WorleyFBM(point))
110
+ - middle
111
+ )
112
+ ```
113
+
114
+ The generation pass later forces alpha to `1`, so the default spare A layer is
115
+ not a second generated weather population. Preserve that behavior when using
116
+ the complete packed-layer contract.
117
+
118
+ ### Base shape volume
119
+
120
+ The 3D base texture combines Perlin-Worley and Worley FBM:
121
+
122
+ ```text
123
+ perlinWorley =
124
+ remap(perlin, 0, 1, worleyFBM, 1)
125
+
126
+ baseShape =
127
+ remap(perlinWorley, worleyFBM - 1, 1)
128
+ ```
129
+
130
+ The octave weights are dominated by low frequencies:
131
+
132
+ ```text
133
+ 0.625, 0.25, 0.125
134
+ ```
135
+
136
+ ### Detail volume
137
+
138
+ The detail volume is Worley-only and builds three progressively finer FBM
139
+ bands from frequencies `2, 4, 8, 16`, again weighted toward low frequencies.
140
+
141
+ ### Turbulence
142
+
143
+ The 2D turbulence texture stores a normalized curl field derived from three
144
+ offset Perlin channels. It warps shape coordinates; it is not multiplied into
145
+ final density as arbitrary noise.
146
+
147
+ Generate these textures once or only when their recipes change. A 3D
148
+ render-target path requires one draw per Z layer, so regenerating each frame is
149
+ unacceptable.
150
+
151
+ ## 4. Weather coverage response
152
+
153
+ For each sample:
154
+
155
+ ```text
156
+ heightFraction =
157
+ remapClamped(height, layerMin, layerMax)
158
+ ```
159
+
160
+ Round cloud growth toward the upper portion:
161
+
162
+ ```text
163
+ biased = heightFraction ^ shapeAlteringBias
164
+ x = clamp(2 * biased - 1, -1, 1)
165
+ heightScale = 1 - x²
166
+ ```
167
+
168
+ Sample the four selected weather channels, apply each layer’s exponent, then
169
+ modulate by global coverage:
170
+
171
+ ```text
172
+ factor = 1 - coverage * heightScale
173
+ density =
174
+ remapClamped(
175
+ mix(localWeather, 1, coverageFilterWidth),
176
+ factor,
177
+ factor + coverageFilterWidth
178
+ )
179
+ ```
180
+
181
+ Global coverage therefore shifts/remaps local weather. It is not a final
182
+ density multiplier.
183
+
184
+ Debug separately:
185
+
186
+ ```text
187
+ raw local-weather channels
188
+ weather after exponent
189
+ heightScale
190
+ coverage factor
191
+ coverage-remapped density
192
+ ```
193
+
194
+ ## 5. Base shape and turbulence
195
+
196
+ Advect fields through offsets rather than regenerating them:
197
+
198
+ ```text
199
+ localWeatherOffset += localWeatherVelocity * dt
200
+ shapeOffset += shapeVelocity * dt
201
+ detailOffset += detailVelocity * dt
202
+ turbulenceOffset += turbulenceVelocity * dt
203
+ ```
204
+
205
+ The density path adds a radial “evolution” offset related to weather speed,
206
+ then optional turbulence:
207
+
208
+ ```text
209
+ surfaceNormal = normalize(position)
210
+ evolution = -surfaceNormal * length(weatherOffset) * 20000
211
+
212
+ turbulence =
213
+ displacement
214
+ * (curlTexture * 2 - 1)
215
+ * lowHeightMask
216
+ ```
217
+
218
+ The turbulence mask fades out by roughly the lower 30% of each layer, so it
219
+ distorts bases and growth without scrambling the entire cloud.
220
+
221
+ Base shape:
222
+
223
+ ```text
224
+ shapePosition =
225
+ (position + evolution + turbulence)
226
+ * shapeRepeat
227
+ + shapeOffset
228
+
229
+ density =
230
+ remapClamped(
231
+ weatherDensity,
232
+ (1 - shapeNoise) * shapeAmount,
233
+ 1
234
+ )
235
+ ```
236
+
237
+ Shape amount is per layer. High cirrus uses less base-shape influence.
238
+
239
+ ## 6. Detail changes topology by height
240
+
241
+ The detail modifier is not uniform erosion.
242
+
243
+ ```text
244
+ top modifier = detail^6
245
+ bottom modifier = 1 - detail
246
+
247
+ modifier =
248
+ mix(
249
+ top modifier,
250
+ bottom modifier,
251
+ remapClamped(heightFraction, 0.2, 0.4)
252
+ )
253
+ ```
254
+
255
+ This makes upper cloud detail fluffy and lower detail whippy/eroded. Then:
256
+
257
+ ```text
258
+ modifier *= shapeDetailAmount
259
+ density =
260
+ remapClamped(
261
+ density * 2,
262
+ modifier * 0.5,
263
+ 1
264
+ )
265
+ ```
266
+
267
+ Detail is skipped at coarse mip levels using a jittered threshold. Do not spend
268
+ high-frequency texture reads when the sample footprint cannot resolve them.
269
+
270
+ Finally:
271
+
272
+ ```text
273
+ densityVector =
274
+ saturate(
275
+ densityVector
276
+ * densityScales
277
+ * profile(heightFraction)
278
+ )
279
+
280
+ totalDensity = sum(densityVector)
281
+ layerWeight = densityVector / totalDensity
282
+ scattering = totalDensity * scatteringCoefficient
283
+ extinction =
284
+ totalDensity * absorptionCoefficient
285
+ + scattering
286
+ ```
287
+
288
+ Guard zero total density before using layer weights in an independent
289
+ implementation.
290
+
291
+ ## 7. Planetary ray interval
292
+
293
+ Intersect view rays with concentric spheres at:
294
+
295
+ ```text
296
+ planet radius
297
+ minimum cloud altitude
298
+ maximum cloud altitude
299
+ shadow top altitude
300
+ ```
301
+
302
+ Select near/far based on camera state:
303
+
304
+ ```text
305
+ below clouds
306
+ inside total cloud layer
307
+ above clouds
308
+ ray intersects ground
309
+ ```
310
+
311
+ Then clamp the far distance against opaque scene depth. The beauty march never
312
+ runs beyond the nearest opaque surface.
313
+
314
+ Return explicit diagnostic flags:
315
+
316
+ ```text
317
+ ground intersection
318
+ scene occlusion
319
+ camera region
320
+ near distance
321
+ far distance
322
+ selected sphere intersections
323
+ ```
324
+
325
+ ## 8. Primary march policy
326
+
327
+ High/default values:
328
+
329
+ ```text
330
+ max iterations: 500
331
+ minimum step: 50 m
332
+ maximum step: 1000 m
333
+ maximum ray distance: 200 km
334
+ perspective step scale: 1.01
335
+ minimum density: 1e-5
336
+ minimum extinction: 1e-5
337
+ minimum transmittance: 1e-2
338
+ ```
339
+
340
+ Initial step size grows with ray entry distance:
341
+
342
+ ```text
343
+ step =
344
+ minStep
345
+ + (perspectiveScale - 1) * rayNear
346
+ ```
347
+
348
+ Jitter the first step with spatiotemporal blue noise. Double the jitter
349
+ distance when needed to suppress spatial aliasing.
350
+
351
+ At each sample:
352
+
353
+ 1. skip packed empty altitude gaps;
354
+ 2. sample rough weather;
355
+ 3. if all layer densities are below threshold, take a longer mip-aware step;
356
+ 4. otherwise sample base shape, optional turbulence, and detail;
357
+ 5. if extinction is significant, evaluate lighting and integrate;
358
+ 6. terminate at the transmittance threshold.
359
+
360
+ Long empty-space steps can band near a dense crossing. Treat this as a known
361
+ defect, not a solved feature. A robust adaptation can binary-search the first
362
+ dense crossing.
363
+
364
+ ## 9. Lighting contract
365
+
366
+ Per occupied sample, evaluate:
367
+
368
+ ```text
369
+ sun irradiance
370
+ sky irradiance
371
+ short optical-depth march toward sun
372
+ Beer shadow-map optical depth beyond that short march
373
+ multi-scattering approximation
374
+ optional ground bounce
375
+ sky gradient contribution
376
+ powder attenuation
377
+ ```
378
+
379
+ The phase function defaults to two Henyey-Greenstein lobes. An optional fitted
380
+ large-particle phase path exists, but it requires adequate multiple scattering
381
+ to remain plausible.
382
+
383
+ Multi-scattering uses octave accumulation:
384
+
385
+ ```text
386
+ for each octave:
387
+ contribution +=
388
+ attenuationA
389
+ * exp(-opticalDepth * attenuationB)
390
+ * phase(cosTheta, attenuationC)
391
+ attenuation *= 0.5
392
+ ```
393
+
394
+ Default high quality uses eight octaves.
395
+
396
+ Energy-conserving integration:
397
+
398
+ ```text
399
+ stepT = exp(-extinction * stepLength)
400
+ stepScatter =
401
+ (radiance - radiance * stepT)
402
+ / max(extinction, epsilon)
403
+
404
+ accumulatedRadiance += accumulatedT * stepScatter
405
+ accumulatedT *= stepT
406
+ ```
407
+
408
+ Representative depth is a transmittance-weighted sample distance. It is used
409
+ for aerial perspective and temporal velocity, not merely visualized.
410
+
411
+ ## 10. Quarter-resolution temporal upscale
412
+
413
+ The temporal-upscale path renders the current clouds at one quarter linear
414
+ resolution:
415
+
416
+ ```text
417
+ lowWidth = ceil(fullWidth / 4)
418
+ lowHeight = ceil(fullHeight / 4)
419
+ ```
420
+
421
+ A 4×4 Bayer pattern chooses one current full-resolution pixel per low-resolution
422
+ texel over 16 frames. Projection jitter follows the same offset.
423
+
424
+ Current targets store:
425
+
426
+ ```text
427
+ RGBA cloud radiance/transmittance
428
+ RGB representative depth + velocity
429
+ optional shadow length
430
+ ```
431
+
432
+ Resolve:
433
+
434
+ 1. use the newly rendered current texel when its Bayer index matches the frame;
435
+ 2. otherwise choose the closest-depth sample in a 3×3 neighborhood;
436
+ 3. reproject with velocity;
437
+ 4. reject history outside the viewport;
438
+ 5. variance-clip history against current neighbors;
439
+ 6. write the resolved result and swap history buffers.
440
+
441
+ For full-resolution TAA, blend clipped history toward current with default
442
+ `temporalAlpha = 0.1`.
443
+
444
+ Reset history on:
445
+
446
+ ```text
447
+ camera cut
448
+ resolution or render-scale change
449
+ weather/shape discontinuity
450
+ layer topology change
451
+ projection mode change
452
+ ```
453
+
454
+ ## 11. Cloud shadow representation
455
+
456
+ The shadow system is not a grayscale beauty march. Each cascade stores:
457
+
458
+ ```text
459
+ R front depth
460
+ G mean extinction
461
+ B maximum accumulated optical depth
462
+ A optical-depth tail estimate after early termination
463
+ ```
464
+
465
+ Beauty lighting reconstructs optical depth beyond a local short sun march from
466
+ this compact representation.
467
+
468
+ Shadow marching uses structured volume sampling:
469
+
470
+ 1. choose one of three icosahedral structure normals from ray direction and
471
+ jitter;
472
+ 2. intersect regularly spaced planes perpendicular to that normal;
473
+ 3. march samples on those planes.
474
+
475
+ This intentionally trades some spatial aliasing for strong temporal stability,
476
+ which matters for low-resolution cascaded shadow maps.
477
+
478
+ Default shadow budget:
479
+
480
+ ```text
481
+ 3 cascades
482
+ 512 × 512 maps
483
+ 50 iterations
484
+ 100–1000 m step size
485
+ minimum transmittance 1e-4
486
+ ```
487
+
488
+ Low tier:
489
+
490
+ ```text
491
+ 2 cascades
492
+ 256 × 256 maps
493
+ 25 iterations
494
+ minimum transmittance 1e-2
495
+ ```
496
+
497
+ ## 12. Quality tiers must remove expensive mechanisms intentionally
498
+
499
+ The low tier disables:
500
+
501
+ ```text
502
+ light shafts
503
+ shape detail
504
+ turbulence
505
+ ground bounce
506
+ accurate sun/sky lookup
507
+ ```
508
+
509
+ It keeps:
510
+
511
+ ```text
512
+ weather-shaped density
513
+ base 3D shape
514
+ one short sun march
515
+ temporal reconstruction
516
+ cloud shadows at reduced quality
517
+ ```
518
+
519
+ This is a legitimate fallback because silhouette, weather control, and
520
+ directional self-shadowing survive.
521
+
522
+ ## 13. Required diagnostics
523
+
524
+ Expose:
525
+
526
+ ```text
527
+ weather RGBA
528
+ per-layer height fractions
529
+ packed empty intervals
530
+ coverage-remapped density
531
+ base shape
532
+ detail modifier
533
+ turbulence displacement
534
+ final per-layer density vector
535
+ total scattering/extinction
536
+ ray near/far and scene clamp
537
+ primary/shape/detail sample counts
538
+ sun optical depth
539
+ Beer shadow-map channels
540
+ transmittance
541
+ representative depth
542
+ velocity
543
+ history UV
544
+ variance bounds
545
+ history rejection
546
+ shadow cascade index
547
+ shadow structured-sampling planes
548
+ ```
549
+
550
+ ## 14. Failure diagnosis
551
+
552
+ ```text
553
+ clouds disappear between low and high layers:
554
+ occupied ranges were mistaken for packed empty gaps
555
+
556
+ all cloud types share one silhouette:
557
+ layer vectors were summed before profile/shape controls
558
+
559
+ porous smoke:
560
+ detail was added uniformly instead of height-dependent remapping
561
+
562
+ boiling motion:
563
+ field offsets use unrelated directions/speeds or textures regenerate
564
+
565
+ bright flat interior:
566
+ short sun optical depth or shadow map is missing
567
+
568
+ dark featureless cloud:
569
+ multi-scattering, sky light, or powder balance is absent
570
+
571
+ edge trails:
572
+ representative depth/velocity is wrong or history lacks variance clipping
573
+
574
+ flickering cloud shadows:
575
+ beauty jitter was reused instead of temporally stable structured sampling
576
+
577
+ cost scales with view distance:
578
+ shell interval, scene depth clamp, or empty-gap skipping is broken
579
+ ```
@@ -5,26 +5,41 @@ description: Build analytic water surfaces for Genex Three.js games. Use for riv
5
5
 
6
6
  # Genex Three.js Water Optics
7
7
 
8
- Use analytic water when the game needs readable local water with clear
9
- interaction, refraction, and shading without a full ocean simulation.
8
+ Treat water as geometry motion, surface orientation, and a participating optical layer. A blue transparent material is not a water system.
10
9
 
11
- Read [references/water-optics.md](references/water-optics.md) for wave,
12
- normal, refraction, and fallback patterns.
10
+ For large stochastic seas driven by directional spectra and GPU FFTs, use
11
+ `$genex-threejs-spectral-ocean` instead.
13
12
 
14
- ## Build order
13
+ ## Analytic surface build order
15
14
 
16
- 1. Define water role: pool, river, lake, shoreline, hazard, boundary, or
17
- traversal affordance.
18
- 2. Build shared wave displacement and normals from named wave bands.
19
- 3. Add Fresnel reflection, absorption, depth color, and controlled refraction.
20
- 4. Derive crest foam and shoreline foam from wave height, slope, or masks.
21
- 5. Add interaction ripples only after the base water reads.
22
- 6. Expose debug views for displacement, normals, depth, refraction, and foam.
15
+ 1. Define wave bands and evaluate displacement.
16
+ 2. Derive the normal analytically from the same waves.
17
+ 3. Choose displaced geometry or explicitly normal-only water.
18
+ 4. Establish scene-color ownership for heuristic refraction.
19
+ 5. Declare whether absorption uses true depth or a fallback path-length estimate.
20
+ 6. Blend analytic reflection/refraction through side-aware Fresnel.
21
+ 7. Derive foam and glints from the shared wave response.
22
+ 8. Filter unresolved normal bands from derivatives.
23
23
 
24
- ## Rules
24
+ Read [references/water-optics.md](references/water-optics.md)
25
+ for the exact five-wave displaced ocean, six-band normal-only water, optical
26
+ hierarchy, and the limits that distinguish both from the spectral-ocean skill.
25
27
 
26
- - Use the same wave state for geometry, normals, and foam.
27
- - Keep refraction optional; provide a readable fallback.
28
- - Avoid screen-space refraction artifacts at silhouettes and edges.
29
- - Bound normal intensity so water does not shimmer in motion.
30
- - Keep gameplay collision and visual displacement expectations aligned.
28
+ ## Failure conditions
29
+
30
+ - normal texture motion does not agree with displaced crests;
31
+ - heuristic refraction can sample foreground objects but the limitation is undisclosed;
32
+ - fallback path length is presented as reconstructed scene thickness;
33
+ - bounded pool caustics are a decorative projection detached from simulated
34
+ height normals;
35
+ - micro-waves alias into sparkling noise;
36
+ - foam is a scrolling texture unrelated to the shared crest metric;
37
+ - Fresnel is replaced by constant opacity;
38
+ - reflection, refraction, and transparency are all added without energy control.
39
+
40
+ ## Routing boundary
41
+
42
+ Use `$genex-threejs-spectral-ocean` for stochastic directional spectra, FFT
43
+ cascades, Jacobian breaking, and persistent ocean foam. This skill owns
44
+ authored analytic waves, bounded heightfield simulation, ray-traced
45
+ pool-volume optics, and bounded-water optics.