@genex-ai/cli-demo 0.93.0-dev.247 → 0.94.0-dev.249

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 (53) hide show
  1. package/dist/index.js +25 -4
  2. package/package.json +1 -1
  3. package/templates/skills/genex-ai-model/SKILL.md +3 -2
  4. package/templates/skills/genex-ai-skybox/SKILL.md +3 -3
  5. package/templates/skills/genex-game-director/SKILL.md +321 -411
  6. package/templates/skills/genex-game-director/references/design-contract.md +130 -179
  7. package/templates/skills/genex-game-director/references/routing-map.md +242 -362
  8. package/templates/skills/genex-threejs-exposure-color-grading/SKILL.md +3 -7
  9. package/templates/skills/genex-threejs-procedural-assets/SKILL.md +112 -0
  10. package/templates/skills/genex-threejs-procedural-materials/SKILL.md +3 -7
  11. package/templates/skills/genex-threejs-procedural-vfx/SKILL.md +6 -11
  12. package/templates/skills/genex-threejs-shadow-systems/SKILL.md +2 -3
  13. package/templates/skills/genex-threejs-visual-validation/SKILL.md +0 -4
  14. package/templates/skills/genex-threejs-atmosphere-aerial-perspective/SKILL.md +0 -46
  15. package/templates/skills/genex-threejs-atmosphere-aerial-perspective/references/atmosphere.md +0 -213
  16. package/templates/skills/genex-threejs-bloom/SKILL.md +0 -44
  17. package/templates/skills/genex-threejs-bloom/references/bloom.md +0 -187
  18. package/templates/skills/genex-threejs-exposure-color-grading/references/exposure-grading.md +0 -205
  19. package/templates/skills/genex-threejs-game-content/SKILL.md +0 -198
  20. package/templates/skills/genex-threejs-game-content/references/content-tables.md +0 -269
  21. package/templates/skills/genex-threejs-image-pipeline/SKILL.md +0 -56
  22. package/templates/skills/genex-threejs-image-pipeline/references/image-pipeline.md +0 -197
  23. package/templates/skills/genex-threejs-lighting-design/SKILL.md +0 -144
  24. package/templates/skills/genex-threejs-lighting-design/references/light-recipes.md +0 -137
  25. package/templates/skills/genex-threejs-open-world/SKILL.md +0 -149
  26. package/templates/skills/genex-threejs-open-world/references/terrain-streaming.md +0 -215
  27. package/templates/skills/genex-threejs-precipitation-surfaces/SKILL.md +0 -59
  28. package/templates/skills/genex-threejs-precipitation-surfaces/references/precipitation-surfaces.md +0 -181
  29. package/templates/skills/genex-threejs-procedural-architecture/SKILL.md +0 -50
  30. package/templates/skills/genex-threejs-procedural-architecture/references/architecture-systems.md +0 -509
  31. package/templates/skills/genex-threejs-procedural-fields/SKILL.md +0 -61
  32. package/templates/skills/genex-threejs-procedural-fields/references/field-systems.md +0 -232
  33. package/templates/skills/genex-threejs-procedural-geometry/SKILL.md +0 -39
  34. package/templates/skills/genex-threejs-procedural-geometry/references/mesh-systems.md +0 -202
  35. package/templates/skills/genex-threejs-procedural-materials/references/material-systems.md +0 -198
  36. package/templates/skills/genex-threejs-procedural-planets/SKILL.md +0 -48
  37. package/templates/skills/genex-threejs-procedural-planets/references/planet-systems.md +0 -498
  38. package/templates/skills/genex-threejs-procedural-vegetation/SKILL.md +0 -52
  39. package/templates/skills/genex-threejs-procedural-vegetation/references/vegetation-systems.md +0 -314
  40. package/templates/skills/genex-threejs-procedural-vfx/references/vfx-systems.md +0 -218
  41. package/templates/skills/genex-threejs-raymarched-space-effects/SKILL.md +0 -37
  42. package/templates/skills/genex-threejs-raymarched-space-effects/references/space-effects.md +0 -194
  43. package/templates/skills/genex-threejs-screen-space-ambient-occlusion/SKILL.md +0 -35
  44. package/templates/skills/genex-threejs-screen-space-ambient-occlusion/references/ambient-occlusion.md +0 -441
  45. package/templates/skills/genex-threejs-spectral-ocean/SKILL.md +0 -52
  46. package/templates/skills/genex-threejs-spectral-ocean/references/spectral-ocean.md +0 -473
  47. package/templates/skills/genex-threejs-temporal-surfaces/SKILL.md +0 -41
  48. package/templates/skills/genex-threejs-temporal-surfaces/references/temporal-surfaces.md +0 -207
  49. package/templates/skills/genex-threejs-visual-validation/references/visual-validation.md +0 -427
  50. package/templates/skills/genex-threejs-volumetric-clouds/SKILL.md +0 -49
  51. package/templates/skills/genex-threejs-volumetric-clouds/references/volumetric-clouds.md +0 -579
  52. package/templates/skills/genex-threejs-water-optics/SKILL.md +0 -57
  53. package/templates/skills/genex-threejs-water-optics/references/water-optics.md +0 -195
@@ -1,194 +0,0 @@
1
- # Curved-ray numerical integrators
2
-
3
- Use this reference for an RK4 wormhole integrator and an artistic inverse-square curved-ray accretion volume, including state reduction, disk accumulation, background lensing, and numerical diagnostics.
4
-
5
- ## Contents
6
-
7
- - Wormhole state reduction
8
- - Wormhole RK4 integration
9
- - Universe selection
10
- - accretion volume screen-volume integration
11
- - Disk density and color
12
- - Background lensing
13
- - Observed defects and boundaries
14
- - Diagnostics
15
-
16
-
17
- ## Wormhole state reduction
18
-
19
- The wormhole renderer uses a spherically symmetric throat model. It reduces
20
- each 3D ray to a two-dimensional integration state:
21
-
22
- ```text
23
- y.x = signed radial coordinate l
24
- y.y = radial momentum pL
25
- impact parameter b = length(cross(rayOrigin, rayDirection))
26
- throat radius Rth = 1.2
27
- ```
28
-
29
- It constructs an orbital plane:
30
-
31
- ```text
32
- normal = normalize(cross(origin, direction))
33
- u = normalize(origin)
34
- v = cross(normal, u)
35
- ```
36
-
37
- Near-radial rays use fallback axes to avoid a zero cross product.
38
-
39
- Initial signed coordinate:
40
-
41
- ```text
42
- l = sqrt(max(length(origin)^2 - Rth^2, 0.001))
43
- pL = dot(normalize(origin), direction)
44
- ```
45
-
46
- ## Wormhole RK4 integration
47
-
48
- The derivative is:
49
-
50
- ```text
51
- r2 = l^2 + Rth^2
52
- dl/ds = r2 * pL
53
- dpL/ds = b^2 * l / r2
54
- ```
55
-
56
- The shader runs fourth-order Runge–Kutta with:
57
-
58
- ```text
59
- maximum iterations = 920
60
- base step = 0.0042
61
- per-ray step jitter = +/- 0.00045
62
- escape distance = abs(l) > 40
63
- azimuth accumulation = step * b
64
- ```
65
-
66
- On escape:
67
-
68
- ```text
69
- finalDirection =
70
- normalize(u * cos(phi) + v * sin(phi))
71
- ```
72
-
73
- The sign of final `l` selects which exterior universe is visible. Failure to
74
- escape renders a bright fallback color, making iteration-cap pixels observable.
75
-
76
- This is materially stronger than a UV swirl because the final environment
77
- direction comes from numerical integration.
78
-
79
- ## Universe selection
80
-
81
- The two exterior universes are independent procedural directional fields. Both
82
- use five-octave FBM, animated coordinate drift, broad/fine structure, and
83
- different plane orientation.
84
-
85
- Sample those fields only after integration. Lensing must change the lookup
86
- direction rather than distort an already rendered screen image.
87
-
88
- A small direction-hashed grain of amplitude `0.01` reduces visible gradient
89
- banding.
90
-
91
- ## accretion volume screen-volume integration
92
-
93
- The black-hole effect is evaluated on a sphere surrounding the effect. Defaults:
94
-
95
- ```text
96
- iterations = 128
97
- step = 0.0071
98
- ray jitter = 0.01
99
- bending power = 0.3
100
- core radius = 0.13
101
- disk half-width = 0.03
102
- ```
103
-
104
- Per step:
105
-
106
- ```text
107
- r = length(rayPosition)
108
- steerMagnitude = step * power / r^2
109
- steerRange = remapClamped(r, 1 -> 0.5, 0 -> 1)
110
- newDirection = normalize(direction - radial * steerMagnitude * steerRange)
111
- ```
112
-
113
- The ray direction is bent toward the center only inside the configured range.
114
- Unlike the wormhole, this is an artistic inverse-square steering field, not a
115
- validated metric geodesic.
116
-
117
- ## Disk density and color
118
-
119
- Disk coordinates rotate around the local Z axis with radius and time:
120
-
121
- ```text
122
- rotation phase = radialDistance * 4.27 - time * 0.1
123
- noise UV = rotatedPosition * 2
124
- ```
125
-
126
- A repeated deep-noise texture is multiplied by a quadratic band across
127
- `[-width, 0, +width]`. Radial distance, noise value, and a nearby noise sample
128
- produce a ramp coordinate.
129
-
130
- The three-point color ramp is:
131
-
132
- ```text
133
- white-hot at 0.06
134
- gold at 0.33
135
- dark amber at 1.0
136
- emission scale 1.95
137
- additional emission color (1.0, 0.72, 0.26)
138
- ```
139
-
140
- The central sphere below `originRadius` is black. Disk opacity accumulates
141
- front-to-back into `alphaAcc`; color accumulates using remaining transmittance.
142
-
143
- ## Background lensing
144
-
145
- After the fixed loop, the final bent direction samples a deterministic
146
- equirectangular star texture generated from `5200` seeded stars on a sphere.
147
-
148
- ```text
149
- final = accumulated disk color
150
- + remaining transmittance * star environment
151
- ```
152
-
153
- The deterministic star field is important: lensing motion can be compared
154
- without random stars moving between runs.
155
-
156
- ## Observed defects and boundaries
157
-
158
- - The demonstrated accretion-volume loop advances `rayPosition` twice per
159
- iteration while its steering magnitude uses a single `step`. Treat the
160
- effective distance step as `2 * step`, or remove the duplicate advance and
161
- retune the complete density-and-bending system explicitly.
162
- - accretion volume has no early exit and no termination IDs; every pixel pays the full
163
- iteration count.
164
- - Its disk is detected by local band density at samples, not by a continuous
165
- plane-crossing test. A large step can skip a thin disk.
166
- - The artistic inverse-square steering must not be described as general
167
- relativity.
168
- - The wormhole uses a fixed high iteration cap and per-ray step jitter but has
169
- no CPU reference-ray tests.
170
- - Both effects render on bounded proxy geometry; coordinate transforms must be
171
- verified if the proxy is nonuniformly scaled or moved far from the origin.
172
- - The star texture is finite-resolution and can alias under extreme
173
- magnification.
174
-
175
- ## Diagnostics
176
-
177
- Expose:
178
-
179
- ```text
180
- wormhole l and pL
181
- impact parameter and orbital-plane basis
182
- RK4 step count and escaped/capped state
183
- final exterior side and environment direction
184
- accretion volume radius and steering magnitude
185
- effective traveled distance
186
- disk band, noise, ramp coordinate, and local alpha
187
- accumulated alpha and remaining transmittance
188
- core-hit mask
189
- final bent background direction
190
- NaN/invalid-state mask
191
- ```
192
-
193
- Add CPU reference rays for the wormhole before claiming physical parity, and a
194
- continuous disk-crossing variant before increasing accretion volume’s step size.
@@ -1,35 +0,0 @@
1
- ---
2
- name: genex-threejs-screen-space-ambient-occlusion
3
- description: Implement screen-space ambient occlusion for Genex Three.js games. Use for GTAO-style horizon sampling, bent normals, contact grounding, depth reconstruction, bilateral upsampling, halo diagnosis, and AO that supports readable form.
4
- ---
5
-
6
- # Genex Three.js Screen-Space Ambient Occlusion
7
-
8
- AO estimates missing ambient visibility. It must modulate indirect lighting, not repaint all scene color with a dark multiply.
9
-
10
- ## Workflow
11
-
12
- 1. Verify linear depth and view-space normals.
13
- 2. Reconstruct view position consistently.
14
- 3. Sample horizon visibility in a controlled radius.
15
- 4. Estimate AO and optional bent normal.
16
- 5. Denoise with depth/normal-aware filters.
17
- 6. Apply to indirect diffuse and environment response.
18
-
19
- Read [references/ambient-occlusion.md](references/ambient-occlusion.md).
20
-
21
- ## Failure conditions
22
-
23
- - direct light and emission are darkened;
24
- - radius is specified only in pixels;
25
- - foreground silhouettes cast thick screen-space halos;
26
- - depth discontinuities are blurred together;
27
- - AO remains strong at distances where its world radius is subpixel;
28
- - bent normals are treated as ordinary geometric normals;
29
- - the implementation claims temporal accumulation even though this path has none.
30
-
31
- ## Routing boundary
32
-
33
- This skill owns GTAO gathering, bent normals, denoising, and AO application.
34
- Use `$genex-threejs-image-pipeline` only when its depth/normal buffers or pass order
35
- must be coordinated with other image-space systems.
@@ -1,441 +0,0 @@
1
- # GTAO and bent-normal pipeline
2
-
3
- Use this reference for a bounded-cost WebGPU/TSL ambient-visibility pass with half-resolution horizon integration, bent normals, bilateral reconstruction, and directional ambient tint.
4
-
5
- > **Renderer note:** this reference assumes `WebGPURenderer` + TSL node materials. Check the project's actual renderer first — the Genex scaffold ships vanilla WebGL three.js. On WebGL, adapt the technique with standard materials / `EffectComposer` passes or pick a simpler alternative; never switch renderers mid-project. Either way the effect obeys the device tier (`$genex-threejs-adaptive-quality`): expensive passes are desktop-tier, and on WebGPU the per-target MSAA sample count is a runtime knob the governor may drive.
6
-
7
- ## Contents
8
-
9
- 1. Gather budget and depth convention
10
- 2. World-radius projection and horizon integration
11
- 3. Bent-normal encoding
12
- 4. Bilateral reconstruction
13
- 5. Indirect-light composite
14
- 6. Implementation defects, adaptation, and diagnostics
15
-
16
- ## 1. Preserve the actual budget
17
-
18
- The gather uses:
19
-
20
- ```text
21
- resolution scale 0.5 × 0.5
22
- slices 2
23
- steps per side 4
24
- sides per slice 2
25
- depth taps 16 per half-resolution pixel
26
- target RGBA16F
27
- RGB bent direction encoded to [0, 1]
28
- A scalar visibility, 1 = open
29
- ```
30
-
31
- Half linear resolution means one quarter of full-resolution fragments.
32
-
33
- The implementation targets an approximately `2 ms` budget by combining:
34
-
35
- - half-resolution gather;
36
- - few slices;
37
- - interleaved-gradient-noise rotation;
38
- - direct UV marching;
39
- - one view-position reconstruction per tap;
40
- - sky early-outs in gather and composite.
41
-
42
- Do not increase slices first. Validate whether the bilateral pass and stable
43
- rotation already remove directional structure.
44
-
45
- ## 2. Preserve the depth convention
46
-
47
- The implementation uses reversed depth:
48
-
49
- ```text
50
- sky threshold 0.000001
51
- maximum reconstruction 0.999999
52
- ```
53
-
54
- Sky is cleared to zero. Far terrain remains above the sky threshold.
55
-
56
- Gather:
57
-
58
- ```text
59
- if rawDepth <= 1e-6:
60
- output visibility = 1
61
- output encoded bent = encoded view normal
62
- skip all 16 taps
63
- ```
64
-
65
- Composite clamps depth to `[0, 0.999999]` before linearization so sky
66
- neighbours do not create extreme view-Z values.
67
-
68
- Do not port these thresholds to a forward-depth target unchanged.
69
-
70
- ## 3. Preserve world-radius projection
71
-
72
- Default controls:
73
-
74
- ```text
75
- radius 0.5 m
76
- intensity 1.0
77
- power 1.6
78
- thickness 0.35 m in view Z
79
- bentNormalStrength 0.6
80
- ```
81
-
82
- The horizontal projection scale is cached from:
83
-
84
- ```text
85
- camera.projectionMatrix.elements[0]
86
- ```
87
-
88
- and refreshed every frame.
89
-
90
- World radius becomes UV reach:
91
-
92
- ```text
93
- radiusUv =
94
- radius
95
- * projectionScaleX
96
- / max(-viewPosition.z, 0.0001)
97
- * 0.5
98
-
99
- radiusUv = clamp(radiusUv, 0.004, 0.08)
100
- ```
101
-
102
- This clamp prevents near surfaces searching half the screen and stops far
103
- surfaces collapsing to a useless footprint.
104
-
105
- Observed adaptation issue: only the X projection term is used, then one scalar
106
- radius is applied to both UV axes. At unusual aspect ratios or asymmetric
107
- projections, derive a `vec2` reach from both projection axes.
108
-
109
- ## 4. Rotate two horizon slices per pixel
110
-
111
- For slice `i`:
112
-
113
- ```text
114
- noise = interleavedGradientNoise(screenCoordinate)
115
- angle = (i / 2 + noise) * PI
116
- sliceDirection = (cos(angle), sin(angle))
117
- ```
118
-
119
- The axis covers both positive and negative directions, so angles only span
120
- `PI`, not `2 * PI`.
121
-
122
- Step spacing:
123
-
124
- ```text
125
- t = (stepIndex + noise + 0.5) / 4
126
- stepUv = sliceDirection * radiusUv * t
127
- ```
128
-
129
- The shared noise rotates slices and jitters their radial positions.
130
-
131
- The pass has no temporal accumulation. Its stability depends on the
132
- noise being screen-stable and the full-resolution spatial composite.
133
-
134
- ## 5. Keep horizon angle and distance falloff separate
135
-
136
- For each positive and negative sample:
137
-
138
- ```text
139
- delta = sampleViewPosition - centerViewPosition
140
- distance = max(length(delta), 0.0001)
141
- falloff = saturate(1 - distance / max(radius, 0.0001))
142
- ```
143
-
144
- Accept the sample only when:
145
-
146
- ```text
147
- abs(delta.z) < thickness
148
- ```
149
-
150
- Raw horizon cosine:
151
-
152
- ```text
153
- cosine = dot(delta, viewDirection) / distance
154
- ```
155
-
156
- Apply distance falloff by mixing toward fully open:
157
-
158
- ```text
159
- horizon = mix(-1, cosine, falloff)
160
- maxHorizon = max(maxHorizon, horizon)
161
- ```
162
-
163
- Do not multiply the cosine directly by falloff. Mixing toward `-1` weakens a
164
- distant occluder without changing the angle of a nearby one.
165
-
166
- Per slice:
167
-
168
- ```text
169
- positiveAngle = acos(clamp(positiveHorizon, -1, 1))
170
- negativeAngle = acos(clamp(negativeHorizon, -1, 1))
171
- visibility += saturate((positiveAngle + negativeAngle) / PI)
172
- ```
173
-
174
- Final scalar:
175
-
176
- ```text
177
- visibility = visibility / 2
178
- visibility = visibility ^ power
179
- visibility = saturate(mix(1, visibility, intensity))
180
- ```
181
-
182
- Disabling the pass sets intensity to zero; the gather still runs unless the
183
- owner removes or bypasses the node. If disabled cost matters, bypass the pass
184
- at pipeline construction or add an update/render gate.
185
-
186
- ## 6. Treat the bent direction as an observed heuristic
187
-
188
- For accepted samples, the gather accumulates:
189
-
190
- ```text
191
- bentDirection +=
192
- normalize(delta)
193
- * saturate(cosine * falloff)
194
- ```
195
-
196
- Then:
197
-
198
- ```text
199
- bent = normalize(
200
- mix(
201
- viewNormal,
202
- normalize(viewDirection + bentDirection),
203
- bentNormalStrength
204
- )
205
- )
206
- ```
207
-
208
- The output stores `bent * 0.5 + 0.5`.
209
-
210
- Important objective finding: the accumulated vectors point toward accepted
211
- sample positions. A physically derived bent normal normally points toward
212
- unoccluded directions, so do not assume this sign convention is correct in an
213
- adaptation.
214
-
215
- Required validation:
216
-
217
- ```text
218
- place a flat receiver beside one vertical wall
219
- show geometric normal
220
- show decoded bent direction
221
- show environment sample direction
222
- verify the direction turns away from the blocked hemisphere
223
- ```
224
-
225
- If it turns toward the wall, negate/rederive the directional accumulator
226
- before using it for environment lighting.
227
-
228
- ## 7. Own gather rendering state
229
-
230
- `GtaoNode.updateBefore()`:
231
-
232
- 1. saves/reset renderer state through `RendererUtils`;
233
- 2. reads drawing-buffer dimensions;
234
- 3. resizes the half-resolution target;
235
- 4. refreshes projection scale;
236
- 5. renders one fullscreen `QuadMesh`;
237
- 6. restores renderer state.
238
-
239
- Dispose both the target and node material.
240
-
241
- Do not let a post node leak render target, viewport, or material state into the
242
- main pipeline.
243
-
244
- ## 8. Upsample with the exact kernel
245
-
246
- The full-resolution composite gathers eight neighbours:
247
-
248
- ```text
249
- left, right, up, down
250
- four diagonals
251
- center omitted
252
- ```
253
-
254
- Each weight is depth-only:
255
-
256
- ```text
257
- weight = exp(-abs(sampleViewZ - centerViewZ) / 0.5)
258
- ```
259
-
260
- If total weight is above `0.01`, normalize the eight-sample sum. Otherwise use
261
- the center AO texel.
262
-
263
- This is an eight-neighbour `3×3` ring with the center skipped, not a cross.
264
-
265
- The rationale is to cover the four-pixel interleaved-gradient-noise repeat
266
- while sampling across half-resolution AO texels.
267
-
268
- Observed limitation: `screenTexelHint()` returns only:
269
-
270
- ```text
271
- 1 / screenWidth
272
- ```
273
-
274
- and uses that scalar for both X and Y offsets. At non-square viewports the
275
- vertical step is wrong. Adapt as:
276
-
277
- ```text
278
- texel = vec2(1 / width, 1 / height)
279
- ```
280
-
281
- Observed limitation: the filter has no normal-similarity weight despite having
282
- the normal buffer available later in the composite. Thin foreground/background
283
- contacts may need:
284
-
285
- ```text
286
- weight *= pow(saturate(dot(centerNormal, sampleNormal)), normalPower)
287
- ```
288
-
289
- Add this only after confirming the depth-only kernel causes cross-edge leakage;
290
- normal buffers can be noisy at hard edges.
291
-
292
- ## 9. Apply AO only to reconstructed indirect light
293
-
294
- Do not multiply final scene color by AO.
295
-
296
- It approximates indirect light:
297
-
298
- ```text
299
- irradiance =
300
- PMREM sampled along bent direction at texture level 1
301
- or fallback cavity color (0.55, 0.62, 0.78)
302
-
303
- indirectEstimate =
304
- albedo
305
- * environmentIntensity
306
- * irradiance
307
-
308
- indirect = min(indirectEstimate, sceneColor)
309
- direct = sceneColor - indirect
310
- ```
311
-
312
- The clamp ensures direct light never becomes negative.
313
-
314
- Then:
315
-
316
- ```text
317
- occludedIndirect = indirect * visibility
318
-
319
- deviation =
320
- saturate(1 - dot(decodedBentView, geometricViewNormal))
321
-
322
- tintAmount =
323
- deviation
324
- * (1 - visibility)
325
- * bentTintStrength
326
-
327
- bentTintStrength default = 0.35
328
-
329
- tintedIndirect =
330
- mix(
331
- occludedIndirect,
332
- occludedIndirect * irradiance,
333
- saturate(tintAmount)
334
- )
335
-
336
- output = direct + tintedIndirect
337
- ```
338
-
339
- This keeps direct sun and most specular response out of the AO multiply.
340
-
341
- The indirect reconstruction is still approximate because it works from a
342
- forward-shaded scene color and an albedo MRT. Specular energy can leak into
343
- the `direct` residual. Prefer a renderer-provided indirect-diffuse signal when
344
- available.
345
-
346
- ## 10. Verify view/world transform semantics
347
-
348
- The composite decodes the bent direction in view space and calls:
349
-
350
- ```text
351
- transformDirection(bentView, cameraViewMatrix)
352
- ```
353
-
354
- while describing the result as view-to-world.
355
-
356
- Matrix-direction semantics in TSL are version-sensitive. Verify the installed
357
- Three.js behavior with axis probes:
358
-
359
- ```text
360
- camera facing -Z:
361
- view (0, 0, 1) maps to expected world direction
362
-
363
- camera rotated 90 degrees:
364
- decoded bent direction rotates with the camera exactly once
365
- ```
366
-
367
- Do not copy the matrix expression solely from the comment.
368
-
369
- ## 11. Temporal behavior
370
-
371
- This pipeline has no motion vectors, history target, reprojection,
372
- neighborhood clamp, or disocclusion rejection.
373
-
374
- Do not describe it as temporally accumulated GTAO.
375
-
376
- If adding temporal accumulation:
377
-
378
- 1. preserve raw half-resolution visibility and bent direction;
379
- 2. add representative depth/normal validity;
380
- 3. reproject with velocity;
381
- 4. clamp scalar visibility to the current neighborhood;
382
- 5. constrain bent history by angular deviation;
383
- 6. reset on camera cuts and resolution changes.
384
-
385
- First verify whether the current stable-noise plus bilateral pass already meets
386
- the target. Temporal history adds ghosting risk to moving procedural geometry.
387
-
388
- ## 12. Required diagnostics
389
-
390
- Expose:
391
-
392
- ```text
393
- raw reversed depth and linear view Z
394
- sky classification
395
- view normal
396
- projected radius UV/pixels
397
- slice angle and jitter
398
- positive/negative horizon cosine
399
- thickness acceptance
400
- distance falloff
401
- visibility before power/intensity
402
- raw encoded and decoded bent direction
403
- one-sided-wall bent-direction test
404
- eight bilateral sample depths and weights
405
- X/Y texel offsets
406
- upsampled visibility
407
- albedo and environment irradiance
408
- indirect estimate before/after scene-color clamp
409
- direct residual
410
- tint deviation and amount
411
- final direct versus indirect contribution
412
- GPU time for gather and composite
413
- ```
414
-
415
- Failure diagnosis:
416
-
417
- ```text
418
- AO radius changes with distance incorrectly:
419
- world radius was replaced by a fixed pixel radius
420
-
421
- far surfaces lose all contact:
422
- projected radius was not clamped to a minimum
423
-
424
- thick silhouette halos:
425
- thickness or depth-only bilateral weights cross discontinuities
426
-
427
- vertical blur differs from horizontal blur:
428
- width-derived scalar texel size was used for Y
429
-
430
- bent tint points into walls:
431
- the observed accumulator sign was accepted without a one-sided-wall test
432
-
433
- sunlit surfaces become gray:
434
- visibility multiplied final scene color instead of reconstructed indirect
435
-
436
- disabled AO still costs the full pass:
437
- intensity was set to zero without bypassing gather rendering
438
-
439
- camera rotation changes tint incorrectly:
440
- view-to-world direction transform semantics were not verified
441
- ```