Documentation / scene / WaterSurfaceSampler
Class: WaterSurfaceSampler
Defined in: libs/scene/src/scene/water_surface_sampler.ts:92
Height queries against a water surface, driven by the material's own evaluation of it.
Why this and not a CPU-side reconstruction of the waves: the displacement the material draws with is produced on the GPU, and any second implementation of it - re-deriving the spectrum, decoding the height textures, summing the dominant waves - is a different function that has to be kept in step by hand. Water.getSurfacePoint asks the material instead, so it is exact by construction, and it includes whatever else displaces the surface, such as a WaterInteraction field. What it costs is one point-list draw and one readback per batch, which is why queries here are batched and throttled rather than issued per call.
The queries are placed on a lattice at construction and never move. A frame asks for the same small set of positions every time, so the whole set costs one draw and one readback - the same as a single query would - and the answer is interpolated across the lattice on demand. Positions that move (a hull's own footprint, say) ride along through addExtraPoints.
The motion
The reported height eases towards the newest measurement, exponentially, and nothing else is done to it. Compensating the query lag is tempting - the measurement describes the surface a round trip before it can be used - but every attempt at it bought its smoothness back by other means: predicting from a velocity needs that velocity smoothed, extrapolating a wave diverges as the square of the distance, and rate limiting the result reintroduces the stepping it was meant to remove. A plain ease has none of those failure modes, and the lag it leaves is the lag a floating body has anyway. A rigid body should read sampleWorldYRaw instead and supply its own inertia.
Consequences a caller has to accept:
- Resolution is the lattice spacing. A grid at
hmetres resolves nothing shorter than about2 * h. - A probe outside the lattice is answered by the nearest cell rather than by a wrapped one; this is a window on the water, not a repeating field.
- Nothing is known until the first batch lands; until then queries return the still-water level.
Constructors
Constructor
new WaterSurfaceSampler(
water,options?):WaterSurfaceSampler
Defined in: libs/scene/src/scene/water_surface_sampler.ts:126
Creates a sampler over a body of water.
Parameters
water
The water to sample.
options?
WaterSurfaceSamplerOptions = {}
Lattice and rate options.
Returns
WaterSurfaceSampler
Accessors
waveTime
Get Signature
get waveTime():
number
Defined in: libs/scene/src/scene/water_surface_sampler.ts:171
Water clock of the newest accepted batch, in seconds.
Returns
number
updateHz
Get Signature
get updateHz():
number
Defined in: libs/scene/src/scene/water_surface_sampler.ts:181
Upper bound on the query rate in hertz.
A ceiling, not a schedule: a batch is issued as soon as the previous one has landed if that is sooner. Raising it past what a batch costs changes nothing.
Returns
number
Set Signature
set updateHz(
val):void
Defined in: libs/scene/src/scene/water_surface_sampler.ts:184
Parameters
val
number
Returns
void
timeConstant
Get Signature
get timeConstant():
number
Defined in: libs/scene/src/scene/water_surface_sampler.ts:192
Seconds for the reported height to close most of the gap to a new measurement. In seconds rather than per frame so that the behaviour does not change with frame rate.
Returns
number
Set Signature
set timeConstant(
val):void
Defined in: libs/scene/src/scene/water_surface_sampler.ts:195
Parameters
val
number
Returns
void
readCount
Get Signature
get readCount():
number
Defined in: libs/scene/src/scene/water_surface_sampler.ts:199
Batches completed since construction.
Returns
number
failCount
Get Signature
get failCount():
number
Defined in: libs/scene/src/scene/water_surface_sampler.ts:203
Batches that failed.
Returns
number
pending
Get Signature
get pending():
boolean
Defined in: libs/scene/src/scene/water_surface_sampler.ts:207
True while a batch is in flight.
Returns
boolean
pendingSeconds
Get Signature
get pendingSeconds():
number
Defined in: libs/scene/src/scene/water_surface_sampler.ts:211
Seconds the batch in flight has been outstanding, or 0 when none is.
Returns
number
lastLatency
Get Signature
get lastLatency():
number
Defined in: libs/scene/src/scene/water_surface_sampler.ts:215
Batch latency in seconds, as of the last one that landed.
Returns
number
batchFrames
Get Signature
get batchFrames():
number
Defined in: libs/scene/src/scene/water_surface_sampler.ts:219
Frames the newest batch took to come back.
Returns
number
batchSize
Get Signature
get batchSize():
number
Defined in: libs/scene/src/scene/water_surface_sampler.ts:223
Points evaluated per batch, the cost driver of this sampler.
Returns
number
ready
Get Signature
get ready():
boolean
Defined in: libs/scene/src/scene/water_surface_sampler.ts:227
True once a batch has landed and queries return surface heights.
Returns
boolean
spacing
Get Signature
get spacing():
number
Defined in: libs/scene/src/scene/water_surface_sampler.ts:231
World metres between lattice samples.
Returns
number
waterLevel
Get Signature
get waterLevel():
number
Defined in: libs/scene/src/scene/water_surface_sampler.ts:235
World Y of the still-water level.
Returns
number
Methods
addExtraPoints()
addExtraPoints(
inputs,onResult): () =>void
Defined in: libs/scene/src/scene/water_surface_sampler.ts:251
Register world positions to evaluate alongside the lattice, every batch.
The array is held by reference and read when a batch is issued, so a caller updates the vectors in place each frame and the next batch picks them up. The listener receives the surface positions for those inputs when the batch lands, in the same order. Making these a second call to the water instead would put two feedback renders in one frame.
Parameters
inputs
Vector3[]
World positions; only X and Z are used.
onResult
(results, inputs) => void
Called per batch with the surface positions.
Returns
A function that unregisters the points.
() => void
update()
update(
deltaSeconds):void
Defined in: libs/scene/src/scene/water_surface_sampler.ts:268
Advance the sampler. Call once per frame with the frame's delta.
Parameters
deltaSeconds
number
Frame delta in seconds.
Returns
void
sampleWorldY()
sampleWorldY(
x,z):number
Defined in: libs/scene/src/scene/water_surface_sampler.ts:317
Surface world Y at a world XZ, eased.
Bilinear over the lattice, clamped at the edges rather than wrapped. The table this reads is advanced once a frame by update, so this is a pure lookup and can be called as often as a caller likes.
For something placed directly at the height it reads, which has no inertia of its own and needs the height to move smoothly.
Parameters
x
number
z
number
Returns
number
sampleWorldYRaw()
sampleWorldYRaw(
x,z):number
Defined in: libs/scene/src/scene/water_surface_sampler.ts:327
Surface world Y at a world XZ, from the newest measurement with no easing.
For a rigid body. Feeding it the eased height adds a second lag on top of the one the query already carries, and a body a quarter second behind a falling surface is a body in the air.
Parameters
x
number
z
number
Returns
number
sampleNormal()
sampleNormal(
x,z,out?):Vector3
Defined in: libs/scene/src/scene/water_surface_sampler.ts:336
Surface normal from the eased lattice, by central differences one cell apart.
Parameters
x
number
z
number
out?
Vector3
Destination, or a new vector.
Returns
Vector3
Unit normal, Y up.