smokeRTT

@three-blocks/coreWebGPURTT
smokeRTT(pointer : THREE.Vector2, simRes : number, dyeRes : number, iterations : number, densityDissipation : number, velocityDissipation : number, pressureDissipation : number, curlStrength : number, pressureFactor : number, radius : number, useBoundaries : boolean, pointerScale : number, neighborStride : number, speedFactor : number) : Node

Smoke RTT Simulation (TSL) – a 2D velocity–pressure solver using RenderTargets.

This is an RTT-based variant of the smoke simulation that uses RenderTarget + fragment shaders instead of StorageTexture + compute shaders. This provides broader WebGPU compatibility as it doesn't require Tier2 read-write storage texture support.

The API is identical to smoke() - drop-in replacement for environments without Tier2 support.

Features

  • Semi-Lagrangian advection for velocity and density
  • Vorticity confinement (curl) and divergence-free projection (pressure solve)
  • Configurable dissipation, pressure iterations and curl strength
  • Optional pointer-driven splats via a vec2 uniform
  • Drop-in for post-processing: postProcessing.outputNode = smokeRTT(pointer, 128, 512, ...)

Example: Basic postprocessing setup

Example: Interactive pointer-driven splats

import * as THREE from 'three/webgpu';
import { smokeRTT } from '@three-blocks/core';

const pointer = new THREE.Vector2();

// Pass pointer as first argument - motion automatically injects splats
const fluidNode = smokeRTT(pointer, 128, 512, 3, 0.97, 0.98, 0.8, 20, 0.2, 0.1, true, 45);

// Update pointer on mouse move (NDC coordinates: -1 to +1)
document.addEventListener('mousemove', (e) => {
  pointer.x = (e.clientX / window.innerWidth) * 2 - 1;
  pointer.y = -(e.clientY / window.innerHeight) * 2 + 1;
});
Parameters
pointeroptionalTHREE.Vector2
NDC-like pointer in [-1, 1]; when present, motion injects splats.
simResoptionalnumber
Square resolution for velocity/pressure buffers.
Default is 128.
dyeResoptionalnumber
Square resolution for density buffer.
Default is 512.
iterationsoptionalnumber
Pressure Jacobi iterations per solve.
Default is 3.
densityDissipationoptionalnumber
Density dissipation factor in [0, 1].
Default is 0.97.
velocityDissipationoptionalnumber
Velocity dissipation factor in [0, 1].
Default is 0.98.
pressureDissipationoptionalnumber
Damp factor for pressure clear step.
Default is 0.8.
curlStrengthoptionalnumber
Vorticity confinement scale.
Default is 20.
pressureFactoroptionalnumber
Pressure factor constant in Jacobi updates.
Default is 0.2.
radiusoptionalnumber
Gaussian splat radius in UV^2. Increase for larger splats.
Default is 0.1.
useBoundariesoptionalboolean
Mirror-velocity boundary conditions at screen edges.
Default is true.
pointerScaleoptionalnumber
Multiplier applied to pointer delta when generating splats.
Default is 45.
neighborStrideoptionalnumber
Multiplier for curl/divergence/pressure neighbor texel offsets.
Default is 1.
speedFactoroptionalnumber
Scales sub-stepping relative to frame time (lower = more substeps).
Default is 1.
Returns
Node — Color node sampling the current dye texture of the fluid simulation.
Example
import * as THREE from 'three/webgpu';
import { smokeRTT } from '@three-blocks/core';

const renderer = new THREE.WebGPURenderer();
await renderer.init();

const postProcessing = new THREE.PostProcessing(renderer);
const pointer = new THREE.Vector2();

// smokeRTT(pointer, simRes, dyeRes, iterations, densityDissipation, velocityDissipation,
//          pressureDissipation, curlStrength, pressureFactor, radius, useBoundaries, pointerScale)
const fluidNode = smokeRTT(pointer, 128, 512, 3, 0.97, 0.98, 0.8, 20, 0.2, 0.1, true, 45);

postProcessing.outputNode = fluidNode;

renderer.setAnimationLoop(() => postProcessing.render());