EP.008 — ← 返回日志

《赤怒之腹》—— 火焰特效拆解

主导一部恐怖片高潮戏的火焰特效制作 —— 8 个镜头、6 位艺术家、2 个月,所有人都在兼顾课业的同时 完成这项工作。这篇文章会讲流程搭建、团队结构、棘手的技术难题,以及我投入最多心力的那一个镜头的深入拆解。

特效指导 + 特效组长
6 位艺术家
8 个火焰镜头,从模拟到交付
2 个月,兼职
Houdini · Nuke · USD · ComfyUI · SCAD 渲染农场
SH180 —— 整栋房屋完全被火焰吞没,最终渲染
SH180 —— 最终渲染,整栋房屋完全被火焰吞没

注:这篇拆解仍在持续修订中 —— 后续会加入更多镜头和细节。待补充内容:我如何用 AI 工具生成便于合成的功能贴图(utility maps)、更多针对制作中各种怪现象的技术问答,以及另外 2 个镜头定稿后的内容。

概览

《赤怒之腹》是一部恐怖超自然题材的毕业短片,由 SCAD 电影系的 Sophia Pozetta 执导。影片高潮:主角摔在地上的一盏灯笼引发火势,最终蔓延成整栋房屋被火焰吞没 —— 共 8 个特效镜头。

我以特效指导兼特效组长的身份主导了这部分工作:为期两个月,包括我在内的每个人都在同时兼顾课业和其他项目。这个限制条件塑造了整个流程的搭建、任务分配,以及哪里能省力、哪里不能省。

这篇文章覆盖了完整的制作过程 —— 创意需求、流程搭建、团队结构、棘手的技术难题 —— 并对我投入最多心力的 SH180 做了深入拆解。其余七个镜头收录在配套的拆解视频中。

TL;DR

  • 主导影片高潮戏的火焰特效制作 —— 8 个镜头、6 位艺术家、2 个月,所有人(包括我)都在兼顾课业。
  • 在筹备阶段反对了实拍微缩模型燃烧的方案,力主改用全 CG 房屋 —— 换来对火焰行为、比例与迭代更强的掌控力。
  • 核心镜头 SH180 运行了多个拆分开的独立模拟以获得最大掌控力,也暴露出整个段落里大部分最棘手的流程漏洞 —— Cryptomatte 与渲染农场的兼容性问题、路径引发的农场崩溃、EXR 竞态条件,以及跨机器的色彩不一致。
  • 在真实的时间压力下带领六个人,意味着要尽早统一流程标准、预留时间缓冲,并在有人进度落后时亲自下场帮忙,而不是简单地把工作转派给别人。
  • 我个人最大的收获是:做指导不代表要掌握所有答案 —— 而是要懂得倾听、对最终画面负责,并带领团队一起找到正确的方向。

创意需求 / 参考

没有任何一处是凭空想象的。这个段落里的每一个创意决定,都能追溯到具体的参考来源,而不是靠猜。

每一个镜头都严格依据参考来制作 —— 没有任何自行发挥的行为表现。参考来源包括 Shotdeck 上的电影截帧,以及 YouTube 上真实房屋燃烧的素材,针对每个镜头分别挑选,以匹配分镜和现场拍摄的素材。

我把所有这些内容 —— 参考图、分镜和现场素材 —— 整理进每个镜头各自的一块 PureRef 参考板,分享给整个团队。统一的参考标准,避免团队成员之间的理解出现偏差。

镜头追踪表 —— SH180、SH200、SH166、SH179 的分镜、参考与运动笔记
镜头追踪表 —— SH180、SH200、SH166、SH179
镜头追踪表 —— SH178、SH190、SH167、SH86 的分镜、参考与运动笔记
镜头追踪表 —— SH178、SH190、SH167、SH86
镜头追踪表第 3 页
镜头追踪表(续)
镜头追踪表第 4 页
镜头追踪表(续)
镜头追踪表第 5 页
镜头追踪表(续)

整个段落概览

在深入讲某一个镜头之前,先说说整个段落的整体形态,以及我在其中具体参与了哪些部分。

我从头到尾监督了全部 8 个镜头 —— 为整个团队提供创意方向与技术支持 —— 并亲自制作了其中 3 个镜头的火焰特效。

现场监督

连接两个团队

特效工作并不是从 Houdini 里开始的,而是从片场开始的。再好的厨师也需要好食材;如果素材拍摄时根本没考虑后期需求,再多的后期流程功夫也补救不回来。

我在片场的任务,就是确保这道裂缝永远不会出现。我和导演沟通,理解她对每个镜头的具体诉求,再把这些诉求翻译成摄影指导能落地执行的具体条件 —— 灯光、构图和拍摄设置,确保这些选择真正能支撑后期最终需要交付的东西。这项现场监督覆盖了整个段落,而不只是某一个镜头。这也是这个剧组第一次和特效指导在现场合作,所以这份工作关系是双向磨合出来的。

采集参考素材

我亲自用 Insta360 X4 拍摄了卧室和房屋外景的 HDRI,为后期提供精确的灯光参考。

我还带了团队里的两位艺术家以特效制片助理的身份上片场,负责测量后续建模或摄影机匹配所需的一切数据 —— 房屋尺寸、关键距离、参考点位 —— 同时拍摄参考照片,并为后期记录摄影机数据。严格来说,这份工作只需要一位制片助理就够了。我带了两个人,是因为他们俩都没上过片场,这是一次让他们积累现场经验的机会。

力主全 CG 房屋

在筹备阶段,导演、制片人和美术部门提议实际搭建一个房屋微缩模型并实拍燃烧。我提出了反对意见:实拍燃烧只有一次机会,对火焰实际燃烧行为毫无控制力,比例在镜头里往往显得不对,而且微缩模型很可能根本无法让人信服这是一栋真实尺寸的房子。我因此力主改用全 CG 房屋,团队最终采纳了这个方案 —— 换来了对火焰行为、比例,以及所需迭代次数的完全掌控。

发现节奏问题

在做分镜的阶段,我问过导演每个镜头里火势应该有多强,当时的计划在纸面上看起来很合理。到了片场,当我真正理解这些镜头最终会如何剪接在一起时,我发现了一个真实感问题:分镜计划里房屋从起火星到完全被吞没只用了 15 到 20 秒 —— 火势没有那么快蔓延。我当场向导演提出了这个问题,我们随即调整了节奏,让火势升级显得可信,而不是瞬间发生。

一次关于协作一致性的教训

有两个涉及演员眼中火光倒影的镜头,剧组在拍摄时没有和我沟通灯光设置或摄影机数据(镜头、光圈、距离)。我当时就在片场,随时可以被咨询,但直到拍完之后才有人告诉我这是一个特效镜头。这不是致命问题,我们的合成师最终还是把它做出来了,但这也算不上专业。这种沟通缺失会给后期团队增加额外工作量,也有可能导致最终效果不如一开始就做对来得好。这清楚地说明了片场"好食材"在实际操作中究竟意味着什么。

流程架构

8 个镜头、6 位艺术家并行工作,流程必须在任何人动手之前就敲定 —— 而不是一个镜头一个镜头地临时摸索。这件事没有唯一正确的做法,不同工作室处理色彩、渲染与互通格式的方式各不相同。以下是我选择的方案,以及它为什么能在整个段落里稳定运作。

色彩 —— ACES/OCIO。 现场素材是用 RedWideGamut 色彩空间、Log3G10 曲线拍摄的 —— 和任何 CG 渲染的色彩空间都不一样。把所有内容统一到同一个工作色彩空间(ACEScg)是没有商量余地的:这是给出准确色彩笔记的唯一方式,也是合成师判断一块 CG 素材是否真正贴合现场画面的唯一方式。选择 ACES 也是出于实际考虑,因为流程中每一款主要的 DCC 软件 —— Houdini、Nuke、Maya —— 都原生支持它,不会有任何工具跟色彩流程"打架"。合成完成后,合成师会把最终画面转换回 RedWideGamut,匹配现场素材原生的色彩空间,这样剪辑师就能在 CG 镜头和实拍镜头之间统一管理色彩。

渲染 —— USD、Solaris、Karma。 所有的火焰和烟雾特效都是在 Houdini 中制作的,所以相比导出给第三方渲染器,Solaris 和 Karma 原生的体积渲染显然是更合理的选择。有一个镜头打破了这个规律:我们的首席建模/效果开发艺术家 Jay 已经在 Maya 里搭建了一套带有庞大资产库的 CG 汽车后视镜场景,所以那个镜头把火焰模拟以 VDB 形式带入、在 Maya 原生的 Arnold 中渲染,反而比在 Houdini 里重建整个场景更省事。

格式互通 —— FBX。 摄影机和房屋模型都是在 Maya 中搭建的,通过 FBX 格式导入 Houdini。

提前把这些标准统一下来,意味着在任何艺术家动手之前,每个镜头就已经"说着同一种语言"—— 相同的色彩空间、相同的渲染路径、相同的导出格式。

在 SCAD 实验室与 Jay 一起测试流程搭建
与 Jay 一起测试流程搭建

深入拆解:SH180 燃烧的房屋

一共八个镜头,但这一个是我"活"在里面的镜头。SH180 是整部影片的高潮:火焰以一道持续、有方向性的弧线从窗口喷涌而出,是整栋房屋彻底陷入燃烧的那一刻。如果说有哪一个镜头必须扛起"怒"这个字的分量,就是它了。

创意目标

和这个段落里的每个镜头一样,严格依据参考制作 —— 但这里的标准更高,因为 SH180 必须让人感受到这是整部影片的转折点,而不只是又一个"房屋燃烧"的画面节拍。火焰需要给人一种有方向、有意图的感觉,像是刻意地从窗口向外喷涌,而不是笼统地翻滚扩散。这个区别几乎影响了此后每一个模拟决策。

模拟

SH180 的火焰不是一次模拟,而是多次 —— 刻意拆分开,为的是获得最大程度的掌控力。三扇窗户各自运行了独立的模拟。屋顶的火是单独一次模拟。地面散布的火、室内填充火,以及一个次要的漏烟模拟,也都各自独立。这样拆分意味着我可以独立调整每一处火焰的行为,而不必和一个想要一次性搞定所有事情的庞大单体模拟死磕。

模拟中最难的问题,是让窗口火焰沿着屋檐边缘弯曲,而不是径直向外喷。我的第一直觉是用 Pyro 的曲线力微解算器(curve force microsolver),但它把火焰形状扭曲得太厉害,细节也丢失了 —— 看起来不再像自然的火焰,只是一个被强行弯折的形状。我最终改用初始速度加风速的方式实现这条弧线路径,让火焰依靠自身的运动沿着那条弧线走,而不是直接强行扭曲它的形状。

材质

这种按来源拆分的做法也延续到了材质环节。窗口的火焰需要比屋顶火更稀薄、密度更低的烟雾,所以每一处都有自己独立调整的材质 —— 颜色、强度和密度都分开调节,以准确呈现那处火焰真实的样子,而不是把同一种"look"硬套在所有来源上。具体到窗口火焰,我给火焰内部加上了局部透明度,再把透过它能看到的室内填充火模拟叠加进去,让火焰读起来像是"悬浮在一个正在燃烧的室内空间前方",而不是一个扁平的剪影形状。

渲染

用 Karma 渲染。为了让这个镜头在合成阶段保持灵活性,我做了几个刻意的选择。我没有追求无噪点渲染,而是让 Karma 渲染时保留一定噪点,再用 Nuke 里的 Neat Video 做降噪 —— 这样能在事后对"噪点与细节"的取舍保留更多控制权,而不是把降噪的决定提前烘焙进渲染结果里。运动模糊也是同样的处理思路:我没有直接渲染出运动模糊,而是输出了一路运动矢量(motion vector)通道,把运动模糊留给合成阶段处理,这样就可以针对每个镜头单独调整或关闭运动模糊,而不需要重新渲染。

Cryptomatte 本身就是一个独立的难题。SCAD 的渲染农场没办法正确输出这个段落的 Cryptomatte —— 在这个版本的 Karma(21.0.440)中,除非显式指定一个 manifest 文件路径,否则 Cryptomatte 在 Nuke 里就是读不对。AOV 通道也经历了一番试错,其中还包括一个真实存在的 Karma XPU bug。(这两个问题的具体解决方法详见下方的问答部分。)

团队与领导力

流程为每个镜头提供了共同的基础。而领导力,就是确保六个各自还要兼顾其他事情的人,能够真正用好这套流程。

制作表 —— 目录、命名规范与链接
制作表 —— 命名规范与链接
制作表 —— 人员与进度追踪
制作表 —— 人员与进度追踪
制作表 —— 截止日期与每周会议记录
制作表 —— 截止日期与会议记录

团队结构

特效团队隶属于一个更大的剧组:导演、制片人和剪辑师,特效这条线由我向上汇报。特效内部,我们六人大致按专业分工 —— 建模/效果开发、特效、合成 —— 但责任归属是按镜头、而不仅仅是按部门来追踪的:

Jay Jeon 首席建模 / 效果开发 —— 房屋、汽车后视镜、硬表面资产
Emilie Jones 建模 / 效果开发 —— 场景陈设资产:鸟屋、风扇、相机、铃铛
Evie Wang 特效艺术家 —— 灯笼火焰、卧室火焰、树木燃烧
Alyssa Lin 合成师
Yijia Che 合成 / 摄影机匹配 / 灯光艺术家
特效指导兼制片人 / 特效艺术家 —— 窗口火焰、房屋火焰、树木火焰

在限制条件下分配任务

由于每个人都要兼顾课业和其他项目,排期不能假设任何人(包括我自己)能全职投入。我把两个月拆分成按周划分的阶段 —— 预演/布局、建模/效果开发、特效、合成、渲染/交付 —— 每个人的镜头是按周分配的,而不是一次性全部派发,这样计划就能随着大家档期的变化灵活调整。我还刻意把截止日期定得比严格意义上需要的更早,为大家日程带来的、我早就预料到的延误预留出缓冲。这份未雨绸缪不止一次派上了用场。

沟通与复盘节奏

我们每周开一次制作会议(周日晚上 9 点到 11 点,美东时间,在 Discord 上进行),有四个固定目标:检查进度、收集反馈、分配下一周的任务,以及排查任何卡住进度的问题。出席不是硬性要求 —— 如果有人当周已经提前向我汇报过进度,就不需要坐完整整两个小时。除了这个会议之外,只要有技术问题冒出来,或是某个镜头需要方向性决定,我都会尽量第一时间回应。团队的默认预期是经常在 Discord 上发布 WIP(制作中)内容,并主动向同伴征求反馈,这样问题能在截止日期之前浮现,而不是等到截止日期那天才暴露。

一次领导力时刻

并不是每一次任务分配都很顺利。有一位艺术家,我给了他一门付费课程和充足的准备时间,但他还是明显落后了 —— 落后到我不得不亲自介入:自己教他技术基础,并多次帮他调试作品。

当下确实很令人沮丧。但我的工作不是去感受沮丧,而是要让镜头交付、让这位艺术家重新走上正轨。我保持耐心,和他一步一步走完整个流程,坚持到他能重新独立工作为止。结果算不上完美,但很扎实,他也完成了自己的任务。

领导他人教会我的事

当我监督的镜头出了问题时,重要的不是追究是谁的错,而是接下来该做什么才能把它完成。这是那位我曾亲自介入帮助的艺术家教会我的一课,也是在整个段落制作过程中反复出现的一课。

对我来说,领导力的另一半是倾听。我尊重和我合作的每一位艺术家,也经常主动征求他们的意见:有没有更好的做法,我们现在的时间真的做得完吗,这个画面真的能传达出我们想要的效果吗。我是指导,但同时也和他们一样,仍然是一名在学习这门手艺的学生。对此保持谦逊,把他们的不同意见当作有用的信息,而不是对我权威的挑战,这样做出来的镜头,始终比我一个人说了算要更好。

最终成果

经验总结 / 复盘

如果重来一次,我会怎么做

如果让我重新做一次这个段落,有几件事我会改变:

我会亲自参加更多筹备会议。 火势节奏的问题是在片场才被发现的,但它本不应该需要靠最后一刻去补救 —— 我被咨询过每个镜头的火势强度,但并没有深度参与整个段落节奏是如何被规划串联起来的。如果我能更早地"在场",而不只是在决定大多已经定下来之后再去审查,这个问题本可以在分镜阶段就被发现。

在制作开始之前、而不是过程中,就统一渲染机器的设置。 SH180 出现跨机器色彩不一致的问题,根源在于不同艺术家电脑上的 OCIO/Karma 默认设置不一样。这本该是我在搭建流程时花五分钟就能检查完的事,而不是在截止日期压力下、段落制作到一半时才去排查的问题。

更早、更直接地去关心准备工作和课程进度。 我给了一位艺术家一门付费课程和准备时间,但直到他明显落后之后,我才发现他根本没学完。如果能更早、更直接地主动去问一下 —— 而不是等每周例会自然暴露出来 —— 这个差距本可以在变成更大的问题之前就被发现。

反思

进入这个项目之前,我把自己定位成一个"恰好在做监督"的特效艺术家。做完之后,我不再这么认为了。技术层面的工作 —— 火焰模拟、Karma 渲染、流程调试 —— 是我本来就会做的部分。我真正学到的,是围绕在它周围的一切:在一帧画面都还没拍之前就为全 CG 房屋据理力争,通过真正倾听故事将如何呈现来发现片场的节奏问题,保持足够的耐心去教会一个人基础知识,而不是直接把镜头收回来自己做。

我最引以为豪的,不是某一个具体的修复方案,而是贯穿始终的那份谦逊 —— 就是我在"团队与领导力"那部分提到的、始终保持倾听的那种本能。我依然是一名在学习这门手艺的学生,和团队里的每一个人一样。这个项目教会我:做指导不代表要掌握所有答案,而是要确保团队能一起、及时地找到正确的答案。

给带团队/做指导的建议

如果你即将第一次担任特效段落的指导,以下是在这个项目里真正起了作用的经验。

制作开始之前

在真实限制条件下分配任务

在片场

保持谦逊

给出创作方向

为最终画面负责

问答 —— 制作中的怪现象与解决方法

整个段落制作过程中遇到的技术问题及其解决方法,持续更新中。并不完整 —— 想起更多的时候会继续补充。

Q:火焰笔直向上升,但上方的烟雾却向侧面飘 —— 为什么两者对不上?

浮力压过了风力。如果温度场强度相对于风力过高,火焰会在风还来不及影响烟柱之前就已经"跑"过去了。解决方法:重新平衡温度场强度和风力的关系,让风真正能作用在火柱上。

Q:我需要让火焰最热的核心呈现为透明,但密度和温度是关联在一起的 —— 该如何把它们分开?

在体积缓存(volume cache)这一层,通过 fit remap(VEX 或 Volume VOP)把密度和温度解耦,而不是试图在材质端用遮罩去处理。把解耦后的结果缓存下来,可以在多个渲染通道中复用。

Q:我的体积 AOV 渲染出来是纯黑色 —— 是材质坏了吗?

通常有两个独立的原因:(1)如果你检查的是 diffuse AOV,这其实是正常现象 —— 体积没有 diffuse BSDF,应该改看 Volume Direct/Indirect 和 Emission 通道。(2)如果专门的体积 AOV 是黑的,先检查灯光的 Volume contribution 开关,然后排查一个已知的 Karma XPU bug —— 体积 AOV 会渲染出空白。规避方法是关闭材质 AOV VOP 上的"Create Render Var"选项,并在 Image Output → Extra Render Vars 中手动添加对应的 render var。

Q:Cryptomatte 在本地渲染完全正常,但从渲染农场渲染出来后在 Nuke 里就看不到了。

Karma 的多层 EXR 写入器无法稳定地把 Cryptomatte manifest 元数据嵌入文件。解决方法:在 Karma Cryptomatte LOP 上显式设置一个 Manifest File 路径,让 husk 把它写成一个附属的 .json 文件,而不是嵌入 EXR 元数据里,然后把 Nuke 里 Cryptomatte 节点的 Manifest Source 指向这个文件。

Q:渲染农场渲染崩溃,退出代码 139(段错误)—— 该从哪里开始排查?

先检查是否有写死的绝对路径。$HIP/$OS 这类表达式可能会在 USD 导出时就被烘焙成某台特定机器的绝对路径(例如 Windows 的盘符),而不是在渲染农场上由 husk 在运行时才求值,这会导致在不同操作系统上 EXR 写入器出错。解决方法:使用相对的、可移植的路径,不带任何特定机器的前缀。

Q:修好路径之后还是崩溃 —— 还可能是什么原因?

当过多的 AOV 通道以单扫描线 ZIP 压缩的方式被写入同一个多层 EXR 时,OpenEXR 的多线程扫描线压缩器可能会触发竞态条件。解决方法:把体量较大的通道(比如 Cryptomatte)拆分成它们自己独立的 Render Product,并改用多扫描线 ZIP 区块以减少线程争用。如果瓶颈在于通道数量,降低 Cryptomatte 的 rank 也会有帮助。

Q:同一个场景在两台不同机器上渲染出的火焰颜色不一样 —— 哪个才是对的?

检查 EXR 文件实际嵌入的色彩空间标签,而不要只凭假设 —— 它很可能准确反映了一个真实存在的不一致(例如某台机器默认使用 Linear Rec.709 而不是 ACEScg),而不是标签本身出错。解决方法:按每个文件各自正确的原生色彩空间读取,合成前用一个明确的 OCIOColorSpace 节点转换到你的工作色彩空间。预防措施:在开始制作之前,就统一每一台渲染机器的 OCIO/Karma 输出设置,而不是等不一致出现之后才去处理。


← 返回日志