世界级动态图形在 After Effects 中的工艺流程
首先建立共同基础,接着遵循相关模式进行操作,最后完成质量保证和交付:
- 部分 A – 连接到 After Effects。 建立对你自己 AE 实例的可靠控制。
- 部分 B – 始终适用的规则。 在开始构建前阅读通用的动画和可编辑性规则。
- 部分 C – 重现流程。 通过分析、测量和对比来匹配参考视频。
- 部分 D – 创建流程。 通过研究、概念、故事和构建来开发原创动画。
- 部分 E – 完成。 验证最终渲染并打包所需的交付物。
工作模式
| 模式 | 目标 | 如何开始 |
|---|---|---|
| 重现 | 在时间、布局、运动和外观上 1:1 匹配参考视频,并以本地方式重建。 | 分析并测量参考视频;它定义了故事。 |
| 创建 | 为品牌或产品制作 原创 动画。 | 进行研究、概念、故事和情绪板,然后开始构建。 |
部分 A – 连接到 After Effects
目标是拥有一个私有的、可靠的、可脚本化的 After Effects 实例,没有任何其他代理可以干扰,并且您可以在不接触 GUI 的情况下驱动它。
A1. 启动你自己的实例
- 记录正在运行的 AE 进程 ID:
pgrep -f "Contents/MacOS/After Effects"。 - 启动一个新实例:
一个小的 Swift 启动器(open -n "/Applications/Adobe After Effects 2026/Adobe After Effects 2026.app" --args -mNSWorkspace.openApplication配合createsNewApplicationInstance=true和参数-m -ApplePersistenceIgnoreState YES)可以完成相同的事情并直接返回 PID。- 不要 通过
subprocess.Popen启动原始二进制文件。该进程未注册 bundle,无法接收 AppleEvents。
- 不要 通过
- 对比 PID 列表,为后续命令保留新 PID。
- AE 在启动后可能以新的 PID 重新生成。获取拥有 "Adobe After Effects" 主窗口的 PID(通过 Quartz
CGWindowListCopyWindowInfo)。 - Bundle ID 是
com.adobe.AfterEffects.application。
- AE 在启动后可能以新的 PID 重新生成。获取拥有 "Adobe After Effects" 主窗口的 PID(通过 Quartz
- 清除启动对话框(崩溃修复 → 继续)。这些实例中的 Adobe 登录窗口是已知的显示故障:忽略它,切勿输入凭据,也不要将其上报给用户。
ensure_ae.py自动化了所有这些过程:当 PID 挂掉时重新启动,确认小对话框,检测重新生成的 PID,并重新打开项目。
A2. 仅通过 PID 与之通信
tell application "Adobe After Effects 2026"会命中 任何 实例,包括其他代理的实例。永远不要使用它。aedo(Swift)向一个 PID 发送 AppleEventmisc/dosc(DoScript)。ae.py script.jsx或ae.py -e "code"包装每个脚本:- 包含 ES3 JSON polyfill (
json.jsx); - 调用
app.beginSuppressDialogs(); - 在 try/catch 内运行
$.evalFile; - 将
{ok, value, error, line, file, ms}写入结果文件。AppleEvent 返回值不可靠,因此始终读取文件。
- 包含 ES3 JSON polyfill (
- 项目身份保护: 在执行任何修改脚本之前,验证目标 PID 和
app.project.file是否与正在编辑的项目匹配。切勿关闭或退出未经你验证的实例。 - 一次只运行一个 AE 脚本。脚本通常不是幂等的,因此在批量更改前请备份或另存为。
A3. 开始实际工作前的健康检查
通过一个脚本,读取回:
app.version以及项目是否属于你;- 合成渲染器(需要
ADBE Advanced 3d才能使用 3D 模型图层和环境光); - 字体:
app.fonts.getFontsByPostScriptName(name).length必须大于 0(针对你计划使用的每种字体); - 测试
saveFrameToPng出现在磁盘上。
还要设置允许脚本写入文件和访问网络的首选项(Pref_SCRIPTING_FILE_NETWORK_SECURITY)。
A4. 构建流程:数据 → 本地项目
使用可用的构建辅助工具或实现等效功能;下面辅助工具的名称描述了它们的作用。
- Python 将动画描述为数据。
kit.pyDSL 提供:K()带有命名缓动的稀疏关键帧;shape、text、precomp、null、camera、model、L(图层);- 按匹配名称(matchName)的效果、蒙版、轨道遮罩、表达式、标记、注释、标签。 将场景规范合并为单个构建规范。
kit.jsx从规范构建本地图层。- 它自底向上创建图层,因此它们已经处于最终顺序。避免使用
moveTo进行大规模重新排序,这可能会阻塞 AE。 - 然后应用父子关系、效果、蒙版、变换、缓动、遮罩和环境光连线。
- 它自底向上创建图层,因此它们已经处于最终顺序。避免使用
build.py spec.json --new --only "A|B" --stills "Comp:t1,t2" --save output.aep--new关闭当前项目 而不保存(CloseOptions.DO_NOT_SAVE_CHANGES)。否则newProject()会打开一个“另存为”对话框并挂起。
- 静态帧:
stills.py "Comp" t1,t2 prefix。saveFrameToPng是 异步的(轮询直到文件存在)并写入 16 位 PNG(在 8 位查看前需要除以 257)。
- 定向运动渲染:
render.py "Comp" start end out.mp4 [--half] [--hq],或使用带有-s/-e参数的 aerender。 - 完整渲染:
aerender_job.py "Comp" out.mp4 [--half] [--hq]。- 它保存一个作业副本并在 一个单独的进程中 运行
aerender -project job.aep -rqindex 1 -sound ON。 - 它比应用内队列更快,并且崩溃不会影响工作实例。
- 它保存一个作业副本并在 一个单独的进程中 运行
- 联系人表单:
contact.py(来自视频的帧)和sheet.py(静态帧,保持宽高比)。在查看之前始终缩小图像。
A5. ExtendScript 规则 (ES3)
- 没有
JSON和Array.indexOf:使用 polyfill 或循环。使用eval('('+text+')')读取 JSON。 - 永远不要使用链式三元运算符(
a?x:b?y:z评估不正确)。使用 if/else。 - 通过 matchName 寻址属性。显示名称查找有 39 字节限制并且是本地化的。
- 相机不是
threeDLayer:测试matchName==='ADBE Camera Layer'。 - 规范化值维度:将标量传递给分离的维度,将 3 元素数组传递给 3D 属性。
shutterPhase必须是整数。- 在设置文本填充颜色之前设置
applyFill=true。 - 每层创建一个新的
TextDocument。在设置样式前调用resetCharStyle()/resetParagraphStyle()。 - "属性或父级隐藏" 错误意味着该属性不适用于那里。例如:环境光的 Y 旋转无法设置;应为其源贴图设置动画。
- 形状渐变填充颜色无法通过脚本设置。使用渐变斜线效果或分层光源组。
A6. 与其他代理共存
- 其他代理可能会 "按名称" 退出 AE,这也会影响你的实例。经常保存,并让
ensure_ae.py随时待命。 - 在触发退出的 "Save changes?" 对话框上按 Escape 键会退出 AE。
- 计算机使用和无障碍工具可能只能看到其他实例的窗口。通过按 PID 过滤的 Quartz 窗口列表加上
screencapture -l <windowId>来诊断你自己的窗口。通过系统事件在你的 PID 上关闭它们(按键代码 36 = Return,53 = Escape)。 - 披露任何对其他 AE 实例的意外干扰。
部分 B – 始终适用的规则
在两种模式下都应用这些规则,以保持运动流畅且项目可编辑。
B1. 关键帧:尽可能少
- 使用尽可能少的关键帧来获得流畅的运动。 十个带曲线的关键帧胜过一千个平板关键帧。
- 一个手势需要 2-4 个关键帧:开始、结束,以及一个真正的保持或一个真正的极值(峰值、谷值、相位变化)。
- 每个属性最多约 7-12 个关键帧。更多关键帧通常意味着运动未经设计。
- 永远不要将运动烘焙为逐帧(或每两帧)的线性关键帧。编辑器无法编辑它,而且看起来机械。
- 当运动来自测量或遗留数据时,拟合它(参见 B3)。永远不要粘贴样本。
B2. 曲线:速度图中的平滑弧线
- 打开每个动画属性的 速度图。
- 平滑的钟形或弧线 意味着流畅的运动。
- 有棱角的、阶梯状的 图形(每个关键帧都缓入缓出为零)意味着运动有顿挫感。
- 尖峰 意味着急动,除非是有意的强调。
- 一个连续手势的内部关键帧 不能 停止。
- 使用连续的贝塞尔关键帧。
- 将内部速度设置为相邻斜率的调和平均数,即当两者符号相同时为
2ab/(a+b),否则为 0,影响力约为 33.3。 - 永远不要对连续手势应用全局缓入缓出:它会创建楼梯步。
- 缓动词汇表(前一关键帧的输出影响力 / 此关键帧的输入影响力):
| 名称 | 影响力 |
|---|---|
| ease | 33/33 |
| smooth | 70/70 |
| inout | 82/82 |
| out | 12/88 |
| expo | 6/94 |
| snap | 3/97 |
| in | 88/12 |
| soft | 45/75 |
自定义缓动是 {'o':[speed,inf],'i':[speed,inf]}。例如,软回拉:{'o':[0,55],'i':[0,92]}。
- 空间切线默认为零,这避免了路径过冲。仅在有意时使用弧线。
- 太短且带有强烈 expo 开始的移动会被视为急动。加长它(0.5 → 0.8 秒)并软化缓动,而不是添加关键帧。
- 将子动作重叠为一个手势。 分别执行折叠、翻转和推动会带来走走停停的运动。在前一个动作结束前开始下一个动作。
B3. 从数据拟合曲线
重现模式,或转换任何密集数据时:
- 使用
valueAtTime或从测量中密集采样目标运动(50-200 Hz)。 - 在开始和结束处、精确保持处(零速度)以及显著的极值处(该轴上的零斜率)固定节点。
- 通过最小二乘法针对样本求解速度和影响力:速度受符号约束,影响力限制在 0.04-0.94 范围内。
- 仅在误差超过容差时添加节点:
| 属性 | 容差 |
|---|---|
| 位置 | 2-3 px(相机 3 px) |
| 缩放 | 0.4-0.65 |
| 不透明度 | 0.5-2.5 |
| 模糊 | ~1 |
| 旋转 | 0.4 |
- 对于矢量属性,通过分割贝塞尔曲线(de Casteljau)合并各轴上的节点时间。断言在每个内部关键帧处,输入速度等于输出速度。
- 保持原样,并附上书面原因:表达式、时间重映射、打字节奏、故意保持开关、单帧可见性切换。
B4. 每个场景一个 3D 相机
- 每个场景有一个
CAMERA • scene(单节点,NO_AUTO_ORIENT,分离的 X/Y/Z)。相机负责取景、平移、推拉和缩放。 - 不要对每个元素都进行位置/缩放动画来模拟相机移动。
- 从录制的 UI 运动中推导出相机(主层位置
P,缩放s,合成中心C,缩放Z0):camera XY = C + (C − P)/scamera Z = −Z0/s然后以本地方式重新表达所有自身运动的对象。
- 相机讲述故事:到达 → 动作 → 加速 → 可读的稳定,以及宏观细节 → 拉远揭示。
- 本地动画保持本地:光标路径、点击按压、滚动、卡片翻转。父级点击脉冲 在 组件内部,因此它们在透视下跟随父级。
- 标题位于 3D 世界之上的稳定 2D 平面上,因此相机推拉永远不会剪切它们。通过投射文本边界检查来验证。
B5. 运动模糊、清晰度和景深
- 合成运动模糊开启(快门 135-180°,12-16 个样本)。
- 在非常快的拉远或 UI 拖尾时,将快门降低到 45-90°。
- 在运动模糊使文本模糊的图层上关闭运动模糊。
- 保持 UI 的大缩放清晰:使用 2-4 倍超采样渲染平面预合成,以保存可编辑的矢量 UI,并在相机场景上保持不折叠。
- 高级 3D 渲染器:保持平行平面之间 ≥ 4 个单位,否则会 Z 冲突并显示接缝。
- 空对象的不透明度不影响其子对象。将不透明度传播到所有后代。
- 模糊发光必须 关闭重复边缘像素,否则会显示矩形边界。全画幅径向渐变可制作最佳光场。
B6. 转场:连续性,而非效果
- 转场应该是 有动机的:
- 匹配剪辑: A 的最后一帧等于 B 的第一帧。在渲染中测量姿态。
- 变形: 一个形状将其大小、圆度、颜色和位置动画化为下一个元素。
- 对象交接: 提取一个元素并将其变为下一个场景的主角。
- 相机潜入 一个暗色元素,使下一个场景从黑色中浮现。
- 产品后面的亮色或暗色圆盘揭示 通过轨道遮罩。
- 禁止:
- 全画幅白色或灰色闪光;
- 在黑暗和明亮场景之间的交叉淡入淡出,会产生中灰色帧;
- 每次剪辑都使用相同的擦拭;
- 灰色背景的 "扫动" 条纹。 将闪光放在它们物理上所属的位置:在显示器上,对象后面带有彩色绽放。
- 每个影片最多使用 2-3 个全画幅遮挡擦拭。
B7. 仅原生,始终可编辑
- 资产下载: 无需事先询问用户即可下载任务所需的任何资产,包括 Logo、图标、字体、3D 模型、纹理、图像、视频参考、音乐和音效。优先选择官方或可靠来源,保留所需的许可归属,并在 AE 中使用资产时应用以下本地项目规则。
- 原生 意味着文本、形状、蒙版、效果、预合成、相机、灯光和原生 3D 模型图层(GLB/OBJ)。可以导入音频。
- 永远不要导入截图、参考裁剪、预渲染、摄像头循环或用于替代原生图层的栅格化替代品。
- 在声称 "原生" 之前,审计每个素材项目。
- 可编辑 意味着实时文本、用于控制的滑块、清晰的图层名称和可重复使用的组件预合成,这些预合成可以在任何使用它们的地方传播更改。
- 通过使用
sourceRectAtTime的锚点表达式,在编辑后保持文本居中。
B8. 排版
- 仅使用实时文本,并使用真实的品牌字体。使用
getFontsByPostScriptName检查,并在需要时以唯一的系列名称安装静态实例。 - 标题简短、粗体、首字母大写,并有句号。字间距 -20 到 -40。
- 逐字或逐词揭示:不透明度 0,模糊 20-24,Y +14-26,缓动输出持续 0.45-0.55 秒。退场镜像入场:0.25-0.35 秒,向上模糊。
- 针对真实 TTF 测量宽度(PIL 以 4 倍超采样),以便下划线、药丸、