Estoy haciendo un tipo de juego estilizado de baja poli. Tengo un terreno con un poco de agua y quiero muchos árboles; Tengo 10.000 árboles colocados en masa, por el momento. Cada árbol consta de no más de 200 triángulos, por lo que no son demasiado exigentes.
El principal problema es que hay lagos, y los lagos son bastante grandes. En realidad, no puedes ver ningún árbol al otro lado del lago, y eso se ve muy mal, especialmente cuando caminas allí y de repente aparecen árboles.
Para solucionar esto, tengo que aumentar la distancia del árbol para que puedas ver una cantidad decente de árboles al otro lado del lago, pero eso reduce el rendimiento a 40-50 fps, y todavía no hay casi nada más en el juego. Estoy usando una GTX 1080, si eso ayuda.
¿Qué puedo hacer para que mi juego funcione más rápido con más árboles?
fuente
Respuestas:
Hay un par de cosas que puede hacer para aumentar el rendimiento del dibujo.
Dijiste que estaban bastante lejos. Podría usar LOD para disminuir el conteo de vértices de esos árboles, y así disminuir el tiempo requerido para atravesar todos los vértices que se están dibujando. Aunque es muy probable que este no sea el problema en cuestión (GTX1080 con solo 10k árboles con 200 tris cada uno, números insignificantes para el gpu), todavía lo incluí. La valla publicitaria es una herramienta eficaz para el nivel más bajo de LOD, ya que es esencialmente un plano plano que siempre mira hacia la cámara con una imagen renderizada del árbol. Pierde la sensación de profundidad, por lo que es bueno para el nivel más bajo, ya que el jugador probablemente no notará la diferencia.
¿Ha habilitado el procesamiento por lotes ? El procesamiento por lotes dinámico generalmente se realiza automáticamente si el recuento de vértices de las mallas es bastante bajo. El procesamiento por lotes estático también se puede probar haciendo que los árboles estén estáticos marcando la casilla de verificación en el editor de la unidad en el objeto del juego principal. Esto no funciona bien con objetos animados. Necesita que los objetos tengan material compartido para que esto funcione.
El procesamiento por lotes personalizado le permite controlar el renderizado generando los fragmentos usted mismo en lugar de dejar que Unity lo maneje, y también permite el procesamiento por lotes para mallas más grandes. Esto se hace fácilmente por Mesh.CombineMeshes . Esto tampoco funciona bien con objetos animados. Necesita que los objetos tengan material compartido para que esto funcione. Probablemente quieras dividir tu mundo en algún tipo de trozos y crear lotes a partir de ellos. La forma en que deberían generarse esos fragmentos depende realmente de cómo se mueve su cámara en el mundo.
Habilite la creación de instancias en los sombreadores. La instancia permite que el motor dibuje múltiples objetos (con la misma malla) con solo una llamada de dibujo. Necesita que los objetos tengan malla compartida y sombreador compartido para que esto funcione. El material puede variar, pero el sombreador debe admitir todas las diferentes propiedades variables.
Para hacer que el motor cree mejores lotes de renderizado instanciado, probablemente desee agrupar las mismas mallas en la escena. También jugar con la cola de renderizado de material le dará buenos resultados si una malla tiene siempre el mismo material. Durante el desarrollo del juego móvil en el que estoy trabajando actualmente, utilicé esto para reducir las llamadas a más de la mitad en mi escena de prueba. Además, desde Unity 5.6, asegúrese de marcar la
Enable Instancing
casilla de verificación en el material.Mantenga sus llamadas y sus llamadas SetPass bajas en general. Estas son las llamadas crudas para que su GPU dibuje cosas, y tienen una gran sobrecarga. La reducción de las llamadas de extracción (que es lo que está haciendo el procesamiento por lotes y la creación de instancias) aumentará el rendimiento general que puede proporcionar su CPU, ya que es necesario que espere mucho menos. Las llamadas SetPass son cambios en sus sombreadores actuales, por lo que si tiene muchos materiales diferentes, tendrá varias llamadas SetPass, lo que también hará que la CPU espere un poco.
Si su escena es enorme y su tiempo de CPU pasa para revisar todos los objetos de la escena, intente reducir los objetos en la escena. Agrupe algunos árboles en lugar de colocarlos invidualmente y téngalos como un solo objeto. También asegúrese de no mover los árboles o los objetos principales, ya que eso hace que Unity descarte las transformaciones almacenadas en caché y recalcule todo el árbol de la escena.
Si su escena es enorme y su tiempo de CPU todavía se dedica principalmente a Unity caminando por el árbol de la escena para hacer listas para renderizar todos los objetos, una cosa que podría hacer es no permitir que Unity se encargue del renderizado. Si tiene una mejor manera de rastrear objetos dibujables, puede usar CommandBuffer.DrawMeshInstanced o Graphics.DrawMeshInstanced para dibujarlos a mano. No voy a entrar en muchos detalles sobre esto, ya que es mucho más avanzado e implica sacrificio obedece a ti mismo y todo lo demás.
En caso de que el procesamiento por lotes estático o dinámico no funcione correctamente (lo que puede ver al verificar el depurador de trama), debe asegurarse de que está utilizando material compartido y no está haciendo copias del material por accidente con la llamada
meshRenderer.material
. Llamar al.material
hará copias de sus materiales y dividirá el procesamiento por lotes. Usar en su.sharedMaterial
lugar.Desde Unity 5.6 puede usar el Depurador de tramas para determinar por qué ciertas llamadas no se combinaron con las llamadas anteriores. Esto será realmente útil al tratar de reducir las llamadas de su juego.
La instancia tiene las siguientes ventajas sobre el procesamiento por lotes estático / dinámico / personalizado:
Además, como inconveniente, es una característica bastante nueva en Unity y puede ser un poco inestable. Además, las GPU de dispositivos móviles o anteriores no son necesariamente compatibles con la creación de instancias.
fuente
Ok, entonces el problema era simplemente que no estaba usando GI precomputado en tiempo real. Lo comprobé hace un momento, pero no tuvo un efecto inmediato, así que lo dejé y lo olvidé, y el tiempo de procesamiento de la iluminación también fue muy largo. Sin embargo, acaba de terminar de procesarlo, y mi palabra, mi fps ha aumentado 3 veces. ¡Así que por ahora, lo dejaré así y en el futuro me aseguraré de usar siempre GI en tiempo real de precomputadora!
Si todavía hay algo más que podría estar haciendo para mejorar aún más el rendimiento, hágamelo saber, ¡estaría muy agradecido!
fuente