Primary implementation surface
These routes are generated from canonical source. Their exact status remains separate from implementation availability.
Build workload-selected analytic, bounded, and coastal water in Three.js r185 WebGPU/TSL. Use for generated archipelagos and shorelines, bathymetry-aware shoaling/refraction, mild-slope or shallow-water wet/dry solver selection, sparse active tiles, StorageTexture heightfields, exact displacement and normals, local disturbances, transported foam and wetness, receiver-space caustics, depth-aware refraction, absorption, Fresnel, and offshore/nearshore handoffs.
These routes are generated from canonical source. Their exact status remains separate from implementation availability.
This skill contributes to the following cross-skill owner graphs.
Bounded water couples a compute heightfield with physically-grounded shading. The simulation integrates the damped wave equation on a storage-texture ping-pong:
$$\frac{\partial^2 h}{\partial t^2} = c^2 \nabla^2 h - \beta\,\frac{\partial h}{\partial t}$$Underwater light follows Beer–Lambert absorption along the refracted path length $d$, per RGB channel (red dies first):
$$L(d) = L_0\, e^{-\sigma_a d}, \qquad \sigma_a = (\sigma_r, \sigma_g, \sigma_b)$$Caustics come from the differential-area ratio of a refracted beam — brightness is the inverse Jacobian of the ray-footprint map, and Fresnel splits reflection/refraction by angle (Schlick approximation):
$$I_c \propto \left|\det \frac{\partial \mathbf x_{floor}}{\partial \mathbf x_{surface}}\right|^{-1}, \qquad F(\theta) = F_0 + (1-F_0)(1-\cos\theta)^5$$Every image identifies what it proves. Page screenshots demonstrate the published presentation only; generated inputs demonstrate asset channels only; canonical acceptance still requires render-target readback and a schema-v2 bundle.
4 published images
generated asset preview
generated asset preview
generated asset preview
generated asset preview
The complete SKILL.md as loaded by agents — verbatim, rendered.
Use this skill for generated coastlines and archipelagos, bounded interactive
water, authored analytic surfaces, shallow transparent volumes, wet/dry flow,
and local optical effects. Use $threejs-spectral-ocean when the offshore
spatial range is a stochastic directional sea synthesized by FFT cascades; its
periodic field does not own transformation around islands or the shoreline.
This is a simulation-and-transport contract, not a blue-material recipe. The module owns water state, displacement, derivatives, optical evaluation, and diagnostics. The host owns the renderer, scene partition, camera, lighting, transparent ordering, and final image pipeline.
“Host owns lighting” means the water shader consumes the shared typed
LightingTransportSnapshot: incident radiance, receiver-normal surface/sky
irradiance, direct-solar irradiance, source direction, and transmittance each keep
their quantity, SI radiometric unit, spectral/working basis, footprint, factor
identity/version, validity, and error. Lighting transport is a provider, never
an InteractionRecord; atmosphere, cloud, opaque-visibility, and water
extinction factors are identified and applied exactly once.
Before implementation, read the shared physics-domain and interaction contract. All physical water state lives in its SI physics frame. World/scene conversion, clock/instant/interval identity, graph ordering, interaction exchange, residency, version propagation, and presentation interpolation use that contract rather than a water-local dialect.
This skill publishes the canonical WaterSurfaceProvider interface and
WaterSurfaceSample. A canonical PhysicsSampleRequest is batched and
channel-requested. It carries context/provider/signal/schema IDs, the requested
PhysicsInstant, physics-frame-metre points or oriented footprints, channel
masks, filter/frequency response, per-channel tolerances, maximum staleness,
acceptable residency/latency, and batch extent. Descriptor discovery supplies
a stable descriptor-table reference; the request does not deep-copy a complete
descriptor. The returned sample always exposes freeSurfacePoint,
freeSurfaceNormal, the gauge-invariant scalar
geometricNormalVelocityMps, and the exact
WaterSurfaceParameterization; only when represented it exposes
surfacePointVelocityMps, materialCurrentVelocityMps,
waterColumnDepthMeters, densityKgPerM3,
materialAccelerationMps2, pressurePa, bathymetryPoint, and wetDryState.
Each channel is a complete SampledChannel with actual time/support/filter,
validity, error, and stateVersion. The result returns the complete canonical
PhysicsSignalDescriptor, bundle sampleInstant, and each channel's
actualPhysicsTime resolving to a PhysicsInstant; requested and actual
instants may differ only within the
declared latency/staleness gates. Consumers preserve that result envelope rather
than copying a water-local subset. Packed GPU batches use stable descriptor-table
handles plus SoA channels, not per-sample descriptor copies. Missing channels
follow missingChannelPolicy and are never zero-filled. For a parameterized
surface r(u,v,t), the exact projection identity is
geometricNormalVelocityMps = dot(surfacePointVelocityMps, freeSurfaceNormal) whenever the optional full fixed-coordinate velocity is
present at the same actual time, support/filter, and state version; its channel
propagates the correlated velocity/normal error. An implicit/level-set or
reduced owner publishes the scalar normal speed directly when that vector is
absent. The scalar normal speed is parameterization invariant. The tangential
part of surfacePointVelocityMps depends on the serialized surface gauge, while
materialCurrentVelocityMps is the material fluid velocity and is not surface
motion. Both vector channels are physical polar vectors in physicsFrameId:
cross-frame transport rotates their basis only. A moving-frame coordinate
derivative is a distinct coordinate-rate schema and must not receive or lose
frame-transport terms by masquerading as physical velocity.
Analytic waves, bounded heightfields, coastal solvers, spectral donors, and
external free-surface solvers implement adapters to this one ABI. Raw helper
functions such as getWaterHeight() are implementation details and cannot be
passed directly to motion, creature, collision, or force consumers.
Every quantitative choice must carry one of these tags in implementation notes, presets, and validation artifacts:
Unlabelled integers inside exact equations, vector dimensions, byte identities, and API names are [D]. Do not publish an unlabelled resolution, timestep, coefficient, iteration count, memory limit, or millisecond target.
| Requirement | Surface algorithm | Error and cost boundary |
|---|---|---|
| Fixed/perceptual island shot; prescribed waterline; no interactive flow | Coast SDF plus phase-locked analytic shoreline bands | No mass, momentum, diffraction, run-up, or wake claim; nearest-coast ambiguity and crest aliasing are gated. |
| Small authored wave set; no local disturbance | Parametric Gerstner-style map with exact tangents | Cost is linear in component count; CPU parity requires inversion of horizontal displacement. |
| Bounded local interaction; mild non-breaking waves | GPU linear wave equation in ping-ponged storage textures | CFL-limited; cannot represent overturning, hydraulic jumps, or shoreline topology changes. |
| Fixed bathymetry needs shoaling/refraction but not nonlinear flow | Frequency/direction wave-action or ray transport | Geometric rays do not model diffraction/interference and require phase/energy regularization. |
| Fixed islands need linear diffraction/interference | Frequency-domain mild-slope solution, normally precomputed | Invalid for strong nonlinearity, breaking/run-up, moving bathymetry, or broad live spectra. |
| Long waves over permanently wet variable bathymetry | Conservative linearized shallow-water elevation/discharge system | Cannot own moving wet/dry fronts, breaking, or finite-amplitude bores. |
| Run-up, bores, bulk current, obstacle wakes, or changing wet/dry topology | Well-balanced positivity-preserving finite-volume shallow water | Hydrostatic and nondispersive; requires conservative fluxes, wet/dry gates, and fixed-step evidence. |
| Visible finite-depth dispersion beyond shallow water | Validated Boussinesq-family nearshore solver | Higher derivatives/state and fragile boundaries are unjustified unless phase/run-up error is observable. |
| Flat or distant surface where silhouette motion is sub-pixel | Derivative-filtered normal bands only | Lowest geometry cost; explicitly no geometry/normal parity. |
| Large stochastic sea over decades of wavelength | $threejs-spectral-ocean |
FFT cascades and spectral derivatives. |
| Overturning breakers, entrained air, jets, or three-dimensional vortices | External free-surface/particle/VOF solver | This skill consumes its visual state; a single-valued or depth-averaged model cannot own the phenomenon. |
Choose from spatial scale, smallest resolved wavelength, interaction radius, allowed phase/error, wet/dry topology, conservation needs, bathymetric variation, and sustained GPU budget. Do not select by visual style. Do not stack every row as quality; use the least complex valid model and explicit handoffs only.
Before selecting a water algorithm, define:
z_b(x,z) = upward-positive bed elevation in metres,
eta(x,z,t) = free-surface elevation in metres,
h = max(eta-z_b,0),
phi > 0 on land, phi = 0 at the authored still-water coast,
phi < 0 in water. [D]
Record one owner for bathymetry, water datum, coast SDF/nearest-coast ID,
substrate IDs, obstacle boundaries, offshore wave record, water state, foam,
wetness, optical depth, and final geometry. Horizontal SDF distance is not
vertical water depth. The SDF zero contour and z_b=eta_0 contour must agree
within a declared gate [G,M].
For reference-like generated islands, prove the causes separately: continuous deep-to-shallow bathymetry; sand/reef/rock receivers; incident phase transformed by coast/depth; causal breaking or prescribed crest arrival; transported foam; wet-sand history; water-column absorption/scatter; and one surface/normal cause. A cyan halo, radial island gradient, or unrelated scrolling foam texture does not satisfy the contract.
The API contract below is verified against the repository's installed
three@0.185.1 [G]:
WebGPURenderer, RenderPipeline, StorageTexture, and node materials come
from three/webgpu.three/tsl.await renderer.init() before inspecting
renderer.backend.isWebGPUBackend or renderer.hasFeature().Fn(...).compute(...); after initialization submit an
ordered node or node array with renderer.compute(...). computeAsync() is
the initialization-safe wrapper, not a GPU-completion fence.StorageTexture.colorSpace = NoColorSpace,
generateMipmaps = false, and mipmapsAutoUpdate = false for simulation
state unless a compute kernel deliberately writes every sampled mip.pass(scene, camera), optional mrt(...), and one RenderPipeline.
PassNode.setResolutionScale() is current. If renderOutput() is explicit,
set pipeline.outputColorTransform = false; otherwise leave the pipeline as
the sole output-transform owner.const renderer = new WebGPURenderer( { antialias: false } );
await renderer.init();
if ( renderer.backend.isWebGPUBackend !== true ) {
throw new Error( 'WebGPU is required for this water system.' );
}
renderer.compute( [ impulseNode, propagateNode, derivativeNode ] );
pipeline.render();
The opaque color/depth pass sampled by water must exclude the water surface. Transparent objects need an explicit ordering policy; do not silently include them in opaque refraction inputs.
For cell sizes dx, dz, wave speed c, and fixed step dt, the explicit
second-order wave stencil must satisfy the derived stability condition
C_x^2 + C_z^2 <= 1, C_x = c dt / dx, C_z = c dt / dz. [D]
For square cells this becomes c dt / dx <= 1/sqrt(2) [D]. Damping does
not legalize a CFL violation. Record the selected CFL margin [G], phase and
amplitude error against an analytic mode [M], and the boundary reflection
coefficient [M].
Boundary mode is part of the model:
For local depth h, wavenumber k, current U, and intrinsic frequency
sigma_i, use the declared finite-depth dispersion model:
sigma_i^2 = (g k + tau k^3) tanh(k h),
omega_abs = sigma_i + k dot U,
grad(theta) = k,
partial_t(theta) = -omega_abs. [D]
Wave-action transport uses N=E/sigma_i and ray velocity
dx/dt=U+partial sigma_i/partial k [D]. Record incident, outgoing,
dissipated, clipped, and regularized energy by frequency/direction band
[M]. A ray field must report phase-loop/curl residual and cannot claim
diffraction or interference. Use a converged mild-slope solution when those
linear phenomena are required over fixed bathymetry.
At an offshore/nearshore handoff, choose one contract. A phase-resolved handoff
transfers frequency, direction, complex surface-elevation amplitude, wavenumber,
intrinsic frequency, energy, and phase-reference PhysicsInstant. A phase-averaged handoff transfers
action/energy quadrature and direction with no crest-phase claim; local phase is
a separate owner. Match model validity before blending. Do not alpha-crossfade
independently phased geometric surfaces; one owner supplies height and
derivatives at each location. Measure reflection by frequency and incidence
angle [M]. If a coherent display overlap is unavoidable, amplitude weights
sum to one and derivatives include their spatial gradients; square-root power
weights apply only to proven independent/orthogonal fields, not two
representations of one wave.
Whichever handoff is selected, every instantaneous surface/query publication
uses the same canonical WaterSurfaceProvider ABI: mandatory
freeSurfacePoint, freeSurfaceNormal, geometricNormalVelocityMps, and
WaterSurfaceParameterization, plus only the represented optional
fixed-parameterization surfacePointVelocityMps, material
materialCurrentVelocityMps, depth, density, acceleration, pressure,
bathymetry, and wet/dry channels. The handoff preserves the complete descriptor,
requested/actual PhysicsInstant, footprint/filter, frame/origin/transform,
state/resource version, validity, error, latency, and residency envelope. A
phase-averaged owner without a separately versioned display-phase synthesis
cannot publish an instantaneous surface bundle and reports that provider query
invalid instead of inventing phase.
For wet/dry flow, conservative state is q=(h,m_x,m_z)^T, m=h u:
partial_t q + partial_x F(q) + partial_z G(q) = S,
F = (m_x, m_x^2/h + g h^2/2, m_x m_z/h)^T,
G = (m_z, m_x m_z/h, m_z^2/h + g h^2/2)^T,
S_momentum = -g h grad(z_b) + S_friction + S_external. [D]
Use one canonical numerical flux per face, well-balanced bathymetry treatment,
a positivity-preserving update, and an explicit dry-state policy before any
division by h. The invariant u=0, h+z_b=constant must remain a lake at
rest [G,M]. A post-update depth clamp that loses unreported mass is a
failure.
For an explicit unsplit rectangular-grid update, derive and enforce
dt <= C_CFL min_cells 1 /
[ (|u_x|+sqrt(g h))/dx + (|u_z|+sqrt(g h))/dz ]. [D,G]
Select Rusanov, HLL, HLLC, reconstruction order, and friction integration from
positivity, diffusion, conservation, convergence, and target-GPU evidence—not
algorithm prestige. Compare shallow-water dispersion
omega=sqrt(g h_0) k against omega^2=g k tanh(k h_0) over the injected band
[G,M]. Load a dispersive model only when this error is observable and its
extra boundary/stability/state cost passes.
Use modeled breaking dissipation, calibrated shock/entropy loss, surface compression, exact Jacobian/curvature, or prescribed crest arrival—in that priority order—as the foam source. Raw numerical entropy loss changes with flux/grid and is not physical dissipation without convergence calibration. Declare whether state is dimensionless coverage transported by a material derivative or conserved areal density transported by a divergence flux; do not mix their equations. Apply timestep-correct source/decay, optional diffusion, and bounds. Noise may alter microstructure; it cannot create source coverage. Partition breaking dissipation once at a model handoff and drive one foam history; foam coverage is not conserved wave energy.
Exactly one receiver stores exposed-bed wetness separately. Water publishes
exactly one typed inundation/wash SurfaceExchange to that route-selected
receiver, with the canonical context, interval, source/receiver identities,
frame/origin/transform, support/measure, payload semantics, state versions,
error, and exact-once batch ledger. If water is explicitly selected as the sole
receiver, it consumes that routed exchange in its graph stage rather than
bypassing the ABI; no weather or material owner integrates another copy. A
receiver-to-water runoff exchange committed over interval n is immutable
input to water interval n+1. Water gathers it once into the provisional
source assembly, and its exact-once application ledger advances only with the
accepted atomic n+1 commit; retry or rollback cannot apply it again, and
newly written receiver state from n+1 is never read in that same interval.
For a phase-only/no-solver branch,
m_wash is an explicit prescribed beach-inundation mask; static water depth
cannot wet exposed bed:
I_wet = (h >= h_wet) or (m_wash >= m_wet),
w_next = 1 when I_wet,
w_next = w exp(-dt/tau_dry) otherwise. [D]
h_wet, m_wet, and tau_dry are authored inputs [A]. Wetness changes
the bed material response, not water mass or geometric shoreline.
For each normalized direction d_i, amplitude a_i, horizontal ratio Q_i,
k_i = 2 pi / wavelength_i, and phase theta_i, use
P(q,t) = (q_x, 0, q_z)
+ sum_i (Q_i a_i d_ix cos(theta_i),
a_i sin(theta_i),
Q_i a_i d_iz cos(theta_i)). [D]
Compute both parametric tangents by differentiation and the upward normal as
normalize(cross(P_qz, P_qx)). The shortcut
normalize((-height_x, 1, -height_z)) is exact only when horizontal
displacement is absent. Require positive horizontal Jacobian for a
single-valued surface. The conservative no-fold gate
sum_i abs(Q_i a_i k_i) < 1 is [D]; the actual minimum determinant over the
authored domain is [M].
getWaterHeight(x,z,t) cannot obtain Eulerian parity by evaluating analytic
phases directly at (x,z) when horizontal displacement is nonzero. It must
invert the horizontal map with a bounded fixed-point or Newton solve, then
evaluate height at the recovered parameter coordinate. Report iteration limit
[G], residual tolerance [G], and observed residual [M].
The GPU heightfield residual is not bounded by the sum of impulse controls. Choose one honest contract:
H_grid [G], giving a derived analytic-
only query interval of +/- H_grid [D];Never hide readback latency in a per-frame query.
Water/body feedback uses the shared scheduler and InteractionRecord schema;
it is not an actor-side wake callback. For every coupled coordination interval, preserve
the dependency chain
body and water prediction
-> footprint-filtered sampling from both predictors at one declared bracket
-> source InteractionRecord generation
-> conservative load scatter by conservation group
-> water advance (including declared subcycles)
-> reaction InteractionRecord reduction
-> body and water correction, conservation/stability check, atomic commit
-> water PresentedStatePair for coordinator PhysicsPresentationCandidate. [D]
Every CPU, GPU, or external dispatch that advances coupled water state is an
execution of a declared PhysicsGraphStage with an exact
executionInterval, versioned reads/writes, residency dependency, and commit
group. A render callback may consume the sealed presentation publication and
request work, but it never advances the water solver, applies runoff, injects a
disturbance, or performs a private catch-up step.
Declare the coupling class as explicit, semi-implicit, scheduler-bounded
iterated, or monolithic; do not let a body or water subsystem perform an
unbounded private iteration.
For a bounded iteration, repeat prediction, same-bracket sampling, source/
reaction construction, solve, reduction, and correction using the exact prior
iteration versions named by iterationCarriedEdges; a frozen pre-step sample
is only an explicitly selected one-way/explicit scheme, not an iterated solve.
Every two-way source/reaction relation is an all-or-none
InteractionReactionGroup; one source may split across reactions and several
sources may reduce into one reaction. All members are transported to the
group's balance frame/reference point before impulse/torque residuals are
tested. Mass,
linear/angular momentum, energy/work (including declared dissipation/heat), and
species transfers reconcile across their complete conservation group. Volume
is only a separately gated constraint for a fixed-density incompressible model.
Gather and scatter are a discrete-adjoint pair that preserves zeroth and first
kernel moments and gates force, torque, interface-work, and added-mass
stability. Records carry SI units, frame, canonical
applicationInterval: PhysicsTimeInterval,
footprint, producer/consumer identities, ordering key, validity/error,
stateVersion, and conservation-group identity through the complete shared
InteractionRecord; water must not redeclare a subset. Stable interaction and
causal IDs plus application state enforce exactly-once consumption. Reproducible
paths use stable bin/sort and a fixed reduction tree or bounded fixed-point
accumulation, not schedule-dependent floating atomics. The exact
InteractionBatchLedger records published sequence range, per-consumer cursor,
accepted/rejected/late/duplicate counts, overflow policy and sequence ranges,
typed lost/deferred conserved commodities, and exact-once ledger version.
Authoritative overflow backpressures, substeps, or conservatively aggregates.
One-way coupling identifies the authoritative source and records a [G] upper
bound on omitted feedback or explicitly narrows the claim; it emits no reaction
and must not claim feedback. Keep
coupled hot state on one execution side or in a validated shared mirror;
synchronous frame-critical GPU readback is forbidden.
Water contributes a per-binding/provider PresentedStatePair to the
view-independent PhysicsPresentationCandidate, which contains committed
state brackets, leases, and events but no camera, render origin, view matrix,
shadow/cache state, or global-to-render transform. previousPresented and
currentPresented each independently contain a
PresentationSampleProvenance, presentedInstant, PresentationStateHandle,
and PresentationSpatialBinding; motionBinding references the two state
handles and records identity mapping and motion validity. The camera owner then
publishes a per-view CameraViewPublication; visibility/shadow/cache owners
publish ViewPreparationPublication; the sealed
PhysicsPresentationSnapshot references candidate binding IDs and lease refs
rather than copying pairs or transforms. FrameExecutionRecord records all
target/view executions and lease disposition keyed by lease ID. These presented
states need not equal solver states n and n+1. Surface position,
normals, velocity/MRT output, shadows, foam/wetness display, and temporal
rejection resolve through that immutable publication chain and separately
versioned physical instants, physics-frame transforms, and source-data epochs.
A state, residency,
transform/source epoch, or quality migration that invalidates history is
propagated and reset explicitly rather than hidden by interpolation.
Foam, optical, deformation, wet/dry-topology, and disocclusion changes
contribute scoped reactive epochs/affected regions; the coordinator turns them
into per-view ReactivePublication and capability-gated ScopedResetAction
plans in ViewPreparationPublication. Reset/history flags are not undocumented
PresentedStatePair or snapshot fields.
Map each surface differential through Snell refraction to a stated receiver.
For receiver-plane coordinates F(q), use
A_receiver = abs(det(dF/dq)) dq_x dq_z [D]
P_cell = E_incident max(0, -l dot n) A_surface
(1 - F_dielectric) T_light [D]
E_receiver = P_cell / max(A_receiver, A_epsilon). [D]
length(dFdx) * length(dFdy) is not an area; it omits the sine of the angle
between derivatives. Use a determinant in a receiver basis or a cross-product
magnitude. Deposit energy conservatively into receiver texels or solve an
inverse map; merely displaying the ratio at source texels misplaces light.
Clamp only after recording pre-clamp energy and invalid/TIR counts.
Classify the incident medium before evaluating Snell and Fresnel. Use exact unpolarized dielectric Fresnel near total internal reflection; Schlick is allowed only behind a recorded error gate [G] and comparison [M].
sigma_t = sigma_a + sigma_s [D]
T_rgb = exp(-sigma_t_rgb * pathLengthMeters) [D]
omega_0 = sigma_s / max(sigma_t, epsilon_sigma) [D]
L = F L_reflected
+ (1-F) [T L_refracted + (1-T) omega_0 L_source] [D]
sigma_a, sigma_s, and sigma_t have units m^-1 [D]; L_source
contains the declared phase/source-light approximation. Absorbed energy does
not become in-scattering. Reconstruct positions from scene depth,
reject foreground/off-viewport samples, and validate that the reconstructed
point lies on the forward refracted ray before calling its distance a path
length. A specular BRDF already contains the sun glint; do not add a second
unbudgeted glint lobe. Foam replaces an energy-conserving fraction of the water
response instead of adding white radiance.
Quality is a target-specific measured envelope, not a device-class label. Do not publish generic mobile/integrated/discrete timing tables. For each named target, declare the scene, viewport, DPR, grid, fixed cadence, precision, active effects, warm-up, sample window, power state, and pass/fail threshold [G] before measuring [M].
An RGBA16F texture consumes 8 N^2 bytes [D]; enumerate every
persistent, ping-pong, transient, scene-color, depth, geometry, and pipeline
allocation. Measure warm percentile frame time, each bandwidth-sensitive pass,
peak live bytes, allocation churn, and thermal drift on the named target
[M]. Derive tiers only from those measurements.
For tile/mobile GPUs:
InteractionRecord streams as compact SoA with
channel masks, bounded queues, stable IDs distinct from slots, and fixed
deterministic reductions; never allocate one JavaScript object per sample;resourceGeneration and a
frame-in-flight lease/reuse rule instead of deep-copying water fields or
allowing compute to overwrite a rendered generation;QualityTransition transaction
with state projection, conservation/error ledger, queue-drain
boundary, atomic provider-version publication, rollback, and peak old/new
residency; exactly one representation emits reactions during any visual
crossfade;textureLoad for stencil state and filtered sampling only for resolved
display fields;Read references/water-surface-system.md and references/coastal-archipelago-system.md before coastal or archipelago implementation. Validation must include the applicable subset below and every algorithm-specific gate from those references:
WaterSurfaceProvider conformance, absent-channel rejection, footprint
filtering, state-version/error propagation, mandatory normal-velocity
projection identity, valid absence of the optional full surface velocity,
and CPU/GPU adapter parity;PhysicsGraph execution evidence proving every coupled water dispatch,
immutable runoff from interval n into n+1, exactly-once application at
accepted commit, and one typed inundation/wash exchange to the sole receiver;InteractionRecord, conservation-group, and zero-frame-readback evidence;LightingTransportSnapshot channel units/bases/filters and factor ledger
proving solar disc, sky, atmosphere, cloud, visibility, and water extinction
are neither omitted nor double-applied;Fail the build on an unstable stencil, stale derivative state, invalid values, double output conversion, source-space caustics presented as receiver-space light, two geometric surface owners at a handoff, negative/unbalanced shallow water, unexplained mass/energy loss, a cache without units/datum/channel semantics, or any unlabeled quantitative claim.
This skill consumes the versioned coast SDF, bathymetry, obstacle, and substrate
contract from the terrain/data owner and the shared physics ABI from
../threejs-choose-skills/references/physics-domain-and-interaction-contract.md.
It owns shoreline phase, bathymetry-aware
nearshore transformation, water boundary/state, bounded wave grids,
depth-averaged shallow-water wet/dry state, sparse coastal tiles, exact
small-wave parametric surfaces, transported foam, and inundation/wash exchange.
It owns integrated receiver wetness only when explicitly selected as the single
receiver owner; otherwise the route-selected receiver-state owner integrates it.
It also owns depth-aware refraction, water-volume attenuation, and bounded
caustics. Use
$threejs-spectral-ocean for offshore directional spectra and FFT cascades,
then hand off explicitly. Precipitation and surface accumulation consume the
SurfaceExchange/InteractionRecord boundary published by
$threejs-rain-snow-and-wet-surfaces; no additional adapter skill owns this
handoff. Route overturning/three-dimensional free-surface physics to an external
solver and consume its versioned provider and presentation state here.
Preserved concept proxies and generated-asset previews. They are excluded from primary completion counts and link to the canonical lab through the schema-v2 registry.
Concept proxy preview
Generated asset preview preview