The complete SKILL.md as loaded by agents, rendered verbatim.
Ambient Contact Shading
AO is visibility of indirect illumination. It may attenuate indirect diffuse and
environment/specular response. Direct light, emission, UI, and the tone-mapped
frame remain invariant.
$threejs-choose-skills is an optional multi-system coordinator. Use
$threejs-image-pipeline when AO shares depth, normals, velocity, history, or
final-output ownership.
1. Choose the ambient-visibility branch
Use the first branch whose gate passes:
| Gate |
Branch |
Consequence |
| Required occlusion is static/local and can be authored in assets |
material aoMap / aoNode |
One forward render; no dynamic inter-object contact. |
| Dynamic screen contact is required and the renderer exposes indirect lighting separately |
apply GTAO visibility to that term |
One geometry pass can remain possible. |
Stock forward NodeMaterial needs dynamic contact and the complete marginal cost passes |
depth/normal pass -> GTAO -> optional reconstruction -> second lit pass with builtinAOContext() |
Correct placement costs two scene traversals. |
| No previous branch meets its quality and cost gates |
omit screen AO |
Preserve materials, direct shadows, and silhouette readability. |
r185 GTAONode needs current depth/normal before AO exists, while
builtinAOContext() must be present during material lighting. Treat the first
pass as a full material/deformation/alpha-tested scene pass unless a parity-
proven depth/normal-only pass replaces it.
Complete when: the chosen branch names the indirect-light owner and either
charges every added pass/attachment or records screen AO as omitted.
2. Fix the input contract
- Initialize the renderer and require a WebGPU backend before graph creation.
Stock r185 GTAO is gated to standard depth; a custom reversed-depth adapter
must prove sky classification, reconstruction, and occluder ordering.
- Define opaque occluders, opaque receivers, alpha coverage, and one transparent
policy: no screen AO, authored material AO, or a validated custom lighting
model. Stock
builtinAOContext() skips transparent materials.
- Bind AO to the active view's
screenUV, drawing-buffer dimensions, and
projection. Keep width and height independent for non-square/asymmetric views.
- Choose depth-reconstructed normals for reduced raw AO only when edge fixtures
and target timing pass. Choose an MRT normal when it is shared, reconstruction
is materialized, smooth/thin geometry fails, or its measured attachment delta
is cheaper.
- Express physical contact radii in world units:
radiusRender = radiusMeters * renderUnitsPerMeter, with the same conversion
for dimensioned thickness and bias. An authored-look branch instead declares
scene-unit-only controls and revalidates them after asset/world scaling.
When another system supplies scale, motion, or resources, bind units, coordinate
frame, current/previous presentation times, authority, version, resource
generation, validity, and reset conditions before using those inputs.
Complete when: depth convention, screen coordinates, normal source,
transparency, scale meaning, and every external producer are explicit and
dimensionally compatible.
3. Materialize scalar visibility
Build the selected screen-space branch in this order:
shared-or-AO-owned depth + optional normal/velocity
-> GTAO scalar visibility
-> optional materialized edge-aware reconstruction
-> indirect-light application
-> optional temporal resolve
-> one tone-map/output-transform owner
- Reuse a shared scene pass; do not create a second G-buffer for AO.
- Raw reduced-resolution AO receives ordinary texture filtering, not bilateral
reconstruction. When edges fail, evaluate
rtt(denoise(...)) once, then
sample the materialized texture with screenUV.
- Inside a mesh material graph, sample both raw and reconstructed visibility
explicitly with
screenUV; implicit texture coordinates resolve to mesh UVs.
- Keep scalar visibility single-channel. Replace the output graph and mark the
RenderPipeline dirty when AO is disabled so inactive work is unreachable.
When implementing GTAO or choosing reconstruction, read
the r185 GTAO pipeline
and its reconstruction tradeoff.
Complete when: the active graph has one depth/normal owner, visibility is
sampled in screen space, AO reaches only indirect lighting, and AO-off removes
every AO pass and dependency.
4. Admit temporal filtering only with valid history
GTAONode.useTemporalFiltering rotates samples; it does not create or reproject
history. Enable it only with a live TRAA/custom resolve, valid camera and object
motion (including deformation/instancing/alpha coverage), matching beauty/depth/
velocity dimensions, rejection, and reset behavior.
Reset or reseed on camera/projection cuts, uncompensated rebases, geometry or
coverage discontinuities, AO parameter/scale/resolution changes, and quality
migration. r185 TRAANode has no public camera-cut reset: rebuild and dispose
the node, replace the output graph, and mark the pipeline dirty.
When temporal AO is selected, read the
temporal contract
before constructing history.
Complete when: moving-occluder, disocclusion, camera-cut, resize, and AO-
parameter-change fixtures either pass with explicit rejection/reset or temporal
AO is disabled.
5. Add bent normals only after scalar AO passes
A bent normal is the visibility-weighted mean unoccluded direction. Add this
branch only when scalar AO already passes, directional environment response is
visible and required, and the one-wall fixture proves the direction points away
from the blocked hemisphere.
When bent normals are selected, read the
bent-normal contract
for basis, filtering, normalization, storage, and sign checks.
Complete when: scalar visibility remains independently available, the
direction is transformed exactly once, and the one-wall fixture passes; otherwise
directional use stays disabled.
6. Verify the finished graph
Capture raw depth, normals, raw/reconstructed AO, indirect contribution,
direct/emissive residuals, velocity/history rejection when present, and AO off.
Exercise UV-seam meshes, thin silhouettes, transparent crossings, smooth curves,
screen edges, asymmetric projections, motion, resize, and disposal/recreation.
Complete when: direct light and emission are invariant; no UV-following,
cross-edge halo, seam, crawl, or trail remains in the accepted branch; AO-off
shows zero AO work; target-device marginal time and resource use pass; and
recreation returns resource counters to baseline.
Ownership
This skill owns scalar GTAO, reconstruction choice, indirect-light placement,
temporal eligibility, bent normals, and AO diagnostics. The image-pipeline owner
owns shared MRTs, global pass order, history infrastructure, tone mapping, output
conversion, and adaptive resolution.