1. 从性能悬崖说起:实时光照为什么要把场景拖垮
1.1 一次真实的光照性能翻车现场
去年我在某个模拟项目里做一栋三层样板间,塞进去三十多盏点光源加两盏聚光灯,想着反正现代显卡都支持实时渲染,灯光随便摆就行。结果一运行,帧率直接掉到25帧。当时的第一反应是"显卡不够好",后来用Profiler一看,光就是Draw Call翻了三倍——每一盏实时光源都会让周围所有材质重新计算一次光照,多个灯光叠加时这个开销不是线性增长,是乘积形式往上冲的。
这是我第一次正经面对光照烘焙这件事。说实话,以前一直觉得烘焙是"老派做法",是给手游用的省电方案,PC上没必要。直到那次翻车才意识到:实时光照的成本远比想象中高,而大部分场景里的静态物体根本就不需要每一帧都重新算光。
如果你也遇到过类似的情况——场景灯光一多就卡、移动端发热明显、或者明明物体不动但光影一直在做无用计算——那这篇内容对你应该挺有用。我会从光照烘焙的原理开始讲,把核心概念拆开,再走一遍从设置到导出的完整流程,最后把我在实际项目里踩过的坑一并说出来。无论你是刚开始接触烘焙的新手,还是做过几次但总被漏光、接缝问题折磨的老手,这篇应该都能给你一些可以直接用的东西。
1.2 实时光照和烘焙的本质分歧
要理解烘焙,首先得接受一个事实:游戏里的光照几乎都是假的,区别只在于"骗"的方式不同。
实时光照的思路是,运行时对每个光源和每个像素做一次光照计算。引擎会拿光源的方向、颜色、强度,结合材质表面的法线、粗糙度等参数,得出每个像素的颜色值。这个方案灵活,灯光可以动、物体可以动,每个瞬间的光照都是"现场计算"出来的。但代价是每一帧都在重复做同样的事——场景里一面墙不会动,灯光也不会动,为什么要每一帧都重新算它被照亮的程度?
烘焙的思路则是:既然这些物体和光源都是静止的,那我干脆把光照结果提前算好,存成一张纹理贴图,运行时直接采样。这就像做饭和叫外卖的区别——实时光照是你每一次吃饭都现炒,烘焙是你提前把菜做好封装,吃的时候热一下就行。
Unity的光照烘焙,本质上就是一个"预计算"过程。编辑器用内置的离线光照计算后端(Enlighten或Progressive GPU),模拟光子在场景中的传播、反弹、衰减,最终把每个静态表面接收到的间接光照信息写入贴图。运行时,引擎不再做任何光照计算,只是把这些预计算结果当作颜色信息叠加到物体材质上。
这里必须澄清一个常见的误解:烘焙不等于关闭光影。烘焙后场景里依然有阴影和明暗过渡,只是这些信息变成了贴图里的一堆像素,而不是实时计算出来的结果。也就是说,静态场景下烘焙的视觉质量完全可以和实时光照差不多,但性能开销几乎可以忽略——这正是烘焙的核心价值。
另外一个很多人忽略的点:烘焙不只是为了性能。烘焙还能带来实时光照很难做到的效果——比如全局光照中的色彩溢出(Color Bleeding),当一面红色的墙靠近一面白色墙壁时,白墙会被反射出淡淡的红色。这种间接光照效果需要大量采样计算,实时路径下几乎不可能跑得动,但在烘焙中只是"多等几秒"的问题。后文我会在参数部分具体讲怎么做才能得到这种干净细腻的GI效果。
2. 烘焙前必须理解的三块基石:Lightmap、UV2、Light Probe
2.1 Lightmap:把光照"拍"进贴图
光照贴图(Lightmap)是整个烘焙体系的核心产物。它的工作方式可以理解成:把场景里每一个静态物体表面的光照信息,用一张纹理记录下来,物体渲染时再把这张纹理叠加到自身的颜色上。
具体点说,在烘焙过程中,引擎会对每个静态物体的表面做一次"光照采样"。它会计算出这个表面在给定灯光条件下的最终颜色——包括直接光照、间接光照、反射光等——然后把颜色值展开到一张二维贴图的对应像素区域里。这个展开过程依赖于我们平时建模时就存在的UV坐标,只不过它用的不是你在模型上用来贴纹理的那套UV,而是一套专门为光照准备的第二套UV(也叫UV2或Lightmap UV)。这一点后面单独讲。
运行时,Unity会把光照贴图和物体自身的纹理做一次混合输出。你看到的效果就好像物体"自带"了光影,但其实那只是采样贴图的结果。这也是为什么静态物体在烘焙后移动位置会显得"光没跟上"——不是光坏了,是贴图没更新。
理解这个机制后,就能明白烘焙里很多诡异现象的来源。比如Lightmap分辨率不够时,阴影边缘会出现明显的锯齿状断层;UV展开不理想时,光照会在接缝处错位;物体走样时,会出现"太阳在左边阴影却在右边"的滑稽效果。光照贴图本质上是一张"光影快照",快照像素怎么分布,最终画面就长什么样。
2.2 UV2:为什么非要第二套展开
很多从美术转过来的朋友刚开始接触烘焙时,都会卡在UV2这一步。明明模型上已经有UV了,为什么还要再展开一套?直接复用不行吗?
理论上可以把同一套UV用于光照贴图,但现实中几乎没人这么干。原因是纹理UV和光照UV的优化目标完全不同。纹理UV要保证贴图纹理在模型上拉伸小、接缝隐蔽,美工在展UV时考虑的是"这张脸怎么布才能让皮肤纹理自然",至于哪些三角形在纹理空间里挤在一起、哪些区域浪费了空间,反而不是最要紧的。
光照贴图则完全相反。它需要的是纹理空间利用最大化——每一块三角形在贴图里占的面积应该和它在屏幕上实际显示的面积成正比,否则就会出现"小模型占了大片贴图、大模型反而糊成一团"的情况。而且光照UV必须保证每块展开的岛之间留有足够的间隔(Padding),否则光照的颜色会在岛与岛之间"渗"过去,形成难看的色渍。
Unity在烘焙前会自动为没有第二套UV的模型生成一套简化的UV2,但这个自动生成的结果只能说"能用",尤其是复杂模型或者LOD模型,自动展开经常出现重叠、拉伸、岛间距不足等问题。所以我强烈建议:重要模型尽量在建模软件里手动做好UV2再导入Unity。在Maya、Blender或者3ds Max里展开一遍,遵循"面积均等、不留重叠、岛间留白"三个原则,导出的烘焙质量会明显好过一个自动生成的结果。
补充一点:如果你用的是ProBuilder这类Unity内置建模工具,它的UV2检测和处理机制有时会自动出问题,需要单独注意。这个后文避坑部分再展开。
2.3 Light Probe:动态物体的光照补偿方案
光照贴图只能照顾静态物体。角色、NPC、可拾取物品这类动态物体没法用Lightmap,因为它们会移动,贴在身上的"光影快照"会穿帮。但如果不做任何处理,动态物体在烘焙场景里就会显得"没有光照"——灰蒙蒙一片,像是被抠图贴上去的。
解决方案就是光照探针(Light Probe)。它的原理是在场景里布置一批采样点,烘焙时每个采样点记录下那个位置的光照强度和方向信息(以球谐函数的形式编码)。运行时,动态物体根据自身所在位置,对周围探针数据做插值计算,得到一个大概的环境光照值,再作用于材质。
用大白话说:探针就是场景里放了一堆"光照传感器",动态物体走到哪里就读取附近的传感器数据,取个平均值来照亮自己。
探针的布置是一门学问。核心原则是:探针要覆盖动态物体可能经过的区域,且密度与光照变化剧烈程度正相关。一个走廊拐角处的光照变化通常比空旷大厅更剧烈,所以拐角处要多放几颗探针;如果一个动态物体可以走到窗口旁边,那窗边一定要有探针,否则角色靠近窗户时身上不会有窗光反射的效果。
我在项目里一般是这么处理的:先用自动摆放生成一个基础探针网格,再手动在光照变化剧烈的区域增加密度,比如门洞、窗户、路灯下方、楼梯转角。运行后用Debug模式查看探针的插值结果,如果发现角色在移动过程中亮度出现跳变或闪烁,说明探针密度不够或分布不合理。
3. 一次完整的光照烘焙实操记录
3.1 场景与灯光设置的具体规范
进入烘焙之前,最先要做的是把场景里的物体属性理清楚。Unity里每个GameObject都有一个Lightmap Static选项,在Inspector面板右上角的下拉菜单里可以设置。这个选项决定了物体是否会参与光照烘焙。
我遇到过不少新手,整个场景一个物体都没勾Static就开始烘焙,结果烘焙倒是成功了,但场景里一片黑。因为烘焙只对标记为Static的物体生效,没勾的物体完全被排除在计算之外。正确的操作是:把所有不动的物体——地板、墙壁、家具、建筑构造——全部标记为Contribute GI(参与全局光照计算);如果你希望物体本身也被光照贴图照亮,就选Static。这两个选项的区别在于:Contribute GI是"我能被光照影响",而Static是"我也要把光照结果写进贴图"。
灯光设置上也有讲究。每盏灯在Inspector里都有一个Mode选项,包含Realtime、Mixed和Baked三种模式:
| 模式 | 含义 | 适用场景 |
|---|---|---|
| Realtime | 完全实时计算 | 动态光源,可移动、变色 |
| Mixed | 混合模式,烘焙一部分、实时一部分 | 需要动静结合的光源 |
| Baked | 完全烘焙 | 纯静态光源,不参与运行时计算 |
如果整个场景都打算走烘焙路线,最简单的做法是把所有灯光设成Baked。但如果场景里有需要动态开灯关灯的情况,或者有一盏灯跟着角色移动,那这盏灯必须用Realtime。要注意的是,Mixed模式虽然灵活,但配置不当会在运行时出现"烘焙贴图和实时光影打架"的情况——阴影重叠、亮度不一致等等。我的建议是:一个场景尽量少混用模式,全Baked是最省心的,Mixed留给"必须动态控制的光源"。
3.2 烘焙窗口参数逐项说明
灯光和物体都设置好之后,打开Window > Rendering > Lighting面板,切到Scene选项卡,这里就是烘焙的大本营。
顶部是Lightmap Settings区,需要设置的参数不少,我挑几个影响最大的挨个说。
Lightmapper:后端解算器选择。Unity提供Progressive GPU和Progressive CPU两种,讲实话在绝大多数电脑上,Progressive GPU的速度优势非常明显,只是显存占用高一些。如果你的项目使用了大量高精度模型,显存不够时会出现烘焙中途崩溃——这时候切成CPU版虽然慢,但至少稳定。
Lightmap Resolution:分辨率。这个参数的单位比较绕,它不是绝对像素数,而是"每个texel(纹素)占据多少单位长度"。数值越小,每个纹素覆盖的真实世界面积越小,贴图精度越高。默认值是2(每2个单位长度一个纹素),我通常在建筑场景里用到1.5甚至1。但要注意,这个参数越小,贴图总量越大——每减半一次,贴图内存占用约翻四倍,烘焙时间也会指数上升。所以不要盲目拉高,要根据场景大小和物体精细程度来定。
Lightmap Size:单张光照贴图的最大尺寸上限,常见256、512、1024、2048。Unity会自动把场景中的物体划分到多张贴图里,超过上限的物体不会被分配到这张图,而会被切到下一张或者调整自身占的精度。实际项目中我一般设1024,除非极端大型场景才考虑2048——越高加载越慢,内存压力越大。
Direct Samples / Indirect Samples:直接光照和间接光照的采样数。采样越多,光影结果越细腻、噪点越少,但烘焙时间越长。默认值偏保守,如果你发现阴影边缘有颗粒感,可以适当提高这两项。我自己的习惯是直接光照保持默认,间接光照采样数略微上调到两倍左右,因为间接光的噪点是烘焙中最影响观感的部分。
Light Probes / Reflection Probes / Lightmap Parameters:这几个属于进阶设置,刚入门时可以不管,后面再细说。
烘焙设置全部调好后,点击Generate Lighting按钮,等进度条走完,场景就会按照你设定的参数运算出光照贴图。第一次走这个流程时,我建议先把参数调低(Resolution调到2.5,采样数降到最小),先跑通流程,确认效果方向没问题,再把参数拉回正常值重新烘焙。否则参数开高了,等了一个小时烘焙出来发现问题,真想砸电脑。
3.3 从纯静态到Mixed:混合光照的选择
全Baked的方案干净利落,但它有一个天然限制:场景里没法移动灯光。如果你做一个交互式项目,玩家需要能开关灯、或者有一盏手电筒跟随角色,那就必须引入部分实时光照。
我的做法是采用Mixed模式,这样既保留了大部分静态场景的烘焙效果,又让"那几盏关键的灯"保持实时。但Mixed的逻辑比纯Baked复杂一些,理解它的行为模式很重要。
Mixed光照有一个关键概念叫Shadowmask。简单说,烘焙时引擎会为Mixed灯光生成一张阴影遮罩图,记录这些灯光下的静态物体阴影。运行时,被灯光直接照到的静态表面依然用实时光照计算,但它们投下的阴影在较远处会切换成烘焙好的Shadowmask数据。这个设计是为了在"直接可见区域"和"远处阴影"之间做一个平滑过渡,避免出现需要实时渲染海量阴影的性能问题。
实际操作中,把一盏点光灯改成Mixed后,Inspecter里会出现一个Shadowmask模式选项,选Distance Shadowmask还是Shadowmask,效果差别不小。Shadowmask模式只烘焙间接光阴影,实时部分负责直接阴影;Distance Shadowmask则会在一段距离后把直接阴影也切换到烘焙结果。前者效果好但开销大,后者性能好但远处阴影可能有点"呆"。这个权衡没有标准答案,我的建议是:如果你场景里的动态灯光数量少,选Shadowmask;数量多,就选Distance Shadowmask,性能优先。
4. 光照贴图参数背后的物理逻辑
4.1 分辨率怎么定:从像素密度反推
Lightmap Resolution这个参数,对烘焙效果的影响是最直接的。它决定了场景里光照细节的精细程度,但很多人根本不知道该怎么选。
我习惯用"像素密度"来思考。假设你有一段长两米、宽半米的台阶,你希望这段台阶上的光影过渡能看得清楚,那每10厘米怎么也得有8到16个像素来记录光照变化吧。那这段台阶在光照贴图里大概需要160×40像素。再看整个场景里所有需要精细处理的地面、墙面,估算一下总量,就能反推出合适的Resolution数值。
举个例子:一个20米×20米的室内空间,主要看地面和四壁的光影过渡。如果Resolution设为2,那一米内有5个纹素,20米就是100个纹素,意味着这张光照贴图里地面的精度只有100像素×100像素——说实话,这种精度下阴影边缘会糊成一片。如果把Resolution调到1,精度翻倍,变成200像素×200像素,体感上会明显清晰不少。
但精度变高的代价是贴图数量和内存吃紧。我曾经在一个样板间项目里把Resolution从1.5调到1,结果光照贴图总内存从90MB暴涨到450MB,加载时间多了将近三秒。所以我的建议很务实:重要的交互区域用低数值高精度,次要区域(比如天花板、柜子背面、玩家基本不会靠近的地方)可以在模型单独的Static设置里覆盖全局参数,用高数值低精度。Unity支持给每个物体单独设置光照贴图参数(Lightmap Parameters),这样就能做到"该清晰的清晰,该省的省"。
4.2 Compressed与HDR:色彩范围与内存的博弈
光照贴图在导出时可以选不同的编码格式,最常见的是Compressed(一般走RGBM编码)和HDR两种。
先解释什么是RGBM:假设一张RGBA贴图里,RGB通道存的是光照颜色的RGB值,而A通道存了一个倍率(M),实际亮度就是RGB乘以M。这个方案的优点是用通常8位贴图就搞定了,内存占用低,兼容性好。缺点很明显——动态范围有限,遇到高亮度的区域容易过曝,丢失细节。
HDR光照贴图则使用更高位深的贴图格式,能存下RGBM无法表达的高动态范围,烘焙出来的光照层次更丰富,亮部不容易"死白"。但HDR贴图内存占用高出一截,移动端兼容性也差一些。
项目里怎么选?如果是PC/主机项目,我基本直接选HDR——视觉质量的提升对得起那点内存开销。如果是移动端,我会先用Compressed跑一版看效果,如果场景里有大面积的高亮光源(比如朝太阳的窗户、大量白色光源),那就必须上HDR,否则那些区域会糊成一片白,什么细节都不剩。这一点在室内靠窗的位置尤其明显——窗外的阳光打在釉面砖上,过曝的反射光在Compressed编码下会直接"爆掉"。
4.3 采样数与反弹次数:噪点和真实感的权衡
烘焙质量的另外两个关键参数是间接光照采样数和光线反弹次数。
反弹次数目前在Unity烘焙里默认是2次(Bounces),最多可以设置到8次。这个参数决定了一条光线在场景中会反弹多少次再记录光照信息。反弹次数越多,间接光照越真实——尤其是那些藏在角落里的区域,光线通常要经过多次反弹才能到达,反弹次数太少时就会显得非常暗。
但反弹次数增加带来的收益是递减的。人类视觉对第4次、第5次反弹的光照贡献感知已经很弱了,而计算时间的增加却是实打实的。我实测过,Bounces从2调到8,烘焙时间大约翻4倍,但视觉差异不仔细看几乎发现不了。所以这个参数我常年保持在2,最多3。只有一种情况我会拉高:场景里有大量色彩丰富的大面积表面(比如红黄色调的墙面、五彩缤纷的道具),这时候色彩溢出是视觉点睛之笔,多几次反弹才能让颜色"溢"得自然。
间接采样数则直接影响烘焙结果的噪点水平。采样数过低时,间接光照区域会出现颗粒感,类似照片在暗光下用高ISO拍出的效果。这种噪点比接缝和漏光更难处理——它不像是某个特定位置的问题,而是整个暗面都在"脏"。遇到这种情况,我的排查思路是:先确认采样数是否足够,而不是急着换后端或者调分辨率。把Indirect Samples从默认值调到两倍以上再重新烘焙,大多数噪点问题都能解决。
5. 动态物体、角色和探针布置的实战细节
5.1 探针布局不是随便摆
前面已经提过探针的基本原理,这里说一些实操层面容易被忽略的问题。
探针在场景里的表现是一堆四面体网格(Tetrahedron),你可以在Lighting面板的Scene选项卡里点开Light Probe Visualization查看。探针之间必须以四面体网格的方式相连,因为插值算法依赖这个四面体结构来算出正确结果。如果探针分布形成了一个"凹"形或者出现悬空节点,那插值区域会不连续,动态物体在经过这些区域时光照会出现跳变。
我踩过的一个坑是:在墙角两面临近的地方各放了一颗探针,但没有在这两颗探针之间补一颗,结果角色绕过墙角时,脸上的光照忽然从亮变暗又变亮。后来补了一颗探针在墙角正中位置,让四面体网格平滑连接,问题就消失了。
还有个细节是探针的高度。默认自动生成的探网是贴在物体表面的,但动态物体(尤其是角色)的光照参考点通常在世界空间半人高的位置更为合理。手动放置探针时,我通常把每颗探针的高度定在1.5米左右——接近角色的胸部高度,这样角色在地面上行走时,插值到的光照值最接近真实情况。如果探针太低(贴近地面),角色面部光照会偏暗;太高(贴近天花板),又会整体偏亮。
5.2 运行时加载与烘焙数据管理
一个容易被忽视的问题是烘焙数据的打包和加载。光照烘焙完成后,所有贴图数据并不是存在场景里的,而是生成在场景同名的光照贴图资源文件夹中。如果你用Addressable或AssetBundle做项目,这些光照贴图也必须一起打包,否则运行时场景会变成一片漆黑。
我遇到过一次线上问题的排查经历:某个版本更新后,玩家进入关卡时场景是黑的,只有角色和UI正常显示。查了很久,最后发现是AssetBundle打包时漏了光照贴图文件夹。从那以后,我的项目里都会在构建脚本里额外检查光照贴图资源是否被正确包含,并且打包后做一次"进场景看亮度"的冒烟测试——这种问题很难通过代码测试发现,但玩家一进游戏立刻就能感知。
另外,如果项目里用了多个场景且场景之间共享光照环境(比如主菜单到主场景),要注意烘焙数据是按场景独立存储的。跨场景切换时,光照数据不会自动延续,有可能出现"上一场景很亮、下一场景突然变暗"的观感问题。处理方案有两种:要么两个场景分别烘焙,切换时通过Shader或环境光参数做平滑过渡;要么用多个场景共享一套光照贴图。后者配置起来更复杂,但省内存,适合场景数量多且光照特征一致的项目。
我个人的习惯是:优先保证每个场景独立烘焙数据,切换时先做一次短暂的"适应期"(Fade out/in),这样虽然技术上保守一点,但稳定、可控,也不会出错。
6. 避坑:漏光、接缝、暗斑与暗角排查实录
6.1 漏光(Light Leaking):模型尺寸和UV展开的共谋
漏光是我被问得最多的一个问题:明明外面是白天,结果室内墙壁拐角莫名其妙亮了一团;或者一个封闭房间,顶角处出现一片不明光晕。
漏光的原因主要出在网格层面。光线追踪本质上是用无数射线在三角网格上做碰撞检测,如果模型的三角面之间存在细小的缝隙,射线就会从这些缝隙"漏"进室内,照亮不该被照亮的地方。
最常见的产生缝隙的情况是:两个墙面之间并没有真正"拼合",而是用两个独立的Mesh彼此贴得很近。运行时视觉上看不出来,但射线碰撞检测时,两条Mesh的交界处并不是一个严丝合缝的封闭面,于是光线就"钻空子"进去了。
排查方法是先看漏光位置的模型结构。在Unity里把漏光区域的Mesh打开线框模式,检查是否存在重叠面、分离面、或者不必要的开放洞口。处理思路有两种:第一种是把漏光的墙体合并成一个Mesh,让接缝彻底消失;第二种是在内部再加一层专门用来遮挡的平面(重要性加一层屏蔽体),阻断光线的通路。
6.2 UV接缝与暗斑:手动UV2的自我救赎
接缝问题在光照贴图上表现为物体表面有一条明显的明暗分界线,把一块本该均匀受光的平面"切"成两半。这个问题的根源在于UV2的岛与岛之间的颜色插值不完全。
自动展开UV2时,引擎生成的贴图岛之间会有缝隙。正常情况下,这个缝隙会被周围的纹素填充(通过Padding设置),但如果岛的排列过于密集、Padding很小,光照颜色就会从缝隙"渗"到岛外,形成暗线或亮线。
处理这个问题的核心手段是在建模软件里手动重建UV2。我用Blender时,会先选择所有需要烘焙的面,执行一次"Lightmap Pack"操作,这个功能会自动把整个Mesh的UV展开成一个适合光照贴图的布局,并预留足够的间距。关键参数是Margin(间距),我通常设0.005左右,太小容易渗色,太大浪费贴图空间。
还有一个容易忽视的情况:Mirror UV(镜像UV)。项目中经常出现对称物体——比如沙发左右两半共用一套UV,烘焙时左右两半的光照信息会被映射到同一块区域,结果就是"左半边受光、右半边也受同样的光",看起来非常滑稽。解决方式是在建模时就避免对光照UV做镜像操作,或者烘焙前在材质面板里关闭该物体的Lightmap Static后再勾选回来,强制Unity重新生成一次UV2。
6.3 关于我踩过的三个烘焙坑
记录几个真实项目里踩过的坑,希望能帮你绕开。
第一个坑是显存不足导致的烘焙闪退。有一次烘焙一个大型展厅项目,Progressive GPU跑了两分钟,编辑器直接崩了。后来查日志发现是显存溢出——模型面数和反射探针数量加在一起,GPU烘焙时一次性需要加载太多数据。解决方案是把场景拆成几个区域分别烘焙,然后通过Additive场景加载方式在运行时拼起来?不用那么复杂——烘焙实际上可以按物体分批进行:先选中一部分区域,在Lighting面板关掉Others(只对选中物体烘焙),跑完再选另一部分。缺点是有时接缝处光照对不上,需要多烘焙一次来处理。所以我现在更推荐先精简反射探针数量、适当降低模型精度、再考虑分批烘焙。
第二个坑是RGBM编码下的窗光过曝。前面提过HDR和Compressed的差异,这里说一个具体场景。一个朝南的落地窗,外面是正午太阳,室内是暖色调木地板。Compressed格式下,地板上那块被阳光直射的区域会白成一片,完全看不到纹理。我一开始以为是要调地板材质,后来发现是光照贴图编码的问题。改成HDR后再看,地板的木纹在亮部依然清晰可见。堆叠在高亮光源附近时,光照贴图一定要用HDR,这是我一再强调的。
第三个坑是烘焙后模型双击事件丢失。这个坑可能比较偏门,但我确实遇到过。某个版本升级后,场景里烘焙完的物体出现Collider失效的问题。排查了很久发现和烘焙无关——是Collider和烘焙数据在场景加载顺序上出现了兼容性问题。解决方式是确保所有静态物体的Collider组件在进入场景时优先初始化,并且不要依赖光照贴图的加载时机。说起来这个和光照烘焙关系不大,但它提醒了我:烘焙数据是场景数据的一部分,它加载的时机会影响整个场景的初始化顺序。排查问题时如果遇到"场景里某些逻辑异常",先把烘焙数据是否正常加载作为一个排查方向。
7. 光照烘焙与美术产线的配合建议
说实话,光照烘焙做到后面,你会发现问题的根源通常不在Unity本身,而在美术产能和工具链的配合上。模型UV2是否规范、材质ID是否合理、场景分层是否清晰,这些直接决定了烘焙的最终质量。
我在项目里推行过一套静态检查流程:美术提交模型之前,必须确认UV2已展开、Lightmap Static设置正确、材质用途分类明确。代码层面则用Editor工具自动扫描场景里所有Static物体的UV2是否重叠、是否预留足够Padding。跑一次这个检查,能减少大量无意义的返工。
这套流程推行后,新项目的烘焙质量稳定多了。以前那种漏光、接缝、暗斑的问题,出现频率大幅下降。所以如果你有团队协作的需求,一定要尽早把这个流程定下来。烘焙不是一个人点一下Generate Lighting就完事的操作,它是整个美术产线的一部分,每个人的工作方式都会影响最终效果。
Unity的光照烘焙原理说复杂也复杂,品牌空间、色彩空间、甚至噪声模式的因素交织在一起;说简单也简单,本质上就是"把光照提前算好,存起来"。只要理解了Lightmap、UV2、Light Probe这三块基石,再掌握好分辨率、编码格式和采样参数的选择逻辑,绝大多数场景的效果就能做得又快又好。做项目时也别害怕反复烘焙——每烘焙一次,你对场景的理解就会加深一点。至少我自己的体会是,那些精美的游戏光影背后,都是无数次的调整和重烘焙堆出来的经验。