threejs-worldgen
    Preparing search index...

    Class FluidSurface

    Screen-space fluid rendering of particles (van der Laan et al. 2009): the particles are drawn as sphere impostors into a linear depth buffer and as additive thickness splats, the depth is smoothed by a separable bilateral filter, and a full-screen pass in your scene rebuilds normals from it and shades a water surface: Fresnel reflection of the sky, a GGX sun highlight, refraction of what is behind (the scene's own colour buffer), Beer–Lambert absorption and turbid in-scattering by thickness, and whitewater where the water is fast. Thin sheets and lone drops fade out by thickness, so edges are soft. Needs the WebGPU backend.

    const fluid = new FluidSurface(mpm, WATER_PRESETS.clear.surface)
    scene.add(fluid.object)
    mpm.object.visible = false
    // each frame, before rendering the scene:
    fluid.lighting.fromScene(scene)
    fluid.render(renderer, camera)
    Index

    Sun and sky light.

    object: Mesh

    Add this to your scene: the full-screen composite (drawn after the opaque scene, it reads its colour and depth).

    Resolved settings.

    uniforms: {
        absorption: UniformNode<"vec3", Vector3>;
        direction: UniformNode<"vec2", Vector2>;
        edge: UniformNode<"float", number>;
        f0: UniformNode<"float", number>;
        foam: UniformNode<"float", number>;
        foamColor: UniformNode<"color", Color>;
        foamDensity: UniformNode<"float", number>;
        foamSpeed: UniformNode<"vec2", Vector2>;
        ground: UniformNode<"color", Color>;
        horizon: UniformNode<"color", Color>;
        invDx: UniformNode<"float", number>;
        mist: UniformNode<"float", number>;
        mistSize: UniformNode<"float", number>;
        projection: UniformNode<"vec2", Vector2>;
        radius: UniformNode<"float", number>;
        refraction: UniformNode<"float", number>;
        right: UniformNode<"vec3", Vector3>;
        roughness: UniformNode<"float", number>;
        scatterColor: UniformNode<"color", Color>;
        shutter: UniformNode<"float", number>;
        smoothing: UniformNode<"float", number>;
        spray: UniformNode<"vec2", Vector2>;
        streaks: UniformNode<"float", number>;
        tagRadius: UniformNode<"float", number>;
        texel: UniformNode<"vec2", Vector2>;
        time: UniformNode<"float", number>;
        turbidity: UniformNode<"float", number>;
        up: UniformNode<"vec3", Vector3>;
        volume: UniformNode<"float", number>;
        zenith: UniformNode<"color", Color>;
    } = ...

    Shader uniforms.

    Type Declaration

    • absorption: UniformNode<"vec3", Vector3>

      Absorption per metre.

    • direction: UniformNode<"vec2", Vector2>

      Blur direction (texels).

    • edge: UniformNode<"float", number>

      Edge thickness.

    • f0: UniformNode<"float", number>

      Fresnel F0.

    • foam: UniformNode<"float", number>

      Foam amount.

    • foamColor: UniformNode<"color", Color>

      Foam colour (linear).

    • foamDensity: UniformNode<"float", number>

      Foam opacity per metre.

    • foamSpeed: UniformNode<"vec2", Vector2>

      Foam speeds.

    • ground: UniformNode<"color", Color>

      Ground (linear).

    • horizon: UniformNode<"color", Color>

      Sky horizon (linear).

    • invDx: UniformNode<"float", number>

      1/Δx of the source.

    • mist: UniformNode<"float", number>

      Mist opacity.

    • mistSize: UniformNode<"float", number>

      Mist width, metres.

    • projection: UniformNode<"vec2", Vector2>

      Projection [0][0] and [1][1].

    • radius: UniformNode<"float", number>

      Sphere radius, metres.

    • refraction: UniformNode<"float", number>

      Refraction.

    • right: UniformNode<"vec3", Vector3>

      Camera right, world.

    • roughness: UniformNode<"float", number>

      Roughness.

    • scatterColor: UniformNode<"color", Color>

      Scatter colour (linear).

    • shutter: UniformNode<"float", number>

      Shutter, seconds.

    • smoothing: UniformNode<"float", number>

      Smoothing radius, metres.

    • spray: UniformNode<"vec2", Vector2>

      Spray node-mass thresholds.

    • streaks: UniformNode<"float", number>

      Streak contrast.

    • tagRadius: UniformNode<"float", number>

      Radius multiplier of tagged particles.

    • texel: UniformNode<"vec2", Vector2>

      One texel of the offscreen passes.

    • time: UniformNode<"float", number>

      Seconds (streak animation).

    • turbidity: UniformNode<"float", number>

      Turbidity per metre.

    • up: UniformNode<"vec3", Vector3>

      Camera up, world.

    • volume: UniformNode<"float", number>

      Thickness scale: particle volume over sphere volume (overlapping spheres would overcount).

    • zenith: UniformNode<"color", Color>

      Sky zenith (linear).

    • Draws the offscreen passes for camera (call each frame before rendering the scene that holds object).

      Parameters

      • renderer: Renderer
      • camera: Camera

      Returns this

    • Merges input into the settings.

      Parameters

      • input: {
            absorption?: [number, number, number];
            edge?: number;
            foam?: number;
            foamColor?: string;
            foamDensity?: number;
            foamSpeed?: [number, number];
            ior?: number;
            iterations?: number;
            mist?: number;
            mistSize?: number;
            radius?: number;
            refraction?: number;
            resolution?: number;
            roughness?: number;
            scatterColor?: string;
            shutter?: number;
            sky?: [string, string, string];
            smoothing?: number;
            spray?: [number, number];
            streaks?: number;
            tagRadius?: number;
            turbidity?: number;
        }
        • Optionalabsorption?: [number, number, number]

          Beer–Lambert absorption of the water, per metre (linear RGB): pure water loses red first.

        • Optionaledge?: number

          Water thickness (m) over which the rim of the water fades in (anti-aliased edges; a thin film is still a reflecting surface).

        • Optionalfoam?: number

          Most whitewater coverage, 0…1.

        • OptionalfoamColor?: string

          Colour of whitewater (aerated, fast or broken water), #rrggbb.

        • OptionalfoamDensity?: number

          How opaque aerated water gets per metre of thickness (whitewater is translucent where thin).

        • OptionalfoamSpeed?: [number, number]

          Speeds (m/s) over which water turns to whitewater: none below the first, all above the second.

        • Optionalior?: number

          Index of refraction (sets the Fresnel reflectance; 1.333 for water).

        • Optionaliterations?: number

          Smoothing passes (each a horizontal and a vertical blur), 0…4.

        • Optionalmist?: number

          Opacity of one spray particle's mist.

        • OptionalmistSize?: number

          Width of a spray particle's mist, in particle spacings.

        • Optionalradius?: number

          Particle sphere radius, in particle spacings (Δx/2). About 1 makes neighbours overlap into one surface.

        • Optionalrefraction?: number

          How far the background shifts through the surface, per metre of water thickness (screen fraction).

        • Optionalresolution?: number

          Resolution of the offscreen passes relative to the drawing buffer (0.25…1).

        • Optionalroughness?: number

          Microfacet roughness of the sun highlight (0.02 glassy … 0.3 rippled).

        • OptionalscatterColor?: string

          Colour of the in-scattered light (silt, algae), #rrggbb.

        • Optionalshutter?: number

          Exposure time of the mist's motion blur, seconds (streak length = speed × shutter).

        • Optionalsky?: [string, string, string]

          Reflected sky when no envMap: zenith, horizon and ground colours, #rrggbb (scaled by the lighting's ambient).

        • Optionalsmoothing?: number

          Depth smoothing radius, in particle radii (world space; the bilateral filter keeps silhouettes).

        • Optionalspray?: [number, number]

          Spray: water where the solver's grid is nearly empty (a node mass of a full cell of 1000 kg/m³ = 1) is drawn as soft mist, not as surface; all mist below the first value, all surface above the second (needs a source with a grid).

        • Optionalstreaks?: number

          Contrast of the flow-aligned streaks in falling whitewater, 0…1.

        • OptionaltagRadius?: number

          Radius multiplier of tagged particles (buffers.state.z ≠ 0, e.g. rain splashes): small drops, not blobs.

        • Optionalturbidity?: number

          In-scattering by suspended matter, per metre: 0 is glass-clear, tens is opaque mud within centimetres.

      Returns this

    • Replaces the reflected environment (null: the sky gradient). Rebuilds the composite material.

      Parameters

      • envMap: Texture<unknown, TextureEventMap> | null

      Returns this