VHS Filter
Hold a scene under analog tape — chroma bleed, tape wobble, a head-switch tear and luma noise
$ pnpm dlx shadcn@latest add @remocn/vhs-filterUsage
VhsFilter is a wrapper. Put a scene inside it and every frame of that scene is
sampled and repainted as tape: the colour bleeds sideways off every edge while
the brightness stays sharp, rows slide out of line on a slow wander, the bottom
of the frame tears where a real deck switches heads, and noise settles over all
of it.
It has no duration of its own — it lasts exactly as long as the scene it wraps,
so there is nothing to time and no Sequence to budget.
import { VhsFilter } from "@/components/remocn/vhs-filter";
export const MyScene = () => (
<VhsFilter>
<Scene />
</VhsFilter>
);Driving it per frame
Every knob is a plain number, so the tape can get worse on a beat and recover
after it. intensity scales all four behaviours at once, which makes it the one
to interpolate when you want the scene to surface out of the noise.
import { interpolate, useCurrentFrame } from "remotion";
import { VhsFilter } from "@/components/remocn/vhs-filter";
export const MyScene = () => {
const frame = useCurrentFrame();
const intensity = interpolate(frame, [0, 24], [1, 0.15], {
extrapolateRight: "clamp",
});
return (
<VhsFilter intensity={intensity}>
<Scene />
</VhsFilter>
);
};Props5
| Prop | Type | Default |
|---|---|---|
| bleed | number1 How far colour smears sideways from where it belongs. Brightness never smears with it, which is what makes the picture read as tape rather than as a blur. | |
| wobble | number1 How far rows wander out of line. A slow drift across the frame plus per-line jitter, so edges never sit quite straight. | |
| noise | number1 Strength of the luma grain laid over the whole frame. | |
| intensity | number1 Master amount, 0 to 1. Scales bleed, wobble, noise, scanlines and the head-switch tear together. At 0 the scene comes through untouched. | |
| children | React.ReactNode— The scene the filter wraps and re-reads every frame. | |
- bleednumber
How far colour smears sideways from where it belongs. Brightness never smears with it, which is what makes the picture read as tape rather than as a blur.
Default
1 - wobblenumber
How far rows wander out of line. A slow drift across the frame plus per-line jitter, so edges never sit quite straight.
Default
1 - noisenumber
Strength of the luma grain laid over the whole frame.
Default
1 - intensitynumber
Master amount, 0 to 1. Scales bleed, wobble, noise, scanlines and the head-switch tear together. At 0 the scene comes through untouched.
Default
1 - childrenReact.ReactNode
The scene the filter wraps and re-reads every frame.
Notes
The filter expects a full-bleed, opaque scene. It reads pixels from a displaced coordinate, so where the scene is transparent it has nothing to move and the untouched scene shows through underneath — put a background inside the wrapper rather than behind it.
The wobble and the head-switch tear are functions of the current frame, not of a running clock, and they oscillate rather than accumulate. Two renders of the same frame produce the same pixels, and a filter left on for a minute looks the same at the end as at the start.