# @remotion/noise

Perlin noise for organic, natural-looking motion and visual effects.

**Package:** `@remotion/noise`

## Installation

```bash
npm i @remotion/noise
```

## noise3D() — The Main Function

```tsx
import { noise3D } from '@remotion/noise';
```

### Parameters

```tsx
noise3D(
  seed: string,   // Unique identifier for this noise channel
  x: number,      // First dimension (often spatial X)
  y: number,      // Second dimension (often spatial Y)
  z: number       // Third dimension (often time/frame)
): number         // Returns -1 to 1
```

### Basic Usage

```tsx
import { noise3D } from '@remotion/noise';
import { useCurrentFrame } from 'remotion';

const OrganicMotion = () => {
  const frame = useCurrentFrame();
  
  // Use frame for time dimension
  const offsetX = noise3D('x', 0, 0, frame * 0.02) * 50;
  const offsetY = noise3D('y', 0, 0, frame * 0.02) * 50;
  
  return (
    <div style={{
      transform: `translate(${offsetX}px, ${offsetY}px)`,
    }}>
      Floaty element
    </div>
  );
};
```

## Patterns

### Floating Dot Grid

```tsx
import { noise3D } from '@remotion/noise';
import { interpolate, useCurrentFrame, useVideoConfig } from 'remotion';

const ROWS = 10;
const COLS = 15;

const NoiseGrid = ({ speed = 0.01, maxOffset = 20 }) => {
  const frame = useCurrentFrame();
  const { width, height } = useVideoConfig();
  
  return (
    <svg width={width} height={height}>
      {Array(COLS).fill(0).map((_, i) =>
        Array(ROWS).fill(0).map((__, j) => {
          const baseX = i * (width / COLS);
          const baseY = j * (height / ROWS);
          
          // Normalize position for smooth noise
          const px = i / COLS;
          const py = j / ROWS;
          
          // Different seeds for X and Y movement
          const dx = noise3D('x', px, py, frame * speed) * maxOffset;
          const dy = noise3D('y', px, py, frame * speed) * maxOffset;
          
          // Noise-driven opacity
          const opacity = interpolate(
            noise3D('opacity', i, j, frame * speed),
            [-1, 1],
            [0.2, 1]
          );
          
          return (
            <circle
              key={`${i}-${j}`}
              cx={baseX + dx}
              cy={baseY + dy}
              r={4}
              fill="white"
              opacity={opacity}
            />
          );
        })
      )}
    </svg>
  );
};
```

### Organic Wiggle

```tsx
const wiggle = noise3D('wiggle', 0, 0, frame * 0.05) * 10;

<div style={{ transform: `rotate(${wiggle}deg)` }}>
  Wiggly text
</div>
```

### Pulsing Scale

```tsx
const scale = interpolate(
  noise3D('scale', 0, 0, frame * 0.03),
  [-1, 1],
  [0.9, 1.1]
);

<div style={{ transform: `scale(${scale})` }}>
  Breathing element
</div>
```

### Color Variation

```tsx
const hue = interpolate(
  noise3D('hue', 0, 0, frame * 0.02),
  [-1, 1],
  [180, 220]  // Teal range
);

<div style={{ backgroundColor: `hsl(${hue}, 70%, 50%)` }}>
  Color-shifting element
</div>
```

## Tips

### Use Different Seeds
Each seed creates an independent noise field:
```tsx
const x = noise3D('movement-x', ...);  // One noise field
const y = noise3D('movement-y', ...);  // Different noise field
const rotation = noise3D('rotation', ...);  // Yet another
```

### Control Speed
Multiply the time dimension to control animation speed:
```tsx
noise3D('x', px, py, frame * 0.01)  // Slow, dreamy
noise3D('x', px, py, frame * 0.05)  // Medium, organic
noise3D('x', px, py, frame * 0.1)   // Fast, jittery
```

### Control Magnitude
Multiply the output:
```tsx
noise3D('x', ...) * 10   // Small movement
noise3D('x', ...) * 50   // Medium movement
noise3D('x', ...) * 200  // Large movement
```

### Smooth Spatial Variation
Normalize spatial coordinates to 0-1 range for smooth gradients:
```tsx
const px = x / width;   // 0 to 1
const py = y / height;  // 0 to 1
noise3D('field', px, py, frame * speed)
```

## See Also

- [Remotion docs](https://www.remotion.dev/docs/noise)
