# Visual effects

# Visual effects

Package `@ferret/physics-fx`.

## What it is for

The physics capabilities report numbers and own no look. This package turns the numbers into pictures in a Babylon scene: a brake disc that glows red, a forge's iron that goes white, a lake whose surface the shallow-water solver moves, a spill of particles, a lamp whose light dims and reddens as its filament cools. It is what a game uses or replaces with its own; each binding returns a `dispose`.

## Colour and glow

```ts
import { blackbody, incandescence } from '@ferret/physics-fx';

const red = blackbody(1000), white = blackbody(6500), blue = blackbody(12000);
const dull = incandescence(700), dim = incandescence(1000), bright = incandescence(1400), full = incandescence(1800);
```

- `blackbody(T)` is the colour of a black body at `T` kelvin as `[r, g, b]` in 0..1 (Planck locus fit, within a few percent from 1000 K to 40000 K).
- `incandescence(T, full?)` is how bright it glows, 0..1: nothing below the **Draper point** (798 K, where a dull red first shows in the dark), rising with the visible share of the radiation, 1 at `full` (1800 K by default).

## The bindings

| Binding | Does |
|---|---|
| `glow(scene, mesh, () => T, {full?, strength?})` | the mesh's `emissiveColor` follows a temperature (a heat part's `T`); the mesh needs a material |
| `waterMesh(scene, () => surface.field(), {name?, material?})` | a grid mesh whose heights and normals follow a `WaterSurface` of liquids (skill `ferret`) each frame |
| `fluidView(scene, () => liquid.view(name), {max?, color?, foam?, foamSpeed?})` | a particle liquid as thin instances of one small sphere, from a still colour to a foam colour by speed; up to `max` (8000) particles |
| `lampLight(scene, light, lamp, {rated?, intensity?})` | a scene light follows a lamp of electric (skill `ferret-physics-electric`): colour from the filament temperature, intensity from `incandescence` against the rated temperature (2800 K); a burnt lamp goes dark |

```ts
import { glow } from '@ferret/physics-fx';

const g = glow(scene, discMesh, () => brakePart.T);         // red by 1000 K, white-hot by 1800 K
// later
g.dispose();
```

A dimmed lamp goes red and dark; a burnt one goes out. A water mesh updates positions every frame from the surface field, so size the grid for the frame budget (a 64 × 64 surface is 4096 vertices).

## Debugging

| Symptom | Cause |
|---|---|
| `mesh "x" has no material to glow` | give the mesh a `StandardMaterial` or `PBRMaterial` first |
| No glow below 800 K | correct: nothing is visible below the Draper point |
| Water mesh does not move | the surface was not stepped, or `field()` returns a new object each frame without updating heights |
| Too many particles drawn | raise `max` or lower the liquid's particle count; `drawn()` tells how many are shown |

## Reference

`blackbody`, `incandescence`, `glow`, `waterMesh`, `fluidView`, `lampLight`, `@ferret/physics-fx`.
