跳到正文
cccskills
免费在 GitHub 公开

add-effect

Add a new effect to @remotion/effects, including its implementation, package entry points, documentation, interactive demo, and preview images. Follow the package conventions and verify the changes with tests, formatting checks, and builds.

中文简介正在准备中。当前显示英语简介。

原文查看原文说明

Add a new effect to @remotion/effects, including implementation, package exports, docs, demos, preview images, Remotion skill updates, formatting, and builds.

查看安装方法

适用场景

  • Implementing a new effect for @remotion/effects
  • Registering effect imports and parameter types
  • Creating documentation and an interactive effect demo
  • Rendering preview images and checking the build

包含的文件(1)

  • SKILL.md10.8 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Add a new @remotion/effects effect

Use this skill when adding a new effect to @remotion/effects.

1. Pick the effect shape

  • Prefer the WebGL2 backend for new effects. Use 2D only when WebGL cannot express the effect.
  • Use a single file at packages/effects/src/<effect-name>.ts for simple effects.
  • Use a folder at packages/effects/src/<effect-name>/ plus a top-level re-export file when the effect needs multiple shaders, runtime helpers, or multiple files.
  • Follow naming already used by the package:
    • File/subpath: kebab-case (chromatic-aberration)
    • Function: camelCase (chromaticAberration)
    • Type: PascalCase params (ChromaticAberrationParams)
    • Effect type string: remotion/<kebab-case-name>

2. Implement the effect

In the effect file:

  • Import SequenceSchema and Internals from remotion.
  • Use const {createEffect, createWebGL2ContextError} = Internals;.
  • Define defaults as const values.
  • Define a schema with satisfies SequenceSchema; these fields appear in Studio visual editing.
  • Export the params type.
  • Resolve defaults in a resolve() helper.
  • Validate params using helpers from:
    • packages/effects/src/validate-effect-param.ts
    • packages/effects/src/color-utils.ts
  • Throw createWebGL2ContextError('<effect name> effect') if WebGL2 cannot be acquired.
  • Set documentationLink to https://www.remotion.dev/docs/effects/<slug>.
  • Include every resolved parameter in calculateKey().

For WebGL2 effects, use this general structure:

import type {SequenceSchema} from 'remotion';
import {Internals} from 'remotion';
import {assertOptionalFiniteNumber, validateUnitInterval} from './color-utils.js';
import {assertEffectParamsObject} from './validate-effect-param.js';

const {createEffect, createWebGL2ContextError} = Internals;

const DEFAULT_AMOUNT = 1 as const;

const myEffectSchema = {
	amount: {
		type: 'number',
		min: 0,
		max: 1,
		step: 0.01,
		default: DEFAULT_AMOUNT,
		description: 'Amount',
	},
} as const satisfies SequenceSchema;

export type MyEffectParams = {
	readonly amount?: number;
};

type MyEffectResolved = {
	amount: number;
};

const resolve = (p: MyEffectParams): MyEffectResolved => ({
	amount: p.amount ?? DEFAULT_AMOUNT,
});

const validateMyEffectParams = (params: MyEffectParams): void => {
	assertEffectParamsObject(params, 'My effect');
	assertOptionalFiniteNumber(params.amount, 'amount');
	validateUnitInterval(params.amount ?? DEFAULT_AMOUNT, 'amount');
};

type MyEffectState = {
	readonly gl: WebGL2RenderingContext;
	readonly program: WebGLProgram;
	readonly vao: WebGLVertexArrayObject;
	readonly vbo: WebGLBuffer;
	readonly texture: WebGLTexture;
	readonly uSource: WebGLUniformLocation | null;
	readonly uAmount: WebGLUniformLocation | null;
};

const VERTEX_SHADER = /* glsl */ `#version 300 es
in vec2 aPos;
in vec2 aUv;
out vec2 vUv;

void main() {
	vUv = aUv;
	gl_Position = vec4(aPos, 0.0, 1.0);
}
`;

const FRAGMENT_SHADER = /* glsl */ `#version 300 es
precision highp float;

in vec2 vUv;
out vec4 fragColor;

uniform sampler2D uSource;
uniform float uAmount;

void main() {
	vec4 color = texture(uSource, vUv);
	fragColor = vec4(color.rgb * uAmount, color.a);
}
`;

// Follow existing helpers in halftone.ts or a runtime file for shader
// compilation, program linking, fullscreen-quad setup, and texture setup.

export const myEffect = createEffect<MyEffectParams, MyEffectState>({
	type: 'remotion/my-effect',
	label: 'My Effect',
	documentationLink: 'https://www.remotion.dev/docs/effects/my-effect',
	backend: 'webgl2',
	calculateKey: (params) => {
		const r = resolve(params);
		return `my-effect-${r.amount}`;
	},
	setup: (target) => {
		const gl = target.getContext('webgl2', {
			premultipliedAlpha: true,
			alpha: true,
			preserveDrawingBuffer: true,
		});
		if (!gl) {
			throw createWebGL2ContextError('my effect effect');
		}

		gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);

		return createMyEffectState(gl, VERTEX_SHADER, FRAGMENT_SHADER);
	},
	apply: ({source, width, height, params, state, flipSourceY}) => {
		const r = resolve(params);

		state.gl.viewport(0, 0, width, height);
		state.gl.bindFramebuffer(state.gl.FRAMEBUFFER, null);
		state.gl.activeTexture(state.gl.TEXTURE0);
		state.gl.bindTexture(state.gl.TEXTURE_2D, state.texture);
		state.gl.pixelStorei(state.gl.UNPACK_FLIP_Y_WEBGL, flipSourceY);
		state.gl.texImage2D(
			state.gl.TEXTURE_2D,
			0,
			state.gl.RGBA,
			state.gl.RGBA,
			state.gl.UNSIGNED_BYTE,
			source as TexImageSource,
		);

		state.gl.useProgram(state.program);
		if (state.uSource) state.gl.uniform1i(state.uSource, 0);
		if (state.uAmount) state.gl.uniform1f(state.uAmount, r.amount);
		state.gl.bindVertexArray(state.vao);
		state.gl.drawArrays(state.gl.TRIANGLE_STRIP, 0, 4);
	},
	cleanup: ({gl, program, vao, vbo, texture}) => {
		gl.deleteTexture(texture);
		gl.deleteBuffer(vbo);
		gl.deleteProgram(program);
		gl.deleteVertexArray(vao);
	},
	schema: myEffectSchema,
	validateParams: validateMyEffectParams,
});

Look at existing WebGL2 effects such as halftone.ts, blur/blur-runtime.ts, chromatic-aberration/chromatic-aberration-runtime.ts, and wave/wave-runtime.ts before adding new helpers. In the template above, createMyEffectState() stands for the shader compilation, program linking, fullscreen-quad, texture, and uniform-location setup used by those files.

3. Register package entry points

Update:

  • packages/effects/bundle.ts — add the new src/<effect-name>.ts entrypoint.
  • packages/effects/package.json:
    • Add exports["./<effect-name>"].
    • Add the typesVersions entry.

If using a folder implementation, add a top-level file that re-exports from the folder:

export {myEffect, type MyEffectParams} from './my-effect/index.js';

4. Build and verify

Run the existing tests and build:

cd packages/effects
bun test src/test
bunx turbo make --filter="@remotion/effects"

5. Add docs

Create packages/docs/docs/effects/<effect-name>.mdx.

Follow existing effect pages:

  • Frontmatter: slug, title, sidebar_label, crumb: '@remotion/effects'.
  • Add image: only after running bun render-cards.ts.
  • H1: # effectName()<AvailableFrom v="..." />.
  • Include _Part of the [@remotion/effects](/docs/effects/api) package._.
  • Add a short description.
  • Add <EffectsDemo type="effects-<effect-name>" />.
  • Add a twoslash example with title="MyComp.tsx".
  • Document each option as its own ### heading, using ? for optional parameters.
  • Add a disabled? section.
  • Add a See also section.

Update:

  • 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.

Use the writing-docs skill for documentation wording.

6. Add the interactive docs demo

Create packages/docs/components/effects/effects-<effect-name>-preview.tsx.

Use the same preview source as other effects:

import {myEffect} from '@remotion/effects/my-effect';
import React from 'react';
import {CanvasImage} from 'remotion';
import {EFFECTS_PREVIEW_IMAGE_SRC} from './effects-preview-image';

export const EffectsMyEffectPreview: React.FC<{
	readonly amount: number;
}> = ({amount}) => {
	return (
		<CanvasImage
			src={EFFECTS_PREVIEW_IMAGE_SRC}
			width={1280}
			height={720}
			fit="cover"
			effects={[myEffect({amount})]}
		/>
	);
};

Use fit="cover" for docs effect previews so the shared preview image fills the 16:9 canvas and does not leave transparent bars.

Register the demo in packages/docs/components/effects-demos/registry.ts:

  • Import the preview component and the real effect schema (or read it from effect().definition.schema).
  • Add an entry with id: 'effects-<effect-name>'.
  • Add initialValues only for required fields whose schema default is undefined.

Use the docs-demo skill for demo details.

7. Add and render the table-of-contents preview composition

The TOC card must come from a real Remotion composition in packages/docs, not a hand-written asset. Always render preview assets as PNG files.

Add a Still to packages/docs/src/remotion/Root.tsx under the effect-previews folder:

<Still
	id="effects-my-effect-preview"
	component={EffectsMyEffectPreview}
	width={1280}
	height={720}
	defaultProps={{
		amount: 1,
	}}
/>

Use the same width and height as the preview component's CanvasImage. If the preview component uses the shared docs preview image, keep fit="cover" on CanvasImage. Rendering a 16:9 preview component into a different aspect ratio can leave black bars in the generated TOC image.

Then render from packages/docs:

bunx remotion still src/remotion/entry.ts effects-my-effect-preview static/img/effects-my-effect-preview.png --overwrite --image-format=png

Commit both:

  • The composition entry in packages/docs/src/remotion/Root.tsx
  • The rendered image in packages/docs/static/img/

8. Generate docs card

Run:

cd packages/docs
bun render-cards.ts

Commit the generated packages/docs/static/generated/articles-docs-effects-<effect-name>.png and the new image: frontmatter line.

If render-cards.ts opportunistically generates unrelated missing cards, remove those unrelated files unless they belong to the current change.

9. Update the Remotion skill

Keep the agent-facing Remotion skill in sync with the new effect.

Update packages/skills/skills/remotion-markup/effects.md only if the new effect changes general usage mechanics, import conventions, installation guidance, or custom-effect recommendations. Do not duplicate the full effect list there; use the docs table of contents as the canonical list.

10. Format, build, and verify

Run:

cd packages/effects
bunx oxfmt src --write
cd ../..
bun run build
bun run formatting

If the change touches docs source, bun run formatting covers packages/docs/src. For MDX-only edits, do not run formatters on docs pages.

Before committing, check:

git diff --check
git status --short

Common pitfalls

  • Do not forget package.json exports and typesVersions; subpath imports like @remotion/effects/my-effect depend on them.
  • Do not forget bundle.ts; otherwise the ESM subpath will not be built.
  • Do not leave temporary render entry points in packages/docs/src/remotion.
  • Do not use a hand-written SVG for the effect TOC preview.
  • Preserve alpha unless the effect intentionally changes it.
  • For pixel math, be aware canvases store premultiplied alpha.
  • WebGL color math often needs to unpremultiply the sampled RGB before luminance or threshold calculations, then premultiply the output RGB again.

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

add-bug

免费

Add a reported Remotion bug to the bugs API with its affected versions, a short title, and upgrade guidance. Follow the existing entry format and place the new record first so recent bugs appear at the top.

中文简介正在准备中。当前显示英语简介。

  • Adding a reported bug to the Remotion bugs API
  • Recording which versions a bug affects
  • Including upgrade guidance in a bug description
remotion-dev/remotion6.5万2026年10月18日 更新

Add a Remotion command-line or configuration option, or convert a hardcoded flag into a shared option definition. Connect parsing, configuration setters, help entries, and generated documentation so the option is consistently available and documented.

中文简介正在准备中。当前显示英语简介。

  • Add a new Remotion command-line flag
  • Convert a hardcoded flag into a shared option
  • Connect an option to Config setters
remotion-dev/remotion6.5万2026年10月18日 更新

Add a person to the Remotion experts page by placing their portrait, entering their profile and contact links, and generating an expert card image. The instructions specify file locations, profile fields, and how to verify card generation.

中文简介正在准备中。当前显示英语简介。

  • Add a new person to the Remotion experts page
  • Register a portrait, specialties, and contact links
  • Generate an expert card image
remotion-dev/remotion6.5万2026年10月18日 更新

Create a new @remotion package within the Remotion monorepo, a repository containing multiple packages. Set up its files, register it across the project, and prepare documentation, usage examples, and build configuration.

中文简介正在准备中。当前显示英语简介。

  • Creating a new @remotion package
  • Registering a package across the monorepo
  • Adding documentation and usage examples
remotion-dev/remotion6.5万2026年10月18日 更新

add-sfx

免费

Add a new sound effect to @remotion/sfx, from registering the audio file to exporting its URL and documenting its use. The workflow covers playback examples, attribution, navigation entries, waveform generation, and the package build.

中文简介正在准备中。当前显示英语简介。

  • Add a sound effect to @remotion/sfx
  • Create documentation with playback and usage examples
  • Update sound effect navigation and waveform data
remotion-dev/remotion6.5万2026年10月18日 更新

Add browser WebCodecs bugs to the Remotion Mediabunny documentation. It checks the linked issue’s title, filing date, reporter, and resolution, then adds a table row while preserving the existing format.

中文简介正在准备中。当前显示英语简介。

  • Adding a Chromium bug to the documentation
  • Recording WebKit or Firefox issues
  • Checking reporter details and fix status before adding a row
remotion-dev/remotion6.5万2026年10月18日 更新

查看 remotion-dev 的全部技能

报告此技能的问题