ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

UE4迁移UE5场景闪烁?排查灯光参数与Lumen光照系统是关键

UE4迁移UE5场景闪烁?排查灯光参数与Lumen光照系统是关键

项目前段时间接手一个老工程,说是从 UE4 迁到 UE5 之后,场景里一片一片地闪,就像老式荧光灯管启动时那种明暗抖动,别人看着都以为是我显卡坏了。排查了一圈驱动、渲染API、显存占用,全都没问题,最后才把目光落到灯光参数上。

实际上,UE4 工程迁到 UE5 后出现闪烁,绝大多数都不是引擎坏了,而是光照系统在底层换了逻辑。UE5 默认开启 Lumen 实时全局光照,旧的烘焙光照方案、灯的强度单位、阴影偏移的默认值全都和 UE4 不一样。迁移过程自动转换了部分参数,但没转换全,于是一堆隐藏数值开始打架。这次记录的就是一次完整排查过程,适合正在做版本迁移、或者工程升级后遇到光源闪烁、阴影抖动的兄弟们直接参考。

1. 先把“场景闪烁”这件事定性,再动手改参数

我见过不少人在版本迁移后遇到闪烁问题,第一反应就是翻材质蓝图、检查贴图压缩,甚至怀疑是 GPU 驱动问题。这实际是把问题想复杂了。闪烁在 UE5 里通常有三种完全不同的表现,排查方向也完全不同,第一步应该先把现象归类。

1.1 明暗交替、阴影抖动和高光闪烁:三种常见现象怎么区分

最常见的现象是整个场景或大块墙面在做周期性的明暗变化,亮个几百毫秒又暗下去,反复来,这种通常和间接光照缓存、Lumen 的收敛状态、自动曝光有关。第二种是局部阴影边缘在抖动,看起来像阴影边界在“呼吸”,这种基本是阴影偏移量、距离场阴影或虚拟阴影贴图的参数不对。第三种是模型表面的高光点和反射区域出现一帧一帧的跳变,这种更容易出现在金属材质、粗糙度较低的车漆材质或者打开硬件光追的工程里。

我这边的模拟项目X是个城市场景,主要表现是第一种和第二种混合:墙面整体微闪,路灯下面的阴影边缘持续抖动。判断方法其实很笨但很管用:用控制台命令临时关掉间接光照,只保留直接光,如果闪烁减弱到只剩阴影抖动,说明 Lumen 是元凶之一;再把动态阴影全部关掉,如果画面彻底稳定,那阴影系统也要背锅。这个二分法两分钟就能定位问题的大方向。

1.2 为什么 UE4 工程在 UE5 里才闪:迁移过程埋下的雷

很多人在 UE4 里做项目时,灯光早就烘焙进光照贴图,画面稳定得一塌糊涂。迁移到 UE5 后默认开启 Lumen,引擎会把旧的 Lightmap 数据丢掉或重新生成,但很多工程里 Mesh 的 Lightmap 坐标和材质设置根本没做好重新烘焙的准备。于是实时的间接光照数据在场景里到处乱算,表现为大面积闪烁、噪点跳动。

还有个更容易忽略的点:UE4 的老版本里灯光强度单位默认是按旧式倍率习惯来调,很多人直接给一盏点光源填了个几千上万的值,在 UE4 的烘焙光照体系下能正常曝光。UE5 自动转换单位后,同一个数值被换算成了物理单位,结果某些灯过曝、某些灯过暗,间接光照一混合,整个场景的明暗就在一个范围内反复震荡。迁移不是简单把工程文件夹打包过来,灯光参数是要重新过一遍的,这一步躲不掉。

2. 灯光底层逻辑换了:UE4 到 UE5 光照系统的主要差异

要真正解决闪烁问题,不能只靠乱调参数碰运气,你得知道 UE5 到底改了哪些底层的规则。UE4 工程里那套灯光参数习惯,在 UE5 里很大一部分已经不适用了。

2.1 Lumen 实时全局光照与传统烘焙的根本区别

UE4 的静态光照核心思路是烘焙:把间接光照预先计算成光照贴图,运行时不计算,画面稳定、性能好。缺点是灯光一旦变化,光照贴图就要重新烘焙。UE5 默认用 Lumen 做实时全局光照,光照在运行时持续计算,任何光源参数变化、网格体移动、甚至相机角度变化,都会触发重新采集。

这是好事,但代价是 Lumen 的最终汇聚过程带有一定噪点。当场景里存在多重嵌套的间接光,或者某个区域的采样率不足,画面就会出现“闪烁式噪点”。老工程里很多模型是美术在 UE4 烘焙光照环境下调整的,它们在 Lumen 下可能采样密度不够,于是相邻几个屏幕像素的亮度就在一帧一帧地跳变,肉眼看起来就是闪。理解这一点很重要:你看到的很多闪烁,不是灯光坏了,而是 Lumen 在实时算光照的时候“来不及收敛”。

2.2 灯光强度单位变更与自动转换的坑

UE5 的灯光强度单位升级成了物理单位体系,在细节面板里明确给出了 Lux、Candela、Lumen 三个选项,并且引入了基于 EV100 的曝光体系。UE4 老工程迁移进 UE5,引擎会自动做一次单位换算,但这个换算只覆盖了“被识别为标准单位”的灯光。

实际项目中,很多老灯光的 Intensity Units 根本没有设置成标准模式,美术可能直接沿用旧模板里的数值,却没有同步迁移单位标识。结果引擎把几千的强度值直接当成 cd 处理,一盏点光源可能变成了探照灯级别。过曝的灯光会把整个曝光系统拉得忽高忽低,配合自动曝光,场景明暗就会闪烁。

排查时我建议先打开灯光列表,把所有光的 Intensity Units 逐个检查一遍。点光源和聚光灯建议统一用 Candela,天光用 Lux,矩形光用 Lumen,不要混用。混用单位本身不是错误,但数值的量级差异会让间接光照的平衡变得非常敏感。

2.3 阴影相关默认参数的隐性变化

灯光之外,阴影参数是第二个重灾区。UE4 默认的阴影偏移和过渡参数,迁移到 UE5 后,很多细节面板里的默认值已经变了。尤其是启用了 Lumen 和虚拟阴影贴图之后,引擎对阴影过滤的算法和 UE4 不同,旧的 Shadow Bias 值如果设置过大,阴影边缘就会抖动。

比较典型的就是路灯、窗户框这种细长结构的投影边缘,会像呼吸一样闪烁。这个问题单独看直接光不明显,一旦和 Lumen 的间接光叠在一起,画面就显得不稳定。排查时把几个关键参数——Dynamic Shadow Radius Scale、Shadow Bias、Shadow Filter Sharpen——逐个归零或调回默认,观察阴影边缘是否稳定下来。这个动作能快速排除阴影参数导致的闪烁。

3. 排查灯光参数的完整实操清单

如果项目里灯光数量少还好说,几十上百盏灯的时候就容易一头雾水。我这里记录了一套自己常用的排查顺序,从单位到偏移再到重叠光源,一步步缩小范围。

3.1 先统一灯光单位与强度区间,避免数值过山车

第一步是在场景里把全部灯光单位归拢。打开 World Outliner,按灯光类型筛选,批量选中后检查细节面板的 Intensity Units。实战中见过一个项目,路灯是 Lumens,室内筒灯是 Candela,补光是直接用默认值没设置单位,结果整个场景的灯光强度分布完全没有章法,间接光照算出来的亮度忽高忽低。

归拢单位之后,再看具体数值是否落在合理区间。室内点光源通常在 500 到 2000 Candela 左右,主流做法是配合正确的 Attenuation Radius 来限制范围;聚光灯如果想模拟路灯,强度可能需要上万,但注意要把 Source Radius 调大一点来弱化阴影边缘。数值本身没有绝对标准,但同场景内的灯光量级不能差三四个零,否则曝光系统会一直跳。

一个非常实用的习惯:在项目设置里把自动曝光关闭,先用 Manual 曝光找出一个固定曝光值测试。这样灯光强度过曝导致闪烁的现象,可以被直接放大暴露出来。把自动曝光关了之后,如果闪烁大幅度减弱,说明问题大概率在灯光量级和默认曝光的配合上。

3.2 把阴影偏移参数逐一过一遍

灯光强度解决好之后,开始处理阴影抖动。这里我建议按从上到下的顺序,从 Project Settings 里的 Shadow 分类开始,再到灯光细节面板里面的 Shadow Bias 和 Contact Shadow。

最常出问题的是灯光细节面板里的 Shadow Bias。UE4 里习惯了把 Bias 调得偏大来防止阴影“漏光”,但这个值在 UE5 的 Lumen 和虚拟阴影下会导致阴影位置偏移过大,阴影边界不稳定。我现在的习惯是先把 Shadow Bias 降到一个极低的值,比如 0.1 甚至 0,看阴影是否贴合模型表面,然后逐步加到刚好不产生阴影痤疮的临界点。这个过程看起来繁琐,但能从根本消除阴影边缘的抖动。

Contact Shadow Length 也要检查,这个参数控制几何体接触位置的短距离阴影强度。很多美术喜欢把它开到很大,在 UE4 烘焙里没有明显问题,但 UE5 实时计算场景里,过大的接触阴影长度会导致角色和物体移动时阴影不断跳变。

3.3 检查重叠动态光源:删除无效灯光比调参更快

排查到后期可能还会遇到一个特别让人头疼的情况:单独看每盏灯都没问题,凑在一起就闪。这种现象多半是因为场景里同时有几个动态点光源覆盖同一个区域,尤其是一条街好几盏路灯灯光范围互相重叠,每一盏灯都在跑实时阴影,阴影贴图采样叠在一起互相干扰。

我手上这个模拟项目X的场景就是典型:一个十字路口放了四盏路灯,灯光范围覆盖了同一个街区,迁移到 UE5 后自动变成动态实时阴影,四份阴影叠加,画面边缘持续抖动。最后没有调任何参数,直接把其中两盏灯改成 Static 或 Stationary,配合烘焙阴影,另一盏保留动态作为主光,闪烁当场消失。

所以排查时不要只盯着参数,先看灯光数量。同一区域动态灯超过三盏,画面不稳定基本可以预判。先删灯、再降阴影、最后才调偏移,这个顺序效率最高。

3.4 用控制台命令做 A/B 测试,快速锚定问题环节

盲目调参最浪费时间,我一般会用控制台命令直接把某个系统整体开关,做 A/B 对比。常用的是:

  • r.Lumen.DiffuseIndirect.Allow 0,关闭 Lumen 漫反射间接光照,看闪烁是否消失
  • r.Lumen.Reflections.Allow 0,关闭 Lumen 反射,排除高光闪烁
  • r.Shadow.Virtual.Enable 0,关闭虚拟阴影贴图,观察阴影抖动是否恢复
  • r.EarlyZPass 0,关闭早期 Z 预 pass,排查深度相关的光斑闪烁

通过一轮开关,你能快速把问题锁定在间接光照、反射、阴影或深度缓冲这几大类里。注意控制台命令是运行时临时生效,启动项目时需要每次都输入一遍,所以定位问题用它们非常合适,但最终修复还是要落实到项目配置里。比如确认是 Lumen 间接光照的问题后,再考虑调 Lumen 的最终汇聚质量参数,而不是直接关掉 Lumen 交差。

4. 一次真实场景的调参记录:从“频闪”到“稳定”

这块记录一下模拟项目X当时的完整排查路径,虽然场景不同,但思路可以复用。排查用的机器配置不算高,把一些画质参数调到中等档,方便快速迭代。

4.1 复现环境与初始表现

复现环境是 UE5 的一个中等规模城市场景,开放街区加少量室内空间,灯光数量约 60 盏,多数为路灯和建筑窗户内的补光。迁移时使用的是老工程自带的烘焙光照数据,没有做全新的重新烘焙。启动后场景表现如下:整条主街道的墙面亮度周期性波动,波动的频率约每秒 3 到 4 次;路灯下的地面阴影边缘持续抖动,像是阴影在“毛边”状态切换;个别玻璃幕墙的高光反射出现点状跳动。

这组现象刚好覆盖了上一节提到的三个类型。最优先处理的是会影响整体观感的明暗波动,因为它影响的范围最大。

4.2 逐项排查的时间线和参数记录

第一轮排查先关闭自动曝光,切换到固定曝光值后,整体明暗波动明显减弱,但仍存在局部阴影抖动。此时可以初步判断问题分两层:曝光波动和灯光量级有关,阴影抖动是单独的系统问题。

第二轮检查灯光单位,发现场景里 80% 的路灯单位是 Candela,但数值设置异常,有一盏路灯的强度达到五万多,它在 Lumen 下直接把附近的间接光照权重拉满,造成周边墙面反复过曝。将该路灯强度调回八千,整个明暗波动的频率大幅度下降。这里提醒一句:关闭自动曝光之前,记得先把曝光补偿设置到一个中间值,比如 EV100 设为 2,否则画面容易过亮或过暗,影响判断。

第三轮处理阴影。当时将确认有问题的两盏路灯的 Dynamic Shadow 模式改为 Stationary,并把 Shadow Bias 调整为默认值的三分之一左右。我把修改前后的参数记录了一下:

参数修改前修改后说明
灯光强度(路灯)50000 cd8000 cd避免局部过曝
自动曝光开启手动曝光固定 EV2便于定位亮度波动
Shadow Bias0.50.15阴影边缘更贴合
Contact Shadow Length1.00.2弱化动态阴影跳变
动态路灯数量4 盏2 盏降低阴影贴图叠加

调整完这三步,场景画面基本稳定。最后剩下玻璃幕墙上的点状高光闪烁,是反射相关的 Lumen 采样精度不足,把材质里对该类表面的 Roughness 稍稍提高了一点,并把 Lumen Reflections 的 Screen Space 强度降低,问题就不再出现了。这个动作属于视觉效果微修,如果不影响整体体验,其实也可以放着不改。

4.3 最终生效的参数组合参考

最终生效的组合并不复杂。灯光单位全部统一为 Candela,数值控制在一千到一万之间;自动曝光关闭,手动固定曝光值;路灯保留两盏动态阴影主光,其余全部静态;全局阴影偏移调低,接触阴影长度调短。这个组合在模拟项目X里稳定跑了两周没有复发,也侧面说明这套思路是可复现的。

如果你项目里的场景不是城市场景,而是室内场景,逻辑也一致:灯越多,越要谨慎保留动态阴影。室内大量筒灯和补光可以直接设为静态灯光,配合 Lumen 做间接光照,画面稳定性比全动态好得多。

5. 常见问题速查表与迁移前后的三个建议

排查完毕不代表以后不会再遇到,版本迁移这个事,最好在动手之前就做好预防。最后把常见问题和一些个人建议整理在下面。

5.1 高频问题:现象、根因与解决方案速查

表现常见根因快速解决
整个场景明暗周期性波动灯光强度数值相差过大;自动曝光参与关自动曝光;统一强度单位;检查单位是否错乱
墙面或地面噪点闪烁Lumen 间接光照采样不足调高 Lumen 最终汇聚质量;适当增加三角面密度;减少过密的重叠光源
阴影边缘持续抖动Shadow Bias 过大;过多动态灯叠加降低 Bias;减少动态灯数量;改用 Stationary 光源
金属/玻璃上高光跳变Lumen 反射采样精度不足;粗糙度偏低调低 Screen Space 反射强度;微调材质粗糙度
灯光过曝导致局部闪白单位换算后强度远超合理范围检查 Intensity Units 和具体数值,批量归一

出现上面任何一类问题,首先建议用控制台命令做 A/B 开关,别急着逐个参数微调。开关能立刻给你一个方向,后面再处理细节,效率完全不同。

5.2 下次再迁工程,我会提前做的事

这次排查花了不少冤枉时间,主要是因为工程迁移前没有做预处理。现在总结下来,下次再迁移 UE4 老工程,我不会再直接打开了。第一件事是先用一个专门的空场景,把老工程的核心灯光模板复制进去,跑通基础光照,确认单位换算没出问题再迁移主场景。这个小场景测试能提前暴露绝大多数单位错乱问题。

第二件事是迁移后第一时间做一次全场景光照重建。不要以为 UE5 的 Lumen 会帮你自动处理好一切,重新构建光照能清理掉旧工程携带的 Lightmap 脏数据,大大减少意外闪烁。如果项目不允许重新构建,再考虑通过调整 Lumen 参数来弥补。

第三件事是设置灯光模板。把室内点光、路灯、装饰补光都定义成带单位、带强度区间的模板预设,新加灯光一律从模板拖拽,不要手动输入数值。这个习惯养成之后,后续维护灯光系统会省下大量时间。

我个人的体会是,UE4 升 UE5 并不是一个单纯的版本号增加,更准确的等价说法是光照方案变了。旧工程运行稳定,并不代表光照参数合理,只是因为老的烘焙逻辑恰好包容了那些不合理数值。迁移后触碰到底层机制的变化,所有不合理都会以闪烁、噪点这些直观的形式冒出来。把灯光单位、阴影偏移、动态灯数量这几项管住,场景稳定就是水到渠成的事。如果你正在排查类似问题,建议顺着这个顺序走一遍,大概率不会空手而归。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进