Unity Draw call batching 动态合并(2017.2.0版本Unity)

Draw call batching动态合并

To draw a GameObject on the screen, the engine has to issue a draw call to the graphics API (such as OpenGL or Direct3D). Draw calls are often resource-intensive, with the graphics API doing significant work for every draw call, causing performance overhead on the CPU side. This is mostly caused by the state changes done between the draw calls (such as switching to a different Material), which causes resource-intensive validation and translation steps in the graphics driver.

为了在屏幕上绘制一个游戏对象,引擎必须向图形API(比如OpenGL或Direct3D)发出一个绘制调用。绘制调用通常是资源密集型的,图形API在每次绘制调用时都做了大量工作,从而导致CPU方面的性能开销。这主要是由于在绘制调用(例如切换到不同的材料)之间进行的状态更改造成的,这会导致图形驱动程序中的资源密集型验证和转换步骤。


Unity uses two techniques to address this:

Unity使用了两种技术来解决这一问题:

  • Dynamic batching: for small enough Meshes, this transforms their vertices on the CPU, groups many similar vertices together, and draws them all in one go.
  • 动态批处理:对于足够小的网格,这将在CPU上转换它们的顶点,将多个类似的顶点组合在一起,并一次性将它们全部绘制出来。
  • Static batching: combines static (not moving) GameObjects into big Meshes, and renders them in a faster way.
  • 静态批处理:将静态(不移动)游戏对象合并为大网格,并以更快的方式呈现它们。

Built-in batching has several benefits compared to manually merging GameObjects together; most notably, GameObjects can still be culled individually. However, it also has some downsides; static batching incurs memory and storage overhead, and dynamic batching incurs some CPU overhead.

与手动合并游戏对象相比,内置的批处理有几个优点;最值得注意的是,游戏对象仍然可以单独进行挑选。然而,它也有一些缺点;静态批处理会导致内存和存储开销,动态批处理会产生一些CPU开销。

Material set-up for batching批处理的材质设置

Only GameObjects sharing the same Material can be batched together. Therefore, if you want to achieve good batching, you should aim to share Materials among as many different GameObjects as possible.

只有共享相同材料的游戏对象才能被批量处理。因此,如果你想要获得好的批处理,你应该尽量在尽可能多的不同的游戏对象之间共享材料。

If you have two identical Materials which differ only in Texture, you can combine those Textures into a single big Texture. This process is often called Texture atlasing (see the Wikipedia page on Texture atlases for more information). Once Textures are in the same atlas, you can use a single Material instead.

如果你有两种完全不同的材质,你可以把这些材质组合成一个单一的大纹理。这个过程通常被称为纹理地图集(请参阅维基百科页面上的纹理地图集,以获得更多信息)。一旦纹理在同一地图集中,你就可以使用单一材质。


If you need to access shared Material properties from the scripts, then it is important to note that modifying Renderer.material creates a copy of the Material. Instead, use Renderer.sharedMaterial to keep Materials shared.

如果您需要从脚本中访问共享的材料属性,那么注意修改渲染器是很重要的。材料创造了一份材料。相反,使用渲染器。分享材料以保持材料的共享。



Shadow casters can often be batched together while rendering, even if their Materials are different. Shadow casters in Unity can use dynamic batching even with different Materials, as long as the values in the Materials needed by the shadow pass are the same. For example, many crates could use Materials with different Textures on them, but for the shadow caster rendering the textures are not relevant, so in this case they can be batched together.

在渲染的时候,即使他们的材质不同,也可以在渲染的时候把它们组合在一起。即使有不同的材料,在统一的阴影下的施法者也可以使用动态的批处理,只要影子传送所需要的材料的值是相同的。例如,许多板条箱可以使用不同材质的材料,但对于阴影施法者来说,纹理是不相关的,所以在这种情况下,它们可以被一起使用。

Dynamic batching 动态批处理合并

Unity can automatically batch moving GameObjects into the same draw call if they share the same Material and fulfill other criteria. Dynamic batching is done automatically and does not require any additional effort on your side.

如果它们共享相同的材料并满足其他标准,Unity可以自动地将移动的游戏对象批量地放入相同的绘制调用中。动态批处理是自动完成的,不需要任何额外的工作。

  • Batching dynamic GameObjects has certain overhead per vertex, so batching is applied only to Meshes containing fewer than 900 vertex attributes in total.
    批处理动态配子具有一定的每个顶点的开销,所以批处理只适用于包含少于900个顶点属性的网格。
    • If your Shader is using Vertex Position, Normal and single UV, then you can batch up to 300 verts, while if your Shader is using Vertex Position, Normal, UV0, UV1 and Tangent, then only 180 verts.
    • 如果你的Shader使用的是顶点位置,正常的和单一的UV,那么你可以批量处理300个顶点,而如果你的Shader使用的是顶点位置,法线,UV0,UV1和正切,那么只有180个顶点。
    • Note: attribute count limit might be changed in future.
    • 注意:属性计数限制可能会在将来改变。
  • GameObjects are not batched if they contain mirroring on the transform (for example GameObject A with +1 scale and GameObject B with –1 scale cannot be batched together).
  • 如果在转换中包含镜像的话,游戏对象就不会被批处理(例如,带有+1比例的游戏对象A和带有1比例的游戏对象B不能被组合在一起)。
  • Using different Material instances causes GameObjects not to batch together, even if they are essentially the same. The exception is shadow caster rendering.
  • 使用不同的材质实例,即使它们本质上是相同的,也会导致配子不能一起批量处理。唯一的例外是阴影施法者的渲染。
  • GameObjects with lightmaps have additional renderer parameters: lightmap index and offset/scale into the lightmap. Generally, dynamic lightmapped GameObjects should point to exactly the same lightmap location to be batched.
  • 带有lightmaps的游戏对象具有额外的渲染参数:lightmap索引和offset/scale到lightmap中。一般来说,动态的light映射游戏对象应该指向相同的lightmap位置,以进行批处理。
  • Multi-pass Shaders break batching.
    多路着色器取消合并。
    • Almost all Unity Shaders support several Lights in forward rendering, effectively doing additional passes for them. The draw calls for “additional per-pixel lights” are not batched.
    • 几乎所有的Unity着色器都支持向前渲染的几盏灯,有效地为它们做额外的传球。对于“额外的像素点”的呼吁并没有被批处理。
    • The Legacy Deferred (light pre-pass) rendering path has dynamic batching disabled, because it has to draw GameObjects twice.
    • 遗留延迟(轻型预传递)呈现路径具有动态批处理能力,因为它必须两次绘制game对象。

Because it works by transforming all GameObject vertices into world space on the CPU, it is only an advantage if that work is smaller than doing a draw call. The resource requirements of a draw call depends on many factors, primarily the graphics API used. For example, on consoles or modern APIs like Apple Metal, the draw call overhead is generally much lower, and often dynamic batching cannot be an advantage at all.

因为它的工作原理是将所有的游戏对象的顶点转换成CPU上的世界空间,如果这项工作比做一个绘制调用要小,那就是一个优势。一个绘制调用的资源需求取决于许多因素,主要是使用的图形API。例如,在控制台或像Apple Metal这样的现代api上,绘制调用的开销通常要低得多,而且经常动态的批处理根本就不是一个优势。

Static batching 静态合并

Static batching allows the engine to reduce draw calls for geometry of any size provided it shares the same material, and does not move. It is often more efficient than dynamic batching (it does not transform vertices on the CPU), but it uses more memory.

静态批处理允许引擎减少对任何尺寸的几何图形的调用,只要它有相同的材料,并且不动。它通常比动态批处理更有效(它不会在CPU上转换顶点),但是它使用更多的内存。

In order to take advantage of static batching, you need to explicitly specify that certain GameObjects are static and do not move, rotate or scale in the game. To do so, mark GameObjects as static using the Static checkbox in the Inspector:

静态批处理允许引擎减少对任何尺寸的几何图形的调用,只要它有相同的材料,并且不动。它通常比动态批处理更有效(它不会在CPU上转换顶点),但是它使用更多的内存。

Using static batching requires additional memory for storing the combined geometry. If several GameObjects shared the same geometry before static batching, then a copy of geometry is created for each GameObject, either in the Editor or at runtime. This might not always be a good idea; sometimes you have to sacrifice rendering performance by avoiding static batching for some GameObjects to keep a smaller memory footprint. For example, marking trees as static in a dense forest level can have serious memory impact.

使用静态批处理需要额外的内存来存储组合的几何图形。如果几个游戏对象在静态批处理之前共享相同的几何图形,那么为每个游戏对象创建一个几何图形,无论是在编辑器中还是在运行时。这可能不是一个好主意;有时,为了保持较小的内存占用,需要牺牲一些游戏对象的静态批处理来牺牲呈现性能。例如,在茂密的森林中标记树木是静态的,可能会产生严重的内存影响。

Internally, static batching works by transforming the static GameObjects into world space and building a big vertex and index buffer for them. Then, for visible GameObjects in the same batch, a series of simple draw calls are done, with almost no state changes in between. Technically it does not save 3D API draw calls, but it saves on state changes between them (which is the resource-intensive part). Batches are limited to 64k vertices and 64k indices on most platforms (48k indices on OpenGLES, 32k indices on macOS).

在内部,静态批处理工作通过将静态游戏对象转换为世界空间,并为它们构建一个大的顶点和索引缓冲区。然后,对于同一批中可见的game对象,就完成了一系列简单的绘制调用,其中几乎没有任何状态更改。从技术上讲,它并没有保存3D API绘制调用,但是它节省了它们之间的状态变化(这是资源密集型的部分)。在大多数平台上,批次被限制为64k的顶点和64k的索引(在macOS上有48k的索引和32k的索引)。

Tips

Currently, only Mesh Renderers, Trail Renderers, Line Renderers, Particle Systems and Sprite Renderers are batched. This means that skinned Meshes, Cloth, and other types of rendering components are not batched.

目前,只有网格渲染器、跟踪渲染器、线渲染器、粒子系统和精灵渲染器被批处理。这意味着皮肤的网格、布和其他类型的呈现组件不会被批量处理。

Renderers only ever batch with other Renderers of the same type.

渲染器只对同一类型的其他渲染器进行批处理。

Semi-transparent Shaders usually require GameObjects to be rendered in back-to-front order for transparency to work. Unity first orders GameObjects in this order, and then tries to batch them, but because the order must be strictly satisfied, this often means less batching can be achieved than with opaque GameObjects.

半透明的着色器通常要求以反序的顺序呈现游戏对象,以使透明度工作。Unity首先在这个顺序下订单游戏对象,然后尝试对它们进行批处理,但是由于订单必须得到严格的满足,这通常意味着可以实现比不透明的游戏对象更少的批处理。

Manually combining GameObjects that are close to each other can be a very good alternative to draw call batching. For example, a static cupboard with lots of drawers often makes sense to just combine into a single Mesh, either in a 3D modeling application or using Mesh.CombineMeshes.

手动组合那些彼此靠近的游戏对象可以是一个很好的选择,可以用来绘制调用批处理。例如,一个有很多抽屉的静态橱柜通常是有意义的,可以将其组合成一个单一的网格,无论是在三维建模应用程序中,还是使用mesh.组合emeshes。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值