URP | Unity图形优化
什么影响渲染性能
URP性能优化,主要是3个一个是Batches 和 Saved by Batching ,在加一个SetPass calls 渲染状态的次数

Batches
渲染场景需要多少个批次(也就是需要渲染多少次)
Set Pass calls
设置渲染状态的次数。
所以优化效果,需要考虑这俩方面都很重要
unity为我们提供了哪些方法?


静态批处理
批处理条件
标记为 Batching Static 的物体
在使用相同材质的条件下
可以理解
打包的时候Unity会自动将这些物体合并到一个大Mesh里
(程序提取这些共享材质的静态模型的顶点和索引数据放到一个共享的Vertex buffer 和 Index Buffer里)
设置开启
标记为Batching Static物体,

注意: 不可以移动物体,比如场景物体设置这个模式,
标记后物体运动时不能移动,旋转,缩放。
如果有子物体,会提示字物体是否改成一样的。

优点
提高渲染效率
并不减少Draw call ,减少了渲染状态设置。
但是编辑器会显示Batches 减少
没优化前

优化结果

缺点
打包后体积增大
运行时内存占用增大
多个不同的GameObject 引用同一个Mesh的情况下:
不开启Static batching Mesh会在应用程序,内存里存在一份,绘制的时候提交模型顶点信息,然后设置每一个GameObjec材质信息,分别调用渲染API绘制
开启Static batching unity 执行编译的时候,场景中所有引用相同模型的GameObject都必须将模型顶点信息复制,并且计算变化到一个大模型。
包体和内存占用都增大。

动态批处理
Unity 在运行时对符合条件的动态对象在一个Draw call内绘制渲染,降低Draw Call数量。
基本条件
不超过300个顶点(不超过总计900个属性)
Shader使用顶点位置,法线,UV可以包含300个顶点(三个属性就只能是300个顶点)
Shader使用顶点位置,法线,UV0,UV1,切线,则只能包含180个顶点 (五个属性就只能是180个顶点)
不包含镜像的Scale缩放
比如物体A Scale 为1 , 物体B Scale 为 -1
材质一样
物体的loghtmap指向的位置一样

开启动态合批
在URP管线里开启动态合批

问题:消耗CPU
动态批处理原理
运行时,在进行场景绘制前,Cpu上将所有的共享同一材质的模型,顶点信息变换到世界空间下。
然后通过一次Draw call绘制多个模型,达到合批的目的。
缺点
动态合批在降低Draw call的同时会导致额外的CPU性能消耗,所以仅仅合批操作的性能消耗小于不合批,
动态合批才有意义。
动态合批相当于静态合批不需要预先复制模型顶点,所以在内存占用和包体方面优于静态合批。
注意:如果包体大内存占用多,使用动态合批,CPU压力大,使用静态合批。
合批中断情况
因为动态合批要求高,所以在使用过程可能出现合批中断问题。
物体如果都符合条件优先参与静态批处理,再是GPU Instancing ,然后才是动态合批
如果使用多Pass Shader的物体会禁用 动态合批(Dynamic batching)
多个物体必须都是同一个材质,但是对于Shadow casters 的渲染是一个列外。
尽管Shadow casters使用不同材质,但是只要他们的材质中给Shadow Caster Pass 使用参数是相同的,
他们也能够进行 动态合批。
在Unity中使用前向渲染(Forward Rendering Path) 中如果 一个模型接受多个光照,也不能进行合批。
因为多个光照多次绘制。(URP中多光源是一次绘制)


GPU Instancin (GPU实例化)
GPU Instancin 是什么?
使用少量diaw call 绘制多个相同的Mesh。
比如场景中的建筑,树,草,石头等。
如何开启
Unity 默认Shader 在材质下方勾选,就可以开启。

自定义Shader 如何使用GPU Instancing
参考 : https://docs.unity3d.com/Manual/GPUInstancing.html
GPU Instancin原理
同材质,同Mesh的物体,
仅绘制一个
其他物体”复制“出来,(其他物体储存的顶点位置信息和顶点变化的数值,复制出来)
GPU Instancin限制
同模型同材质才能合并到一个Draw call中
支持MeshRenderer和Graphics.DrawMesh调用
不支持(SjinnedMerhRenderer)带骨骼动画的模型。
GPU Instancin无法合批的情况
缩放为负值的情况
代码动态改变材质变量后不算同一个材质,但可以通过将颜色变化等变量加入常量缓冲器中实现。
受限于常量缓冲器在不同设备上的大小的上限,同批的个数可能不同。
只支持一盏实时光,要在多个光源的情况下使用实例化,只能切换到延迟渲染路径。

SRP Batcher
SRP Batcher 是一个渲染循环,可加速相同着色器变体的多种材质在场景中的CPU渲染速度。
原理
Shader中的变体一致
降低Set Pass Call的消耗
SRP Batcher 通过批处理(batching)—— 系列绑定(Bind)和绘制(Draw)GPU 命令,来减少DrawCalls之间的GPU 设置(工作量)

设置
首先在Pipeline Asset(渲染管线中)里勾选SRP Batcher。

在下方勾选SRP Batcher

Shader 支持
在Shader界面我们可以看到是否支持这个效果,才会起作用。

效果
在渲染输出里查看支持情况,

优点
支持模型带骨骼动画
SRP Batcher 无法合批情况
对象不可以是粒子
Shader中变体不一致,如Suface Options不一致,导致变体不一致而无法合并
一个不透明物体,一个是透明物体

位置不相邻且中间夹杂着不同Shader或者不同变体的其他物体,不会进行同批次处理。

总结
优先顺序
SRP Batcher > Static Batching > GPU Instancing > Dynamic Batching
优先使用SRP Batcher > 静态合批 > GPU Instancing > 动态合批

资料
【直播回放】Unity 批处理/GPU Instancing/SRP Batcher_哔哩哔哩_bilibili
Unity SRP Batcher的工作原理_zakerhero的博客-CSDN博客
Unity 性能优化 之 非常酷的SRP Batcher!_zakerhero的博客-CSDN博客