GPU water surfaces — engine25 / batches19–21 Create interactive pools, ripple experiments and boat-game water. await createGPUWater("pool",16,12,{center:{x:0,y:0,z:0},resolution:128,picking:true}); This is a rectangular horizontal heightfield, not a liquid particle volume. The GPU solves a damped wave equation with finite differences and CFL-bounded substeps; four surfaces maximum, resolution16..256. Surface shapes do not represent pouring, overturning/breaking waves, coastline clipping or erosion. RAM water and the existing IPBF fluid tools remain separate choices. Coordinates use Unity/world XYZ like other GPU tools; legacy CS object.pos.x has the opposite X convention. Use matching coordinates when placing actors. Click the pool when picking:true, or inject a localized ripple from code. disturbGPUWater("pool",-2,1,3,.8); Arguments: name, worldX, worldZ, vertical-velocity strength(-5..5), radius(metres). The positive/negative Gaussian profile limits net volume injection. Radius must cover at least one grid cell. It adds velocity, not an instantaneous height jump. Choose traveling waves, propagation, damping and edge behavior. setGPUWater("pool",{waveSpeed:3,damping:.6,boundary:"absorb",amplitude:.08,wavelength:4,angle:25}); waveSpeed is metres/second; damping per second; boundary reflect or absorb. Analytic directional waves use deep-water dispersion sqrt(g*k) and share the exact rendered/query surface equation. Ripples use the configurable constant waveSpeed; this combined visual model is not a calibrated shallow-water solver. Use gentle amplitude/wavelength ratios. maxHeight(.01..4) caps ripple excursions and zeros velocity when clipped. Configuration rejects excessive substep budgets. Dimensions/center/resolution require recreation; other settings may be patched. Control color, depth absorption, opacity, highlights and reflections. setGPUWater("pool",{shallowColor:"#159eaa",deepColor:"#063d59",opacity:.8,depthScale:3,smoothness:.92,foam:1,foamThreshold:.8,reflections:true}); Depth uses the opaque scene depth; provide a floor below a pool. With no floor, water approaches its deepColor/opacity instead of turning black with infinity. Normals follow the deformed surface plus small visual ripples. Fresnel reflections use the environment; optional reused planar capture is256pixels at10Hz and adds one scene render. Foam follows ripple vertical motion and fades. This is not screen-space refraction, volumetric scattering, breaking foam or underwater fog. Set a sky and light the scene so water has something to reflect. Pause waves without turning off rigidbody buoyancy; reset only the water state. pauseGPUWater("pool"); stepGPUWater("pool",.02); resetGPUWater("pool"); startGPUWater("pool"); Reset clears impulses/clock/diagnostics; it does not reposition existing actors. Measure the current GPU surface at up to128 world-space points. var result=await sampleGPUWater("pool",[{x:0,y:0,z:0},{x:2,y:0,z:1}]); result.waterSamples gives height, verticalVelocity, foam and inside per point. Await this result before using it; queries read back only requested sample points. Make an existing CS object float and generate wakes. await addGPUWaterBody("pool","crate",{density:1000,drag:3,wake:.3}); Requires an existing root Rigidbody and box/sphere collider proxy. Auto volume comes from collider dimensions; volume can override it (cubic metres). density is WATER density(kg/m3), not object density. Object mass remains ordinary CS mass. Four off-centre points estimate submerged fractions. Archimedes upward force and point-velocity drag are applied in Unity FixedUpdate with AddForceAtPosition. This permits pitch/roll; the tool never continually positions or freezes a body. No change to interpolation, mass, gravity, constraints or existing CS registration. Kinematic bodies generate wakes but receive no forces. Maximum16bodies/surface; one surface may own a body's buoyancy. Compound/mesh shapes need a box/sphere proxy. This is a coarse flotation approximation, not exact submerged geometry. A moving body produces a bounded dipole wake. This feedback is not an exact equal/opposite momentum-conserving fluid solve. Sparse asynchronous samples may lag. Samples older than0.2seconds are ignored; optional height extrapolation is limited to0.05seconds. maxAcceleration(default30m/s2) caps aggregate force. Use drag and a sensible mass/volume ratio; monitor staleFrames and forceClamps. Do not add a second buoyancy script or transform-follow loop to the same body. removeGPUWaterBody("pool","crate"); Inspect behavior and performance without downloading the grid every frame. var state=await getGPUWaterState("pool"); state.water: simulated time, fixed steps/substeps, grid resolution/buffer bytes, body count, sparse readbacks/sampleAge, staleFrames, forceClamps/maxForce, lastDisturbance/disturbances and sampled maxDisplacement/maxVelocity/invalid. GPU diagnostic reduction is asynchronous: repeat after a frame for fresh numbers. heightSquareSum is a quantized ripple-displacement proxy, not physical energy. Use getSceneStats for actual FPS. Full grid never crosses to JavaScript each frame. Buffer memory is bounded separately: <=~2MiB per256x256water, excluding mesh and reflection texture. Reflection render cost depends on the rest of the scene. Remove a surface; its ordinary CS objects remain. removeGPUWater("pool"); clearGPUInstances / ordinary clearRun dispose water too. Saved activities must include create/setup code, just like other GPU effects; live wave states are not implicitly checkpointed. Reopening the activity restarts its authored water setup. Recipes: gpu-water-ripples.js, gpu-water-appearance.js, gpu-water-buoyancy.js. Use modern responsive controls, sound toggle and existing CS cameras. Refresh the whole Game iframe after deployment; getGPUCapabilities().version>=25. References: https://developer.nvidia.com/gpugems/gpugems/part-i-natural-effects/chapter-1-effective-water-simulation-physical-models https://developer.nvidia.com/gpugems/gpugems2/part-ii-shading-lighting-and-shadows/chapter-18-using-vertex-texture-displacement https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Rigidbody.AddForceAtPosition.html https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Rendering.AsyncGPUReadback.html https://docs.unity3d.com/6000.0/Documentation/ScriptReference/MonoBehaviour.FixedUpdate.html