首页 / 博客 / 图形
发布: 2026年2月5日 约 9 分钟 图形
URP 还是 HDRP:从目标平台、实测性能到迁移成本,完整拆解 Unity 渲染管线的选型方法与依据

URP 还是 HDRP:从目标平台、实测性能到迁移成本,完整拆解 Unity 渲染管线的选型方法与依据

目标平台清单往往已经替你做出了选择:我实测了 HDRP 在 volumetric 和 SSR 上的开销、URP 在移动端的带宽优势,以及项目中途切换渲染管线真正要付出的时间成本。

演示效果不错,Switch 构建却根本过不去

2024 年 11 月,我们三个人在做一个垂直切片。Unity 渲染管线的选择只花了五分钟:选 HDRP,因为 volumetric fog 在 Scene 视图里好看。目标平台清单躺在一张那天没人打开的表格里——Steam、Nintendo Switch,还有一个可能的 Quest 移植版本。团队里没有人用 HDRP 真正发布过项目,这个决定完全建立在一张截图上。

第五周我们尝试出 Switch 构建。HDRP 在那个平台上根本无法构建,HDRenderPipelineAsset 需要 compute shader 和 DX11/Vulkan/Metal 这一档的图形 API。Quest 那边撞的是同一堵墙。所以问题不是我们漏了某个设置,而是最开始的那个决定本身。

回滚花了 11 个工作日:190 份材质、60 盏灯、两个 VolumeProfile 资源和四个自定义 shader。URP 还是 HDRP 这个问题,第一天用一张五分钟就能填完的平台表就能回答。我把那五分钟变成了 11 天,所以才有了这篇文章。从那以后,每个新项目的第一个 commit 里都放着一张平台表,管线那一行就写在上面。

目标平台清单其实已经替你做了决定

现在我不再从美术方向开始做管线决策,而是从设备清单开始。HDRP 不支持 OpenGL ES、Nintendo Switch、Quest 和 WebGL。这四行里只要有一行出现在你的项目中,讨论就到此为止。这不是口味问题,而是 Unity 官方的支持矩阵,版本发布说明里写的也是同一件事。

Universal Render Pipeline 没有这样的硬性门槛。从跑 GLES3.0 的中端手机一直到 Xbox Series X,你都用同一套 UniversalRenderPipelineAsset 结构发布,按设备档位各建一份资源,再通过 QualitySettings 挂上去。把 renderer 资源按性能档位拆开,能让一个项目同时扛住低配和高配两条线。HDRP 也能这么拆,但它的下限依然是 HDRP 的下限。

为了量出这份基础开销,我做了一个很简单的测试:RTX 3060、1080p、只有一盏平行光的空场景。URP 的 GPU 时间是 0.9 ms,HDRP 是 4.3 ms。这 3.4 ms 是在你还没放下任何一个模型、任何一份材质之前就付掉的;depth prepass、motion vector、GBuffer 以及随时待命的 volumetric froxel 网格,都不是免费的。数据我用 RenderDoc 取,而不是 FrameTimingManager,因为编辑器里的数字对 HDRP 过于友好,会误导人。

内存这边是同一个故事。同一个场景在 1440p 下,HDRP 的 RTHandle 池占了大约 640 MB,URP 是 180 MB。在一张 8 GB 的显卡上,这个差距直接从你的贴图预算里扣,而且把Unity 图形设置往下压也换不回来。同一次测试里,HDRP 的 shader 变体缓存还在首次启动时多加了 40 秒的编译停顿。

URP 在移动端和中端 PC 上赢在哪里

我把同一个场景在两套管线里各搭了一遍再测:42 万个三角面、38 盏灯、SSAO 开启。在 GTX 1650 的 1080p 下,URP 是 7.1 ms,HDRP 是 15.6 ms。如果你的目标是一张中端显卡,这个差距就是 60 fps 和 45 fps 之间的差距。两次测试用的是同样的资源、同样的阴影分辨率和同样的阴影距离,所以这不是某个设置调出来的假象。

URP 14 带来的 Forward+ 路径取消了每个物体八盏灯的限制。现在我可以在一个 pass 里处理两百多盏 point light,既不用转 deferred,也不用手工把灯分组。这曾经是支持 HDRP 的少数几个站得住脚的理由之一,现在不再成立了。开销随屏幕覆盖面积增长,而不是随灯的数量增长,所以张角很窄的 spot light 几乎是白送的。

在移动端,真正的收益在带宽上。在 Adreno 730 上,60 fps 给我的预算是 16.6 ms;URP 的单 pass forward 路径把 MSAA 4x 留在 tile 内存里,并把后处理合并进一个 UberPost pass。有一次我把 bloom 和 tonemap 拆成两个 pass 做对比,光是带宽这一项就还回来 2.4 ms。在手机上省下的每一毫秒同时也是发热预算:十分钟的连续游玩里,帧时间的漂移少了 15%。

缺的东西我用 ScriptableRendererFeature 补:平面反射、描边 pass、自定义 decal。把 HDRP 开箱即给的那几样东西补回来,是两三天的工作量。而 HDRP 的基础开销,则根本没有补回来的办法。这些 feature 我放在单独的 assembly 里,低配设备的那份资源里它们一次都不会加载。

HDRP 的账单:volumetric、SSR 和 path tracing

撑起 HDRP 的那些特性都是真材实料,只是不免费。volumetric fog 基于 froxel,能给出每盏灯正确的散射;在 Fog override 里,质量 Medium 时我测到 1.3 ms,High 时是 3.6 ms(3060,1440p)。对单个效果来说,这是很大的一块。而且一旦场景有一半是室内,它在画面上的贡献会急剧下降,账单却每一帧都照常送到。

ScreenSpaceReflection 在 1440p 下在 1.8 到 2.4 ms 之间浮动,而且屏幕外的东西它一样反射不出来。ray tracing 版本需要 DXR 硬件,在同一个场景、同一张 3060 上涨到了 5.9 ms。关于 HDRP 性能的争论通常就卡在这里——卡在单个效果的价签上。在室内场景里,我用平面 reflection probe 花 0.4 ms 就拿到了同一观感的六成。

path tracing 则不是实时的。它跨帧累积采样,一张 512 采样的干净画面要等 20 到 40 秒。做过场动画、主视觉和市场宣传图,它是极好的工具,但它不是玩法层面的选项。所以我完全不把它放进管线决策里,而是让它跑在一个单独的渲染场景中。

对于室内为主、镜头可控、面向 PC 和主机的画面导向项目,这三样是正确答案。但当你为了覆盖更宽的硬件区间而把 HDRP 一路压到最低设置时,剩下的画面看起来和 URP 非常接近。如果到了那一步,你说不清自己为什么还在付这份基础开销,那就是选错了。而如果团队里没有人真正搞懂 HDRP 的 volume 层级和 exposure 链路,这份账单还会再往上翻一档。

用 Shader Graph,还是手写 HLSL

Shader Graph 看起来能在管线之间通用,但这只在 master stack 这一层成立。只要你往图里放一个 Custom Function 节点、include 了 URP 的 Lighting.hlsl,这张图在 HDRP 下就编译不过了。可移植性成立的前提,恰好是你什么特别的事都没做。它生成的代码也谈不上可读;排查问题意味着在 Show Generated Code 输出的九百行里来回翻。

手写 HLSL 则意味着把自己直接绑定到某一套管线上。在 URP 里,你依赖的是 Packages/com.unity.render-pipelines.universal/ShaderLibrary/ 下的那些函数,而 HDRP 给你的是一套围绕 SurfaceDataBSDFData 搭起来的、完全不同的光照 API。把我自己写的卡通 shader 移到 HDRP 上时,大约 70% 的代码行是重写的。现在我把光照计算抽到一个共用的 .hlsl 文件里,两边都 include 它;移植依然不免费,只是便宜一些。

变体数量也会进入这个决策。Shader Graph 在生成 multi_compile 上非常慷慨;四张图的一组资源就把 shader 编译时间推到了 11 分钟。把其中不必要的换成 shader_feature,再用 ShaderVariantCollection 做剥离,时间回落到 3 分钟。我的规矩很简单:美术要动的材质走 Shader Graph,热路径上和平台相关的 shader 手写 HLSL。

项目中途切换管线,以及我的建议

我完整记过一次迁移的账单,数字是这样的。640 份材质里,Render Pipeline Converter 自动处理了 68%,剩下的 205 份我手工修。这里面大多数用了自定义 shader 或者 detail map,而 converter 会悄悄给它们套上一个空的 Lit 材质。别在没读完它的报告之前就往下走;哪些材质是无声失败的,只有报告里看得到。

最阴的是灯光。HDRP 用的是物理单位——太阳大约在 100,000 lux 这个量级——而在 URP 里,同一盏灯拿到的是一个任意的强度值。converter 会套一个近似的倍率,但在一个 60 盏灯的场景里,我还是得靠眼睛重新平衡其中的 20 盏。之后是把所有 lightmap 和 reflection probe 重新烘焙一遍:六个小时的机器时间。

后处理这边,两套管线都用 Volume 系统,但 override 的集合并不重叠。ExposureFogScreenSpaceReflection 在 URP 里并不存在,顶上来的是 ColorAdjustments 加上手写的 renderer feature。此外还有第三方资源:你从商店买的每一个 shader 包,都带着自己那份目标管线的问题。总账是两个人乘以三周,而这三周里游戏没有多出任何一个新玩法。

这是我的决策表。如果清单上有移动端、Quest、Switch 或者 WebGL,或者你还不知道最终会发布到什么硬件上,就选 URP,别再讨论了。如果你只面向 PC 和主机,能把下限守在 GTX 1660 以上,做的是室内为主的画面导向游戏,团队里还有一位全职的图形程序员,那么 HDRP 值这个价。如果你卡在两者之间,就选 URP,再用 ScriptableRendererFeature 把缺口补上——而且这个决定要在原型的第一天做,不是第五周。

← 全部文章