Newton Fluid Support
Prototype implementation of particle-fluid simulation and ViewerGL water rendering for Newton, focused on giving solver developers a reusable fluid visualization path.
Updated 2026-06-07 from branch eric-heiden/fluid-support, based on origin/main a046d613. Media was rendered with ViewerGL.get_frame().
Candidate AS: 1280x720 at 30 Mbps CBR, 26,880 particles, scene-depth floor caustics, tropical shallow/deep absorption, sharper env-map Fresnel reflection, refraction, and screen-space ripple detail.
viewer.log_fluid() with particle centers and radii, then get screen-space depth smoothing, translucent composition, tropical optical absorption, approximate refraction, screen-color reflection, Fresnel-weighted environment-map reflection, caustic/ripple distortion, and foam approximation without reimplementing GL water shaders.
High-Bitrate Water Fidelity Pass
Variants AS-AX respond to the compression and water-depth feedback directly. These are rendered at 1280x720 with 30 Mbps CBR H.264, trading resolution for far fewer codec artifacts. AS-AV focus on water optics: stronger environment-map reflection/refraction, clearer tropical shallow-to-deep color separation, scene-depth floor caustics, and more visible three-dimensional surface cues. AW-AX use the corrected interactive tank example: the basin is larger/deeper, the initial fluid is carved around the rigid boxes so they do not launch out of the water on frame one, and a gentler scripted picking force keeps the cubes suspended inside the water volume.
AS-AV are high-particle water-optics renders. AW-AX are interactive-tank renders with pickable rigid cubes suspended against the transparent water body.
Best current water-fidelity candidate. The shader uses the opaque scene depth behind the refracted water sample to add floor caustic streaks under the water volume.
1280x720; frames=120; bitrate=30M CBR; particles=26,880; opacity=0.54; env=1.05; reflect=0.25; refract=0.090; depth_cues=1.20; surface_caustic=2.30; floor_caustic=3.60
Open MP4 render
Pushes the ViewerGL environment map more aggressively with low reflection LOD and high env intensity, so the water surface picks up the same bright structure as metallic materials.
1280x720; frames=120; bitrate=30M CBR; particles=26,880; env_intensity=3.15; opacity=0.50; env=1.75; reflect=0.36; refract=0.058; floor_caustic=2.20
Open MP4 render
Higher density plus stronger optical-depth contrast. Shallow water stays pale turquoise while thicker regions shift toward dark tropical blue.
1280x720; frames=120; bitrate=30M CBR; particles=42,240; opacity=0.66; thickness=3.45; absorption=4.10; depth_cues=1.85; env=1.10; floor_caustic=2.80
Open MP4 render
Clearer water with the strongest refraction and floor caustics in this pass. This clip is the stress test for transparent, refractive beach-water behavior.
1280x720; frames=120; bitrate=30M CBR; particles=42,240; opacity=0.46; env=1.35; reflect=0.28; refract=0.125; surface_caustic=2.55; floor_caustic=4.00
Open MP4 render
Scripted version of the corrected interactive demo. The boxes are initialized inside a deeper water volume with carved-out particle cavities, then a gentle picking-style force moves one cube without ejecting the cluster.
1280x720; frames=105; bitrate=30M CBR; particles=20,736; boxes=5; basin_z=1.48; box_height=0.46; carve=0.055; opacity=0.32; env=0.85; refract=0.070; floor_caustic=2.70; pick-style force=2
Open MP4 render
Same corrected interactive tank with stronger env reflection and floor caustics. The production example exposes these settings through GUI sliders for live tuning and right-click picking.
1280x720; frames=105; bitrate=30M CBR; particles=20,736; boxes=5; basin_z=1.48; box_height=0.46; carve=0.055; opacity=0.36; env=1.35; reflect=0.24; refract=0.085; floor_caustic=3.20
Open MP4 render
High-Particle 1080p Realism Sweep
Variants AG-AN are the latest pass. They rerender the dam-break with 26,880 to 42,240 particles at 1920x1080 and use the revised water shader: the repo's ViewerGL environment map is sampled for both Fresnel reflection and refracted transmission, then filtered through a water tint so the indoor panorama contributes highlight structure without turning tropical water brown. The shader also adds optical-depth absorption, procedural ripple distortion, brighter caustic strokes, and softer screen-space foam.
AG-AN broad-view sweep. AG is the balanced candidate, AH pushes environment reflection, AI pushes refraction, AJ pushes deep-blue absorption, AK pushes caustics, AL pushes foam, and AM/AN use 42,240 particles for smoother surfaces.
Balanced candidate for the current shader: shallow turquoise, darker depth absorption, moderate env reflection, and restrained foam.
1920x1080; frames=120; particles=26,880; opacity=0.62; thickness=2.15; absorption=2.2; env=0.72; reflect=0.17; refract=0.045; caustic=1.15 @ 185; foam=0.07 @ 45
Open MP4 render
Pushes the same environment map used for metallic materials so Fresnel reflection is more visible on glancing water angles.
1920x1080; frames=120; particles=26,880; env_intensity=1.75; opacity=0.58; absorption=1.9; env=1.15; reflect=0.24; refract=0.040; caustic=0.95 @ 175
Open MP4 render
More transparent water with stronger normal and ripple-driven refraction. Useful for judging distortion before it becomes too noisy.
1920x1080; frames=120; particles=26,880; opacity=0.52; thickness=1.70; absorption=1.55; env=0.58; reflect=0.13; refract=0.095; caustic=1.35 @ 205
Open MP4 render
Pushes tropical depth grading harder: shallow water stays turquoise while thicker regions move toward darker lagoon blue.
1920x1080; frames=120; particles=26,880; opacity=0.78; thickness=3.20; absorption=3.2; deep=(0.0, 0.02, 0.30); env=0.62; refract=0.040
Open MP4 render
Stress test for visible caustic/ripple strokes. This remains a screen-space approximation, not floor-projected photon caustics.
1920x1080; frames=120; particles=26,880; opacity=0.62; thickness=1.95; absorption=1.7; env=0.68; refract=0.060; caustic=2.60 @ 260
Open MP4 render
Foam is now a softer thickness/curvature edge band with procedural breakup. Solver-side foam particles are still a future step.
1920x1080; frames=120; particles=26,880; opacity=0.65; thickness=2.05; absorption=2.0; env=0.70; refract=0.050; foam=0.38 @ 35
Open MP4 render
Higher particle density and wider smoothing. This is the best broad-view check for hiding individual particle samples.
1920x1080; frames=120; particles=42,240; radius_scale=2.65; blur=22 x 4.1; opacity=0.62; thickness=2.20; absorption=2.2; env=0.72
Open MP4 render
Dense-particle version with more reflection, refraction, and deep-water absorption.
1920x1080; frames=120; particles=42,240; opacity=0.72; thickness=2.85; absorption=2.6; env=0.95; reflect=0.22; refract=0.065; caustic=1.45 @ 220
Open MP4 render
Close-Up Optical Stress Tests
Variants AO-AR use the same 26,880-particle setup but record an earlier, taller fluid state from a closer camera. These are less useful as final beauty shots, but they make reflection/refraction/caustic/foam artifacts easier to evaluate than a flat puddle.
Close view with strong env-map reflection and refracted transmission through thicker water.
1920x1080; frames=90; particles=26,880; opacity=0.62; thickness=2.35; absorption=2.4; env=1.05; reflect=0.24; refract=0.075; caustic=1.55 @ 210
Open MP4 render
Darkest absorption trial for evaluating whether deep regions read as blue water rather than uniform aqua.
1920x1080; frames=90; particles=26,880; opacity=0.82; thickness=3.70; absorption=4.2; deep=(0.0, 0.015, 0.24); env=0.78; refract=0.050
Open MP4 render
Pushes screen-space caustics and foam together to expose where the approximation becomes too busy.
1920x1080; frames=90; particles=26,880; opacity=0.66; thickness=2.50; absorption=2.5; caustic=3.20 @ 245; foam=0.55 @ 30
Open MP4 render
Most transparent/high-refraction trial. Useful for judging whether the refracted checker and env-map transmission are too strong.
1920x1080; frames=90; particles=26,880; opacity=0.48; thickness=1.65; absorption=1.55; env=0.70; reflect=0.16; refract=0.120; caustic=1.85 @ 220
Open MP4 render
Architecture
newton.solvers.SolverSPHis an experimental weakly-compressible SPH solver using Warp kernels and awp.HashGridneighbor search.ViewerBase.log_fluid()adds a backend-neutral fluid logging API. Backends without fluid support fall back to point rendering.ViewerGL.log_fluid()stores particle centers/radii in a GL buffer and renders them through a screen-space fluid pass.- The ViewerGL pass writes nearest fluid depth and optical thickness, applies separable bilateral depth smoothing, then composites water over the opaque scene using shallow/deep optical absorption, chromatic refraction offsets, screen-color reflection, Fresnel-weighted environment-map reflection, env-map transmission, scene-depth floor caustics, procedural ripple/caustic strokes, screen-space foam, and a specular highlight.
- Additional material controls now include blur radius, shallow/deep colors, gradient strength, absorption strength, depth-cue strength, refraction/reflection strength, environment-map reflection strength/LOD/color preservation, surface caustics, floor caustics, and foam strength/scale, so fluid solver authors can iterate visually without rewriting shaders.
- Particle billboards are expanded in a geometry shader instead of relying on
gl_PointCoord, which was unreliable in the target headless GL context. example_fluid_sph_interactive_tank.pycouples SPH particles to suspended rigid boxes, enables ViewerGL right-click picking, carves the initial SPH particle volume around the boxes to avoid explosive overlap impulses, and exposes water shader controls through the live GUI so solver and rendering parameters can be tuned in one demo.
Visual Variants
The gallery below explores ten rendered directions. Each card is a separate ViewerGL.get_frame() MP4 render with the exact settings shown under the video, so the visual tradeoffs can be compared directly.
Contact sheet of the generated variants. D and I use higher particle counts; the others use the same 1,008-particle SPH setup with different ViewerGL material controls.
Closest to the first implementation. Useful baseline, but individual particle silhouettes remain visible.
particles=1,008; radius_scale=1.35; blur=4 x 1.0; opacity=0.75; thickness=1.8; caustic=0.00; refract=0.022; reflect=0.07
Open MP4 render
More continuous surface extraction from the same particles. The blob reads smoother but loses some small-scale detail.
particles=1,008; radius_scale=1.95; blur=9 x 2.6; opacity=0.78; thickness=2.0; caustic=0.18 @ 80; refract=0.022; reflect=0.07
Open MP4 render
Adds caustic-like procedural strokes, stronger refraction, and a glassier surface. Current best candidate for a nice water default.
particles=1,008; radius_scale=1.85; blur=8 x 2.3; opacity=0.74; thickness=2.0; caustic=0.62 @ 105; refract=0.034; reflect=0.11
Open MP4 render
Tests the solver/render path with more particles and smaller radii. The surface has fewer visible particle cells before smoothing.
particles=5,376; radius_scale=1.35; blur=8 x 1.8; opacity=0.78; thickness=2.1; caustic=0.35 @ 85; refract=0.022; reflect=0.07
Open MP4 render
More opaque and volumetric. This may suit viscous fluid presets better than clear water.
particles=1,008; radius_scale=1.65; blur=8 x 2.1; opacity=0.90; thickness=3.3; caustic=0.22 @ 75; refract=0.020; reflect=0.07
Open MP4 render
Highest caustic/refraction settings. It is visually lively but may be too sparkly for a default water material.
particles=1,008; radius_scale=1.70; blur=7 x 2.0; opacity=0.64; thickness=1.35; caustic=0.95 @ 145; refract=0.046; reflect=0.14
Open MP4 render
Baseline render mode for comparison. The individual SPH samples are fully visible and do not read as a continuous liquid surface.
particles=1,008; render_mode=particles; fluid pass disabled; same SPH state and camera as A-C
Open MP4 render
Isolates the screen-space surface extraction idea: large overlapping billboards plus aggressive bilateral depth smoothing.
particles=1,008; radius_scale=2.25; blur=11 x 3.0; opacity=0.80; thickness=2.2; caustic=0.00; refract=0.018; reflect=0.055
Open MP4 render
Pushes particle count and smaller radii. This reduces the particle-cell look before the render pass has to smooth the surface.
particles=10,080; radius_scale=1.45; blur=9 x 2.0; opacity=0.72; thickness=2.4; caustic=0.28 @ 92; refract=0.030; reflect=0.095
Open MP4 render
A deliberately exaggerated clear-water material. It shows the upper range of caustic and refraction controls.
particles=1,008; radius_scale=1.85; blur=8 x 2.4; opacity=0.60; thickness=1.25; caustic=1.10 @ 170; refract=0.055; reflect=0.16
Open MP4 render
Variant Settings Matrix
| Variant | Approach | Particles | Surface settings | Material settings |
|---|---|---|---|---|
| A | Control fluid render | 1,008 | radius_scale=1.35, blur=4 x 1.0 |
opacity=0.75, thickness=1.8, caustic=0.00 |
| B | Soft blob extraction | 1,008 | radius_scale=1.95, blur=9 x 2.6 |
opacity=0.78, thickness=2.0, caustic=0.18 @ 80 |
| C | Caustic glass candidate | 1,008 | radius_scale=1.85, blur=8 x 2.3 |
opacity=0.74, caustic=0.62 @ 105, refract=0.034, reflect=0.11 |
| D | Higher particle count | 5,376 | radius_scale=1.35, blur=8 x 1.8 |
opacity=0.78, thickness=2.1, caustic=0.35 @ 85 |
| E | Milky volumetric water | 1,008 | radius_scale=1.65, blur=8 x 2.1 |
opacity=0.90, thickness=3.3, caustic=0.22 @ 75 |
| F | Thin clear caustics | 1,008 | radius_scale=1.70, blur=7 x 2.0 |
opacity=0.64, thickness=1.35, caustic=0.95 @ 145 |
| G | Raw particle baseline | 1,008 | render_mode=particles |
Fluid surface pass disabled. |
| H | Blob extraction only | 1,008 | radius_scale=2.25, blur=11 x 3.0 |
opacity=0.80, thickness=2.2, caustic=0.00 |
| I | Dense clear water | 10,080 | radius_scale=1.45, blur=9 x 2.0 |
opacity=0.72, thickness=2.4, caustic=0.28 @ 92 |
| J | Clear caustic pool | 1,008 | radius_scale=1.85, blur=8 x 2.4 |
opacity=0.60, caustic=1.10 @ 170, refract=0.055, reflect=0.16 |
Beach Water Env-Map Sweep
Variants K-R use the updated shader path. The fluid composite samples the same ViewerGL environment map used by metallic surfaces, then weights it with a water-style Fresnel term. These videos are longer than A-J and include warmup frames so the dam-break surface has moved before recording starts.
Contact sheet for the new environment-map/Fresnel sweep. K is the current recommendation; M, N, O, and R intentionally push one parameter family harder to expose tradeoffs.
Current recommended beach-water look: brighter turquoise base color, visible caustics, and moderate Fresnel env reflection.
particles=1,008; radius_scale=1.85; blur=9 x 2.35; opacity=0.66; thickness=1.60; env=0.28; caustic=0.72 @ 120; refract=0.045
Open MP4 render
Lower opacity and environment strength. Useful if the default reads too glossy or too stylized.
particles=1,008; radius_scale=1.75; blur=8 x 2.15; opacity=0.58; thickness=1.25; env=0.12; caustic=0.42 @ 105; refract=0.035
Open MP4 render
Pushes environment reflection to show the upper end of the control. Good for reading sky reflections, but it may be too dark/glassy for a default.
particles=1,008; radius_scale=1.80; blur=8 x 2.25; opacity=0.62; thickness=1.45; env=0.55; caustic=0.58 @ 120; reflect=0.14
Open MP4 render
Raises caustic strength and frequency. This is the clearest stress test for whether caustic strokes look useful or too busy.
particles=1,008; radius_scale=1.85; blur=8 x 2.25; opacity=0.64; thickness=1.35; env=0.25; caustic=1.25 @ 190; refract=0.055
Open MP4 render
Lower optical thickness and a greener aqua tint. This variant explores a shallow beach-water preset rather than deep blue water.
particles=1,008; radius_scale=1.70; blur=7 x 2.10; opacity=0.52; thickness=0.95; env=0.32; caustic=0.88 @ 150; refract=0.050
Open MP4 render
Higher particle count with the new material. This tests whether density reduces visible cells before the screen-space pass has to smooth them.
particles=10,080; radius_scale=1.50; blur=9 x 2.0; opacity=0.64; thickness=1.75; env=0.30; caustic=0.62 @ 130; refract=0.042
Open MP4 render
Combines denser particles with aggressive bilateral smoothing. It reads as the most continuous surface, but small waves are softened.
particles=5,376; radius_scale=1.60; blur=12 x 2.75; opacity=0.68; thickness=1.85; env=0.26; caustic=0.50 @ 120; refract=0.040
Open MP4 render
Same bright material family with low smoothing. This shows how much the blob extraction step matters even when the water material is improved.
particles=1,008; radius_scale=1.30; blur=2 x 1.0; opacity=0.64; thickness=1.45; env=0.28; caustic=0.72 @ 120; refract=0.040
Open MP4 render
Env-Map Settings Matrix
| Variant | Question | Particles | Surface settings | Water material settings |
|---|---|---|---|---|
| K | Recommended beach-water default | 1,008 | radius_scale=1.85, blur=9 x 2.35 |
env=0.28, caustic=0.72 @ 120, color=(0.22, 0.95, 1.0) |
| L | How subtle should env reflection be? | 1,008 | radius_scale=1.75, blur=8 x 2.15 |
env=0.12, opacity=0.58, caustic=0.42 @ 105 |
| M | How glossy can Fresnel reflection get? | 1,008 | radius_scale=1.80, blur=8 x 2.25 |
env=0.55, reflect=0.14, caustic=0.58 @ 120 |
| N | How visible should caustics be? | 1,008 | radius_scale=1.85, blur=8 x 2.25 |
env=0.25, caustic=1.25 @ 190, refract=0.055 |
| O | Can we get a shallow aqua tint? | 1,008 | radius_scale=1.70, blur=7 x 2.10 |
env=0.32, opacity=0.52, thickness=0.95 |
| P | Does very high particle count help? | 10,080 | radius_scale=1.50, blur=9 x 2.0 |
env=0.30, caustic=0.62 @ 130, refract=0.042 |
| Q | Does dense + wide blur make the best blob? | 5,376 | radius_scale=1.60, blur=12 x 2.75 |
env=0.26, opacity=0.68, caustic=0.50 @ 120 |
| R | What if material improves but smoothing stays low? | 1,008 | radius_scale=1.30, blur=2 x 1.0 |
env=0.28, caustic=0.72 @ 120, refract=0.040 |
High-Quality Tropical Gradient Sweep
Variants S-X use the new shallow/deep color-gradient controls and were rendered at 1280x720 with 96 frames per clip. The palette options are based on typical tropical beach water: pale mint or emerald shallows, cyan mid-water, deeper blue/teal thickness, white-blue caustic highlights, and subtle Fresnel environment reflection.
Contact sheet for the high-quality tropical gradient videos. These are the preferred clips for visual feedback because they preserve more resolution than the earlier A-R exploration renders.
Recommended high-quality direction. Mint/aqua shallow color blends into deeper tropical blue, with moderate env reflection and caustics.
1280x720; frames=96; particles=1,008; shallow=(0.16, 1.00, 0.90); deep=(0.00, 0.42, 0.84); gradient=0.78; env=0.30; caustic=0.86 @ 145
Open MP4 render
Greener lagoon palette. This keeps the water bright without pushing as far into cobalt blue.
1280x720; frames=96; particles=1,008; shallow=(0.05, 0.96, 0.74); deep=(0.02, 0.48, 0.78); gradient=0.88; env=0.24; caustic=0.95 @ 160
Open MP4 render
More saturated deep-water option. The surface stays cyan while thicker regions shift toward reef-blue/cobalt.
1280x720; frames=96; particles=1,008; shallow=(0.20, 0.95, 1.00); deep=(0.00, 0.22, 0.78); gradient=0.95; env=0.42; caustic=0.74 @ 135
Open MP4 render
Lighter and shallower, closer to water over sand. The lower opacity and lighter shallow color make it less glassy.
1280x720; frames=96; particles=1,008; shallow=(0.56, 1.00, 0.82); deep=(0.06, 0.68, 0.90); gradient=0.64; env=0.28; caustic=1.05 @ 170
Open MP4 render
Stress test for bright caustic strokes and stronger blue-green variation. Useful if the default still feels too flat.
1280x720; frames=96; particles=1,008; shallow=(0.12, 0.96, 0.95); deep=(0.02, 0.30, 0.95); gradient=0.92; env=0.32; caustic=1.45 @ 215
Open MP4 render
Combines the tropical gradient material with denser SPH particles. This reduces the particle-cell look before smoothing.
1280x720; frames=96; particles=10,080; shallow=(0.18, 0.96, 1.00); deep=(0.00, 0.40, 0.88); gradient=0.82; env=0.34; caustic=0.84 @ 150
Open MP4 render
HQ Gradient Settings Matrix
| Variant | Palette | Particles | Gradient settings | Render/material settings |
|---|---|---|---|---|
| S | Mint shallow to blue depth | 1,008 | shallow=(0.16,1.00,0.90), deep=(0.00,0.42,0.84), gradient=0.78 |
1280x720, blur=10 x 2.45, env=0.30, caustic=0.86 @ 145 |
| T | Emerald lagoon | 1,008 | shallow=(0.05,0.96,0.74), deep=(0.02,0.48,0.78), gradient=0.88 |
1280x720, blur=9 x 2.35, env=0.24, caustic=0.95 @ 160 |
| U | Cyan to cobalt reef | 1,008 | shallow=(0.20,0.95,1.00), deep=(0.00,0.22,0.78), gradient=0.95 |
1280x720, blur=10 x 2.45, env=0.42, caustic=0.74 @ 135 |
| V | Pale sandbar mint | 1,008 | shallow=(0.56,1.00,0.82), deep=(0.06,0.68,0.90), gradient=0.64 |
1280x720, opacity=0.52, env=0.28, caustic=1.05 @ 170 |
| W | Vivid caustic gradient | 1,008 | shallow=(0.12,0.96,0.95), deep=(0.02,0.30,0.95), gradient=0.92 |
1280x720, env=0.32, caustic=1.45 @ 215, refract=0.060 |
| X | Dense tropical gradient | 10,080 | shallow=(0.18,0.96,1.00), deep=(0.00,0.40,0.88), gradient=0.82 |
1280x720, blur=10 x 2.15, env=0.34, caustic=0.84 @ 150 |
Translucency, Reflection, and Foam Sweep
Variants Y-AF investigate three material dimensions requested for follow-up: water translucency, shallow/deep color-gradient strength, and reflectiveness. They also prototype foam generation. The current foam pass is intentionally rendering-side and solver-agnostic: it uses screen-space thickness, free-surface edges, normal variation, and a procedural breakup pattern to create edge/crest foam. A physically better next step would be a solver-side foam emitter based on velocity, vorticity, air exposure, and particle lifetime, but this screen-space version is cheap and works for any solver that calls viewer.log_fluid().
Contact sheet for the Y-AF sweep. Y/AB/AA isolate translucency and reflection; AC/AD/AE explore screen-space foam strength and scale; AF is a low-gradient, low-reflection control.
A clearer, more glassy option with lower optical thickness and restrained environment reflection.
1280x720; frames=96; opacity=0.42; thickness=0.95; gradient=0.78; env=0.16; reflect=0.065; foam=0.00
Open MP4 render
A moderate blend of translucency, tropical gradient, env reflection, caustics, and light edge foam.
1280x720; frames=96; opacity=0.60; thickness=1.35; gradient=0.84; env=0.32; reflect=0.10; foam=0.32 @ 120
Open MP4 render
Pushes Fresnel/environment reflection to see how much sky reflection the material can carry before becoming too glassy.
1280x720; frames=96; opacity=0.64; gradient=0.90; env=0.62; reflect=0.16; refract=0.043; foam=0.20 @ 105
Open MP4 render
Higher opacity and stronger deep-blue thickness gradient. Useful for testing whether the water should read denser.
1280x720; frames=96; opacity=0.82; thickness=2.20; gradient=1.00; env=0.22; caustic=0.48 @ 120; foam=0.18 @ 100
Open MP4 render
Main foam candidate. Foam appears as subtle mint-white edge/crest breakup while preserving the underlying water material.
1280x720; frames=96; opacity=0.62; gradient=0.82; env=0.30; caustic=0.82 @ 150; foam=0.78 @ 125
Open MP4 render
Stress test with stronger high-frequency foam and caustics. It exposes where the screen-space foam can start to look noisy.
1280x720; frames=96; opacity=0.60; gradient=0.92; env=0.32; caustic=1.35 @ 220; foam=1.15 @ 230
Open MP4 render
Combines the dense-particle run with moderate foam. This checks whether better particle density changes how much foam is needed.
1280x720; frames=96; particles=10,080; opacity=0.64; gradient=0.82; env=0.34; caustic=0.82 @ 150; foam=0.55 @ 135
Open MP4 render
Control case for the new sweep. This keeps the material close to a single tint with low reflectiveness and no foam.
1280x720; frames=96; opacity=0.62; gradient=0.18; env=0.10; reflect=0.065; caustic=0.45 @ 120; foam=0.00
Open MP4 render
Foam Investigation Matrix
| Variant | Main question | Translucency | Gradient/reflectiveness | Foam settings |
|---|---|---|---|---|
| Y | How transparent can the water be? | opacity=0.42, thickness=0.95 |
gradient=0.78, env=0.16 |
foam=0.00 |
| Z | Balanced default candidate with light foam | opacity=0.60, thickness=1.35 |
gradient=0.84, env=0.32 |
foam=0.32 @ 120 |
| AA | How reflective should beach water be? | opacity=0.64, thickness=1.45 |
gradient=0.90, env=0.62, reflect=0.16 |
foam=0.20 @ 105 |
| AB | Does stronger opacity/depth color help? | opacity=0.82, thickness=2.20 |
gradient=1.00, env=0.22 |
foam=0.18 @ 100 |
| AC | Does screen-space edge foam read well? | opacity=0.62, thickness=1.35 |
gradient=0.82, env=0.30 |
foam=0.78 @ 125 |
| AD | Where does foam become too noisy? | opacity=0.60, thickness=1.20 |
gradient=0.92, caustic=1.35 @ 220 |
foam=1.15 @ 230 |
| AE | Does dense particle sampling reduce foam need? | opacity=0.64, thickness=1.65 |
particles=10,080, gradient=0.82, env=0.34 |
foam=0.55 @ 135 |
| AF | Control: low gradient/reflection/no foam | opacity=0.62, thickness=1.35 |
gradient=0.18, env=0.10 |
foam=0.00 |
Rendering Prototype
The same SPH state rendered as raw particle spheres and as the new ViewerGL fluid surface. The fluid path is rendering-only; it does not change solver state.
Prototype smoothing comparison. The selected path combines a rendering radius multiplier with bilateral screen-space depth smoothing. Low smoothing preserves every particle; the smoothed path reads more like a continuous liquid surface while remaining cheap.
Solver Prototype
SolverSPH supports active-particle filtering, density/pressure evaluation, pressure forces, viscosity, gravity, external particle forces, axis-aligned world bounds, velocity damping, and velocity clamping. It preallocates density and pressure buffers and reserves the particle hash grid at construction time.
The solver is deliberately not a full production fluid method. It is intended as a first Newton-native fluid solver and as a compact example for solver authors who want to produce particles that can be rendered as liquid through the shared ViewerGL path.
| Component | Current status | Notes |
|---|---|---|
| Neighbor search | Warp HashGrid |
Used for density, pressure, and viscosity loops; CUDA graph capture was verified after warm-up allocation/compilation. |
| Fluid rendering | Screen-space GL pass | Depth, thickness, bilateral smoothing, translucent composition, tropical absorption, approximate reflection/refraction, Fresnel-weighted environment-map reflection, env-map transmission, ripple distortion, and procedural caustic highlights. |
| Surface smoothing | Explored: inflated billboards, wider bilateral blur, more particles | The best-looking variants combine more overlap, a larger blur radius, and subtle caustics. True meshing remains a possible later backend. |
| Splash/foam | Prototype screen-space foam | Current pass estimates edge/crest foam from thickness, normal variation, and procedural breakup. Solver-side foam particles remain deferred. |
Examples
The branch adds newton/examples/fluid/example_fluid_sph_dam_break.py. It exposes the SPH parameters and ViewerGL fluid controls, including --render-mode, --beach-lighting, --ground-color, --environment-intensity, --fluid-color, --fluid-deep-color, --fluid-color-gradient-strength, --fluid-radius-scale, --fluid-smoothing-iterations, --fluid-smoothing-radius, --fluid-thickness-scale, --fluid-absorption-strength, --fluid-depth-visualization-strength, --fluid-env-map-strength, --fluid-env-reflection-lod, --fluid-env-color-preserve, --fluid-caustic-strength, --fluid-caustic-scale, --fluid-floor-caustic-strength, --fluid-foam-strength, --fluid-foam-scale, and --capture-graph.
The branch also adds newton/examples/fluid/example_fluid_sph_interactive_tank.py. It creates a deeper transparent water body with suspended rigid boxes, carves the initial particle volume around those boxes, applies SPH-to-box coupling forces, enables ViewerGL picking forces, and provides GUI sliders for the water shader, environment intensity/exposure/specular scale, picking stiffness/damping, suspension, and water-box coupling parameters.
Example invocation:
uv run --extra dev -m newton.examples fluid_sph_dam_break --viewer gl --headless --no-show-bounds
uv run --extra dev -m newton.examples fluid_sph_interactive_tank --viewer gl --no-show-bounds
Verification
uv run --extra dev -m newton.tests -k test_solver_sph: passed on CPU and CUDA, including CUDA graph capture oncuda:0.uv run --extra dev -m newton.tests -k test_viewer_fluid: passed.uv run --extra dev -m newton.tests -k test_interactive_tank_rollout_keeps_boxes_submerged_and_stable: passed after reproducing the pre-fix failure at 1696.94 m/s maximum box speed; the corrected rollout keeps boxes submerged, under 4 m/s, and inside the larger basin.uv run --extra dev -m newton.examples fluid_sph_dam_break --viewer null --test --num-frames 5: passed.uv run --extra dev -m newton.examples fluid_sph_interactive_tank --viewer null --test --num-frames 5 --dim-x 10 --dim-y 8 --dim-z 8 --box-count 3: passed.- Headless OpenGL smoke tests generated nonblank frames through
ViewerGL.get_frame()for raw particles, fluid rendering, env-map Fresnel water, scene-depth floor caustics, and the interactive tank renderer. - Report media check decoded 50 variant MP4 renders: A-J are 960x540 with 54 frames each, K-R are 960x540 with 72 frames each, S-AF are 1280x720 with 96 frames each, AG-AN are 1920x1080 with 120 frames each, AO-AR are 1920x1080 with 90 frames each, AS-AV are 1280x720 with 120 frames each at 30 Mbps CBR, and AW-AX are 1280x720 with 105 frames each at 30 Mbps CBR.
Next Work
- Add fluid collision against arbitrary shapes instead of only axis-aligned bounds.
- Replace or augment screen-space foam with optional solver-side foam/splash particles for high-velocity, high-vorticity free-surface regions.
- Expose per-fluid material presets for water, viscous liquid, and sand-like particle rendering.
- Consider a mesh or neural/splat surface backend later, while keeping
log_fluid()as the stable frontend API.