shader-gen

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Shader Generator

Shader 生成器

If
submit_shader
or
inspect_item
are not loaded yet, load them with
ToolSearch
before calling them, so you use their real parameters instead of guessing.
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.
如果
submit_shader
或
inspect_item
尚未加载,请先使用
ToolSearch
加载它们,再进行调用,以确保使用其真实参数,而不是靠猜测。
仅用于提交:创建一个后端生成任务并返回
jobId
。提交后,使用
track_progress
工具跟踪任务生命周期。
**新 Shader 始终使用
generate.ts
。**手动编写仅用于编辑已有资产代码——绝不能作为生成失败时的后备方案。

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
browse_assets
.
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
browse_assets
.
Apply catalog entries with
edit_item
, do not call
submit_shader
.
Good catalog searches:
text
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.
在生成 Shader 之前,除非用户给出了一个已经在
browse_assets
中可见的精确资产 ID,否则先调用
browse_library
。
browse_library
是内置效果、内置转场和项目效果/转场资产的唯一事实来源。内置项是稳定的全局资产 ID,而非每个项目的数据库资产,因此它们可能不会出现在
browse_assets
中。
使用
edit_item
应用目录条目,不要调用
submit_shader
。
有效的目录搜索:
text
browse_library(query: "zoom")
browse_library(category: "transitions", query: "dissolve")
browse_library(category: "audio-fx")

builtin:zoom
uses the same track-bound placement as every effect

builtin:zoom
与所有效果一样使用绑定轨道的放置方式

Effects always have timeline geometry. For a whole-clip effect, pass
targetItemId
; ChatCut resolves it to a clip-anchored range covering that clip. For an explicit timeline range, pass
trackId
+
trackBoundFrom
+
trackBoundDurationInFrames
.
text
undefined
效果始终具有时间线几何结构。对于整段片段效果,传入
targetItemId
;ChatCut 会将其解析为覆盖该片段的、以片段为锚点的范围。对于明确的时间线范围,传入
trackId
+
trackBoundFrom
+
trackBoundDurationInFrames
。
text
undefined

Zoom on the entire video clip

Zoom on the entire video clip

edit_item(json: '{"adds":[{"type":"effect","assetId":"builtin:zoom","targetItemId":"<clip-id>","propertyOverrides":{"magnification":1.5,"shape":"hold"}}]}')
edit_item(json: '{"adds":[{"type":"effect","assetId":"builtin:zoom","targetItemId":"<clip-id>","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)

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"}}]}')

Use `preview_timeline({views:["timeline"],tracks:["V1"]})` to obtain track item ids and timeline-frame ranges. Use `inspect_item({itemId:"..."})` when exact item detail is needed.

| 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.
edit_item(json: '{"adds":[{"type":"effect","assetId":"builtin:zoom","mode":"track-bound","trackId":"<trackId>","trackBoundFrom":90,"trackBoundDurationInFrames":60,"propertyOverrides":{"magnification":2,"shape":"punch"}}]}')

使用 `preview_timeline({views:["timeline"],tracks:["V1"]})` 获取轨道项 ID 和时间线帧范围。需要精确的项详情时,使用 `inspect_item({itemId:"..."})`。

| 键 | 类型 | 范围 / 值 | 默认值 | 说明 |
| --------------- | ------ | ------------------------------------------ | ------- | ---------------------------------------------- |
| `magnification` | number | 1–4 | `1.5` | 缩放倍率;1 = 无缩放,2 = 放大 2× |
| `focalPointX` | number | 0–1 | `0.5` | 水平焦点(0 = 左侧,1 = 右侧) |
| `focalPointY` | number | 0–1 | `0.5` | 垂直焦点(0 = 顶部,1 = 底部) |
| `shape` | select | `punch` / `hold` / `slow-push` / `instant` | `hold` | 动画曲线 |
| `focalMode` | select | `auto` / `manual` | `auto` | `auto` 自动选择主体;`manual` 使用 focalPoint |
| `easeInFrames` | number | 0–60 | `8` | 渐入所需帧数 |
| `easeOutFrames` | number | 0–60 | `8` | 渐出所需帧数 |

若使用默认缩放效果,请完全省略 `propertyOverrides`。仅发送需要更改的键——采用补丁语义。

Clip-anchored vs adjustment-track

片段锚定与调整轨道

Effect items have two placements, both with a concrete time range:
  • Clip-anchored: pass
    targetItemId
    for the whole clip, or include an explicit range that intersects the clip. The stored range is local to that clip and follows it when it moves.
  • Adjustment-track: pass
    trackId
    +
    trackBoundFrom
    +
    trackBoundDurationInFrames
    for a range over empty track space. The range is absolute on the timeline.
Use
targetItemId
for whole-clip effects. Use explicit track geometry only when the requested range differs from a clip's full duration.
效果项有两种放置方式,二者都有明确的时间范围:
  • 片段锚定(Clip-anchored):传入
    targetItemId
    应用于整段片段,或包含一个与该片段相交的明确范围。存储的范围是片段内的局部范围,并在片段移动时随之移动。
  • 调整轨道(Adjustment-track):针对空白轨道空间上的范围,传入
    trackId
    +
    trackBoundFrom
    +
    trackBoundDurationInFrames
    。该范围在时间线上是绝对位置。
对于整段片段效果,使用
targetItemId
。仅当所需范围与片段的完整时长不同时,才使用明确的时间线几何信息。

Built-in LUT properties

内置 LUT 属性

text
edit_item(json: '{"adds":[{"type":"effect","targetItemId":"<clip-id>","assetId":"builtin:slog3-s709","propertyOverrides":{"intensity":1}}]}')
KeyTypeRangeDefaultNotes
intensity
number0–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.
User-uploaded
.cube
LUT assets take this exact same shape — only
assetId
differs. See "Applying an Existing LUT Asset" below.
text
edit_item(json: '{"adds":[{"type":"effect","targetItemId":"<clip-id>","assetId":"builtin:slog3-s709","propertyOverrides":{"intensity":1}}]}')
键类型范围默认值说明
intensity
number0–1
1
LUT 强度;1 = 完全应用
要替换 LUT:删除该效果,并使用另一个
assetId
重新添加。要移除:删除该效果项。
用户上传的
.cube
LUT 资产采用完全相同的结构——只有
assetId
不同。参见下文“应用已有 LUT 资产”。

Supported Targets

支持的目标

Effects and transitions apply to
video
,
image
, and
gif
items.
效果和转场可应用于
video
、
image
和
gif
项。

Type Routing

类型路由

Before generating anything, check two non-generation paths first:
  1. Catalog entry — use
    browse_library
    for built-in and project effects/transitions.
  2. User-uploaded
    .cube
    LUT asset
    that already exists in the project library — bind it instead of generating, see "Applying an Existing LUT Asset" below. It shows up in
    browse_assets
    as
    type: effect
    with a
    lut
    -typed entry in
    editableProperties
    .
User wants
--type
Video appearance (color, blur, glow, grain, distortion)
effect
Color grade / look (teal-orange, cinematic, vintage, LUT-style)
effect
Visibility control (mask, reveal, wipe, shape cutout, gradient fade)
effect
Blend between clips (crossfade, dissolve, slide, 3D cube/page flip)
transition
"LUT-style" in the table means generating a fresh GLSL color grade that resembles a LUT — only when the user wants something new. If they want to apply a
.cube
file already in the library, don't generate; bind the existing asset instead.
No separate LUT or mask generator for the generation path — those are all
effect
.
在生成任何内容前,先检查以下两条非生成路径:
  1. 目录条目——使用
    browse_library
    查找内置效果和项目效果/转场。
  2. 项目中已存在的用户上传
    .cube
    LUT 资产
    ——直接绑定它,而不是生成;参见下文“应用已有 LUT 资产”。它会在
    browse_assets
    中显示为
    type: effect
    ,并且
    editableProperties
    中包含一个
    lut
    类型的条目。
用户需求
--type
视频外观(颜色、模糊、辉光、颗粒、扭曲)
effect
调色 / 风格(青橙、电影感、复古、LUT 风格)
effect
可见性控制(mask、reveal、wipe、shape cutout、gradient fade)
effect
片段间混合(crossfade、dissolve、slide、3D cube/page flip)
transition
表格中的“LUT-style”是指生成一种类似 LUT 的全新 GLSL 调色——仅当用户想要新效果时才这样做。如果用户想应用库中已有的
.cube
文件,不要生成;直接绑定已有资产。
对于生成路径,没有独立的 LUT 或蒙版生成器——它们都属于
effect
。

Applying an Existing LUT Asset

应用已有 LUT 资产

Default target is the timeline. "Apply this LUT" means an
edit_item
effect on the clip. Only reach for
edit_asset sourceLut
when the user asks for the source itself everywhere it appears — every clip cut from that asset, or a log-to-Rec.709 normalization of the footage — because that changes every instance of the asset on every timeline.
.cube
files uploaded by the user become effect assets with
category: "lut"
. Applying one to a clip is not generation — it is the same
edit_item
effect shape as a built-in LUT, with that asset's own id as
assetId
:
text
edit_item(json: '{"adds":[{"type":"effect","targetItemId":"<clip-id>","assetId":"<lut-effect-asset-id>","propertyOverrides":{"intensity":1}}]}')
Key points:
  • assetId
    is the LUT effect asset's real id. There is no literal
    "lut"
    assetId, and no LUT binding nested inside
    propertyOverrides
    .
  • propertyOverrides
    carries only
    intensity
    (0–1, default 1). The
    .cube
    binding lives on the asset, not on the effect item.
  • Find the id with
    browse_assets type:"effect"
    : a LUT asset is the one whose
    editableProperties
    contain a
    lut
    -typed key. Built-in LUTs come from
    browse_library category:"luts"
    .
  • targetItemType
    defaults to
    video
    ; also supports
    image
    ,
    gif
    .
  • To swap: delete the effect and re-add with the other LUT's
    assetId
    . To remove: delete the effect item.
  • To grade a whole source clip everywhere it appears instead of one timeline item, use
    edit_asset
    update with
    {"sourceLut":{"assetId":"<lut-effect-asset-id>"}}
    on the video/image/gif asset;
    {"sourceLut":null}
    removes it.
  • If the
    .cube
    is not in the project yet, you cannot get it in: this surface has no LUT import path, and
    .cube
    is not an accepted chat attachment either, so never ask the user to send you the file. Ask them to drag it into the editor's media pool instead — the editor registers it as a LUT asset and it then shows up in
    browse_assets
    . Do not tell them ChatCut cannot handle
    .cube
    ; the editor can.
Do not call
submit_shader
for this path.
After applying, confirm with
preview_timeline
that the effect is listed on the target clip's track. Do not report success from the
edit_item
response alone.
默认目标是时间线。“应用这个 LUT”意味着在片段上添加
edit_item
效果。只有当用户明确要求将该源素材本身应用到它出现的所有位置——由该素材切出的每个片段,或对素材执行 log-to-Rec.709 标准化——才使用
edit_asset sourceLut
,因为这会改变该素材在每个时间线上的所有实例。
用户上传的
.cube
文件会成为
category: "lut"
的效果资产。将其中一个应用到片段属于应用操作,不是生成——其结构与内置 LUT 的
edit_item
效果完全相同,只是
assetId
改为该资产自己的 ID:
text
edit_item(json: '{"adds":[{"type":"effect","targetItemId":"<clip-id>","assetId":"<lut-effect-asset-id>","propertyOverrides":{"intensity":1}}]}')
要点:
  • assetId
    是 LUT 效果资产的真实 ID。不存在字面量
    "lut"
    作为
    assetId
    ,LUT 绑定也不会嵌套在
    propertyOverrides
    中。
  • propertyOverrides
    只承载
    intensity
    (0–1,默认 1)。
    .cube
    绑定位于资产上,而不是效果项上。
  • 通过
    browse_assets type:"effect"
    查找 ID:LUT 资产是
    editableProperties
    中包含
    lut
    类型键的资产。内置 LUT 来自
    browse_library category:"luts"
    。
  • targetItemType
    默认为
    video
    ;也支持
    image
    、
    gif
    。
  • 要替换:删除效果并使用另一个
    assetId
    重新添加。要移除:删除效果项。
  • 要对源素材进行全局调色(应用到它出现的所有位置),而不是只处理一个时间线项,请对 video/image/gif 资产使用
    edit_asset
    update,并设置
    {"sourceLut":{"assetId":"<lut-effect-asset-id>"}}
    ;设置
    {"sourceLut":null}
    可将其移除。
  • 如果
    .cube
    尚未进入项目,则无法通过此入口导入:该界面没有 LUT 导入路径,
    .cube
    也不是受支持的聊天附件,因此绝不能让用户发送文件。应请用户将其拖入编辑器的媒体池;编辑器会将其注册为 LUT 资产,随后它会出现在
    browse_assets
    中。不要告诉用户 ChatCut 无法处理
    .cube
    ;编辑器可以处理。
对于此路径,不要调用
submit_shader
。
应用后,使用
preview_timeline
确认该效果已列在目标片段的轨道上。不要仅根据
edit_item
的响应就报告成功。

Usage

使用方法

Before calling
submit_shader
, restate the user's intent in one concrete sentence, then proceed immediately. After
track_progress
returns, state what was produced in one line — do NOT ask "Keep it or regenerate it?".
ts
submit_shader({
  type: "effect",
  prompt: "Chromatic aberration with RGB split",
  name: "Chromatic Aberration",
});

submit_shader({
  type: "transition",
  prompt: "Smooth crossfade with soft edge",
  name: "Crossfade",
});

submit_shader({
  type: "effect",
  prompt: "Cinematic teal-orange color grade",
});

submit_shader({
  type: "effect",
  prompt: "Stronger version",
  referenceAssetIds: ["effect_asset_id"],
});
调用
submit_shader
前,先用一句具体的话重述用户意图,然后立即执行。
track_progress
返回后,用一行说明生成了什么——不要询问“保留还是重新生成?”
ts
submit_shader({
  type: "effect",
  prompt: "Chromatic aberration with RGB split",
  name: "Chromatic Aberration",
});

submit_shader({
  type: "transition",
  prompt: "Smooth crossfade with soft edge",
  name: "Crossfade",
});

submit_shader({
  type: "effect",
  prompt: "Cinematic teal-orange color grade",
});

submit_shader({
  type: "effect",
  prompt: "Stronger version",
  referenceAssetIds: ["effect_asset_id"],
});

Strategy

策略

  • Submit, then stop. Tell user the job was created.
  • Use the
    track_progress
    tool for status/wait after submission.
  • Generation always produces a library asset — never refuse because the timeline isn't ready.
  • Apply is separate and optional. Only apply when user explicitly asks ("加到视频", "apply", "用到第一段"). When ambiguous, default to library-only.
  • 提交后即停止。告知用户任务已创建。
  • 使用
    track_progress
    工具跟踪状态或等待任务完成。
  • 生成始终会产出一个库资产——绝不要因为时间线尚未就绪而拒绝。
  • 应用是独立且可选的。只有当用户明确提出要求(“加到视频”、“apply”、“用到第一段”)时才应用。若意图不明确,默认仅生成到库中。

Editing Existing Properties

编辑已有属性

Any time you're about to edit shader
asset.properties
, applied effect/transition
item.propertyOverrides
, or promote a hardcoded shader value, read
references/property-changes.md
first.
It reinforces that shader
properties
is an array, but the allowed shader property types are only
number
,
boolean
,
color
,
select
, and
vec2
. Motion Graphic properties are also arrays, but use a different type set.
每当你准备编辑 Shader 的
asset.properties
、已应用效果/转场的
item.propertyOverrides
,或提升硬编码的 Shader 值时,先阅读
references/property-changes.md
。
该文档强调,Shader 的
properties
是数组,但允许的 Shader 属性类型仅包括
number
、
boolean
、
color
、
select
和
vec2
。Motion Graphic 的属性也是数组,但使用不同的类型集合。

Parameters

参数

ParamDescriptionDefault
type
"effect"
or
"transition"
(req'd)
—
prompt
Description of the shader (req'd)—
name
Asset name shown in library—
referenceAssetIds
Asset ids. Image id → model LOOKS AT it for visual inspiration. Effect/transition id → reuse its code as style anchor (≤1 per submit, kind must match
type
).
—
参数说明默认值
type
"effect"
或
"transition"
(必填)
—
prompt
Shader 的描述(必填)—
name
在库中显示的资产名称—
referenceAssetIds
资产 ID。图像 ID → 模型会参考它获取视觉灵感。特效/转场 ID → 复用其代码作为风格锚点(每次提交最多 1 个,类型必须与
type
一致)。
—

Output

输出

Returns
{ success, job: { jobId, status }, manage: { status, wait, watch } }
.
返回
{ success, job: { jobId, status }, manage: { status, wait, watch } }
。

Applying to Timeline

应用到时间线

Only when user explicitly requests. Refresh the affected timeline with
view:"timeline"
, passing
track
to narrow the read when appropriate.
仅在用户明确要求时执行。通过
view:"timeline"
刷新受影响的时间线,并在适当时传入
track
以缩小读取范围。

Effect

效果

text
edit_item(json: '{"adds":[{"type":"effect","targetItemId":"<id>","assetId":"<id>","enabled":true,"propertyOverrides":{}}]}')
text
edit_item(json: '{"adds":[{"type":"effect","targetItemId":"<id>","assetId":"<id>","enabled":true,"propertyOverrides":{}}]}')

Transition

转场

Requires two adjacent same-track endpoints.
edit_item
validates live seam feasibility and refuses durations that would require freeze frames or overlapping neighboring transitions. If the add fails, retry with the suggested
durationInFrames
, trim the clips to expose handles, delete/shorten neighboring transitions, or keep a hard cut.
text
edit_item(json: '{"adds":[{"type":"transition","assetId":"<id>","outgoingItemId":"<id1>","incomingItemId":"<id2>","durationInFrames":30}]}')
需要两个位于同一轨道上的相邻端点。
edit_item
会验证实时连接点的可行性,并拒绝那些需要定格帧或与相邻转场重叠的持续时间。如果添加失败,请按照建议的
durationInFrames
重试,修剪片段以留出操作余量,删除或缩短相邻转场,或者保留硬切。
text
edit_item(json: '{"adds":[{"type":"transition","assetId":"<id>","outgoingItemId":"<id1>","incomingItemId":"<id2>","durationInFrames":30}]}')

Validation & Verification

验证与检查

Backend Validation

后端验证

When generating via
generate.ts
, the backend handles validation automatically (transpile, AST security, class structure, retry on failure).
通过
generate.ts
生成时,后端会自动处理验证(转译、AST 安全检查、类结构、失败后重试)。

Manual Code Verification

手动代码验证

NEVER write shader code from scratch. Always use
generate.ts
for new shaders. This section is ONLY for modifying existing shader code that was already generated.
When writing shader code manually, read
references/design-principles.md
first. If the change touches editable properties, also read
references/property-changes.md
.
Typical workflow:
  1. inspect_asset
    with the shader
    assetId
    and
    includeCode: true
    — read the current source.
  2. Edit the source in your own context.
  3. edit_asset
    with
    action=update
    , the same
    assetId
    , and the full replacement source inline in
    json.code
    . Validation runs automatically on update — if code is invalid, the update is rejected with error details.
**绝不要从头编写 Shader 代码。**新 Shader 始终使用
generate.ts
。本节仅适用于修改已经生成的现有 Shader 代码。
手动编写 Shader 代码时,先阅读
references/design-principles.md
。如果修改涉及可编辑属性,还要阅读
references/property-changes.md
。
典型工作流:
  1. 使用
    inspect_asset
    并传入 Shader 的
    assetId
    和
    includeCode: true
    ——读取当前源代码。
  2. 在你自己的上下文中编辑源代码。
  3. 使用
    edit_asset
    ,设置
    action=update
    、相同的
    assetId
    ,并在
    json.code
    中内联提供完整的替换源代码。更新时会自动运行验证——如果代码无效,更新将被拒绝并返回错误详情。