美文网首页
静态批处理、动态批处理

静态批处理、动态批处理

作者: 忆中异 | 来源:发表于2022-06-10 18:06 被阅读0次

静态批处理

定义

标明为 Static 的静态物件,如果在使用相同材质球的条件下,在Build(项目打包)的时候Unity会自动地提取这些共享材质的静态模型的Vertex buffer和Index buffer。根据其摆放在场景中的位置等最终状态信息,将这些模型的顶点数据变换到世界空间下,存储在新构建的大Vertex buffer和Index buffer中。并且记录每一个子模型的Index buffer数据在构建的大Index buffer中的起始及结束位置。

在后续的绘制过程中,一次性提交整个合并模型的顶点数据,根据引擎的场景管理系统判断各个子模型的可见性。然后设置一次渲染状态,调用多次Draw call分别绘制每一个子模型。

Static batching并不减少Draw call的数量(但是在编辑器时由于计算方法区别Draw call数量是会显示减少了的),但是由于我们预先把所有的子模型的顶点变换到了世界空间下,所以在运行时cpu不需要再次执行顶点变换操作,节约了少量的计算资源,并且这些子模型共享材质,所以在多次Draw call调用之间并没有渲染状态的切换,渲染API(Command Buffer)会缓存绘制命令,起到了渲染优化的目的 。

在每次调用Draw Call 之前, CPU 需要向GPU 发送很多内容,包括数据、状态和命令等。在这一阶段, CPU 需要完成很多工作,例如检查渲染状态等。而一旦CPU 完成了这些准备工作, GPU 就可以开始本次的渲染。GPU 的渲染能力是很强的,渲染200 个还是2 000 个三角网格通常没有什么区别,因此渲染速度往往快于CPU 提交命令的速度。如果Draw Call 的数量太多, CPU 就会把大量时间花费在提交Draw Call 上,造成CPU 的过载。

但Static batching也会带来一些性能的负面影响。Static batching会导致应用打包之后体积增大,应用运行时所占用的内存体积也会增大。

另外,在很多不同的GameObject引用同一模型的情况下,如果不开启Static batching,GameObject共享的模型会在应用程序包内或者内存中只存在一份,绘制的时候提交模型顶点信息,然后设置每一个GameObjec的材质信息,分别调用渲染API绘制。开启Static batching,在Unity执行Build的时候,场景中所有引用相同模型的GameObject都必须将模型顶点信息复制,并经过计算变化到最终在世界空间中,存储在最终生成的Vertex buffer中。这就导致了打包的体积及运行时内存的占用增大。例如,在茂密的森林级别将树标记为静态会严重影响内存。

无法参与批处理情况

1.改变Renderer.material将会造成一份材质的拷贝,因此会打断批处理,你应该使用Renderer.sharedMaterial来保证材质的共享状态。

相同材质批处理断开情况

1.位置不相邻且中间夹杂着不同材质的其他物体,不会进行同批处理,这种情况比较特殊,涉及到批处理的顺序,我的另一篇文章有详解。
2.拥有lightmap的物体含有额外(隐藏)的材质属性,比如:lightmap的偏移和缩放系数等。所以,拥有lightmap的物体将不会进行同批处理(除非他们指向lightmap的同一部分)。

流程原理

Drawcall_static.jpg

动态批处理

定义

在使用相同材质球的情况下,Unity会在运行时对于正在视野中的符合条件的动态对象在一个Draw call内绘制,所以会降低Draw Calls的数量。

Dynamic batching的原理也很简单,在进行场景绘制之前将所有的共享同一材质的模型的顶点信息变换到世界空间中,然后通过一次Draw call绘制多个模型,达到合批的目的。模型顶点变换的操作是由CPU完成的,所以这会带来一些CPU的性能消耗。并且计算的模型顶点数量不宜太多,否则CPU串行计算耗费的时间太长会造成场景渲染卡顿,所以Dynamic batching只能处理一些小模型。

Dynamic batching在降低Draw call的同时会导致额外的CPU性能消耗,所以仅仅在合批操作的性能消耗小于不合批,Dynamic batching才会有意义。而新一代图形API( Metal、Vulkan)在批次间的消耗降低了很多,所以在这种情况下使用Dynamic batching很可能不能获得性能提升。Dynamic batching相对于Static batching不需要预先复制模型顶点,所以在内存占用和发布的程序体积方面要优于Static batching。但是Dynamic batching会带来一些运行时CPU性能消耗,Static batching在这一点要比Dynamic batching更加高效。

无法参与批处理情况

1.物件Mesh大于等于900个面。
2.代码动态改变材质变量后不算同一个材质,会不参与合批。
3.如果你的着色器使用顶点位置,法线和UV值三种属性,那么你只能批处理300顶点以下的物体;如果你的着色器需要使用顶点位置,法线,UV0,UV1和切向量,那你只能批处理180顶点以下的物体,否则都无法参与合批。
4.改变Renderer.material将会造成一份材质的拷贝,因此会打断批处理,你应该使用Renderer.sharedMaterial来保证材质的共享状态。

批处理中断情况

1.位置不相邻且中间夹杂着不同材质的其他物体,不会进行同批处理,这种情况比较特殊,涉及到批处理的顺序,我的另一篇文章有详解。
2.物体如果都符合条件会优先参与静态批处理,再是GPU Instancing,然后才到动态批处理,假如物体符合前两者,此次批处理都会被打断。
3.GameObject之间如果有镜像变换不能进行合批,例如,"GameObject A with +1 scale and GameObject B with –1 scale cannot be batched together"。
4.拥有lightmap的物体含有额外(隐藏)的材质属性,比如:lightmap的偏移和缩放系数等。所以,拥有lightmap的物体将不会进行批处理(除非他们指向lightmap的同一部分)。
5.使用Multi-pass Shader的物体会禁用Dynamic batching,因为Multi-pass Shader通常会导致一个物体要连续绘制多次,并切换渲染状态。这会打破其跟其他物体进行Dynamic batching的机会。
6.我们知道能够进行合批的前提是多个GameObject共享同一材质,但是对于Shadow casters的渲染是个例外。仅管Shadow casters使用不同的材质,但是只要它们的材质中给Shadow Caster Pass使用的参数是相同的,他们也能够进行Dynamic batching。
7.Unity的Forward Rendering Path中如果一个GameObject接受多个光照会为每一个per-pixel light产生多余的模型提交和绘制,从而附加了多个Pass导致无法合批.

流程原理

image.png

相关文章

  • Unity3d面向英特尔 x86 平台的 Unity* 优化指南

    目录 编辑器优化 压缩纹理 移动存储着色器 静态批处理 动态批处理 HDR – 高动态范围 选择最佳渲染路径 注意...

  • 静态批处理、动态批处理

    静态批处理 定义 标明为 Static 的静态物件,如果在使用相同材质球的条件下,在Build(项目打包)的时候U...

  • 大数据之Storm

    1、批处理与流处理 大数据分类两类:静态数据和动态数据。针对这两类数据的计算模式分别是批处理和流处理。 静态数据:...

  • Unity非UI方面优化

    1.DrawCall优化 1-1:Drall Call Batching (批处理) 静态批处理:场景中所有的静态...

  • 错误整理合集

    静态批处理 取消勾选static Batchingimage.png

  • 动态进行静态批处理优化

    public class Aab : MonoBehaviour {GameObject[] allObjs; }...

  • 静态批处理

    这是我在《Unity游戏优化 (第2版)》看的,记录一下~ Unity也提供了第二种批处理机制:静态批处理 其最大...

  • 动态批处理

    这是我在《Unity游戏优化 (第2版)》看的,记录一下~ 动态批处理可以降低DrawCall,他有啥优势呢?1....

  • 批处理书目录

    批处理典型业务场景 批处理关键领域模型及关键架构 批处理实现作业的健壮性与扩展性 批处理框架的不足与增强

  • start与call的区别

    1.call是从批处理程序调用另一个批处理程序,并且不终止父批处理程序(如果不用call而直接调用别的批处理文件,...

网友评论

      本文标题:静态批处理、动态批处理

      本文链接:https://www.haomeiwen.com/subject/krpbmrtx.html