volumeMarch
Walk a ray through the medium front to back, adding up what glows and what dims.
volumeMarch(opts: {
steps: number
entry: Expr
length: Expr
/** A per-pixel offset added to each step's position along the ray, as a fraction of the ray. */
jitter?: Expr
/** A multiplier on every sample's `emit`. */
emissionGain?: Expr
hint?: string
}, sample: (step: VolumeMarchStep) => {emit: Expr; absorb: Expr}): {color: Expr; transmittance: Expr}
Import volume from shaders/std and use volume.volumeMarch.
steps is how many samples to take (4–8 is typical; it is fixed when the shader compiles). entry and length come from interiorRay. For each step your callback returns emit, the rgb light this sample gives off, and absorb, the rgb amount it blocks. Absorption is per channel, so a medium can dim blue more than red. Returns the accumulated color and the transmittance left at the far side: multiply anything behind the medium by it. jitter is a small per-pixel offset along the ray, as a fraction of its length (a hash times 1 / steps works), that trades banding for fine grain. emissionGain scales every sample's glow; use k / steps so brightness does not change with the step count.
Parameters
| Name | Type | Notes |
|---|---|---|
opts | `{ |
steps: number
entry: Expr
length: Expr
/** A per-pixel offset added to each step's position along the ray, as a fraction of the ray. */
jitter?: Expr
/** A multiplier on every sample's `emit`. */
emissionGain?: Expr
hint?: string
}` | |
| sample | (step: VolumeMarchStep) => {emit: Expr; absorb: Expr} | |
Example
const march = volumeMarch({steps: 6, entry: ray.entry, length: ray.length, jitter}, ({z, i}) => ({emit: math.mul(rgb, dens), absorb: math.splat3(math.mul(dens, u.density))}))
Tip. Fewer steps plus
jitterbeats more steps: the noise becomes grain instead of bands.
See also
interiorRay— The line of sight through a shape: where it enters, how far it travels inside, and where it is at any depth.turbulentMedium— A billowing cloud density at a point inside the shape.parallaxPlane— A flat layer at a fixed depth inside the shape, like scenery seen through a window.