Para dibujar un objeto en la pantalla, el motor tiene que emitir un draw call (llamado de dibujo) al API de gráficas (e.g. OpenGL o Direct3D). Los Draw Calls a menudo son costosos, con el API de gráficas haciendo un trabajo significante para cada draw call, causando una sobrecarga en el rendimiento por el lado del CPU. Esto en su mayoría es causado por los cambios de estado hechos entre los draw calls (e.g. cambiando a un material diferente), que causa pasos de validación costosos y de translación en el driver gráfico.
Unity utiliza varias técnicas para abordar esto:
El procesamiento por batching (lotes) integrado ofrece varios beneficios en comparación con la fusión manual de GameObjects; lo más notable, los GameObjects todavía se pueden seleccionar de forma individual. Sin embargo, también tiene algunas desventajas; el procesamiento por lotes estático genera una sobrecarga de memoria y almacenamiento, y el dynamic batching (procesamiento de lotes dinámicos) genera cierta sobrecarga de la CPU.
Solamente los objetos compartiendo el mismo material pueden ser batched juntos. Por lo tanto, si usted quiere lograr un buen batching, usted necesita compartir muchos materiales entre diferentes objetos como sea posible.
Si usted tiene dos materiales idénticos que difieren solo en texturas, usted puede combinar esas texturas a una sola gran textura - un proceso llamado texture atlasing. Una vez las texturas estén en el mismo atlas, usted puede utilizar un solo material más bien.
Si usted necesitar acceder las propiedades compartidas del material desde los scripts, entonces es importante tener en cuenta que modificar Renderer.material va a crear una copia del material. En vez, usted debería utilizar Renderer.sharedMaterial para mantener el material compartido.
Mientras renderice shadow caster (emisores de sombras), estos a menudo pueden ser batched juntos incluso si su materiales son diferentes. Los shadow caster en Unity pueden utilizar dynamic batching incluso con diferentes materiales, con tal de que los valores en los materiales necesitados por el shadow pass sean el mismo. Por ejemplo, muchas cajas pueden utilizar materiales con diferentes texturas, pero para un renderizado de shadow caster las texturas no son relevantes – en este caso estos pueden ser batched juntos.
Unity puede automáticamente batch objetos en movimiento al mismo draw call si ellos comparten el mismo material y cumplen con los otros criterios. El batching dinámico es hecho automáticamente y no requiere un esfuerzo adicional por su lado.
Dynamic batching works by transforming all GameObject vertices into world space on the CPU, so 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.
For components with geometry that Unity generates dynamically, dynamic batching works differently compared to how it works for Meshes.
When measuring the cost of the Graphics Device calls, the slowest part of rendering a Component is the set-up of the Material state. Submitting draw calls at different offsets into a shared Vertex Buffer is very fast by comparison.
This approach is very similar to how Unity submits draw calls when using Static batching.
El Static batching le permite al motor reducir los draw calls por geometría de cualquier tamaño (teniendo en cuenta que no se mueva y comparta el mismo material). A menudo es más eficiente que dynamic batching (no transforma vértices en el CPU), pero utiliza más memoria.
Con el fin de tomar ventaja del static batching, usted necesita especificar que ciertos objetos son estáticos y no se moverán, girarán, ni escalar en el juego. Para hacer esto, usted puede marcar los objetos como estáticos utilizando la casilla de verificación Static en el Inspector:
Utilizar el batching estático va a requerir una memoria adicional para almacenar la geometría combinada. Si varios objetos comparten la misma geometría antes del batching estático, entonces una copia de la geometría será creada para cada objeto, ya sea en el Editor, o en el tiempo de ejecución. Esto no siempre será una buena idea - a veces usted va a tener que sacrificar el rendimiento de renderización evitando el batching estático para algunos objetos para mantener una huella pequeña de memoria. Por ejemplo, marcando árboles como estáticos en un nivel denso de bosque puede tener serios impactos de memoria.
Internally, static batching works by transforming the static GameObjects into world space and building one shared vertex and index buffer for them. If you have enabled Optimized Mesh Data (in the Player settings) then Unity removes any vertex elements that are not being used by any shader variant when building the vertex buffer. There are some special keyword checks to perform this; for example, if Unity does not detect the LIGHTMAP_ON keyword, it removes lightmap UVs from a batch. Then, for visible GameObjects in the same batch, Unity performs a series of simple draw calls, with almost no state changes in between each one. Technically, Unity does not save API draw calls, but instead saves on state changes between them (which is the resource-intensive part). Batch limits are 64k vertices and 64k indices on most platforms (48k indices on OpenGLES, 32k indices on macOS).
Recomendaciones:
Actualmente, solo los Mesh Renderers, Trail Renderers, Line Renderers, Particle Systems y Sprite Renderers están agrupados. Esto significa que skinned Meshes, Cloth (tela) y otros tipos de componentes de renderización no son agrupados.
Los Renderers solo hacen un batch (lote) con otros Renderers del mismo tipo.
Sombreadores semitransparentes en su mayoría requieren que lo objetos sean renderizados en un orden de atrás para adelante para que la transparencia funcione. Unity primero ordena los objetos en este orden, y luego intenta batchlos - pero ya que el orden debe ser estrictamente satisfecho, esto en su mayoría significa que menos batching puede lograrse con objetos opacos.
Combinar los objetos que están cerca manualmente puede ser una buena alternativa para draw call batching. Por ejemplo, un armario con muchos cajones puede tener sentido en solo combinarlo a un solo mesh, ya sea en una aplicación de modelado 3D o utilizando Mesh.CombineMeshes.
2017–10–26 Page amended with limited editorial review
Added note on dynamic batching being incompatible with graphics jobs in 2017.2