Unity URP/SRP 渲染管线浅入深出

SRP/URP/HDRP之间的关系

下图是各个管线的关系图

image

根据上图所示,URP是Unity可编程渲染管线(SRP)的一种,所以了解URP之前需要先了解SRP是什么。(在文章最下面,额外内容里附了张渲染管线流程图)

SRP是什么?

SRP全称为Scriptable Render Pipeline(可编程渲染管线/脚本化渲染管线),是Unity提供的新渲染系统,可以在Unity通过C#脚本调用一系列API配置和执行渲染命令的方式来实现渲染流程,SRP将这些命令传递给Unity底层图形体系结构,然后再将指令发送给图形API。

说白了就是我们可以用SRP的API来创建自定义的渲染管线,可用来调整渲染流程或修改或增加功能。

它主要把渲染管线拆分成二层:

  • 一层是比较底层的渲染API层,像OpenGL,D3D等相关的都封装起来。

  • 另一层是渲染管线上层,上层代码使用C#来编写。在C#这层不需要关注底层在不同平台上渲染API的差别,也不需要关注具体如何做一个Draw Call

URP是什么?

它的全称为Universal Render Pipeline(通用渲染管线), 它是Unity官方基于SRP提供的模板,它的前身是LWRP(Lightweight RP即轻量级渲染管线), 在2019.3开始改名为URP,它涵盖了范围广泛的不同平台,是针对跨平台开发而构建的,性能比内置管线要好,另外可以进行自定义,实现不同风格的渲染,通用渲染管线未来将成为在Unity中进行渲染的基础 。

平台范围:可以在Unity当前支持的任何平台上使用

HDRP是什么?

它的全称为High Definition Render Pipeline(高清晰度渲染管线),它也是Unity官方基于SRP提供的模板,它更多是针对高端设备,如游戏主机和高端台式机,它更关注于真实感图形和渲染,该管线仅于以下平台兼容:

  • Windows和Windows Store,带有DirectX 11或DirectX 12和Shader Model 5.0
  • 现代游戏机(Sony PS4和Microsoft Xbox One)
  • 使用金属图形的MacOS(最低版本10.13)
  • 具有Vulkan的Linux和Windows平台
  • 在此文章对HDRP不过多描述。

2. 为什么诞生SRP?

内置渲染管线的缺陷

  • 定制性差:过去,Unity有一套内置渲染管线,渲染管线全部写在引擎的源码里。大家基本上不能改动,除非是买了Unity源码客户,当然大部分开发者是不会去改源码,所以过去的管线对开发者来说,很难进行定制。

  • 代码脓肿,效果效率无法做到最佳:内置渲染管线在一个渲染管线里面支持所有的二十多个平台,包括非常高端的PC平台,也包括非常低端的平台,很老的手机也要支持,所以代码越来越浓肿,很难做到使效率和效果做到最佳。
    目的:

  • 为了解决仅有一个默认渲染管线,造成的可配置型、可发现性、灵活性等问题。决定在C++端保留一个非常小的渲染内核,让C#端可以通过API暴露出更多的选择性,也就是说,Unity会提供一系列的C# API以及内置渲染管线的C#实现;这样一来,一方面可以保证C++端的代码都能严格通过各种白盒测试,另一方面C#端代码就可以在实际项目中调整。


    image.png

在看URP 和 内置渲染管线 性能对比之前最好先了解DrawCall,Batches,SetPassCalls分别是什么值。

DrawCall,Batches,SetPass calls文章:https://blog.csdn.net/qq_30259857/article/details/110062397

3. URP 和 内置渲染管线 性能对比

主要提速的有两个方面

  1. 光照处理(包括阴影)

  2. SRP Bacher (SRP 批处理)(重点)

其他可以看看官网图,下面是官网的对比表链接和图。

https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@8.2/manual/universalrp-builtin-feature-comparison.html

image.png

1. 首先来说说光照处理部分

image.png

如上图所示,老的渲染管线使用Multi-Pass的Forward Rendering,就是多Pass的正向渲染。最大的问题是如果要在场景里要加很多动态光的话,每一个动态光都有可能会增加一个Pass,这个动态光所影响的物体要多画一遍。

这就导致如果游戏里想要有多个动态光的话,可能这个场景会被画很多遍,性能会很差。它带来的问题是所有的游戏几乎都不会用多个动态光,因为实在太费性能了。

在过去制作移动的游戏的过程中,大家的标准做法都是烘焙Lightmap。

现在URP就解决了这个问题。实现了一个单PASS的正向渲染。可以支持多盏动态光,但是全部动态灯光都会放在一个Pass里渲染,这样带来的问题是要限制灯光的数量,因为每次Draw Call去画的时候,传给GPU的参数是有限的。

如果灯光数量特别多,参数太多,那就会无法在一次Draw Call里完成很多个灯光。所以我们有一些限制,在轻量级渲染管线LWRP里,目前是支持1盏平行光,每个对象可能只能接受4个动态光。每个摄像机也有一些限制,这是为了我们可以把所有的计算放在一个Pass里面。

接下来看看内置渲染管线和URP各种情况下的光照处理实验对比

以下是分别在四种情况下对比所得出的结论

1.无光源。 (没区别)
2.一个平行光,无阴影。(没区别)
3.一个平行光,一个点光源,无阴影。
结论:内置渲染管线跟只有一个平行光时比起来Batches将近增加了一倍,而URP的Batches和SetPass calls跟一个平行光时一样,一点都没有增加。
4.一个动态光,有阴影。
结论:在阴影的处理方面URP性能比内置渲染管线好很多。

URP光照处理最终结论:

1. 性能上阴影处理方面比内置渲染管线好很多。
2. URP平行光基础上添加动态光没有带来额外的Batches和SetPass calls性能开销。
  1. 性能上阴影处理方面比内置渲染管线好很多。

  2. URP平行光基础上添加动态光没有带来额外的Batches和SetPass calls性能开销。

下面有图有真相

1. 无光源情况下的对比

内置渲染管线:

image.png

URP:

image.png

结论:Batches,SetPass Calls 基本是一样的,没区别。

2. 一个平行光,无阴影下的对比

内置渲染管线:

image.png

URP:

image.png

结论:Batches,SetPass Calls 基本是一样的,没区别。

3. 一个平行光,一个点光源,无阴影下的对比

内置渲染管线:

image.png

URP:

image.png

结论:可以发现内置渲染管线的Batches将近增加了一倍,而URP的Batches和SetPass calls跟一个平行光时一样,一点都没有增加。

4. 一个平行光,有阴影下的对比

内置渲染管线:

image.png

URP:

image.png

结论:内置渲染管线处理阴影面数增加了45k,Batches增加了759,URP面数增加了11K,Batches增加了188。处理阴影性能上URP好很多。

2. 接下来看看SRP Batcher(重点)

SRP Batcher 是什么?

官网解释:SRP Batcher 是一个底层渲染循环,可通过许多使用同一着色器变体的材质来加快场景中的 CPU 渲染速度。

个人解释:就算是不同的材质球,只要是用一个着色器变体的物体都可以批处理到一块。(在2019.3.4版本 渲染顺序也会打断批处理,这点上官网没有说明,也许后续版本已经处理了),它的主要目的是减少渲染状态设置的开销,还有就是把物体属性用专用代码快速更新。

上面解释都提到了变体,那么变体怎么理解呢?

multi_compile和shader_feature这两个关键字就是实现着色器变体的指令。

下面是自定义的multi_compile 关键字。


image.png

上图中定义了两个multi_complie,white和black两个关键字,此时Unity会生成两个变体,一个是走white逻辑的变体,另外一个是走black逻辑的变体。然后在脚本中通过Material.EnableKeyWord和Shader.EnableKeyword来开启某功能,通过Material.DisableKeyword和Shader.DisableKeyword来关闭某功能。为什么这么做呢?主要是为了避免分支语句(if )导致的性能下降。

除了关键字还有这些


image.png

参数不一致的话也无法批处理到一块。

shader_feature关键字跟multi_compile不一样的是未被选择的变体会在打包的时候被舍弃(multi_complie不会),shader_feature主要是在材质球选项上控制开关,比如
image.png

这个选项。

URP的Lit Shader里有很多实现变体指令,所以这些Shader生成的变体也有很多。如图:


image.png

主要参考来自以下文章:

多版本shader的编写-multi_compile和shader_feature:https://zhuanlan.zhihu.com/p/190233160?utm_source=wechat_session
https://docs.unity.cn/cn/2019.3/Manual/SRPBatcher.html
https://connect.unity.com/p/srp-batcher-jia-su-xuan-ran

过去,Unity 中,可以在一帧内的任何时间修改任何材质的属性。但是,这种做法有一些缺点。当Draw Calls使用新材质时,需要进行很多处理。场景内的材质越多,设置GPU数据所需的CPU资源就越多。解决此问题的传统方法是减少 DrawCall 的数量以优化 CPU 渲染成本,因为 Unity 在发出 DrawCall 之前必须进行很多设置。实际的 CPU 成本来自该设置,而不是来自 GPU DrawCall 本身(DrawCall 只是 Unity 需要推送到 GPU 命令缓冲区的少量字节)。

这是官网说的提速效果:

Unity 2018引入了可编程渲染管线SRP,其中包含新的底层渲染循环SRP Batcher批处理器,它可以大幅提高CPU在渲染时的处理速度,根据场景内容的不同,提升效果为原来的1.2~4倍不等。

SRP Batcher是怎么优化的?

SRP Batcher使材质数据持久保留在 GPU 内存中。如果材质内容不变,SRP Batcher 不需要设置缓冲区并将缓冲区上传到 GPU。还有 SRP Batcher 会使用专用的代码路径来快速更新大型 GPU 缓冲区中的 Unity 引擎属性,如下图。

image.png

上面的功能能解决什么问题呢?也就是CPU不需要再设置渲染状态和一大堆渲染数据设置,只需要物体跟缓冲区的数据绑定就可以了。

SRP Batcher 正是通过批处理一系列 Bind 和 Draw GPU 命令来减少 DrawCall 之间的 GPU 设置。

内置渲染管线和URP的CPU原理图对比:

image.png

内置渲染管线:(红框部分就是SRP Batcher优化的性能部分)

image.png

URP:

在把材质数据和物体数据上传好后的流程图:(GPU没有详细画,主要看CPU)


image.png

上面流程图中绑定的意思是大家都知道Shader里有很多变量,如纹理贴图,Property定义的变量以及内置变量等,个人理解是把缓冲区里存的渲染数据设置给了Shader变量。

再看看OpenGL API调用情况

内置渲染管线

image.png

URP

image.png

可以发现内置渲染管线有 glUniform4fv API,这是设置一大堆着色器数据的函数,也是耗时的部分,而在URP取而代之的是Bind接口,省去了设置着色器数据的开销。

根据上面内容我们可以知道SRP Batcher并没有减少DrawCall,而是优化了DrawCall之前的设置开销。

SRP Batch值我们可以在Frame Debug窗口可以看得到。


image.png

Statistics窗口上的SetPass calls值,其实就是SRP Batch数量 加上 未能批处理的DrawCall数量。

在下图中可以看到SRP Batch批处理了 189个 DrawCalls.


image.png

image.png

SRP Batcher 兼容性

为了使 SRP Batcher 代码路径能够渲染对象:

  • 渲染的对象必须是mesh或者skinned mesh。该对象不能是粒子。

  • 着色器必须与 SRP Batcher 兼容。HDRP 和 URP 中的所有光照和无光照着色器均符合此要求(这些着色器的“粒子”版本除外)。
    为了使着色器与 SRP Batcher 兼容:

  • 必须在一个名为“UnityPerDraw”的 CBUFFER 中声明所有内置引擎属性。例如:unity_ObjectToWorld 或 unity_SHAr。

  • 必须在一个名为 UnityPerMaterial 的 CBUFFER 中声明所有材质属性。


    image.png

Property定义的属性也是属于PerMaterial.


image.png

可以在 Inspector 面板中查看着色器的兼容性状态。


image.png

可以在 Inspector 面板中检查特定着色器的兼容性。

在看看时间对比

内置渲染管线(未开启任何合批)

image.png

内置渲染管线(开启静态批处理)

image.png

URP未开启SRP Batcfh

image.png

URP环境下(开启SRP Batcher)

image.png

3. URP的增加功能

主要有以下功能

  1. 渲染管线扩展/自定义渲染器

  2. 摄像机堆叠 (待更新)

  3. Shader Graphic(Shader图形编程)(待更新)

1.渲染管线扩展/自定义渲染器(待补充)

官网案例Github地址:https://github.com/Unity-Technologies/UniversalRenderingExamples

以下是官网案例效果(最后一个是自己实现)

1. 第一人称对象

此Demo主要演示的是摄像机堆叠功能,摄像机堆叠功能下面会单独专门讲。


image.png

2. 卡通描边

展示一种创建卡通样式轮廓效果的设置,示例中有两种方法,一种是后处理方法,另一种是船体网格方法。一个示例使用自定义RendererFeature,并且都使用自定义着色器


image.png

image.png

此Demo有两个渲染器

我们来看看第二个渲染器


image.png

主要的卡通描边效果就是在上图中的 Sobel Outlines (Blit)实现,

3. 对象遮挡

当一个对象被另一个对象遮挡时,可以创建效果。

如下图所示,一个角色被建筑挡住时用指定的材质效果来显示角色被遮挡的部分。


image.png

以下是自己实现的扩展功能

4. 模糊清晰混合

此效果是在模糊的基础上把某层的物体清晰显示的效果。


image.png

渲染器列表

HDR(High Dynamic Range Imaging):高动态范围成像,

Anti Aliasing(MSAA):抗锯齿

参考文章:
Unity轻量级渲染管线LWRP源码及案例解析 - 上:https://connect.unity.com/p/unityqing-liang-ji-xuan-ran-guan-xian-lwrpyuan-ma-ji-an-li-jie-xi-shang

Unity轻量级渲染管线LWRP源码及案例解析 - 下:https://connect.unity.com/p/unityqing-liang-ji-xuan-ran-guan-xian-lwrpyuan-ma-ji-an-li-jie-xi-xia

SRP Batcher:加速渲染:https://connect.unity.com/p/srp-batcher-jia-su-xuan-ran

URP扩展案例 Github地址: https://github.com/Unity-Technologies/UniversalRenderingExamples

Unite Now - (中文字幕)使用URP提升游戏画面效果:https://www.bilibili.com/video/BV1fK4y1a78s

关于静态批处理/动态批处理/GPU Instancing /SRP Batcher的详细剖析:https://zhuanlan.zhihu.com/p/165574008

关于静态批处理/动态批处理/GPU Instancing /SRP Batcher的详细剖析:https://zhuanlan.zhihu.com/p/98642798

Batch, Draw Call, Setpass Call:https://zhuanlan.zhihu.com/p/76562300

Unity3D优化技巧系列(一):Draw Call优化:https://gameinstitute.qq.com/community/detail/113025

Unity ConstantBuffer的一些解析和注意:https://zhuanlan.zhihu.com/p/137455866

额外内容

渲染流水线图:

image.png

转载于:https://blog.csdn.net/qq_30259857/article/details/108318528

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,230评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,261评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,089评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,542评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,542评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,544评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,922评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,578评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,816评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,576评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,658评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,359评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,920评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,859评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,381评论 2 342

推荐阅读更多精彩内容