绘制一个对象到 Screen 上,引擎会对图形 API (如 OpenGL 或 Direct3D)发出一次绘画调用(Draw calls),Draw calls 是昂贵的,每个DrawCall 与图形 API 一起做了大量的工作,导致在 CPU 上的性能开销,这主要是由 DrawCall 之间的状态更改引起的(如切换不同的材质),DrawCall 导致了在图形驱动中昂贵的验证和变换过程。
Unity 使用几点技巧来解决这个问题:
1)Static Batching(静态组合),将静态的对象(如不移动的)合并到一个大的 Meshes,更快速渲染。
2)Dynamic Batching(动态组合),对于足够小的 Meshes,在 CPU 上做一些顶点变换,将相似的网格体分组到一起,然后一起绘制。
内置的 Batching 相对于手动合并物体到一起有几点好处,最显著的是被合并的物体仍然能够单独的被剔除,但它也有一些弊端,静态合并(static batching)会导致一些内存和存储开销,而动态合并(dynamic batching)会导致一些 CPU 开销。
Batching 的材质设置:
只有共享相同材质的对象才能被合并到一起。因此,如果你想实现不错的 Batching,你必须在不同的物体间共享尽可能多的材质。
如果你有两个完全一样的 Materials,只是纹理贴图不一样,你可以合并那些纹理贴图到一个更大的贴图上(通常称为纹理图集,texture atlas)。一旦纹理在同一个图集,你就可以使用单个 Material 替代。
如果你需要从脚本访问共享 Material 的属性,重点注意的是 修改 Renderer.material 将会创建一个 Material 的复制。相反,你应该用 Renderer.sharedMaterial 保持 Material 共享。
当渲染阴影投射(shadow caster)的时候,即使是 Materials 不同也会经常合并到一起。Unity 中的阴影投射甚至能用不同的 Material 进行动态合并,只要阴影通道中所需的材质属性是相同的。例如许多箱子可以使用不同的纹理材质,但对于渲染纹理阴影投射(shadow caster)是不相关的,在这种情况下可以使用批处理(Batching)。
Dynamic Batching(动态批处理):
Unity 能将那些共享相同 Material 和履行其他标准的物体自动合并动态到同一个DrawCall,动态合并(Dynamic Batching)是自动完成的并且不会要求一些附加的工作量。
- 合并动态物体对每个顶点具有一定的开销,所以合并只仅仅用于包含 共少于 900 个顶点属性的 Mesh 。
如果你的 Shader 用于顶点位置、法线和单个 UV ,你可以合并到最多 300 个网格所有顶点,反之,如果你的 Shader 用于顶点位置、法线、UV0、UV1和正切函数,你可以合并到最多 180 个网格所有顶点。
注意:属性数量的限制有可能在未来被改变。
- 如果物体在变换时包含镜像,将不会变换。例如放大1倍的物体A 与缩小1倍的物体 B不能合并到一起。
- 使用不同的 Materail 实例,即使它们本质上是相同的,也不能合并到一起,除非是阴影投射渲染(shadow caster rendering)。
- 物体带有光照贴图(lightmaps)的附加渲染属性:光照贴图指数和光照贴图的偏移/大小(offset/scale),所以一般动态烘焙的对象应该指向完全相同的光照贴图的位置进行批处理(Batching)。
几乎所有的 Unity Shaders 都支持几个灯光的正向渲染,有效地为他们做更多的 Pass 处理,附加像素光照(additional per-pixel lights)中的 DrawCalls 将 不会被 Batching。
延迟渲染(Legacy Deferred)的光照模式(light pre-pass)渲染路径已被动态 Batching 禁止,因为它会对物体绘制两次。
从它在CPU 变换所有对象的顶点到世界坐标上,对于一个 DrawCall 绘制来说只是一个小的胜利,究竟一个 DrawCall 有多昂贵取决于很多因素,主要在图形 API 的使用上,例如,在控制台或者现代 API 如 Apple 的 Metal 上,绘制开销通常低的多,经常的 Dynamic Batching 并不能起多大作用。
Static Batching(静态批处理):
静态 Batching 允许引擎为任何尺寸的几何体(只要不是移动的且共享材质)减少 DrawCall ,它比动态 Batching 更高效,它不会在 CPU 上进行顶点变换,但会耗费更多的内存。
为了是静态 Batching 更加高效,你必须明确指定确定的游戏对象是 Static ,并且将不会在游戏中进行移动、旋转和缩放变换。因此你可以在Inspector面板勾选Static标记。
使用静态 Batching 需要附加的内存存储合并的几何体。如果几个游戏对象在 Static Batching 之前共享相同的几何体,那么在 Editor 或者 运行时,将会为每个对象创建一个几何体的复制。这将不总是一个很好的办法,有时你为了通过避免 Static Batching 来牺牲渲染性能保持较小的内存空间占用。例如,在茂密树林关卡中使用静态树木会对内存有严重的影响。
在内部,静态 Batching 的工作原理是把静态对象变换到世界空间,然后为它们建立一个大的顶点索引缓冲区( vertex + index buffer)。 对于在同一个Batch中的 可见物体,一系列廉价的 DrawCall 将被完成,它们之间几乎没有任何状态改变。所以严格说它不会节省“3D API 绘制调用(DrawCall)”,但它节省了它们之间状态变换所做的更改(这是极其昂贵的)。
其他 Batching 相关提示
目前,只有网格渲染(Mesh Renderers)将会被 Batched。这意味着蒙皮网格(Skinned Meshes)、布料模拟(Cloth)、路径渲染(Trail Renders)和其他类型的渲染组件不会被 Batched。
半透明材质(Semitransparent shaders)经常要求对象按照透明度从后向前的次序进行渲染,Unity 按此顺序获取第一个命令对象,然后尝试 Batch 它们。但因为该顺序是严格遵守的,这意味着更少的 Batching 比不透明的对象更容易实现。
手动合并相临近的游戏对象对于 DrawCall Batching 来说是很好的选择,例如,将带有很多细节的静态抽屉合并到一个 Mesh 是有意义的,无论是在 3D 模型应用中还是使用 Mesh.CombineMeshes。
分享到:
相关推荐
本教程将聚焦于DrawCall优化,这是提高Unity3D应用性能的关键一环。 DrawCall,即渲染调用,是GPU执行渲染命令的次数。当场景中有大量独立的绘制对象时,DrawCall的数量会显著增加。每个DrawCall都会引起GPU切换...
《Unity中的Draw Call优化策略详解》 在3D游戏开发中,Unity引擎因其易用性和高效性被广泛应用。然而,随着场景复杂度的增加,Draw Call(绘制调用)的数量也会急剧上升,这可能导致性能瓶颈,影响游戏运行效率。...
Pro draw call is an editor extension that will easily reduce your draw calls by creating atlases for your models so they can share materials for static/dynamic batching. Custom shaders?, no worries, ...
在Unity引擎中,Draw Call是渲染过程中的一个重要概念,它代表了GPU执行的一次完整绘制操作,包括设置材质、纹理、顶点数据等。当场景中的物体过多或者过于分散时,大量的Draw Call会导致渲染效率降低,影响游戏性能...
谷歌官方发布视频
文件名:Draw Call Optimizer - Just One Click v2.7.2.unitypackage Draw Call Optimizer - Just One Click 是一款为 Unity 开发的插件,旨在帮助开发者优化游戏中的 Draw Call 数量,从而提高游戏的渲染性能,...
资源来自pypi官网。 资源全名:pyams_batching-1.0.1-py3.6.egg
tensorflow 一些关于图像处理的实现 tsq:卷积、池化 LeNet5_mnist:LeNet-5网络处理mnist分类...DataProcess:batching:输入数据处理框架 Dataset:dataset:tf中Dataset的使用\ Dataset:dataset_example:使用Datas
3. 静态批处理(Static Batching):Unity 的静态批处理技术可以将多个物体的顶点坐标合并成一个整体,从而减少 DrawCall 的次数。 4. 动态批处理(Dynamic Batching):Unity 的动态批处理技术可以自动合并送往 GPU...
1. **Draw Call Batching**:SpriteManager 可以自动或手动将精灵分组,使得同一组内的精灵能在同一Draw Call中绘制,减少渲染开销。 2. **动态批处理**:即使在运行时添加或移除精灵,插件也能自动调整批处理,保持...
通过使用Material Batch(材质批处理)或Sprite Atlas(精灵图集),可以将多个使用相同材质的UI元素合并成一个Draw Call,从而降低Draw Call数量。在`UGUI_BatchDemo`中,你可以看到如何设置和使用这些技术。 2. *...
在移动平台上,过多的DrawCall会直接影响性能,因此必须降低DrawCall的数量。 - SetPassCall是DrawCall的一个子集,涉及到材质和着色器的切换。每次材质或着色器改变时,都会产生一个新的SetPassCall。为了优化性能...
1. **减少Draw Call**:Draw Call是Unity渲染过程中调用显卡绘制每个物体的命令。过多的Draw Call会导致性能下降。可以通过合并精灵(Sprite Atlas)和使用同一材质来减少Draw Call。对于ScrollView中的元素,尽量...
当多个物体使用不同的材质或纹理时,Unity会为每个不同的组合创建一个drawcall,这会导致大量的drawcalls,尤其是在场景复杂、物体众多的情况下。 **降低Drawcalls的方法:** 1. **合并材质(Material合并)**:...
Draw Call是CPU的瓶颈之一,因为它涉及大量数据准备和设置。当场景中的每个物体都有独特的材质和着色器时,CPU需要频繁地切换这些设置,导致大量Draw Calls。减少Draw Call的方法包括: 1. **批处理**:通过将具有...
DataProcess:batching:输入数据处理框架 Dataset:dataset:tf中Dataset的使用\ Dataset:dataset_example:使用Dataset的完整例子 LeNet5_mnist_keras:利用keras的API编写LeNet5网络来做mnist的分类,可与文件夹...
4. **优化Draw Call**: Unity的Batching技术可以进一步合并相似的渲染对象,减少Draw Call数量。当多个角色使用相同的动画和材质时,它们可能被批处理为一次绘制操作,这极大地提高了渲染效率。 5. **实现细节差异...
Unity提供了两种批处理技术来优化DrawCall:静态批处理(Static Batching)和动态批处理(Dynamic Batching)。 静态批处理适用于场景中的静态游戏对象,如建筑或环境模型。当游戏对象被标记为静态后,Unity会自动...
2. Draw Call batching:通过合并相似材质的物体,减少渲染调用次数。 3. 资源管理:避免不必要的内存分配,及时释放不再使用的资源。 四、脚本优化 1. 减少不必要的Update函数调用:只在必要的时候更新组件。 2....