Unity性能优化系列设置篇 - URP 移动端设置基线与分档策略

性能优化系列 · 设置篇。一句话摘要:移动端不要一套 URP 配置跑到底,先按高中低设备分档,再决定 HDR、阴影、后处理这些开关在哪些档位保留。每个设置先看官方三档,再弄清它做什么、性能消耗在哪里、关掉画面会不会差;项目没用到、或者中低端吃紧,就按档位牺牲掉。

移动端做 URP 设置,第一件事不是问「这个开关到底该不该开」,而是先问「它该在哪一档设备上开」。高端机可以保留更多画面层次,中端机保留最容易被玩家感知的效果,低端机优先守住帧率、温度和内存。比如 HDR:如果项目强依赖 Bloom、Tonemapping,高端机可以开;中端机要看真机带宽和后处理耗时;低端机如果没有明显画面收益,直接关掉通常更稳。

这也是后面所有建议的前提:不是把画质开关简单分成开和关,而是把它们接到设备档位上。同一个开关在高端机上可能是画面收益,在低端机上可能就是发热、掉帧和全屏带宽。

以默认 URP 工程为例

这篇对着 Unity 2022.3 自带的 URP 模板讲。模板里有三档 Pipeline Asset,Quality 里各绑一份:

  • URP-PerformantPerformant
  • URP-BalancedBalanced
  • URP-HighFidelityHigh Fidelity

设置散在三处,官方也是三处一起切:

  • URP Asset:阴影、附加光、HDR、MSAA、Render Scale、全屏纹理
  • Renderer Asset:Renderer Feature、后处理数据
  • Quality SettingslodBias、蒙皮权重、各向异性,以及这一档用哪份 Pipeline Asset

这套配置不是「只给手机」或「只给 PC」。Quality 里的平台默认档把意图写死了:Android / iPhone / tvOS / WebGL 默认 Balanced ;Standalone 和主机默认 High Fidelity;Server 才是 Performant。

这篇文章以官方 URP 的三个档位作为参考坐标。移动端不要直接照搬官方的 High Fidelity,也不要一上来就压到 Performant;更合理的做法是:先理解官方 Performant / Balanced / High Fidelity 的差异,再以官方 Balanced 作为移动端基础配置,在这个基础上拆出移动端高 / 中 / 低三档

移动端高档可以保留更多接近 Balanced 的效果;移动端中档以 Balanced 为基线逐项 A/B;移动端低档则向 Performant 收,把项目没用到、或者成本明显高于收益的项关掉。High Fidelity 上的 4096 阴影、4 级级联、MSAA 4x、每对象 8 盏附加光,主要面向 PC / 主机,不应该直接搬到手机上。

后面每一项都按同一套格式讲:官方三档、它是干什么的、性能消耗和画面差、建议。性能消耗是低 / 中 / 高;画面差是轻微 / 中等 / 明显。口径来自 URP 手册标的「性能影响」、Unity 对效果本身的定义,以及移动端常见压测经验。

HDR

Performant Balanced High Fidelity

HDR 是让颜色缓冲能记下更亮和更暗的值,而不是把高光直接裁成纯白。开了以后,Bloom、Tonemapping、基于物理的光照才有足够的亮度范围可算;关掉时,颜色写在普通 LDR 缓冲里,带宽更省,但亮部更容易过曝、Bloom 也更容易脏。

性能消耗 画面差
中等

消耗性能的地方在于更大的颜色 RT,以及后续依赖 HDR 的全屏后处理。没有 Bloom、也看不出色带,关了几乎没人察觉。模板 Graphics 里 Lights Use Linear Intensity 默认是开的,和 HDR 配套;只开 HDR、线性强度却关着,画面会「亮了但也不对」。

建议:项目没有 Bloom、Tonemapping,或者中低端带宽已经吃紧,可以关。反过来,如果决定开启 HDR,就不要只孤立地勾 HDR:颜色空间建议使用 Linear,Lights Use Linear Intensity 也要保持开启;Bloom、Tonemapping 这类依赖高动态范围的后处理,再按画面需求和设备档位一起评估。少开其中一环,常见结果是性能成本付了,亮度和高光却不稳定。

MSAA

Performant Balanced High Fidelity
4x

MSAA 是多重采样抗锯齿:在三角边缘多采几个点,把锯齿抹平。它管的是几何边缘,不是贴图模糊,对 UI 图、文字几乎没帮助。

性能消耗 画面差
中等

Unity 手册写明 MSAA 会用带宽在 framebuffer 上来回拷。手机 GPU 是 tile-based,倍数直接打在每个像素上。URP Asset 和 Quality 里的 Anti Aliasing 会一起生效,两处都开等于叠了一次。画面上只有 3D 模型边缘会锯;纯 UI、卡片、偏平的场景,开不开差不多。

建议:如果模型几何边缘锯齿明显,并且目标设备仍有足够的带宽和帧时间余量,最多尝试 2x,并和 Render Scale 一起评估。先降低 Render Scale 再开启 MSAA,往往会让画面更糊,收益不一定成立。中低端设备不建议开启,更不要直接套用 4x。

主光阴影

Performant Balanced High Fidelity
开,1024 开,4096

主光阴影是平行光(太阳光)打出来的实时阴影:先把场景从灯光方向画进一张 shadowmap,再在物体上采样,决定这块是不是在影子里。没有它,角色和建筑不会在地上投下随时间动的影子;有它,远近层次会清楚很多。

性能消耗 画面差
明显

多一张 shadowmap、多一个阴影 Pass,手机还要付采样带宽。分辨率从 1024 拉到 4096,图是 16 倍面积。没有角色在地上走、没有会动的接触阴影,关了几乎看不出;有角色、有建筑落影,一关就扁。

建议:如果场景里没有需要随物体移动的实时阴影,或者中低端设备的 Shadows、SetPass、带宽已经吃紧,可以关闭主光实时阴影,改用烘焙阴影或贴片阴影。不要为了「更清晰」直接把阴影分辨率拉到 4096。

附加光

Performant Balanced High Fidelity
Disabled Per Pixel,每对象 2 Per Pixel,每对象 8

附加光是主光之外的点光、聚光。Disabled 完全不算;Per Vertex 在顶点上算,便宜但大面体会有色块;Per Pixel 在每个像素上算,体积光、近处灯更准,CPU 要按物体循环灯光,片元也更贵。每对象上限决定同一个物体最多吃几盏。

性能消耗 画面差
中~高 中等

Per Pixel 是 CPU + GPU 两边账单。场景里根本没有点光 / 聚光,这项等于白开循环;只有主光的大厅、卡牌桌,关了没画面差。

建议:如果场景里没有点光 / 聚光,或者中低端设备的渲染提交已经吃紧,可以降到 Per Vertex 或 Disabled。不要直接套用每对象 8 盏的上限,先确认同一个物体实际最多会受到几盏灯影响。

附加光阴影

Performant Balanced High Fidelity
开,4096

附加光阴影让点光、聚光也能投影子,例如手电筒打在墙上的光斑边缘。每开一盏,就要再出一份阴影图。

性能消耗 画面差
中等

Unity 自己的性能建议也是:用得着附加光时,先降 atlas,能关阴影就关。没有手电筒、局部灯打墙,开了也看不见。

建议:角色脚下的局部阴影、手电筒一类效果优先考虑 Blob Shadow 或贴片方案。不要只为了一盏附加光,就启用 High Fidelity 那套附加光阴影。

阴影距离

Performant Balanced High Fidelity
50 50 150

阴影距离是实时阴影从摄像机出发能盖多远。超出这段的物体不再进 shadowmap,远处就没有实时影子。距离越大,同一张图要覆盖的世界越大,近处影子越糊,除非再加级联或提高分辨率。

性能消耗 画面差
中等

距离拉长,阴影 Pass 里的物体变多。摄像机永远对着近处桌面,50 米以外的影子本来就没有观众。

建议:如果摄像机视距很近、远处阴影没有实际观感收益,或者中低端设备上的 shadowmap 已经变糊且带宽压力明显,可以进一步缩短阴影距离。移动端不要直接拉到 150。

阴影级联

Performant Balanced High Fidelity
1 1 4

级联是把阴影距离切成几段,近处一张高精度 shadowmap,远处一张低精度。1 级就是整段共用一张图;4 级是近处很细、远处四份图轮着画。级联越多,近处影子越利,Pass 和带宽也越多。

性能消耗 画面差
高(4 级) 中等

Unity 手册写明增加 cascade 会减性能。近处没有角色脚底影子,1 级和 4 级看不出差别。

建议:不要上 4 级联。

软阴影

Performant Balanced High Fidelity

软阴影是在已经有实时阴影之后,对影子边缘做滤波,让边缘不那么硬。它不产生影子,只改影子的样子。

性能消耗 画面差
中等

URP 手册把这项标成性能影响:高。关掉就回退成硬件滤一次。主光阴影都关了,这项零画面、只留变体。

建议:如果主光阴影已经关闭,软阴影也应该一起关闭;如果中低端设备上软阴影滤波的收益不足,也可以关闭。

Render Scale

Performant Balanced High Fidelity
1 1 1

Render Scale 是 3D 场景相对屏幕的渲染分辨率。1 是按屏幕像素画;0.8 是先画小一点再拉伸。它只管填充,不管阴影 Pass、附加光循环这些 CPU 侧提交。UI 仍按设备分辨率画。

性能消耗 画面差
高(填充) 一关就明显(3D 会糊)

下调对 GPU fill 很有效,3D 会立刻软一档,UI 不受影响。不要当唯一手段,降了分辨率,阴影和附加光该贵还是贵。

建议:如果中低端设备的 GPU 填充压力已经很高,并且项目能接受 3D 画面略微变糊,可以下调 Render Scale。

Depth Texture

Performant Balanced High Fidelity

Depth Texture 是把相机深度再拷一份出来,给软粒子、折射、SSAO、某些后处理采样「这一点离相机多远」。开了就是一张常驻全屏图加一次拷贝。

性能消耗 画面差
几乎看不出(没人采样则无差)

Unity 的性能清单把「用不到就关 Depth Texture」写在最前面。没有软粒子、SSAO、深度特效,开着是纯带宽。

建议:没有明确使用者就关。效果砍了开关一起关。

Opaque Texture

Performant Balanced High Fidelity

Opaque Texture 是不透明物体画完后的场景颜色拷贝,给折射、一些扭曲特效去采样「后面是什么」。同样是全屏拷贝 + 常驻显存。

性能消耗 画面差
几乎看不出(没折射 / 扭曲则无差)

和 Depth Texture 同类:没人读就关。

建议:如果没有折射或扭曲效果依赖 Opaque Texture,就保持关闭;一旦开启,必须明确具体由哪个效果使用。

反射探针混合和盒投影

Performant Balanced High Fidelity

反射探针存的是环境反射。混合让物体在两枚探针之间过渡时不要突然换环境;盒投影让室内反射按房间形状贴,而不是按一个圆球贴。画面上是镜子、地面、金属的环境更稳,采样和计算更贵。

性能消耗 画面差
中等

Unity 对低端移动的建议就是关掉这两项。没有反射探针、没有大块金属和室内镜面,开了等于空转。

建议:只有在场景确实使用反射探针,并且探针过渡或室内反射问题明显时,才考虑开启;开启前要确认目标设备仍有足够的性能余量。

SSAO

Performant Balanced High Fidelity
有(降采样) 有(更高精度)

SSAO 是屏幕空间环境光遮蔽:用深度(有时加法线)估像素周围挡没挡住光,把缝、洞、交叉、贴在一起的表面压暗。墙角、洞窟、箱子贴地、角色衣服夹缝会多一层脏暗,体积感出来。它是 Renderer Feature,和 Bloom 那种 Volume 后处理不是一回事,通常还要深度图。

性能消耗 画面差
轻微

消耗性能的地方在于全屏多 Pass。URP 这份实现里,采样半径、采样数官方标的性能影响是 High,模糊质量和降采样是 Very high(降采样是用分辨率换性能)。知乎上拆过 URP SSAO:算完要走采样再走几次模糊,低端机上就是典型填满。

画面差完全取决于几何。官方说明也是 crease、hole、intersection、靠近的表面。没有洞窟、没有深墙角、没有物体贴地贴墙,开不开几乎没影响------大厅、卡牌桌、偏平的 UI 场景最容易白开。强度拉高还会在角色脸上、平面上脏一圈,观感不一定更好。

建议:如果场景里的墙角、接触面用不上这层暗部细节,或者中低端设备的 fill、深度图成本已经吃紧,可以移除 SSAO。要保留 SSAO,就要把深度图成本一起算进去,并且只给真正有缝隙、孔洞和交叉面的场景开启。

后处理

Performant Balanced High Fidelity
挂后处理数据 挂后处理数据 挂后处理数据

后处理是画完场景之后整屏再滤一层:Bloom 把亮部散出发光,Tonemapping 把 HDR 压回能显示的范围,Vignette 压四角,DOF、Motion Blur 再单独算。Renderer 上要挂后处理数据,场景里还要有 Volume 打开对应效果,两边缺一不可。模板场景的 Volume 里有 Bloom、Vignette、Tonemapping。

性能消耗 画面差
中~高 中等

每一项都是全屏 Pass。Bloom 在有 autolight、爆炸、金属高光时一眼能看出;没有过亮像素,开着也只是略雾。DOF、Motion Blur 更贵,电影镜头才用得上,玩法视角一关几乎没人记得住。

建议:如果项目没有使用 Bloom / Tonemapping,或者中低端设备的全屏 Pass 已经吃紧,后处理数据可以不挂载,对应的 Volume 效果也不会执行。DOF、Motion Blur 即便挂了后处理数据,也不建议在移动端默认开启。

SRP Batcher

Performant Balanced High Fidelity

SRP Batcher 是 URP 的默认提交路径:同一套 shader 变体下,多次绘制少做一次渲染状态整理,Draw 次数不一定少,但每次更便宜。它不合并网格,也不替代 Instancing。

性能消耗 画面差
无,是性能优化项

这是提交路径,不是画质开关。材质不兼容时开了也没用。

建议:保持开启。如果材质不兼容,或者 shader 变体过于分散,即使开关开启,Frame Debugger 里也看不到 SRP Batch;这时应先治理材质和变体,细节放到渲染篇讨论。

动态合批

Performant Balanced High Fidelity

动态合批是每帧把合格的小网格在 CPU 上变换、拼成一批再提交,用来减少很小、会动的物体的 Draw。限制很死,拼 mesh 本身也吃 CPU。

性能消耗 画面差
视 CPU

官方三档都关。Batches 降了但 CPU 更忙,就是负优化。

建议:默认关闭。如果要开启,必须用真机 A/B 验证;只看到 Batches 下降还不够,如果 CPU 侧更忙,就应该关闭。

lodBias

Performant Balanced High Fidelity
0.4 1 2

lodBias 在 Quality 面板,不在 URP Asset 里。它乘在 LOD 切换距离上:数字越大,越晚切到低模,近处更精细,同屏面数更高。

性能消耗 画面差
中(面数) 中等

没有 LOD 组,改这个没效果。远景物件较多时,数值过大会明显增加顶点处理压力。

建议:如果中低端设备的面数压力已经很高,可以降到 0.4。不要为了远景精细度直接使用 2,除非远景物件很多,并且目标设备仍有足够的顶点处理余量。档位越高,才应该越晚切到低模。

蒙皮权重

Performant Balanced High Fidelity
2 4 255

蒙皮权重是蒙皮网格上每个顶点最多跟几根骨骼。2 根够大多数角色;4 根关节更圆;255 基本是「全开」,给 PC 看的。

性能消耗 画面差
低~中 中等

没有蒙皮角色,无差。关节多的手指、衣摆,2 和 4 能看出圆不圆。

建议:如果角色没有复杂关节,或者中低端设备的蒙皮成本已经吃紧,可以降到 2。移动端不要使用 255。

各向异性

Performant Balanced High Fidelity
Per Texture Full

各向异性过滤是贴图被斜着看时,减少地面、墙壁那种一拉就糊的感觉。关着最便宜;Per Texture 只对开了各向异性的贴图生效;Full 全开最贵。

性能消耗 画面差
低~中 中等

摄像机几乎平视 UI、没有大块地面,关了看不出。

建议:如果镜头里几乎不会斜看地面和墙壁,或者中低端设备已经吃紧,可以关闭各向异性过滤。移动端不要使用 Full。

垂直同步

Performant Balanced High Fidelity

垂直同步让出帧对齐屏幕刷新,能减撕裂,也可能把帧率锁在刷新率上,并在等刷新时把 CPU 堵住。它不管画得好不好,管的是出帧节奏。

性能消耗 画面差
中(等刷新)

手机更适合用 targetFrameRate

建议:如果垂直同步导致 CPU 等待刷新,中低端设备上的影响会更明显,可以在 Quality 里关闭。

Quality 里还有 pixelLightCountshadowsshadowCascades 这些 Built-in 遗留项。URP 下以 Pipeline Asset 为准,改 Quality 的 Shadow Distance,不会改 URP Asset 里的 50。

切档接到工程里

官方是 Quality 每一档指向一份 Pipeline Asset。Graphics 默认管线指向 High Fidelity;Android / iOS 的平台默认档是 Balanced。运行时按设备能力切一次即可:

pseudo 复制代码
function applyGraphicsTier():
    tier = deviceTier.evaluate()
    asset = pipelineAssets.forTier(tier)    // Performant / Balanced / High Fidelity
    qualitySettings.renderPipeline = asset
    log("graphics tier applied", tier)
  • 切换放在加载阶段之前,进场景后再切会画质跳变,阴影和光照还会在中途重新初始化
  • Quality 档位、平台默认档、运行时切档入口必须指向同一套 Asset,一对一。两处引用不一致,档位变了管线没变
  • 关了主光阴影,软阴影、附加光阴影一起关,和官方 Performant 一致

设备怎么评级是后面设备分级篇的事,这里只消费结果。

怎么查看

  • Unity Profiler(CPU / GPU Frame Time、Main Thread / Render Thread):每个开关改动前后各采一组。连线真机本身有开销,趋势可用,绝对值慎用
  • Frame Debugger :确认关掉的阴影、拷贝、后处理、SSAO 对应的 Pass 真的消失了。「参数关了但 Pass 还在」只有这里能直接证实
  • 真机 + Release 包:Editor 只能快速迭代,结论以真机 Release 为准。快速回归用 SoloPi 看帧率 / CPU / 温度,长期用 UPR 分机型沉淀
  • 每次只改一个开关,记 CPU / GPU / 内存。批量改无法归因

建议怎么落地

不要把这篇当成「每个项目都照抄的参数表」。更稳的做法是把它变成一张项目内的 URP 设置评审表,每个开关只回答四个问题:

  1. 这个效果在当前项目里有没有真实使用场景?
  2. 关掉以后,目标场景里的画面差是轻微、中等,还是明显?
  3. 它主要消耗 CPU 提交、GPU fill、带宽、显存,还是 shader 变体?
  4. 它应该保留在哪些设备档位,高端、中端、低端是否一致?

落地顺序建议这样走:

  1. 先以官方 Balanced 作为手机基线,不直接套 High Fidelity,也不要一上来压到 Performant;
  2. 把低端机最贵的项先收掉:实时阴影、SSAO、后处理、HDR、全屏纹理、MSAA;
  3. 对画面差明显的项,比如主光阴影,不要只做开关选择,要准备替代方案:烘焙、Blob Shadow、贴片阴影、低距离实时阴影;
  4. 对画面差轻微的项,比如很多偏平场景里的 SSAO,优先从低端和中端移除,把预算留给更容易被玩家看到的效果;
  5. 每改一项都用 Frame Debugger 确认 Pass 真的少了,再用真机 Release 看帧时间、温度和内存,不要只看 Editor 画面感觉。

最后,把这些结论固化到三份 Pipeline Asset 和 Quality 档位里,而不是靠口头约定。新增效果时也按同一张表过一遍:先说明收益,再说明成本,最后说明哪些设备档位能开。

容易犯的错误

  • 把 High Fidelity 当手机默认:官方把 Android / iOS 的默认档设成 Balanced,Standalone 才是 High Fidelity
  • Quality 和 Pipeline Asset 对不上:官方是一档一份。两处引用不一致,切档会没效果
  • 关了主光阴影,软阴影还开着:官方 Performant 是一起关的。留下去没有画面,只会干扰变体
  • Opaque / Depth Texture 开了没人用:效果砍了开关还在,低配机白扛全屏拷贝。开启前必须明确具体使用者
  • SSAO 当必开项:官方 Balanced 就挂了。没有缝、洞、贴合面,开不开几乎看不出,中低端 fill 却先满
  • 只改 Quality 里的 Shadow Distance / Cascades:URP 不吃这几个 Built-in 项,要改 URP Asset

总结

  1. 移动端 URP 设置的核心不是追最高画质,而是把画质成本按设备档位分配清楚。 手机默认从 Balanced 起步,高端机可以保留更多效果,中低端要主动收掉不稳定、收益低或成本高的项。
  2. 每个开关都要同时看「性能消耗」和「画面差」。 主光阴影关掉会直接少投影,属于明显画面变化;SSAO 只在缝隙、孔洞、交叉面丰富时才容易体现,很多偏平场景里差异很轻。不能只按开关名字判断重要性。
  3. 低端机优先砍全屏和实时项。 HDR、SSAO、后处理、MSAA、Depth/Opaque Texture、实时阴影都会直接打到带宽、fill 或额外 Pass;项目没用到,或者玩家看不出,就不要让低端机长期背这个成本。
  4. 画面差明显的项要准备替代方案,而不是粗暴关闭。 阴影可以用烘焙、Blob Shadow、贴片或短距离实时阴影兜底;后处理可以只保留最关键的一项;HDR 可以只给确实依赖 Bloom/Tonemapping 的档位。
  5. 所有结论都要落到可验证的 Asset 和流程里。 三档 Pipeline Asset、Quality 默认档、运行时切档入口要一一对应;改完用 Frame Debugger 确认 Pass 消失,用真机 Release 看帧时间、温度和内存,Editor 只负责快速迭代。
相关推荐
鼎艺创新科技12 小时前
不依赖 UE/Unity:我们如何从零搭建一套国产三维 GIS 渲染引擎
人工智能·算法·unity·游戏引擎·三维电子沙盘
新手unity自用笔记19 小时前
unity基于Socket的网络学习
网络·网络协议·学习·unity·c#·游戏引擎
心前阳光21 小时前
Unity之XR Interaction Toolkit | IPointerDownHandler问题
unity·游戏引擎·xr
帅_shuai_2 天前
unity 静态字段内存查找工具
unity·游戏引擎
郝学胜-神的一滴2 天前
[简化版 GAMES 104] 现代游戏引擎 06:从Tick时序到邮局模型,拆解确定性世界的底层密码
开发语言·c++·游戏引擎·图形渲染·软件开发·opengl
鹿野素材屋3 天前
Unity超轻量级中文语音播报,仅5兆大小,无需联网即可使用,适用于弹幕、提示等动态语音播出
unity·游戏引擎
电子云与长程纠缠4 天前
UE5 Lyra PocketWorld进行3D内容UI预览 - 上
开发语言·学习·3d·ue5·游戏引擎
玖玥拾4 天前
Unity3D RPG 入门项目(八)游戏设置面板、帧率控制、快捷技能药品栏、技能解锁系统
游戏·3d·unity·游戏引擎
ellis19704 天前
u3d插件xLua[十] lua侧判空问题
unity