Estoy escribiendo una aplicación que representa una isla aleatoria plantada con árboles. Los árboles son actualmente dos quads, entrecruzados y dibujados con texturas. Planeo tener mallas más complejas que formen diferentes tipos de plantas, por ejemplo, una palmera, roble, hierbas, etc.
El problema que enfrento es que debido a que las texturas son transparentes, debo dibujarlas de atrás hacia adelante. Plan-b es llamar al uso de descarte en el frag shader, pero el orden z da mejores resultados:
uniform float uTreeAlpha;
uniform sampler2D uTexture;
varying vec2 vTexCoordOut;
void main (void)
{
vec4 colour = texture2D(uTexture, vTexCoordOut);
if (colour.a < 0.1) {
discard;
}
gl_FragColor = vec4(colour.rgb, colour.a * uTreeAlpha);
}
El segundo problema es porque el orden cambia según la cámara y el aspecto. No conozco una forma eficiente de dibujarlos en OpenGL en una sola llamada.
En la actualidad, mi código de representación se parece a este pseudocódigo:
if cameraChangedFromLastTime() then
sortTreesBackToFront();
end
for i = 0 to trees.size() -1
drawTree()
end
Donde cada drawTree () establece algunos uniformes, establece la textura y luego llama a glDrawArrays (). Tengo algunas optimizaciones para omitir la configuración de una textura o actualizar los códigos de textura si el último árbol y la corriente son los mismos, y establecer algunos uniformes comunes fuera del bucle y omitir árboles que están demasiado lejos, pero básicamente si tengo 3000 árboles I ir 3000 veces alrededor del bucle.
Dibujar cada árbol individualmente es el asesino de rendimiento. Si pudiera dibujarlos en una sola llamada, o en lotes (manteniendo el orden Z) probablemente lo haría en 1/10 del tiempo.
Entonces, ¿cómo haría eso? Tenga en cuenta que mis árboles son marcadores de posición y eventualmente tendría:
- Mallas diferentes para diferentes árboles.
- Diferentes escalas y ángulos para que los árboles den más variedad
- Diferentes texturas para diferentes árboles, potencialmente múltiples texturas aplicadas a una malla (por ejemplo, deja una textura, tronco otra)
- Los árboles están todos mezclados, así que no hay una manera simple de dibujar un tipo y luego otro
- Alguna forma de animación cíclica simple (ramas flotando en el viento)
- Todas las texturas residirían en un solo atlas
Entonces, ¿cuál es el mejor enfoque aquí? ¿Es factible renderizar en una sola pasada? Si usara glDrawElements, reconstruyendo los índices pero no los vértices, ¿podría lograr esto?