一帧画面是怎么来的

UNIT 14整条管线约 28 分钟 · 核心线

修片台(一):一帧里就看得出的毛病

上一课的办法(排除法,和一句能执行的话),这两课拿来用。九张卡都是你项目里真出过的事,这一课五张:毛病在一张静止的画面里就看得出——反光怪、像拼的、铁丝网成了墙、翅膀穿过身体、五羊画成了绵羊。每张同一个顺序:① 先定位,在八环里点一环;② 再找原因,错的选项多半是当时的第一判断;③ 能造的亲手造一次;④ 看当年怎么修的;有几张最后请你⑤ 写一句指令,或读一份汇报。

卡 1 · C20

机甲身上的反光怪怪的

红魔 v3 · 22–50 秒
红魔 v3 机甲的特写:黑色镜面装甲上是一块块刺眼的白色和红色反光碎片,背景发灰。
红魔 v3 机甲段的一帧,用 Blender 的实时渲染器 EEVEE 渲。

「机器人身上那些光线效果是不是有点奇怪?那些反光,你是用光栅还是光追的?会不会光追更好?还是说这是材质贴图导致的bug」

背景:这一版机甲用 Blender 的 EEVEE 渲,它是光栅化(游戏的算法,第 6 课);产品镜头一直用 Cycles,它是路径追踪(光追的一种,第 7 课)。

① 先定位:出在哪一环?

  1. 画面底子
  2. 建模
  3. 材质
  4. 灯光相机
  5. 渲染
  6. 动画
  7. 引擎
  8. 后期

材质、灯光相机、渲染,点中哪一环都算对:这次是三环叠在一起出的事。三环各是哪一件,下一题找。

② 原因

三环各出了一样。材质:近乎镜面的铬,映什么是什么,自己没有漫反射(第 4 课)。灯光相机:暗场里能映的只有几条灯带,别处全黑。两样叠起来,装甲又是一块块故意抖过、各朝各的小面(第 3 课),于是每一小块要么正好映到一条灯带,是白的,要么映到黑暗,是黑的:碎块就是这么来的。渲染:EEVEE 的反射只在画面里找,画面外的东西退回一张很粗的环境图,碎块的边就发虚(第 6 课)。贴图只是在上面叠了一层花纹,不是病根。

③ 亲手造一次

这张卡的毛病要在第 4 课(金属在黑屋子里)和第 6 课(屏幕空间反射)的实验台上造:把反射物移出画面、把环境关黑,黑白碎块就出来了。

④ 当年怎么修的

你那个问题的答案:当时是光栅;换成光追确实好了一截,但只换它不够。v4 四件事一起改:机甲换成路径追踪的 Cycles(当时以为 Cycles 太慢,其实是悄悄在用 CPU 渲,第 8 课 C21);镜面铬改成缎面金属,装甲的一块块平面(面片)不再故意抖动;加大面积的柔光反射卡,给金属一样好映的东西;装甲上那层面板线花纹(一张贴图)减弱。

同一帧只把渲染器换成 Cycles:背景变黑,装甲上的反光成了连贯的红色和白色高光。
同一帧,只把渲染器换成 Cycles,其余不动。反光已经不一样了:这本身就是一次「只改一个变量」的检查。
⑤ 读汇报

这份汇报里最不牢的是那个数:「约 1 秒一帧」是半分辨率测的。正式档的像素是它的 4 倍,按第 8 课的账(样本数 × 单价,再加每帧的固定开销)重估,或者干脆在正式档上再测一次;另外还没交的,是同一机位改前改后的对比图。

卡 2 · C22

像几个多边体拼起来的

红魔 v4 · 机甲
红魔 v4 的机甲全身:头盔、肩甲、胸甲都是尖锐的平面碎块拼成的,轮廓全是折线。
红魔 v4 的机甲。

「还有一个问题就是机甲表面是不是太过粗糙了,不是指贴图粗糙 ,是现在感觉就像几个多边体拼接一样,特别是头部和肩膀。」

① 先定位:出在哪一环?

  1. 画面底子
  2. 建模
  3. 材质
  4. 灯光相机
  5. 渲染
  6. 动画
  7. 引擎
  8. 后期

建模。你那句话自己先做了一次排除:「不是指贴图粗糙」——材质划掉了。剩下的是形状,而且这台机甲本来就是按这个样子建的,不是后面哪一环把它弄坏的。

② 原因

形状本身就是一块块的。v4 的装甲,是一个十边形截面沿着骨骼放样出来的,每个点还在三个方向上随机抖了最多 1.5 毫米;平直着色再让每一小块只有一个亮度(第 3 课)。灯光、采样、贴图都改不了一个顶点的位置:外轮廓的折线只能在建模这一环改。

④ 当年怎么修的

v5 照 Lovart 画的设计图重做:装甲是让一个截面沿着一条线扫出来的(放样),截面从 10 边形换成圆角的方(超椭圆);再加细分,让表面变光滑,要保留硬棱的边加「折边」(第 3 课);板件加厚;头盔 V 形面罩、肩部三层叠甲。当时有三条路:混元 3D、Tripo(都是用 AI 从图片生成 3D 模型的服务),或继续用代码按规则生成(程序化)。你选了继续程序化。

红魔 v5 的机甲:银色的曲面装甲,头盔和肩甲轮廓圆润,红色点缀。
v5 的机甲。
卡 3 · C43

铁丝网成了一堵实心的灰墙

投篮课成片第一版 · 按 2 倍像素密度渲

背景:投篮课的成片是从网页里一帧帧录出来的。录的时候和平时在网页里交互,渲染设置不完全一样:为了更细,录成片时按两倍的像素渲,再缩小(超采样)。

黄昏的篮球场,少年背对镜头准备投篮;球场四周本该是透光的铁丝网,却是一整面不透明的米灰色墙,墙后什么都看不见。
投篮课成片第一版的一帧。四周的围网,本该是一张透光的铁丝网。

① 先定位:出在哪一环?

  1. 画面底子
  2. 建模
  3. 材质
  4. 灯光相机
  5. 渲染
  6. 动画
  7. 引擎
  8. 后期

材质或渲染都算对:出事的是材质里铁丝网「怎么做透明」的那个设置。可它在网页里是好的,只在成片里坏——两边差在哪,下一题找。

② 原因
③ 亲手造一次

铁丝网贴图里,网眼那部分是透明的。让它透明有两种做法:透明度转覆盖,把透明度换算成「一个像素里盖住几个子样本」,这要靠多重采样(每个像素里多取几个点,叫子样本,用来磨平边缘);透明度裁剪,透明度低于某个数(这里是 0.4)的地方干脆不画。

复现 C-2铁丝网与多重采样
来自材料
两种透明做法、0.4 的阈值、「没有多重采样时退化成不透明」来自投篮课的修复记录(web/src/main.js 38–39 行)与 C43。
本复现的设定
一片 176 × 99 像素的铁丝网和背景是为演示画的;多重采样按每像素 4 个子样本算;「透明度转覆盖」盖住几个子样本按透明度四舍五入,加了一点按位置错开的抖动。
它能证明
同一个材质,只关掉多重采样,就从透光的网变成实心的墙;换成透明度裁剪,有没有多重采样都透光。
它不能证明
每块显卡、每个驱动的抖动方式都一样;真实的网在远处还会有贴图缩小带来的闪烁。
④ 当年怎么修的

成片是按 2 倍像素密度超采样渲的,舞台在这个设置下没开多重采样;铁丝网用的「透明度转覆盖」依赖多重采样,没有它就按不透明写进去。修法:像素密度到 1.75 倍以上(代码里的阈值)时,铁丝网改用透明度裁剪(alphaTest = 0.4),重渲。这个毛病是第一次全片渲完、把各段抽帧拼成一张大图(联系表)时一眼看出来的。

修好后同一个球场:铁丝网透光,网后能看到房子、树、路灯和亮着的窗。
修好以后。

还有一条旁证:修前修后两次编码的参数一模一样,带灰墙的成片 220.6 MB,修好后 415.6 MB。编码器是按画质定码率的(第 12 课):画面越简单,用的数据越少;灰墙没有细节,就省下了近一半。文件突然变小,也是线索。

⑤ 写一句给 AI 的指令
卡 4 · C25

平板变身到后背时穿模了,要不要换 UE5?

红魔 v5 · 40–50.3 秒
红魔 v5:机甲站在圆形平台上,一排平板翅膀从它身前扇过,穿过了头和上身。
红魔 v5 的 41.4 秒:翅膀从身前扇过,穿过头和上身。

「平板变身到后背那儿的时候穿模了,重新渲染解决这个问题要多久。要不要直接试试ue5的?你来决定判断最好的效果」

① 先定位:出在哪一环?

  1. 画面底子
  2. 建模
  3. 材质
  4. 灯光相机
  5. 渲染
  6. 动画
  7. 引擎
  8. 后期

动画:穿模就是某一帧两块网格真的交在了一起。起因是 v5 把肩甲和上臂做大了,但做大没有错;错在翅膀的飞行路线没跟着让开。要改的是路线,所以算动画。

② 换不换引擎
③ 亲手查一次

先把「穿模」说准:某一帧里,两块网格的三角形真的交在了一起。这件事在动画这一环就已经发生了,渲染器只是照实画出来,所以换哪个渲染器、哪个引擎都一样穿。要说一段动画没有穿模,就得每一帧都查过。

一帧要查的东西不少:翅膀有几千个三角形,机体更多,两两都比一次太慢。办法是先比包围盒(刚好框住一块东西的长方体):两个盒子不相交,里面的三角形一定不相交,这一对整个划掉;盒子相交了,才去逐个三角形细查。把盒子一层层往里套(整片翅膀 → 半片 → … → 单个三角形),只往相交的那几层钻,这叫层次包围体(bounding volume hierarchy,BVH)。红魔 v6 的检查脚本用的就是 Blender 自带的 BVH 工具。

v6 改完路线,你每 0.2 秒抽一帧看,一帧都没穿。能不能说这段没有穿模?

  1. 能:0.2 秒已经很密了
  2. 不能:两次抽查之间还有几帧没人看
  3. 不能:要换 UE5 再渲一遍才知道

不能。每秒 30 帧,0.2 秒是 6 帧:看了 1 帧,另外 5 帧没人看。翅膀一帧能飞一大段,擦过身体又离开,完全可以藏在这 5 帧里。所以当年的顺序是:先让程序逐帧算,保证几何上一次都没碰;再用眼睛抽查,看程序没被写来查的东西,比如好不好看、挡没挡住镜头。猜「换 UE5」的,把「画出来」和「查出来」当成了一回事:引擎只会照实画,不会替你查。

复现 C-3逐帧碰撞检查
来自材料
v5 的翅膀从身前飞过、穿过头和上身;v6 先分开、从背后绕过来再滑入、后仰 30°;逐帧检查 40.1–50.3 秒(每秒 30 帧,第 1203–1509 帧)翅膀对机体、翅膀对翅膀 0 次接触,再每 0.2 秒抽一帧目检:来自红魔的检查脚本 check_wings.py 与 C25。
本复现的设定
侧视的二维图:机体简化成四块凸多边形,翅膀是一块板;两条路线的形状和「绕过头顶的高度」是本复现定的,不是红魔的动画曲线。真实的检查是三维的、逐三角形的(Blender 的 BVHTree),这里只有两层:包围盒粗筛,再逐边细查。
它能证明
包围盒一次就能划掉大多数不可能相交的对子;逐帧算能抓到抽帧目检漏掉的短暂擦碰。
它不能证明
三维里前后错开的两块,在侧视图上会叠在一起,这里分不出;v6 查过的翅膀对翅膀,这里没做。

它停在 v5 的第 1300 帧:四块机体都被翅膀穿过,时间轴上红的那一段,就是 v5 穿模的帧。拖 02 看翅膀怎么穿过去,读数里数一数包围盒替你划掉了多少对。再把 01 换成 v6:整段 0 次接触。最后把「绕过头顶的高度」慢慢往下拖到 1.98 米左右,逐帧算查到几帧?把 03 换成「人眼抽查」,又看到几帧?

④ 当年怎么修的

v6:翅膀在背后展开、后仰 30°、前后分层,先分开、从背后绕过来再滑入;写了一个逐帧碰撞检测脚本,40.1–50.3 秒翅膀对机体、翅膀对翅膀 0 次接触,再每 0.2 秒抽一帧目检。只重渲受影响的 1201–1510 帧,从启动到成片约 22 分钟。

红魔 v6 同一时刻:翅膀在机甲身后分层展开,没有穿过身体。
v6 的同一时刻。
卡 5 · C17

五羊石像,画成了五只绵羊

长卷 · 越秀山一段

长卷第二版的五羊石像:螺旋的大角、一身卷毛,越画越「像羊」。你还是说:「还有就是五羊雕像,现在做得太草率了,能不能做得更好、更细致、更像、更逼真」,随后发来一张照片:「五羊雕像是这样的」。(这组对比图在工作机上,这里只有文字。)

① 先定位:出在哪一环?

  1. 画面底子
  2. 建模
  3. 材质
  4. 灯光相机
  5. 渲染
  6. 动画
  7. 引擎
  8. 后期

建模(在 2D 长卷里就是「画的是什么形状」)。更准确地说,是建模之前的那一步:照着什么画。

② 原因
④ 当年怎么修的

照片上是长着弯刀似的长角、长须、细腿的山羊;第二版画的是绵羊。「五羊」加上「羊城」的传说,让画成绵羊显得完全合理,自己检查时根本不会起疑。按照片重画:头羊直立屈膝踏石、口衔稻穗,四只小羊吃草、蹲伏、昂首,石座嶙峋;又对着照片挑了一轮(头羊身体像柱子、小羊太方、石座太整齐)才交,景点说明卡也跟着改。只有「知道去怀疑」的地方,才会被对照到:最保险的是一开始就要照片,一项项核对。

带走一个问题

这五张卡里,C20 是三环叠在一起,C43 是两环碰上。回头找一个你最近指出过的毛病,哪一部片都行:它是一环的事,还是两三环碰在一起?如果是碰在一起,只改哪一处最省?写下你的判断,再写一句能发给 AI 的话。

不看上面,写下这一课撞上的几堵墙,再展开对照
  1. 很多毛病是两三环碰在一起 → 定位到「哪几环的哪个组合」,才知道改哪一处最省(C20、C43)。
  2. 症状的名字像原因 → 「反光怪」不是贴图的 bug,「像拼的」不是贴图粗糙;先问它属于形状、材质还是环境。
  3. 换工具之前,先找到是哪一环 → 穿模在动画,换 UE5 照样穿;贴图治得了墙面,治不了盒子。
  4. 看起来没穿,不等于没穿 → 穿模是几何相交:程序逐帧算(包围盒粗筛、再细查),眼睛只做抽查。
  5. 只有知道去怀疑的地方,才会被对照到 → 先要照片,逐项核对(C17)。