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?
fuente
Respuestas:
Lo que quieres es instancias de hardware . Nota: He hecho esto en XNA (es decir, DirectX), pero no sé mucho sobre OpenGL. Sin embargo, estoy seguro de que hay una característica comparable. Básicamente, lo que equivale es unir los vértices de su modelo de árbol con otra secuencia de vértices que transporta coordenadas mundiales para cada instancia.
fuente
La transparencia solo necesita ser ordenada si usa una mezcla no aditiva. Para una tonelada de vallas publicitarias distantes, la combinación es innecesaria (realmente no se puede ver). Procese al menos los otros con transparencia de recorte (alfa de solo 1 o 0) y no necesita ordenarlos.
Puede usar una especie de hoja de sprites para representar diferentes tipos de árboles, con animaciones horneadas. Dibuja mallas para árboles más cercanos que puedas animar con más fidelidad en función de los vientos o lo que quieras.
fuente