Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .agents/skills/add-effect/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ Follow existing effect pages:

Update:

- `packages/docs/sidebars.ts` — add `'effects/<effect-name>'`.
- `packages/docs/sidebars.ts` — add `'effects/<effect-name>'` in alphabetical order.
- `packages/docs/docs/effects/table-of-contents.tsx` — add a card in the right category.
- `packages/docs/src/data/articles.ts` by running the card generator, not by hand.

Expand Down
2 changes: 2 additions & 0 deletions packages/docs/components/demos/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import {
effectsUvTranslateDemo,
effectsVignetteDemo,
effectsWaveDemo,
effectsWhiteNoiseDemo,
effectsXyTranslateDemo,
ellipseDemo,
fadePresentationDemo,
Expand Down Expand Up @@ -114,6 +115,7 @@ const demos: DemoType[] = [
effectsSpeckleDemo,
effectsMirrorDemo,
effectsNoiseDemo,
effectsWhiteNoiseDemo,
effectsScanlinesDemo,
effectsLinesDemo,
effectsScaleDemo,
Expand Down
33 changes: 33 additions & 0 deletions packages/docs/components/demos/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
} from '../effects/effects-translate-preview';
import {EffectsVignettePreview} from '../effects/effects-vignette-preview';
import {EffectsWavePreview} from '../effects/effects-wave-preview';
import {EffectsWhiteNoisePreview} from '../effects/effects-white-noise-preview';
import {
ClockWipeDemo,
CubeDemo,
Expand Down Expand Up @@ -2060,6 +2061,38 @@ export const effectsNoiseDemo: DemoType = {
],
};

export const effectsWhiteNoiseDemo: DemoType = {
comp: EffectsWhiteNoisePreview,
compHeight: 720,
compWidth: 1280,
durationInFrames: 1,
fps: 30,
id: 'effects-white-noise',
autoPlay: false,
controls: false,
logLevel: 'info',
options: [
{
name: 'amount',
type: 'numeric',
min: 0,
max: 1,
step: 0.01,
default: 1,
optional: 'no',
},
{
name: 'seed',
type: 'numeric',
min: 0,
max: 100,
step: 1,
default: 0,
optional: 'no',
},
],
};

export const effectsScanlinesDemo: DemoType = {
comp: EffectsScanlinesPreview,
compHeight: 720,
Expand Down
19 changes: 19 additions & 0 deletions packages/docs/components/effects/effects-white-noise-preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {whiteNoise} from '@remotion/effects/white-noise';
import React from 'react';
import {CanvasImage} from 'remotion';
import {EFFECTS_PREVIEW_IMAGE_SRC} from './effects-preview-image';

export const EffectsWhiteNoisePreview: React.FC<{
readonly amount: number;
readonly seed: number;
}> = ({amount, seed}) => {
return (
<CanvasImage
src={EFFECTS_PREVIEW_IMAGE_SRC}
width={1280}
height={720}
fit="cover"
effects={[whiteNoise({amount, seed})]}
/>
);
};
7 changes: 7 additions & 0 deletions packages/docs/docs/effects/table-of-contents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,13 @@ const categories: {
name: 'noise()',
description: 'Procedural grain effect',
},
{
link: '/docs/effects/white-noise',
preview: '/img/effects-white-noise-preview.png',
alt: 'white noise effect preview',
name: 'whiteNoise()',
description: 'Random grayscale noise layer',
},
{
link: '/docs/effects/scanlines',
preview: '/img/effects-scanlines-preview.png',
Expand Down
82 changes: 82 additions & 0 deletions packages/docs/docs/effects/white-noise.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
---
image: /generated/articles-docs-effects-white-noise.png
slug: /effects/white-noise
title: whiteNoise()
sidebar_label: whiteNoise()
crumb: '@remotion/effects'
---

# whiteNoise()<AvailableFrom v="4.0.470" />

_Part of the [`@remotion/effects`](/docs/effects/api) package._

Replaces or blends canvas-based components such as [`<Video>`](/docs/media/video), [`<HtmlInCanvas>`](/docs/remotion/html-in-canvas) and [`<Solid>`](/docs/solid) with a grayscale white noise layer.

Use it for TV static, signal loss, or snow-like visuals. For subtle additive film grain, use [`noise()`](/docs/effects/noise) instead.

The effect preserves the source alpha mask. Transparent regions stay transparent.

## Difference from `noise()`

`whiteNoise()` blends the source towards a random grayscale image. By default, it fully replaces visible pixels with white noise.

[`noise()`](/docs/effects/noise) adds centered noise to the existing pixels instead. It is better suited for subtle grain while preserving the image.

## Preview

<Demo type="effects-white-noise" />

## Example

```tsx twoslash title="MyComp.tsx"
import {AbsoluteFill} from 'remotion';
import {Video} from '@remotion/media';
import {whiteNoise} from '@remotion/effects/white-noise';

export const MyComp: React.FC = () => {
return (
<AbsoluteFill>
<Video
src="https://remotion.media/video.mp4"
effects={[
whiteNoise({
amount: 1,
seed: 7,
}),
]}
/>
</AbsoluteFill>
);
};
```

## API

Pass an object with the following properties. You can also call `whiteNoise()` without arguments.

### `amount?`

Blend amount from `0` to `1`. Defaults to `1`.

Use `0` to leave the layer unchanged. Use `1` to fully replace the image with white noise inside the source alpha mask.

### `seed?`

Seed for the random noise pattern. Defaults to `0`.

Change it to get a different static white noise pattern. To animate the noise, pass a value derived from [`useCurrentFrame()`](/docs/use-current-frame).

### `disabled?`

When `true`, the effect is skipped. Defaults to `false`.

## Requirements

`whiteNoise()` uses a WebGL2 backend. During renders, enable WebGL via [`Config.setChromiumOpenGlRenderer()`](/docs/config#setchromiumopenglrenderer) (for example `'angle'`). See [Using WebGL during renders](/docs/remotion/html-in-canvas#using-webgl-during-renders).

## See also

- [`@remotion/effects`](/docs/effects/api)
- [`noise()`](/docs/effects/noise)
- [`scanlines()`](/docs/effects/scanlines)
- [Source code for this effect](https://github.com/remotion-dev/remotion/blob/main/packages/effects/src/white-noise.ts)
1 change: 1 addition & 0 deletions packages/docs/sidebars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ const sidebars: SidebarsConfig = {
'effects/uv-translate',
'effects/vignette',
'effects/wave',
'effects/white-noise',
'effects/xy-translate',
],
},
Expand Down
9 changes: 9 additions & 0 deletions packages/docs/src/data/articles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1961,6 +1961,15 @@ export const articles = [
noAi: false,
slug: 'effects/wave',
},
{
id: 'effects/white-noise',
title: 'whiteNoise()',
relativePath: 'docs/effects/white-noise.mdx',
compId: 'articles-docs-effects-white-noise',
crumb: '@remotion/effects',
noAi: false,
slug: 'effects/white-noise',
},
{
id: 'effects/xy-translate',
title: 'xyTranslate()',
Expand Down
11 changes: 11 additions & 0 deletions packages/docs/src/remotion/Root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
} from '../../components/effects/effects-translate-preview';
import {EffectsVignettePreview} from '../../components/effects/effects-vignette-preview';
import {EffectsWavePreview} from '../../components/effects/effects-wave-preview';
import {EffectsWhiteNoisePreview} from '../../components/effects/effects-white-noise-preview';
import {articles} from '../data/articles';
import {AllTemplates} from './AllTemplates';
import {Article} from './Article';
Expand Down Expand Up @@ -303,6 +304,16 @@ export const RemotionRoot: React.FC = () => {
premultiply: false,
}}
/>
<Still
id="effects-white-noise-preview"
component={EffectsWhiteNoisePreview}
width={1280}
height={720}
defaultProps={{
amount: 1,
seed: 0,
}}
/>
<Still
id="effects-scanlines-preview"
component={EffectsScanlinesPreview}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions packages/effects/bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const effectEntrypoints = [
'src/translate.ts',
'src/vignette.ts',
'src/wave.ts',
'src/white-noise.ts',
];

console.time('Generated.');
Expand Down
8 changes: 8 additions & 0 deletions packages/effects/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@
"module": "./dist/esm/wave.mjs",
"import": "./dist/esm/wave.mjs"
},
"./white-noise": {
"types": "./dist/white-noise.d.ts",
"module": "./dist/esm/white-noise.mjs",
"import": "./dist/esm/white-noise.mjs"
},
"./package.json": "./package.json"
},
"typesVersions": {
Expand Down Expand Up @@ -245,6 +250,9 @@
],
"wave": [
"dist/wave.d.ts"
],
"white-noise": [
"dist/white-noise.d.ts"
]
}
},
Expand Down
40 changes: 40 additions & 0 deletions packages/effects/src/test/effect-params.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {tint} from '../tint.js';
import {uvTranslate, xyTranslate} from '../translate.js';
import {vignette} from '../vignette.js';
import {wave} from '../wave/index.js';
import {whiteNoise} from '../white-noise.js';

test('@remotion/effects expose documentation links', () => {
expect(barrelDistortion().definition.documentationLink).toBe(
Expand Down Expand Up @@ -108,6 +109,9 @@ test('@remotion/effects expose documentation links', () => {
expect(wave().definition.documentationLink).toBe(
'https://www.remotion.dev/docs/effects/wave',
);
expect(whiteNoise().definition.documentationLink).toBe(
'https://www.remotion.dev/docs/effects/white-noise',
);
});

test('@remotion/effects expose API names as Studio labels', () => {
Expand Down Expand Up @@ -139,6 +143,7 @@ test('@remotion/effects expose API names as Studio labels', () => {
expect(vignette().definition.label).toBe('vignette()');
expect(xyTranslate().definition.label).toBe('xyTranslate()');
expect(wave().definition.label).toBe('wave()');
expect(whiteNoise().definition.label).toBe('whiteNoise()');
});

test('barrelDistortion() accepts default params', () => {
Expand Down Expand Up @@ -296,6 +301,41 @@ test('wave() direction produces distinct effect keys', () => {
expect(horizontal.effectKey).not.toBe(vertical.effectKey);
});

test('whiteNoise() accepts default params', () => {
expect(() => whiteNoise()).not.toThrow();
});

test('whiteNoise() rejects non-finite amount', () => {
expect(() => whiteNoise({amount: Number.NaN})).toThrow(
'"amount" must be a finite number',
);
});

test('whiteNoise() rejects amount below range', () => {
expect(() => whiteNoise({amount: -0.1})).toThrow('"amount" must be >= 0');
});

test('whiteNoise() rejects amount above range', () => {
expect(() => whiteNoise({amount: 1.1})).toThrow('"amount" must be <= 1');
});

test('whiteNoise() rejects non-finite seed', () => {
expect(() => whiteNoise({seed: Number.NaN})).toThrow(
'"seed" must be a finite number',
);
});

test('whiteNoise() parameters produce distinct effect keys', () => {
const defaultStatic = whiteNoise();
const subtle = whiteNoise({amount: 0.2});
const reseeded = whiteNoise({seed: 4});

expect(
new Set([defaultStatic.effectKey, subtle.effectKey, reseeded.effectKey])
.size,
).toBe(3);
});

test('grayscale() accepts default params', () => {
expect(() => grayscale()).not.toThrow();
});
Expand Down
Loading
Loading