@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,31 +1,471 @@
|
|
|
1
|
-
# Spectral
|
|
1
|
+
# Spectral cascade ocean system
|
|
2
2
|
|
|
3
|
-
Use this
|
|
3
|
+
Use this reference for a large, unbounded-looking ocean whose identity comes from directional spectral synthesis, staged inverse FFTs, derivative maps, Jacobian whitecaps, and coherent optical shading.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Contents
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
1. Architecture and cascade partition
|
|
8
|
+
2. Directional spectrum and Hermitian packing
|
|
9
|
+
3. GPU inverse FFT and hard validation gate
|
|
10
|
+
4. Spatial displacement and derivative maps
|
|
11
|
+
5. Jacobian foam history
|
|
12
|
+
6. Surface shading, detail, and spray
|
|
13
|
+
7. Quality modes, defects, and diagnostics
|
|
12
14
|
|
|
13
|
-
##
|
|
15
|
+
## 1. Architecture contract
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
- Store foam history when persistence matters.
|
|
17
|
-
- Fade foam by age and water motion.
|
|
18
|
-
- Keep foam masks inspectable separately from final shading.
|
|
17
|
+
Keep these stages distinct and inspectable:
|
|
19
18
|
|
|
20
|
-
|
|
19
|
+
```text
|
|
20
|
+
sea-state parameters
|
|
21
|
+
-> deterministic Gaussian field
|
|
22
|
+
-> initial directional spectrum h0(k)
|
|
23
|
+
-> conjugate packing h0(k), conj(h0(-k))
|
|
24
|
+
-> time-evolved packed frequency fields
|
|
25
|
+
-> horizontal IFFT stages
|
|
26
|
+
-> vertical IFFT stages
|
|
27
|
+
-> centered-spectrum permutation
|
|
28
|
+
-> displacement + derivative + foam-history maps
|
|
29
|
+
-> displaced surface + optical shading
|
|
30
|
+
```
|
|
21
31
|
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
- Keep crest scatter and emission-like highlights bounded.
|
|
32
|
+
One cascade owns one patch length and one disjoint wavenumber interval. Shared
|
|
33
|
+
sea-state uniforms and Gaussian seeds keep the cascades statistically related;
|
|
34
|
+
separate buffers prevent writes from aliasing.
|
|
26
35
|
|
|
27
|
-
|
|
36
|
+
The 256², three-cascade configuration uses:
|
|
28
37
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
38
|
+
```ts
|
|
39
|
+
const oceanPreset = {
|
|
40
|
+
resolution: 256,
|
|
41
|
+
patchLengthsMeters: [250, 17, 5],
|
|
42
|
+
boundaryFactor: 6,
|
|
43
|
+
depthMeters: 500,
|
|
44
|
+
gravity: 9.81,
|
|
45
|
+
choppiness: 1.3,
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Treat these as a validated starting scale, not universal constants.
|
|
50
|
+
|
|
51
|
+
## 2. Cascade partition
|
|
52
|
+
|
|
53
|
+
For cascade `i`, define:
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
deltaK(i) = 2π / patchLength(i)
|
|
57
|
+
handoff(i) = 2π / patchLength(i) * boundaryFactor
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Use:
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
cascade 0: [epsilon, handoff(1)]
|
|
64
|
+
cascade 1: [handoff(1), handoff(2)]
|
|
65
|
+
cascade 2: [handoff(2), largeUpperBound]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The in-band mask must be applied after all singular inputs have been made safe.
|
|
69
|
+
Do not rely on multiplication by zero to hide `1/0`, `sqrt(NaN)`, or infinite
|
|
70
|
+
frequency derivatives. Clamp the evaluated wavenumber first:
|
|
71
|
+
|
|
72
|
+
```glsl
|
|
73
|
+
float kSafe = max(kLength, cutoffLow);
|
|
74
|
+
float inBand =
|
|
75
|
+
step(cutoffLow, kLength) *
|
|
76
|
+
step(kLength, cutoffHigh);
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Debug every cascade as a centered spectrum heatmap. Adjacent bands may touch
|
|
80
|
+
at a boundary; they must not overlap broadly or leave a visible spectral hole.
|
|
81
|
+
|
|
82
|
+
## 3. Initial directional spectrum
|
|
83
|
+
|
|
84
|
+
Generate two independent standard-normal values per grid cell once. Seed the
|
|
85
|
+
generator explicitly so image comparisons and regression tests are stable.
|
|
86
|
+
|
|
87
|
+
For each centered grid coordinate:
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
k = (gridIndex - N/2) * deltaK
|
|
91
|
+
omega(k) = sqrt(g * |k| * tanh(min(|k| * depth, 20)))
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The sea state sums two spectra:
|
|
95
|
+
|
|
96
|
+
```text
|
|
97
|
+
energy =
|
|
98
|
+
localWindSea(omega, direction)
|
|
99
|
+
+ swell(omega, direction)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Each term combines:
|
|
103
|
+
|
|
104
|
+
```text
|
|
105
|
+
JONSWAP frequency energy
|
|
106
|
+
* TMA finite-depth correction
|
|
107
|
+
* directional spreading
|
|
108
|
+
* exp(-shortWaveFade² * |k|²)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Compute JONSWAP peak terms from wind speed and fetch:
|
|
112
|
+
|
|
113
|
+
```text
|
|
114
|
+
alpha = 0.076 * (g * fetch / windSpeed²)^(-0.22)
|
|
115
|
+
peakOmega = 22 * (windSpeed * fetch / g²)^(-0.33)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Use the standard JONSWAP sigma split around the peak (`0.07` below, `0.09`
|
|
119
|
+
above), peak enhancement `gamma`, and an explicit scale per local/swell lobe.
|
|
120
|
+
|
|
121
|
+
Directional spreading must rotate around the configured wind angle and tighten
|
|
122
|
+
as the frequency approaches the energetic range. Blend a broad cosine-squared
|
|
123
|
+
base with a Donelan–Banner-style powered cosine lobe.
|
|
124
|
+
|
|
125
|
+
Initial complex amplitude:
|
|
126
|
+
|
|
127
|
+
```text
|
|
128
|
+
amplitude =
|
|
129
|
+
sqrt(
|
|
130
|
+
energy
|
|
131
|
+
* 2
|
|
132
|
+
* abs(dOmega/dk)
|
|
133
|
+
/ kSafe
|
|
134
|
+
* deltaK²
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
h0(k) = gaussianComplex(k) * amplitude * inBand
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Expose at least:
|
|
141
|
+
|
|
142
|
+
```text
|
|
143
|
+
local-only spectrum
|
|
144
|
+
swell-only spectrum
|
|
145
|
+
combined spectrum
|
|
146
|
+
in-band mask
|
|
147
|
+
frequency derivative
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## 4. Hermitian pairing and packed fields
|
|
151
|
+
|
|
152
|
+
Real spatial fields require conjugate symmetry. Store:
|
|
153
|
+
|
|
154
|
+
```text
|
|
155
|
+
packedH0(k) = [h0(k), conjugate(h0(-k))]
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
At time `t`:
|
|
159
|
+
|
|
160
|
+
```text
|
|
161
|
+
h(k,t) =
|
|
162
|
+
h0(k) * exp(i * omega * t)
|
|
163
|
+
+ conjugate(h0(-k)) * exp(-i * omega * t)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Compute horizontal displacement from `i * k / |k| * h`, vertical displacement
|
|
167
|
+
from `h`, and spatial derivatives by multiplying by the relevant wave-number
|
|
168
|
+
components.
|
|
169
|
+
|
|
170
|
+
Pack two real spatial fields into one complex IFFT input. A useful four-buffer
|
|
171
|
+
layout is:
|
|
172
|
+
|
|
173
|
+
```text
|
|
174
|
+
field 0: horizontal displacement X + i horizontal displacement Z
|
|
175
|
+
field 1: height + i cross derivative
|
|
176
|
+
field 2: height slope X + i height slope Z
|
|
177
|
+
field 3: horizontal derivative XX + i horizontal derivative ZZ
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Packing halves the number of transforms. Document the unpacking algebra next
|
|
181
|
+
to the field contract; a swapped real/imaginary sign can look plausible while
|
|
182
|
+
rotating or mirroring the sea.
|
|
183
|
+
|
|
184
|
+
## 5. GPU inverse FFT schedule
|
|
185
|
+
|
|
186
|
+
Precompute a butterfly table on the CPU for every FFT stage and output column:
|
|
187
|
+
|
|
188
|
+
```ts
|
|
189
|
+
type ButterflyEntry = {
|
|
190
|
+
twiddleReal: number
|
|
191
|
+
twiddleImaginary: number
|
|
192
|
+
inputA: number
|
|
193
|
+
inputB: number
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
For each complex field:
|
|
198
|
+
|
|
199
|
+
1. execute `log2(N)` horizontal butterfly stages;
|
|
200
|
+
2. execute `log2(N)` vertical butterfly stages;
|
|
201
|
+
3. multiply by `(-1)^(x+y)` to reconcile centered frequency coordinates.
|
|
202
|
+
|
|
203
|
+
Ping-pong between the field buffer and a dedicated scratch buffer. Never let
|
|
204
|
+
two logical fields share scratch storage during the same stage.
|
|
205
|
+
|
|
206
|
+
The critical WebGPU backend rule is:
|
|
207
|
+
|
|
208
|
+
```text
|
|
209
|
+
one FFT stage -> one compute submission boundary
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Do not assume writes from one dispatch are visible to the next dispatch inside
|
|
213
|
+
an implementation-defined combined pass. Batch independent fields at the same
|
|
214
|
+
stage into one submission, then submit the next stage:
|
|
215
|
+
|
|
216
|
+
```ts
|
|
217
|
+
for (let stage = 0; stage < logN; stage++) {
|
|
218
|
+
renderer.compute(allHorizontalFieldsAt(stage))
|
|
219
|
+
}
|
|
220
|
+
for (let stage = 0; stage < logN; stage++) {
|
|
221
|
+
renderer.compute(allVerticalFieldsAt(stage))
|
|
222
|
+
}
|
|
223
|
+
renderer.compute(allCenteringPermutations)
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Inspect the installed renderer before relying on this exact API shape.
|
|
227
|
+
|
|
228
|
+
## 6. FFT hard gate
|
|
229
|
+
|
|
230
|
+
Validate the transform before connecting the spectrum:
|
|
231
|
+
|
|
232
|
+
```text
|
|
233
|
+
test A:
|
|
234
|
+
centered DC impulse
|
|
235
|
+
expected spatial result = constant complex (1, 0)
|
|
236
|
+
|
|
237
|
+
test B:
|
|
238
|
+
centered one-bin X-frequency impulse
|
|
239
|
+
expected spatial result =
|
|
240
|
+
cos(2πx/N) + i sin(2πx/N)
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Measure maximum absolute error over every texel. A practical gate for half- or
|
|
244
|
+
single-precision storage is `1e-3`, adjusted only with evidence.
|
|
245
|
+
|
|
246
|
+
If either test fails, stop. Do not tune spectrum amplitude, choppiness, or
|
|
247
|
+
shading around a broken transform.
|
|
248
|
+
|
|
249
|
+
Diagnostic causes:
|
|
250
|
+
|
|
251
|
+
```text
|
|
252
|
+
constant test alternates signs -> missing or duplicated centering permutation
|
|
253
|
+
sine direction reversed -> inverse twiddle sign is wrong
|
|
254
|
+
frequency appears on Y -> horizontal/vertical indexing is swapped
|
|
255
|
+
every other stage corrupts -> ping-pong source/destination parity is wrong
|
|
256
|
+
random blocks -> missing inter-stage visibility boundary
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## 7. Spatial map assembly
|
|
260
|
+
|
|
261
|
+
Assemble filterable repeating textures after the IFFT:
|
|
262
|
+
|
|
263
|
+
```text
|
|
264
|
+
displacement.rgba =
|
|
265
|
+
[lambda * Dx, height, lambda * Dz, foamHistory]
|
|
266
|
+
|
|
267
|
+
derivatives.rgba =
|
|
268
|
+
[dHeight/dx, dHeight/dz, lambda * dDx/dx, lambda * dDz/dz]
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Half-float storage textures are a strong bandwidth/quality compromise when the
|
|
272
|
+
target backend supports storage writes and filtered sampling for that format.
|
|
273
|
+
Verify capabilities rather than assuming them.
|
|
274
|
+
|
|
275
|
+
## 8. Jacobian whitecaps with history
|
|
276
|
+
|
|
277
|
+
Choppy horizontal displacement can fold. Build the 2×2 horizontal mapping
|
|
278
|
+
Jacobian:
|
|
279
|
+
|
|
280
|
+
```text
|
|
281
|
+
jxx = 1 + lambda * dDx/dx
|
|
282
|
+
jzz = 1 + lambda * dDz/dz
|
|
283
|
+
jxz = lambda * dDz/dx
|
|
284
|
+
J = jxx * jzz - jxz²
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Low or negative `J` identifies real fold/compression regions. Store a persistent
|
|
288
|
+
per-texel history initialized to `1`.
|
|
289
|
+
|
|
290
|
+
One effective update shape is:
|
|
291
|
+
|
|
292
|
+
```text
|
|
293
|
+
historyNext =
|
|
294
|
+
min(
|
|
295
|
+
currentJacobian,
|
|
296
|
+
historyPrevious
|
|
297
|
+
+ dt * recoveryRate / max(currentJacobian, 0.5)
|
|
298
|
+
)
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
This snaps toward a breaking event and recovers gradually. Keep simulation
|
|
302
|
+
history separate from the display threshold:
|
|
303
|
+
|
|
304
|
+
```text
|
|
305
|
+
foamCoverage =
|
|
306
|
+
smoothstep(lowCoverage, highCoverage,
|
|
307
|
+
sum(saturate((foamThreshold - history) * foamScale)))
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
Do not include a finest cascade that produces constant speckle merely because
|
|
311
|
+
it is available. Validate each cascade’s foam contribution separately.
|
|
312
|
+
|
|
313
|
+
## 9. Fold-aware surface normal
|
|
314
|
+
|
|
315
|
+
Sum derivative maps across cascades. Horizontal compression changes the height
|
|
316
|
+
slope denominator:
|
|
317
|
+
|
|
318
|
+
```text
|
|
319
|
+
slopeX = sum(dHeight/dx) / (1 + sum(lambda * dDx/dx))
|
|
320
|
+
slopeZ = sum(dHeight/dz) / (1 + sum(lambda * dDz/dz))
|
|
321
|
+
normal = normalize([-slopeX, 1, -slopeZ])
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
This keeps normals coupled to choppy displacement. A normal derived from height
|
|
325
|
+
alone misses overturning/compression behavior.
|
|
326
|
+
|
|
327
|
+
Add sub-grid normal detail only after this resolved normal exists. Sample a
|
|
328
|
+
seamless detail field at two independently scrolling scales and keep its
|
|
329
|
+
strength low enough that it cannot rewrite the swell direction.
|
|
330
|
+
|
|
331
|
+
## 10. Optical composition
|
|
332
|
+
|
|
333
|
+
Use one sky-radiance function for both the dome and reflected ray:
|
|
334
|
+
|
|
335
|
+
```text
|
|
336
|
+
sky(direction) =
|
|
337
|
+
horizon-to-zenith gradient
|
|
338
|
+
+ narrow sun disc
|
|
339
|
+
+ broad sun halo
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
Water-air Fresnel:
|
|
343
|
+
|
|
344
|
+
```text
|
|
345
|
+
F = 0.02 + 0.98 * (1 - saturate(N·V))^5
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
Build the body term from deep color plus crest scatter. Use a
|
|
349
|
+
view/sun/normal half-vector response weighted by crest height, then:
|
|
350
|
+
|
|
351
|
+
```text
|
|
352
|
+
water = mix(body, sky(reflect(-V, N)), F)
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
Foam changes the final response rather than adding a white texture. Shade it
|
|
356
|
+
with sun/sky incidence and modulate brightness with a separate bubbly detail
|
|
357
|
+
field. Do not punch noisy holes in the physically derived foam coverage.
|
|
358
|
+
|
|
359
|
+
The visible sky and reflected sky must share:
|
|
360
|
+
|
|
361
|
+
```text
|
|
362
|
+
sun direction
|
|
363
|
+
sun color
|
|
364
|
+
horizon color
|
|
365
|
+
zenith color
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
Otherwise the reflection will appear pasted onto the surface.
|
|
369
|
+
|
|
370
|
+
## 11. Runtime order
|
|
371
|
+
|
|
372
|
+
Use this order each frame:
|
|
373
|
+
|
|
374
|
+
```text
|
|
375
|
+
update time and dt uniforms
|
|
376
|
+
compute all time-dependent spectra
|
|
377
|
+
submit horizontal FFT stages
|
|
378
|
+
submit vertical FFT stages
|
|
379
|
+
submit centering permutations
|
|
380
|
+
assemble maps and update foam history
|
|
381
|
+
update optional spray
|
|
382
|
+
render ocean and sky
|
|
383
|
+
resolve GPU timing asynchronously
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
Sea-state changes that alter `h0` should recompute the initial spectrum on
|
|
387
|
+
interaction release, not continuously while dragging a control.
|
|
388
|
+
|
|
389
|
+
## 12. Geometry, camera, and fog
|
|
390
|
+
|
|
391
|
+
The presentation uses:
|
|
392
|
+
|
|
393
|
+
```text
|
|
394
|
+
camera FOV: 55°
|
|
395
|
+
camera: (0, 16, 68)
|
|
396
|
+
target: (0, 0, -20)
|
|
397
|
+
surface: 400 m square, 900 × 900 subdivisions
|
|
398
|
+
fog: horizon-colored exponential fog
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
The dense plane is justified because displacement is evaluated per vertex.
|
|
402
|
+
Scale tessellation against the smallest resolved cascade and camera distance.
|
|
403
|
+
Fog must hide the finite mesh edge before the plane ends.
|
|
404
|
+
|
|
405
|
+
Lower-cost modes should preserve the mechanism:
|
|
406
|
+
|
|
407
|
+
```text
|
|
408
|
+
high: 256², 3 cascades, dense mesh, persistent foam
|
|
409
|
+
medium: 256², 2 cascades, lower mesh tessellation, persistent foam
|
|
410
|
+
low: 128², 2 cascades, no spray, reduced detail texture
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
Do not call a four-wave analytic surface a low-quality FFT tier; that is a
|
|
414
|
+
different representation and should be routed to `$genex-threejs-water-optics`.
|
|
415
|
+
|
|
416
|
+
## 13. Required diagnostics
|
|
417
|
+
|
|
418
|
+
Expose:
|
|
419
|
+
|
|
420
|
+
```text
|
|
421
|
+
FFT test errors
|
|
422
|
+
Gaussian seed field
|
|
423
|
+
per-cascade in-band spectrum
|
|
424
|
+
time-evolved frequency magnitude
|
|
425
|
+
spatial height
|
|
426
|
+
horizontal displacement
|
|
427
|
+
height slopes
|
|
428
|
+
horizontal derivatives
|
|
429
|
+
Jacobian determinant
|
|
430
|
+
foam history
|
|
431
|
+
foam display coverage
|
|
432
|
+
resolved normal
|
|
433
|
+
sub-grid normal contribution
|
|
434
|
+
final without foam
|
|
435
|
+
final without detail
|
|
436
|
+
GPU milliseconds by compute and render phase
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
Capture a fixed camera at multiple times. A single attractive frame cannot
|
|
440
|
+
prove temporal stability, transform correctness, or foam persistence.
|
|
441
|
+
|
|
442
|
+
## 14. Failure diagnosis
|
|
443
|
+
|
|
444
|
+
```text
|
|
445
|
+
periodic square tiles:
|
|
446
|
+
cascade lengths or camera coverage expose repetition; add disjoint scales
|
|
447
|
+
|
|
448
|
+
all waves travel in one artificial line:
|
|
449
|
+
directional spread is too narrow or wind/swell angles are identical
|
|
450
|
+
|
|
451
|
+
energy explodes near the center:
|
|
452
|
+
DC/small-k singularities are evaluated before masking
|
|
453
|
+
|
|
454
|
+
surface moves but normals lag:
|
|
455
|
+
derivative maps are stale or sampled with different coordinates
|
|
456
|
+
|
|
457
|
+
white noise foam:
|
|
458
|
+
thresholding finest-cascade compression without temporal filtering
|
|
459
|
+
|
|
460
|
+
foam disappears instantly:
|
|
461
|
+
history is not persistent or recovery is interpreted as decay-to-zero
|
|
462
|
+
|
|
463
|
+
foam never clears:
|
|
464
|
+
recovery sign or Jacobian denominator clamp is wrong
|
|
465
|
+
|
|
466
|
+
glitter detached from sun:
|
|
467
|
+
visible sky and reflection use different sun direction or color
|
|
468
|
+
|
|
469
|
+
GPU corruption after increasing N:
|
|
470
|
+
FFT stage count, butterfly table, index type, or scratch allocation is wrong
|
|
471
|
+
```
|
|
@@ -5,26 +5,35 @@ description: Build temporal screen-space and surface-history effects for Genex T
|
|
|
5
5
|
|
|
6
6
|
# Genex Three.js Temporal Surfaces
|
|
7
7
|
|
|
8
|
-
Use
|
|
9
|
-
Keep the accumulated state inspectable and resettable.
|
|
8
|
+
Use render-target state when the effect depends on history. Do not fake accumulation with a time-only procedural mask.
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
ping-pong buffers, history masks, blur, and reset rules.
|
|
10
|
+
## Pipeline
|
|
13
11
|
|
|
14
|
-
|
|
12
|
+
```text
|
|
13
|
+
screen-space touch source
|
|
14
|
+
→ ping-pong state update
|
|
15
|
+
→ reduced-resolution scene blur
|
|
16
|
+
→ static structure textures
|
|
17
|
+
→ frost composite
|
|
18
|
+
→ normal/refraction output
|
|
19
|
+
```
|
|
15
20
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
3. Write events into the history buffer with stable coordinates.
|
|
20
|
-
4. Apply blur, diffusion, or erosion as separate passes.
|
|
21
|
-
5. Composite the result into material, refraction, opacity, or color.
|
|
22
|
-
6. Expose debug views for input, history, blur, decay, and final composite.
|
|
21
|
+
Read [references/temporal-surfaces.md](references/temporal-surfaces.md)
|
|
22
|
+
for an exact frost pass graph, pointer-history channels, blur and refraction
|
|
23
|
+
coupling, and implementation defects that must be corrected.
|
|
23
24
|
|
|
24
25
|
## Rules
|
|
25
26
|
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
27
|
+
- Separate persistent state from static noise and scene color.
|
|
28
|
+
- Preserve separate visible-mask and tilt-response channels.
|
|
29
|
+
- Use half-float for this history path unless a measured lower format is equivalent.
|
|
30
|
+
- Convert per-frame history decay to frame-rate-independent decay.
|
|
31
|
+
- Run the two-pass scene blur at reduced resolution.
|
|
32
|
+
- Pre-render static procedural textures once.
|
|
33
|
+
- Define and test resize/reset behavior for both history targets and static targets.
|
|
34
|
+
- Do not route world footprints, object-UV paint, or simulation-plane wetness here; this skill is screen-space.
|
|
35
|
+
|
|
36
|
+
## Routing boundary
|
|
37
|
+
|
|
38
|
+
Use `$genex-threejs-procedural-vfx` for world- or object-space residue, particles, and
|
|
39
|
+
dissolves. This skill owns screen-space persistent history and its composite.
|