Repository navigation
Water
render_water draws one Clearwater still of shallow water.

The modules live in extensions/water/. This is a port of Clearwater by Aurélien Gimazane (Lumaris, 2026, MIT). See Extensions.
bed_color repeats assets/pebbles.jpg. It then mixes sand, coarse cobble and weed.
from extensions.water.frame import render_water
from extensions.water.pebbles import pebble_bed
from extensions.water.resolution import SpectrumResolution
from extensions.water.view import FRAME
from render.jpeg import decode
from std.pathlib import Path
from units.si import RADIAN, SECOND, Angle, Duration
var bed = pebble_bed(decode(Path("assets/pebbles.jpg").read_bytes()))
var image = render_water(
1280,
720,
Duration(5.0, SECOND),
FRAME,
False,
SpectrumResolution(256),
64,
256,
SpectrumResolution(128),
False,
bed,
Angle(-0.22, RADIAN),
)False holds the camera still. The next False leaves the ripple window empty. The pitch is -0.22 radians, so the headland matches the photograph. The page starts at -0.72 radians.
Use a WaterScene to draw more than one frame. The scene keeps the resources that do not change with time. It builds the ocean spectrum once. It builds the glare kernels on the first frame that needs them. It owns the ripple window and the clock.
from extensions.water.frame import WaterScene
var scene = WaterScene(
SpectrumResolution(64),
32,
128,
SpectrumResolution(64),
Duration(0.0, SECOND),
)
for frame in range(60):
scene.advance(Duration(1.0 / 30.0, SECOND), frame % 10 == 0)
var image = scene.draw(320, 180, FRAME, True, bed, Angle(-0.72, RADIAN))advance steps the ripple equation once, then moves the clock. Its Bool taps the middle of the ripple window. The step must be finite and nonnegative. draw makes a picture at the scene's clock and does not change the simulation. Equal steps give equal pictures.
reset returns the ripples and the clock to the start. It keeps the spectrum and the glare kernels. The buffers keep their sizes for the life of the scene.
render_water is one scene step and one draw. A scene is the start of persistent scene water, issue 300. It does not compose with a three.js scene yet. It has no GPU path. It does not establish a frame rate.
WaterView names four pictures.
| Name | What it draws |
|---|---|
FRAME |
The graded photograph. |
CAUSTICS |
The caustic texture, scaled by 0.25. |
LINEAR |
The water without glare or bloom. |
GLARE |
The diffraction spikes alone. |
SpectrumResolution is a power of two from 4 through 256. The still uses 256, the same ocean grid as the page. The patch is 4.6 meters. The mean depth is 1.6 meters. The root-mean-square slope is 0.078. Mipmaps and anisotropy filter the ocean, the caustics and the pebbles.
The caustic grid in the still is 64. The page uses 256.
render_water builds a WaterScene, steps the ripple and draws the caustics. It then shades each pixel and grades the color. The shader clock is 0.9 times the frame clock. Dispersion repeats every 60 seconds of shader time.
Texture coordinates name texel centers at (i + 0.5) / n, as in WebGL. Bilinear, cubic and mip samples use the same convention. Caustic triangles use a half-open edge rule, so a shared edge receives light once. A flat surface under a vertical sun has unit caustic intensity.
Underwater absorption and ripple lookup follow the refracted sun direction. The sun is not treated as vertical when it is near the horizon. Invalid spectrum and glare sizes are refused before their grids are allocated.
This extension draws a CPU still. It is not a shared scene-water object or a validated fluid solver. The picture does not establish a real-time frame rate, buoyancy, or engineering fluid accuracy.
Tutorials
How-to
Reference
- Scene graph
- Rotations
- Cameras
- Geometry
- Geometry addons
- Lofts and clipping groups
- Sculptor
- Procedural generators
- Meshes and assets
- Lines
- Points and sprites
- Helpers
- Scene objects
- Animated objects
- Raycasting
- Curves and paths
- Animation
- Skinning
- Materials
- Node materials
- TSL functions
- Lights
- Lighting addons
- Fog
- Textures
- Renderer
- Renderer hooks and material flags
- Rasterization
- GPU backend
- Render target
- Post-processing
- GPU computation
- Compute nodes
- Progressive light map
- Gaussian splats
- Voxel global illumination
- SVG renderer
- Image files
- Image decode queue
- Model files
- More model files
- Exporters
- Scene JSON
- Windowing and controls
- Math
- Norm consumers
- Math addons
- Units
- Coverage tool
- Commands
- Examples
- Benchmarks
- Extensions
- Shared physics
- Physics query snapshots
- Continuous collision
- Tick force restoration
- Water
- Streamline
- Animals
- Buildings
- CARLA
- Femur
- Tibia
- Fibula
- Patella
- Knee
- Muscles
- Vessels
- Lymph
- Nerves
- Integument
- Leg
- Foot
- Pelvis
- Torso
- Arm
- Hand
- Head
- Genome
- Game humanoid
- Humanoid fidelity
- Audio-aligned game faces
- Converted assets
- Mesh quality
- Segment inertia
Explanation
- Software rasterizer
- Scene graph as an array
- Linear color
- Normals are not colors
- Perspective correction
- Fixed-point coverage
- Per-fragment shading
- Mipmaps
- Sorted transparency
- Types and checks
- Render hooks as a trait
- Shared CPU and GPU code
- Bands and threads
- PNG structure
- Extensions beside the port
- CUDA teardown hang
- Mojo compiler hang