第 13 章 一个场景里同时发生了什么
前面十几章,咱们是”一个概念一个概念”地拆的:坐标是坐标,雾是雾,光照是光照,声音是声音。这很好,因为一次只啃一块,你才嚼得烂。
但现在该把它们”合”起来了。我问你一个很关键的问题:
你玩游戏时,屏幕上那一帧画面,到底是”先画完雾、再画光照”,还是”先光照、再雾”?摄像机、三角形、贴图、声音,它们谁先谁后、怎么协作,才变成你看到听到的那一瞬间?
如果你脑子里还是”雾是一个滑块、光照是一个滑块、声音是一个组件,各调各的”,那你还没真正理解游戏是怎么”跑起来”的。这一章,我带你站在”一帧”的视角,看清楚当所有系统同时开动,引擎在一眨眼(十几毫秒,第 1 章)里到底忙了些什么。这是从”懂单个概念”跨到”懂一个游戏”的门槛。
13.1 渲染管线一句话:从坐标到像素的一趟流水线
先说画面。游戏里每一帧要画的东西,本质都是一堆”三角形拼成的物体”世界。把”世界”变成”屏幕上的像素”,中间有一条固定的流水线,行话叫渲染管线(Render Pipeline)。你不用背名词,记住这条顺序就行——它和你学过的章节编号一一对应:
应用逻辑(这帧世界变成啥样了)
→ 变换坐标(第 2 章:把每个点从局部搬到世界、再搬到视图)
→ 投影到屏幕(第 7 章:用摄像机把 3D 压扁成 2D 屏幕坐标)
→ 光栅化三角形(第 4 章:把三角形切成一个个像素格子)
→ 上色贴图(第 5 章:每个像素该涂什么颜色,来自纹理/材质)
→ 光照(第 6 章:根据光源把这个颜色调亮调暗调冷暖)
→ 雾(第 8 章:按距离把颜色混进雾色)
→ 输出到屏幕
我带你一句句过,每句都回扣你学过的章节,你看它们怎么严丝合缝地拼起来。
- 应用逻辑:这一帧,主角往前挪了半米、敌人开了枪、雾的浓度没变。这些都是”世界状态的变化”,由你的代码和物理算出。它是管线的”原料”。
- 变换坐标(第 2 章):每个物体的顶点,先从左耳坐标系(局部坐标)搬到世界坐标,再搬到”以摄像机为原点”的视图坐标。第 2 章讲的”三套门牌、变换就是搬坐标”,这一步就在每帧每顶点地做。没有这步,引擎不知道东西在世界哪、更不知道在摄像机前还是后。
- 投影到屏幕(第 7 章):摄像机把 3D 的视图坐标,用投影矩阵”压扁”成 2D 屏幕坐标(第 2 章结尾埋的”投影”那个伏笔,就是这)。还顺手做”裁剪”——屏幕外的三角形直接扔掉,不浪费算力(这和第 14 章”剔除”是亲兄弟)。
- 光栅化三角形(第 4 章):三角形在屏幕上占了哪些像素格子,这一步把它们”填”出来。一个三角形可能覆盖上千个像素,光栅化就是决定”这上千个格子归这个三角形管”。
- 上色贴图(第 5 章):每个被盖住的像素,该涂什么颜色?查它的纹理(Texture)、套它的材质(Material)。第 5 章讲的”纹理是表面的照片、材质是表面的脾气”,这一步生效。
- 光照(第 6 章):刚涂上的颜色是”物体本来的颜色”,但真实里它受光影响——迎光面亮、背光面暗、不同色温的光染不同冷暖。第 6 章讲的光照模型在这步叠加。没有这步,世界像塑料模型全亮着。
- 雾(第 8 章):最后,按”这个像素离摄像机多远”,把它的颜色往雾色里混。远处的山、远处的敌人,在这步被”藏”进雾里。注意顺序:雾在光照之后——因为先得知道物体原本被光照成啥样,再决定它被雾盖多少。这也解释了为什么第 8 章说雾能”遮丑”:它压轴出场,把前面一切”远处画得不细”的破绽统一抹平。
- 输出:所有像素算完,送显存、上屏幕。这一帧结束。
你盯住这个顺序,会冒出一个重要领悟:这些效果不是”平级地叠在一起”,而是有先后的、像工厂的工序。 雾在光照之后,光照在贴图之后,贴图在三角形之后。这就是为什么你在 Unity 里调参数时,某种效果”看起来不对”,往往不是那个参数错了,而是它依赖的前序步骤没到位。
音频在哪?音频不走这条”画面”管线。声音是另一条并行的线:每帧应用逻辑更新声源位置 → 音频系统按距离/方位算衰减和声像(第 12 章)→ 混成立体声送声卡。它和画面”同时”发生,但各走各的流水线,最后在同一帧里”会师”进你的眼睛和耳朵。这正应了第 1 章那张”读输入→更新世界→算画面→算声音→送出去”的全链路。
13.2 当雾、摄像机、光照、音频同时工作:雾中追人
光背顺序太干,咱们来一个思想实验,把上面所有概念放进同一个场景,看它们怎么一起演一出戏。
设定:一个恐怖游戏,你扮演被追的人,在浓雾森林里逃。这一帧,发生了这些事——
摄像机(第 7 章) 在你头顶,视野角 60 度,朝前看。它定义了”这一帧你眼里能看到的范围”。超出视野的树,在投影那步被裁掉(见 13.1),不画。
光照(第 6 章) 只有一轮惨白的月光(方向光,从斜上方来)+ 你手里的手电(聚光灯,从你面前打出去)。于是:你脚下的地被手电照亮、发冷白;月光给树梢镀一层蓝灰;手电照不到的角落,几乎全黑。
雾(第 8 章) Fog Mode 是 Exp2,Density 0.08,雾色取深蓝灰(和夜空盒同色)。于是:你身后三米内的树还看得清轮廓;十米外只剩模糊蓝影;二十米外彻底溶进雾,等于”世界在雾里断头”。
音频(第 12 章) 你身后三十米有个”追猎者”,它的脚步声是个 AudioSource,Spatial Blend = 1(3D)。它离你三十米,超过 Min Distance,按 Rolloff 曲线衰减得挺小,但你仍听得出”在正后方”(声像定位靠左右声道配比)。手电没有声音;风声是个 Loop 的 2D 环境音,Spatial Blend = 0,永远一样响(它是”氛围”不是”世界声源”)。
现在,把这一帧”组装”起来,你作为玩家体验到的是:
- 眼睛:前方手电照亮一小圈地面,四周树影幢幢,远处全被蓝雾吞没——你看不清追猎者,但他可能就在雾里。纵深感和压迫感,来自”近处锐、远处糊”的雾(第 8 章)。
- 耳朵:背后隐隐约约的脚步,告诉你”危险在后头”,你却看不见人——方位感和距离感,来自 3D 音频的声像+衰减(第 12 章)。
- 氛围:冷白手电 + 蓝灰月光 + 深蓝雾,整体色调阴森——冷暖和明暗来自光照(第 6 章),统一的”蓝”来自雾色和光色的配合。
你看,玩家感受到的”恐怖感”,根本不是某一个参数的功劳,而是雾、光、声、摄像机四套系统在同一帧里协同演出的结果。任何一个拉垮,戏就穿帮:
- 雾 Density 调成 0:远处追猎者清清楚楚站着,吓唬个啥?恐怖感崩。
- 追猎者脚步设成 2D(Spatial Blend=0):你听不出他在哪,失去了”背后有东西”的紧张,只剩画面。
- 手电(聚光灯)关掉:全场靠月光,你脚下黑乎乎,连路都看不清,变成”瞎跑”而非”逃命”。
这就是”合起来”的威力:单个概念你会调,但游戏的手感来自它们的配比。 你以后调参数,别孤立拧一个,要想”它和雾/光/声怎么搭”。
13.3 调参思路:看到问题 → 定位概念 → 改哪个参数
讲完”协同”,给你一套最实用的调试心法。新手调游戏最常犯的病是:看到不对,就在一堆参数里乱试。 我教你的正路是三步法:
1. 看清现象(画面/声音哪里不对)
2. 定位概念(这对应你学过的哪个原理)
3. 改哪个参数(去拧对应的那个旋钮)
下面给三个真实排查例子,你照着学这套”翻译”能力。
例子一:远处敌人太清楚,一点都不吓人
- 现象:恐怖场景里,五十米外的敌人和五米处一样清晰,毫无压迫感。
- 定位概念:这是”远处没被藏起来”——对应第 8 章的雾。现实里远处本该糊(空气透视),游戏里远处清晰 = 雾没起作用或太淡。
- 改哪个参数:去 Lighting 里的 Fog,把
Fog Mode设Exp2,Fog Density调大(比如 0.06~0.1),并确认Fog Color和天空盒同色(否则远处会变白块而非”溶进天”)。同时检查敌人模型是否在雾的 Max 范围外仍被强行渲染——若雾够浓,远处自然被吞。 - 顺带想:如果敌人脚步声在远处还震耳朵(第 12 章),那同样要调
AudioSource的Max Distance和 Rolloff,让远处声音也弱下去,视听一致才吓人。
例子二:角色跑到地图边缘,突然”世界缺一块”
- 现象:玩家往东一直跑,跑到某处,前方不再是风景,而是一片突兀的虚空/硬边,像照片被剪掉。
- 定位概念:这是”可视边界露馅”——第 8 章讲的”边界隐藏”问题。引擎只渲染到一定距离,但没用雾把边界柔化,玩家一眼看穿”世界尽头”。
- 改哪个参数:把
Fog End Distance(Linear)或Fog Density(Exp)调到”刚好在边界处把世界吞没”。让”不渲染远处”和”远处被雾遮”无缝衔接。核心认知:不是去”画更远”,而是”让边界溶进雾”——又回到第 8 章”雾是偷性能的合法掩护”。
例子三: footsteps 声音在左边,但人明明在右边
- 现象:脚步声从左喇叭出,但场景中声源在角色右侧。
- 定位概念:这是”空间化算错方位”——第 12 章讲的声像定位,靠
AudioSource和AudioListener(在摄像机)的相对位置。如果算反了,说明坐标/朝向错了。 - 改哪个参数:先确认
AudioListener确实只在主摄像机上(若主角也挂了一个,双耳打架,定位必乱,第 12 章提醒过)。再确认声源物体的世界坐标(第 2 章)真的在右侧。若都正常,检查Spatial Blend是否真为 1(设成 0 就没有左右之分了,声音会变”固定声道”而非”来自位置”)。 - 顺带:如果声音”左右对、但远近不对”,那是 12.2 的
Min/Max Distance没设好,不是方位问题。你要学会把”左右”和”远近”两个问题分开治。
你看这三例的共同套路:现象是表象,概念是病根,参数是药。 你学完这本教程,最大的收获不是”记住几十个参数名”,而是”看到任何不对劲,能翻译成’这是第几章讲的哪个概念’,然后知道去拧哪几个旋钮”。
13.4 收个尾:一帧,是一场所有系统的合奏
回到开头那个问题——“先画雾还是先光照?“现在你答得出来了:固定顺序,光照在上色之后、雾在光照之后,像工厂工序;而音频是另一条并行线,在同一帧里和画面会师。
更重要的是,你体会到:游戏手感 = 多系统配比,不是单参数英雄。 雾中追人那场戏,少了雾的掩护、少了 3D 声的方位、少了聚光灯的明暗,都不成立。你以后做效果,脑子里要常开一张”协作清单”:这个感觉,需要雾/光/声/摄像机里哪几个一起上?各出多大力?
13.5 一帧到底有多挤:把那十几毫秒的账算给你看
前面反复说”一帧只有十几毫秒”,你可能没实感。这节我带你把”雾中追人”那一帧,粗略拆成时间账,你就知道为什么工程师那么抠门。
假设你目标 60 帧,那一帧预算约 16.6 毫秒。这 16.6 毫秒里,引擎要干完第 13.1 那条流水线全部工序,还要算你的游戏逻辑(敌人 AI、物理碰撞)、算音频。我们粗分一下(数字为示意,不同机器不同):
- 应用逻辑(你写的代码更新世界):约 2 毫秒。
- 变换坐标 + 投影 + 裁剪(第 2、7 章):约 1 毫秒。
- 光栅化三角形(第 4 章,最吃显卡):约 4 毫秒。
- 上色贴图(第 5 章,读纹理):约 2 毫秒。
- 光照(第 6 章,每个像素算光):约 3 毫秒。
- 雾(第 8 章,按距离混色):约 0.5 毫秒。
- 后处理(第 14 章,全屏滤镜):约 2 毫秒。
- 音频(第 12 章,距离衰减+声像):约 1 毫秒。
- 系统开销、显存搬运等:约 1 毫秒。
加起来已经 16.5 毫秒,贴着天花板。注意我还没算”阴影""复杂粒子""物理”。任何一项多加一点,就破 16.6,帧率掉到 50、40、30……你立刻感到”卡”。这就是为什么第 8 章雾要”顺便偷性能”、第 14 章 LOD 和剔除要”砍面数”——不是工程师闲得慌,是 16 毫秒的预算真的一挤就爆。
你从这笔账里,还能读出一个重要结论:越靠后的工序,越该省。 雾(0.5 毫秒)看起来便宜,但它是”全屏每像素都算”的,物体一多、分辨率一高(比如 4K 屏像素是 1080P 的四倍),它就翻四倍到 2 毫秒。后处理同理,全屏算法,分辨率翻倍成本翻倍。所以”全屏类”效果(雾、后处理、景深)最该克制——这和第 14 章”后处理别一股脑全开”完全呼应。反观”逐物体”的光照,物体少就便宜。理解这笔账,你调性能时才知道”先砍哪样最划算”:通常先砍全屏后处理、再砍远处面数(LOD/剔除),最后才动逐物体光照。
13.6 一个你常会忽略的协同:声音和画面的”同步”
再补一个容易被忽视的点:声音和画面虽然是两条线(13.1 讲过),但它们必须”同步到同一帧”。你踩在枯叶上的脚步,画面里脚落地的那一帧,声音也得正好响——差哪怕几十毫秒,你就会觉得”声音和动作对不上”,非常出戏。这种”视听同步”在电影里靠剪辑对齐,在游戏里靠引擎保证:音频系统和渲染系统共用同一个”帧时钟”,声音触发事件(比如脚落地)和画面事件在同一帧发生。
但实时约束下,音频因为有”流式加载延迟""缓冲区”等,偶尔会偏。高级做法是”把声音稍微提前或延后几毫秒去对齐画面”。你看,又是第 1 章”实时下的近似”——连”同步”本身都是被精心维护的近似。你以后做音游(节奏游戏)会深刻理解这点:判定”你按得准不准”,本质是比”你的输入时刻”和”声音/画面的节拍时刻”差多少毫秒。毫秒级的账,全从这来。
还有个有趣的协同反向例子:有时候故意不同步反而有用。比如过场动画里,角色嘴型(画面)和配音(声音)若严格同步但配音有唇形数据缺失,会”嘴对不上声”。这时美术会让嘴型稍微提前或延后,玩家反而觉得自然——因为人脑对”说话时嘴比声略早”有容错。这说明:协同不是死板”完全一致”,而是”在感知容错内对齐”。又是利用感知弱点(第 15 章第二条哲学)的活例子。
把 13.5、13.6 收一句:当你把”一帧的时间账”和”视听同步的容错”都装进脑子里,“雾中追人”就不只是几个效果凑一起,而是一场在 16 毫秒里精打细算、又要骗过你眼睛耳朵的精密合奏。这才是”懂一个场景里同时发生了什么”的真正分量。
13.7 一个必须知道的真相:效果的”先后顺序”决定了”谁能依赖谁”
这一节我点破一个你前面可能隐约感觉到、但没说破的关键:第 13.1 那条流水线,不是随便排的,而是有依赖关系的——后面的工序,依赖前面已经算出的结果。理解这点,你调参时少走无数弯路。
为什么雾必须在光照之后(13.1 讲过)?因为雾要”掩盖远处的破绽”,而远处物体”被光照成啥样”得先算完,雾才能去盖。如果反过来,雾先把颜色混了,光照再照,远处的”被照亮”就把雾盖掉的部分重新显形——依赖关系被破坏,效果就错。同理,后处理(第 14 章)必须在所有物体画完之后,因为它是对”整张成品图”动手;它不能插在”画到一半”的中间,因为那时图还没齐。光照依赖上色(得先知道表面本来的颜色),上色依赖光栅化(得先有像素格子),光栅化依赖投影(得先知道三角形在屏幕哪)。一环扣一环,像工厂的工序,前道不出活,后道没米下锅。
这给你两条实用纪律。第一,调参时别试图用一个”靠后”的效果去补救”靠前”的缺失。比如你想”远处太暗看不清”,不该去加后处理提亮(那是全屏、最末端),而该查”远处光照是不是没打够”(靠前)。用末端补前端的缺,往往越补越怪,因为顺序不对。第二,性能优化时砍”靠后”的全屏效果最安全(13.5 说过),因为它们不参与前道的依赖链——关掉后处理,前面的光照雾照常工作,世界只是少了滤镜;但你若砍”靠前”的投影/光栅化,后面全崩,因为依赖断了。所以”从后往前砍”既是性能账,也是依赖账。
还有个反向提醒:有时你想让某个效果”提前”,就得改管线顺序,那叫”自定义渲染管线”或”渲染事件”,是进阶话题。你现在只需知道”默认顺序是依赖关系决定的、有道理的”,别轻易怀疑它。等你以后学 Shader(第 16 章路径第三阶段),会亲手改这个顺序,那时你这几章的依赖直觉,就是你的安全绳。
把 13.7 压成一句:看到任何”效果不对”,先想”它依赖的前序算对了吗”,再去拧它自己的旋钮。这是把”溯源学习法”从”单个概念”升级到”整条管线”的关键一跃。
13.8 收尾小练习:自己画一条”我这一帧”的管线
学到这,我给你一个立刻能做的练习,比看十遍都有用:打开你正在玩的任何游戏(或一段游戏视频),暂停在一帧画面上,拿张纸,按第 13.1 的顺序,自己写一遍”这一帧引擎干了什么”。
比如你写:“这一帧,先算主角往前走了(应用逻辑);把主角的顶点从局部搬到世界、再搬到摄像机前(变换+投影);主角和墙的三角形被填成像素(光栅化);主角贴图涂上皮肤色(上色);月光和手电把皮肤染出明暗(光照);远处的山按距离混进雾色(雾);最后加一层暗角让视线聚焦(后处理);同时主角的脚步声按距离衰减送进耳朵(音频)。” 写完你会发现,第 13.1 那条抽象流水线,变成了你眼前这帧具体的、有名字的工序。
这个练习的妙处在于:它逼你把”看到的画面”翻译成”引擎的动作”,正好是 15.5 说的”反向用法”。你练几次,再看游戏就自动在脑子里跑管线,调参时自然知道”不对劲的那块,对应管线哪一环”。我把这称作”在脑中装一台小引擎”——你不需要真写代码,但你的理解已经和引擎同频。这,就是第 13 章想交给你的最实在的本事。
13.9 把”协同”翻译成你调试时的检查单
前面讲协同多是”道理”,这节给你一张能直接用的”调试检查单”。下次你做一个场景、觉得不对劲,就按这张单子逐项过,比瞎调快十倍:
- 摄像机:视野角是不是太宽/太窄?近远裁剪面是不是把东西切了?玩家看到的范围对吗(第 7 章)?
- 光照:有没有”该亮的地方没亮、该暗的地方死亮”?方向光从哪来、聚光灯照哪(第 6 章)?整体是偏冷还是偏暖?
- 雾:远处是不是”刚好溶进天空色”,还是”变白块/露边界”?密度和模式对吗(第 8 章)?
- 音频:有位置的声音方位对吗(左右/前后)?远近衰减合理吗?BGM 是不是误设成 3D 了(第 12 章)?
- 协同:光、雾、声的”基调”一致吗(比如都偏蓝=阴森,都偏橙=温暖)?有没有哪个系统拖后腿破坏整体感?
你看,这张单子就是把第 13.2”雾中追人”那场戏,反过来变成”排查清单”。每个系统单独对一遍,再合起来看”基调一致不一致”——这正是 13.3 三步法(现象→概念→参数)的批量版。你养成”做完场景就过一遍单子”的习惯,出品质量会肉眼可见地稳。很多新手做的场景”哪里都差点意思”却说不出哪,根子就是没这张单子,全凭感觉。感觉会飘,单子不会。
把 13.9 收成一句:协同不是玄学,是可拆成”逐系统核对 + 整体基调核对”的工序。你把它变成肌肉记忆,做任何场景都不会乱。
下一章,我带你再往前一步——不只在”一个场景里看它们共存”,而是主动”把概念组合”去解决更大的工程问题:远处的树怎么又省又像(LOD)、看不见的东西怎么干脆不算(剔除)、整幅画怎么加滤镜(后处理)。你会发现,组合本身就是一门手艺。
【思考题】
- 渲染管线里,雾(第 8 章)是在光照(第 6 章)之前还是之后生效?为什么这个顺序很重要(试着从”雾要掩盖远处的破绽”这个角度解释)?
- 音频走的是和画面同一条”渲染管线”吗?它在哪一环和画面”会师”?为什么音频可以独立成一条线?
- “雾中追人”场景里,如果追猎者的脚步声被误设成 Spatial Blend = 0(纯 2D),玩家会失去什么体验?这和雾的”空间感”缺失,是同一类问题吗?
- 用 13.3 的三步法,分析一个现象:“玩家一进山洞,所有声音突然都有了回响”。这对应哪个概念、该调哪个参数?(提示:第 12 章混响区)
- 为什么我说”游戏手感来自多系统配比,不是单参数英雄”?举一个你本章学到的、需要雾+光+声协作才能成立的效果。
【参考答案】
- 雾在光照之后生效。顺序重要的原因:雾的作用是”按距离把颜色混进雾色、掩盖远处画得不细的破绽”。如果先雾后光照,那雾混完的颜色又会被光照重算一遍,远处物体等于又”被照亮显形”,雾就白盖了。必须先把物体上色+照亮的真实样子算出来,最后才用雾统一把远处的存在感压下去——这样前面的所有”远处偷工”才被一次性抹平。这正印证第 8 章”雾压轴遮丑”。
- 不走同一条。画面走”变换→投影→光栅化→上色→光照→雾”的渲染管线;音频走”更新声源位置→按距离/方位算衰减声像→混成立体声送声卡”的另一条线。两者并行,在”同一帧送进眼睛和耳朵”时会师。音频能独立,是因为声音的本质是”一串 PCM 数字被实时加工成有位置感的听感”(第 12 章),它不依赖像素、不依赖三角形,只依赖声源和耳朵的世界坐标(第 2 章),所以自成体系。
- 失去”追猎者在哪个方位”的听觉线索——玩家听不出危险在背后还是身侧,只剩画面压迫、没有声音方位紧张。这和雾的”空间感缺失”是同一类问题:两者都是”3D 位置信息没生效”。雾没生效→看不见远近;声音设成 2D→听不见方位。本质都是”本该随位置变化的感官信号,被拍平成了无位置信号”,空间感因此破产。
- 三步法:现象=进山洞声音有回响;定位概念=空间反射/混响(第 12 章),现实里山洞空旷多反射;改参数=在场景放一个
Reverb Zone(混响区),类型设成”洞穴/长混响”,让进入该区的声音被加上回响;并确认角色/声源的AudioSource有Reverb Zone Mix接入。没进洞时不在区内→无回响,进洞后自动带回声,靠”区域”而非改每个声音实现。 - 因为玩家感受到的体验几乎都是多系统叠加:比如”雾中逃命的压迫感”=雾藏远处(第 8 章)+聚光灯造明暗(第 6 章)+背后 3D 脚步声给方位(第 12 章)+摄像机限定视野(第 7 章)。单独把雾调再浓,没有声音方位和光照明暗,也只是”蓝画面”而非”恐怖”。所以是配比而非单参数。