/shader-gen
AI shader generator for WebGL video effects, transitions, masks, and color grading (LUT / 调色 / 电影感 / film look). Use when the user wants a video effect (滤镜 / 特效), a transition (转场 / crossfade / wipe / cube / 3d), a mask (蒙版 / 遮罩 / reveal), a zoom / push-in (推近 / 推镜头), or a color
$ npx -y skills add 0xsline/OpenChatCut --skill shader-gen --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/shader-gen
Context preview
The summary Claude sees to decide when to auto-load this skill.
AI shader generator for WebGL video effects, transitions, masks, and color grading (LUT / 调色 / 电影感 / film look). Use when the user wants a video effect (滤镜 / 特效), a transition (转场 / crossfade / wipe / cube / 3d), a mask (蒙版 / 遮罩 / reveal), a zoom / push-in (推近 / 推镜头), or a color
SKILL.md
shader-gen.SKILL.mdname: shader-gen
description: |
AI shader generator for WebGL video effects, transitions, masks, and color grading (LUT / 调色 / 电影感 / film look). Use when the user wants a video effect (滤镜 / 特效), a transition (转场 / crossfade / wipe / cube / 3d), a mask (蒙版 / 遮罩 / reveal), a zoom / push-in (推近 / 推镜头), or a color grade — try the built-in effects (zoom, builtin LUTs) before generating a new shader.
user-invocable: true
Shader Generator
Submit-only: creates a backend generation job, returns `jobId`. Use the `track_progress` tool for job lifecycle after submission.
**Always use `generate.ts` for new shaders.** Manual authoring is only for editing existing asset code — never as a fallback when generation fails.
Catalog-first rule — try existing assets before generation
Before generating a shader, call `browse_library` unless the user names an exact asset id that is already visible in `read_project`.
`browse_library` is the source of truth for built-in effects, built-in transitions, and project effect/transition assets. Built-ins are stable global asset ids, not per-project DB assets, so they may not appear in `read_project` asset lists.
Apply catalog entries with `edit_item`, do **not** call `submit_shader`.
Good catalog searches:
browse_library(query: "zoom")
browse_library(category: "transitions", query: "dissolve")
browse_library(category: "audio-fx")
Generate only when no catalog entry matches the user's intent closely enough.
`builtin:zoom` is track-bound only — DO NOT use item-bound
The default effect mode is `"item-bound"` (attach to a single item via `targetItemId`). **`builtin:zoom` does NOT render in item-bound mode** — the renderer reads zoom data exclusively from track-bound effect items. An item-bound zoom inserts into the DB silently but shows nothing in preview.
Use `mode: "track-bound"` with `trackId` + `trackBoundFrom` + `trackBoundDurationInFrames`. These three fields are required.
# Zoom on the entire video clip
edit_item(json: '{"adds":[{"type":"effect","assetId":"builtin:zoom","mode":"track-bound","trackId":"<clip-trackId>","trackBoundFrom":<clip-fromFrame>,"trackBoundDurationInFrames":<clip-durationInFrames>,"propertyOverrides":{"magnification":1.5,"shape":"hold"}}]}')
# Zoom on a sub-range of the clip (e.g. frames 90–150 only, a punch zoom on a beat)
edit_item(json: '{"adds":[{"type":"effect","assetId":"builtin:zoom","mode":"track-bound","trackId":"<trackId>","trackBoundFrom":90,"trackBoundDurationInFrames":60,"propertyOverrides":{"magnification":2,"shape":"punch"}}]}')Get `trackId` / `fromFrame` / `durationInFrames` from `read_project` (each video/image item lists its trackId and timeline-frame range).
| Key | Type | Range / values | Default | Notes | | --------------- | ------ | ------------------------------------------ | ------- | ---------------------------------------------- | | `magnification` | number | 1–4 | `1.5` | Zoom factor; 1 = no zoom, 2 = 2× in | | `focalPointX` | number | 0–1 | `0.5` | Horizontal focal point (0 = left, 1 = right) | | `focalPointY` | number | 0–1 | `0.5` | Vertical focal point (0 = top, 1 = bottom) | | `shape` | select | `punch` / `hold` / `slow-push` / `instant` | `hold` | Animation curve | | `focalMode` | select | `auto` / `manual` | `auto` | `auto` picks subject; `manual` uses focalPoint | | `easeInFrames` | number | 0–60 | `8` | Frames to ramp in | | `easeOutFrames` | number | 0–60 | `8` | Frames to ramp out |
Omit `propertyOverrides` entirely for default zoom. Send only the keys you want to change — patch semantics.
Track-bound vs item-bound — the broader rule
Effect items in the schema have two modes:
- **`item-bound`** (default): `targetItemId` only. Effect covers the whole target item's playback. Works for shader effects, LUTs, color grades, blurs.
- **`track-bound`**: `trackId` + `trackBoundFrom` + `trackBoundDurationInFrames`. Effect covers a timeline range on a track, independent of any item. Required for `builtin:zoom`; also valid for any shader effect when you want it to cover a specific timeline range (e.g. a transition-like color shift across the boundary of two clips).
Default to item-bound for shader effects. Use track-bound when (a) the asset requires it (zoom), or (b) the effect should cover a timeline range that doesn't match a single item.
Built-in LUT properties
edit_item(json: '{"adds":[{"type":"effect","targetItemId":"<clip-id>","assetId":"builtin:slog3-s709","propertyOverrides":{"intensity":1}}]}')| Key | Type | Range | Default | Notes | | ----------- | ------ | ----- | ------- | ------------------------------ | | `intensity` | number | 0–1 | `1` | LUT strength; 1 = full applied |
To swap: delete the effect and re-add with a different `assetId`. To remove: delete the effect item.
These are separate from user-uploaded `.cube` LUT assets (see "Applying an Existing LUT Asset" below) — those use a different code path with `assetId:"lut"`.
Beta Status Gate
New shader generation is beta. Before generating, warn the user and wait for explicit confirmation.
Use the user's language. Chinese: "新的特效/转场生成目前还是 beta 阶段,可能会有不稳定的问题。如果你坚持要做,我可以帮你实现。" Skip if user already acknowledged in the same request.
Supported Targets
Effects and transitions apply to `video`, `image`, and `gif` items.
Type Routing
Before generating anything, check two non-generation paths first:
1. **Catalog entry** — use `browse_library` for built-in and project effects/transitions.
Read more
name: shader-gen description: | AI shader generator for WebGL video effects, transitions, masks, and color grading (LUT / 调色 / 电影感 / film look). Use when the user wants a video effect (滤镜 / 特效), a transition (转场 / crossfade / wipe / cube / 3d), a mask (蒙版 / 遮罩 / reveal), a zoom / push-in (推近 / 推镜头), or a color grade — try the built-in effects (zoom, builtin LUTs) before generating a new shader. user-invocable: true
Shader Generator
Submit-only: creates a backend generation job, returns `jobId`. Use the `track_progress` tool for job lifecycle after submission.
**Always use `generate.ts` for new shaders.** Manual authoring is only for editing existing asset code — never as a fallback when generation fails.
Catalog-first rule — try existing assets before generation
Before generating a shader, call `browse_library` unless the user names an exact asset id that is already visible in `read_project`.
`browse_library` is the source of truth for built-in effects, built-in transitions, and project effect/transition assets. Built-ins are stable global asset ids, not per-project DB assets, so they may not appear in `read_project` asset lists.
Apply catalog entries with `edit_item`, do **not** call `submit_shader`.
Good catalog searches:
browse_library(query: "zoom") browse_library(category: "transitions", query: "dissolve") browse_library(category: "audio-fx")
Generate only when no catalog entry matches the user's intent closely enough.
`builtin:zoom` is track-bound only — DO NOT use item-bound
The default effect mode is `"item-bound"` (attach to a single item via `targetItemId`). **`builtin:zoom` does NOT render in item-bound mode** — the renderer reads zoom data exclusively from track-bound effect items. An item-bound zoom inserts into the DB silently but shows nothing in preview.
Use `mode: "track-bound"` with `trackId` + `trackBoundFrom` + `trackBoundDurationInFrames`. These three fields are required.
# Zoom on the entire video clip
edit_item(json: '{"adds":[{"type":"effect","assetId":"builtin:zoom","mode":"track-bound","trackId":"<clip-trackId>","trackBoundFrom":<clip-fromFrame>,"trackBoundDurationInFrames":<clip-durationInFrames>,"propertyOverrides":{"magnification":1.5,"shape":"hold"}}]}')
# Zoom on a sub-range of the clip (e.g. frames 90–150 only, a punch zoom on a beat)
edit_item(json: '{"adds":[{"type":"effect","assetId":"builtin:zoom","mode":"track-bound","trackId":"<trackId>","trackBoundFrom":90,"trackBoundDurationInFrames":60,"propertyOverrides":{"magnification":2,"shape":"punch"}}]}')Get `trackId` / `fromFrame` / `durationInFrames` from `read_project` (each video/image item lists its trackId and timeline-frame range).
| Key | Type | Range / values | Default | Notes | | --------------- | ------ | ------------------------------------------ | ------- | ---------------------------------------------- | | `magnification` | number | 1–4 | `1.5` | Zoom factor; 1 = no zoom, 2 = 2× in | | `focalPointX` | number | 0–1 | `0.5` | Horizontal focal point (0 = left, 1 = right) | | `focalPointY` | number | 0–1 | `0.5` | Vertical focal point (0 = top, 1 = bottom) | | `shape` | select | `punch` / `hold` / `slow-push` / `instant` | `hold` | Animation curve | | `focalMode` | select | `auto` / `manual` | `auto` | `auto` picks subject; `manual` uses focalPoint | | `easeInFrames` | number | 0–60 | `8` | Frames to ramp in | | `easeOutFrames` | number | 0–60 | `8` | Frames to ramp out |
Omit `propertyOverrides` entirely for default zoom. Send only the keys you want to change — patch semantics.
Track-bound vs item-bound — the broader rule
Effect items in the schema have two modes:
- **`item-bound`** (default): `targetItemId` only. Effect covers the whole target item's playback. Works for shader effects, LUTs, color grades, blurs.
- **`track-bound`**: `trackId` + `trackBoundFrom` + `trackBoundDurationInFrames`. Effect covers a timeline range on a track, independent of any item. Required for `builtin:zoom`; also valid for any shader effect when you want it to cover a specific timeline range (e.g. a transition-like color shift across the boundary of two clips).
Default to item-bound for shader effects. Use track-bound when (a) the asset requires it (zoom), or (b) the effect should cover a timeline range that doesn't match a single item.
Built-in LUT properties
edit_item(json: '{"adds":[{"type":"effect","targetItemId":"<clip-id>","assetId":"builtin:slog3-s709","propertyOverrides":{"intensity":1}}]}')| Key | Type | Range | Default | Notes | | ----------- | ------ | ----- | ------- | ------------------------------ | | `intensity` | number | 0–1 | `1` | LUT strength; 1 = full applied |
To swap: delete the effect and re-add with a different `assetId`. To remove: delete the effect item.
These are separate from user-uploaded `.cube` LUT assets (see "Applying an Existing LUT Asset" below) — those use a different code path with `assetId:"lut"`.
Beta Status Gate
New shader generation is beta. Before generating, warn the user and wait for explicit confirmation.
Use the user's language. Chinese: "新的特效/转场生成目前还是 beta 阶段,可能会有不稳定的问题。如果你坚持要做,我可以帮你实现。" Skip if user already acknowledged in the same request.
Supported Targets
Effects and transitions apply to `video`, `image`, and `gif` items.
Type Routing
Before generating anything, check two non-generation paths first:
1. **Catalog entry** — use `browse_library` for built-in and project effects/transitions.
Open-source, local-first conversational AI video editor with a professional multi-track timeline, Agent Skills, MCP integration, and Remotion rendering.
Repo: 0xsline/OpenChatCut
Other skills on openchatcut.
- /openchatcut
Connect an MCP-capable coding agent to OpenChatCut and edit local video projects. Use when the user asks to install, connect, or set up OpenChatCut; inspect or edit an OpenChatCut project; work with its timeline, transcript, captions, media, generation, motion graphics, audio,
Open skill - /ai-cinematic-short-film
Plan AI short films with story, shots, prompts, and continuity.
Open skill - /asset-import
Use when acquiring or importing media into a OpenChatCut project asset library for video editing or creation, including local/attached videos, user-provided paths, public media URLs, web video/audio/image assets, upload fallback decisions, and deciding between import_media,
Open skill - /create-motion-graphics
Use whenever the agent needs to add, create, hand-author, patch, or place Motion Graphic JSX assets in a OpenChatCut project. This is the direct-authoring path: use create_motion_graphic_from_code / edit_asset / edit_item, not motion-graphic-gen or submit_motion_graphic. Covers
Open skill - /explainer-video
Create finished explainer videos from a topic, script, outline, voiceover, product logic, data, technical concept, course material, or reference assets. Use when the user wants narration, motion graphics, stock footage, generated visuals, or mixed visuals to explain an idea.
Open skill - /export
Use when a OpenChatCut video editing or creation workflow needs export, render, download, share, final delivery, subtitle-file export, render choice, local-only asset handling, or export fallback explanation.
Open skill

