import * as THREE from 'three/webgpu'; import type { TSLFloatNode, TSLMat4Node, TSLStorageNode, TSLTextureNode, TSLUniformNode } from '../types/tsl.js'; import type { WaterCompositeSurface, WaterSurfaceCompositeUniforms } from './WaterNodeMaterial.js'; type WaterFloatUniform = TSLUniformNode<'float', number>; type WaterVec2Uniform = TSLUniformNode<'vec2', THREE.Vector2>; type WaterMat4Uniform = TSLUniformNode<'mat4', THREE.Matrix4>; export interface WaterSurfaceRendererOptions { worldRadius?: number | undefined; worldSigma?: number | null | undefined; resolutionScale?: number | undefined; thicknessScale?: number | undefined; whitewaterScale?: number | undefined; filterIterations?: number | undefined; filterRadius?: number | undefined; depthRangeFactor?: number | undefined; thicknessStrength?: number | undefined; thicknessRadiusScale?: number | undefined; thicknessRangeFactor?: number | undefined; thicknessFalloff?: number | null | undefined; thicknessBlurRadius?: number | undefined; depthSmoothingRadius?: number | undefined; temporalBlend?: number | undefined; depthSource?: WaterSurfaceDepthSource | null | undefined; thicknessSource?: WaterSurfaceThicknessSource | null | undefined; } /** * Replaces the per-particle depth splat with a fullscreen read of an existing * per-pixel surface — a tiled compute rasterizer, a deferred pass, any producer * of nearest-hit view distance. Returns positive linear view distance, `0` where * there is no fluid, sampled at the depth target's own resolution. */ export type WaterSurfaceDepthSource = (surface: WaterSurfaceRenderer) => TSLFloatNode; /** * Replaces the additive per-particle thickness splat with a fullscreen read. * Returns optical thickness in world units, `0` outside the fluid. It runs after * the depth chain, so it may sample this renderer's own `depthNode`. */ export type WaterSurfaceThicknessSource = (surface: WaterSurfaceRenderer) => TSLFloatNode; export interface WaterSurfaceVolumeSource { particleBuffer: TSLStorageNode<'struct'>; particleCount: number; uniforms: { volumeToWorld: TSLMat4Node; }; positions?: never; count?: never; } export interface WaterSurfacePositionsSource { positions: TSLStorageNode<'vec3'>; count: number; particleBuffer?: never; particleCount?: never; uniforms?: never; } export type WaterSurfaceSource = WaterSurfaceVolumeSource | WaterSurfacePositionsSource; export interface WaterSurfaceSceneNodesOptions { depthNode?: TSLTextureNode | null | undefined; } export interface WaterSurfaceCamera extends THREE.Camera { near: number; far: number; } export interface WaterSurfaceRendererUniforms extends WaterSurfaceCompositeUniforms { worldRadius: WaterFloatUniform; worldSigma: WaterFloatUniform; depthRange: WaterFloatUniform; thicknessStrength: WaterFloatUniform; thicknessRange: WaterFloatUniform; thicknessFalloff: WaterFloatUniform; depthTexelSize: WaterVec2Uniform; fullTexelSize: WaterVec2Uniform; thicknessTexelSize: WaterVec2Uniform; fullResolution: WaterVec2Uniform; projectionScale: WaterFloatUniform; near: WaterFloatUniform; far: WaterFloatUniform; projectionMatrix: WaterMat4Uniform; projectionMatrixInverse: WaterMat4Uniform; viewMatrix: WaterMat4Uniform; viewMatrixInverse: WaterMat4Uniform; previousViewProjectionMatrix: WaterMat4Uniform; previousViewMatrix: WaterMat4Uniform; temporalBlend: WaterFloatUniform; historyValid: WaterFloatUniform; } /** * Screen-space fluid reconstruction for particle water. The renderer produces: * * 1. half-resolution analytic sphere depth; * 2. a world-space-sigma narrow-range filter; * 3. full-resolution joint-bilateral R32F depth plus reconstructed normals; * 4. half-resolution, scene/fluid-occluded near-surface thickness; * 5. one density-normalized quarter-resolution whitewater accumulation target. * * Full-resolution depth uses a dedicated R32F target/history; the compatibility * surface texture stores `vec4( viewDepth, normal.xyz )` with normals in 16F. * `depthNode`, `normalNode`, `thicknessNode`, and `whitewaterNode` are stable * texture nodes consumed by {@link createWaterComposite}. * * @short Production SSF reconstruction: adaptive depth filter, full-res normals, bounded thickness, temporal data. * @category Materials * @tags WebGPU, TSL, Water, SSF */ export declare class WaterSurfaceRenderer implements WaterCompositeSurface { renderer: THREE.Renderer; resolutionScale: number; thicknessScale: number; whitewaterScale: number; filterIterations: number; filterRadius: number; thicknessBlurRadius: number; depthSmoothingRadius: number; uniforms: WaterSurfaceRendererUniforms; count: number; rawDepthNode: TSLTextureNode; surfaceDataNode: TSLTextureNode; depthNode: TSLTextureNode; normalNode: TSLTextureNode; thicknessNode: TSLTextureNode; whitewaterNode: TSLTextureNode; width: number; height: number; fullWidth: number; fullHeight: number; private _worldSigmaFactor; private _depthRangeFactor; private _thicknessRadiusScale; private _thicknessRangeFactor; private _thicknessFalloffFactor; private _sceneDepthNode; private _positionNode; private _water; private _depthTarget; private _filterTargets; private _surfaceDepthTarget; private _surfaceDepthTemporalTargets; private _surfaceTarget; private _surfaceTemporalTargets; private _thicknessTarget; private _thicknessTemporalTargets; private _thicknessBlurTarget; private _whitewaterTarget; private _depthMaterial; private _filterInputX; private _filterInputY; private _filterMaterialX; private _filterMaterialY; private _filterQuadX; private _filterQuadY; private _depthSmoothInputX; private _depthSmoothInputY; private _depthSmoothMaterialX; private _depthSmoothMaterialY; private _depthSmoothQuadX; private _depthSmoothQuadY; private _surfaceDepthCurrentInput; private _surfaceDepthHistoryInput; private _surfaceDepthTemporalMaterial; private _surfaceDepthTemporalQuad; private _surfaceCurrentInput; private _surfaceHistoryInput; private _surfaceTemporalMaterial; private _surfaceTemporalQuad; private _thicknessBlurInputX; private _thicknessBlurInputY; private _thicknessBlurMaterialX; private _thicknessBlurMaterialY; private _thicknessBlurQuadX; private _thicknessBlurQuadY; private _thicknessCurrentInput; private _thicknessHistoryInput; private _thicknessTemporalMaterial; private _thicknessTemporalQuad; private _filteredDepthInput; private _fullDepthInput; private _surfaceDepthMaterial; private _surfaceDepthQuad; private _surfaceMaterial; private _surfaceQuad; private _thicknessMaterial; private _depthSource; private _thicknessSource; private _depthSourceMaterial; private _depthSourceQuad; private _thicknessSourceMaterial; private _thicknessSourceQuad; private _splatMesh; private _splatScene; private _whitewaterScene; private _whitewaterMesh; private _whitewaterTargetNeedsClear; private _surfaceTemporalIndex; private _surfaceDepthTemporalIndex; private _thicknessTemporalIndex; private _historyValid; private _clearColor; private _disposed; /** * @param {THREE.WebGPURenderer} renderer Active renderer. * @param {WaterVolume|Object} source Water block or `{ positions, count }`. * @param {Object} [options] * @param {number} [options.worldRadius=0.3] Splat radius in world units. * @param {?number} [options.worldSigma=null] Narrow-range Gaussian sigma in world units; * defaults to `1.35 * worldRadius`. * @param {number} [options.resolutionScale=0.5] Depth/filter target scale. * @param {number} [options.thicknessScale=0.5] Thickness target scale. * @param {number} [options.whitewaterScale=0.25] Whitewater accumulation target scale. * @param {number} [options.filterIterations=2] Narrow-range X+Y iterations. * @param {number} [options.filterRadius=10] Maximum adaptive filter half-width in texels. * @param {number} [options.depthRangeFactor=2] Narrow-range delta as a multiple of `worldRadius`. * @param {number} [options.thicknessStrength=0.35] Per-splat thickness contribution. * @param {number} [options.thicknessRadiusScale=1.25] Thickness splat radius multiplier. * @param {number} [options.thicknessRangeFactor=4] Maximum near-surface thickness depth * as a multiple of `worldRadius` (independent from the tighter normal-filter range). * @param {?number} [options.thicknessFalloff=null] Near-surface exponential falloff; * defaults to `2.5 * worldRadius`. * @param {number} [options.thicknessBlurRadius=4] Wet-weighted Gaussian half-width (texels at * thickness resolution) smoothing the accumulated thickness. The additive splat buffer steps * by whole particle layers, and those steps read as contour rings through the scatter and * roughness ramps at grazing angles; `0` disables. * @param {number} [options.depthSmoothingRadius=2] Range-limited Gaussian half-width (texels at * depth resolution) applied after the narrow-range iterations. The edge-preserving filter * leaves sub-kernel splat texture as piecewise-flat plateaus whose creases ring bright * grazing reflections; this rounds them while silhouettes beyond `depthRange` stay sharp. * `0` disables. * @param {number} [options.temporalBlend=0.82] Local history weight. */ constructor(renderer: THREE.Renderer, source: WaterSurfaceSource, { worldRadius, worldSigma, resolutionScale, thicknessScale, whitewaterScale, filterIterations, filterRadius, depthRangeFactor, thicknessStrength, thicknessRadiusScale, thicknessRangeFactor, thicknessFalloff, thicknessBlurRadius, depthSmoothingRadius, temporalBlend, depthSource, thicknessSource, }?: WaterSurfaceRendererOptions); private _resolveSource; private _buildMaterials; private _buildSceneDependentMaterials; /** Configure the scene depth used by bilateral rejection and thickness. */ setSceneNodes({ depthNode }?: WaterSurfaceSceneNodesOptions): this; /** Attach an indirect whitewater mesh to the quarter-resolution accumulation pass. */ setWhitewaterMesh(mesh: THREE.Object3D | null | undefined): this; /** Drop local surface/thickness history after a reset or discontinuous camera move. */ resetHistory(): this; /** Keep the splat draw count in sync with the simulation. */ setCount(count: number): this; /** Splat radius in world units. */ setWorldRadius(radius: number): this; resize(): this; /** * Render the complete SSF pass chain for this frame. * @param {THREE.WebGPURenderer} renderer Active renderer. * @param {THREE.Camera} camera Scene camera. * @returns {this} */ update(renderer: THREE.Renderer, camera: WaterSurfaceCamera): this; dispose(): void; } export default WaterSurfaceRenderer;