# Out-of-focus backgrounds

> Draw objects softly behind the rest of the scene, as if out of focus, with Blur. A cheap depth-of-field look for hero screens, with falling objects behind a sharp product.

`<Blur>` draws its children softly, **behind everything else**, as if out of focus: fruit tumbling behind a sharp product, a skyline, bokeh. They are lit like the rest of the scene. The blur is drawn at a fraction of the screen's size, so it costs little.

```tsx title="Hero.tsx"
import { Peach } from "@apricot/assets";
import { Blur, Group, Scene, Sphere } from "@apricot/react";

export function Hero() {
  return (
    <Scene style={{ flex: 1 }} look="soft" background="#ffffff" camera={{ position: [0, 0, 8], fov: 35 }}>
      <Blur radius={6}>
        <Group position={[0, 0, -6]}>
          <Sphere position={[-3, 1.5, 0]} color="#ffb38a" />
          <Sphere position={[2.5, -1, 0]} color="#ffd1a8" />
          <Sphere position={[3, 2.5, -2]} color="#ff9f59" />
        </Group>
      </Blur>
      <Peach size={1.1} />
    </Scene>
  );
}
```

| Prop | Default | Meaning |
| --- | --- | --- |
| `radius` | `6` | How soft, in points on the screen. It can change at any time |
| `children` | | What to blur: shapes, models, instances, groups |

## Rules

- Blurred objects are always drawn **behind** the sharp ones, whatever their depth. Place them further back anyway (negative z), so they look right when the camera moves.
- Everything inside `<Blur>` is blurred together, in one layer. Use one `<Blur>` per scene.
- With `frameloop="demand"` the blur is redrawn whenever the scene renders. Animate blurred objects with `useFrame` (returning `true` while they move) or with shared values.
- Until the blurred objects' shaders are ready (the first moments after mount), the layer is blank.

## Falling objects behind a product

Instances animated in `useFrame` make a moving, out-of-focus background for the cost of one draw call per part. A peach spinning in front of smaller peaches tumbling down behind it:

```tsx title="PeachHero.tsx"
import { createPeach, Peach } from "@apricot/assets";
import { disposeObject, seededRandom } from "@apricot/core";
import { Blur, FitCamera, type InstanceItem, Instances, type InstancesHandle, Scene, Spin, useFrame } from "@apricot/react";
import { useEffect, useMemo, useRef } from "react";

const COUNT = 36;

function FallingPeaches() {
  // Small and out of focus: a coarse peach is plenty.
  const peach = useMemo(() => createPeach({ detail: 0.15 }), []);
  useEffect(() => () => disposeObject(peach), [peach]);
  const fallers = useMemo(() => {
    const random = seededRandom(11);
    return Array.from({ length: COUNT }, () => {
      const z = -2.5 - random() * 8;
      const spread = 2.2 + -z * 0.42;
      return {
        x: (random() * 2 - 1) * spread,
        y: (random() * 2 - 1) * (4 + -z * 0.5),
        z,
        speed: 0.5 + random() * 0.7,
        spin: random() * 1.6 - 0.8,
        scale: 0.38 + random() * 0.3,
      };
    });
  }, []);
  const items = useMemo<InstanceItem[]>(() => fallers.map((f) => ({ position: [f.x, f.y, f.z], scale: f.scale })), [fallers]);
  const copies = useRef<InstancesHandle>(null);
  const time = useRef(0);

  useFrame(({ delta }) => {
    const handle = copies.current;
    if (!handle) return true;
    time.current += delta;
    fallers.forEach((f, i) => {
      const height = 4 + -f.z * 0.5;
      f.y -= f.speed * delta;
      if (f.y < -height) f.y += height * 2;
      handle.set(i, { position: [f.x, f.y, f.z], rotation: [time.current * f.spin, time.current * f.spin, 0], scale: f.scale });
    });
    return true;
  });

  return <Instances ref={copies} object={peach} items={items} />;
}

export function PeachHero() {
  return (
    <Scene style={{ flex: 1 }} look="soft" background="#ffffff" camera={{ position: [0, 0, 8], fov: 35 }}>
      <Blur radius={4}>
        <FallingPeaches />
      </Blur>
      <FitCamera size={[1.8, 1.8]} margin={0.1} />
      <Spin speed={0.35}>
        <Peach size={1.1} />
      </Spin>
    </Scene>
  );
}
```

## Related

- [Instances](https://matthiasbrandolin.dev/apricot/guides/instances#animating-copies-every-frame).
- [Labels and blur reference](https://matthiasbrandolin.dev/apricot/reference/labels-and-blur#blur).
