Resumen: obtengo la desaceleración de FPS tan pronto como trato de teñir los sprites (es decir: multiplico la textura con el color en el sombreador de fragmentos)
Detalles:
Hardware: iPod touch 4
Estoy dibujando 700 sprites en la pantalla usando glDrawArrays. Y sí, estoy agrupando todo esto en una sola llamada de sorteo. A continuación se muestra la estructura de datos de Vertex:
struct Vertex {
float Position[2];
float Color[4];
float Texture[2];
};
Sí, estoy enviando color con cada vértice porque selectivamente necesito teñir algunos sprites pero no otros. El siguiente es el fragment shader que estoy usando:
varying lowp vec2 TexCoord;
uniform sampler2D TextureSampler;
void main(void)
{
gl_FragColor = texture2D( TextureSampler, TexCoord );
}
¡Hasta ahora está funcionando GENIAL, dándome 60 FPS completos!
PERO
Tan pronto como cambie el sombreador de fragmentos a lo siguiente (para permitir el tinte):
varying lowp vec4 DestinationColor;
varying lowp vec2 TexCoord;
uniform sampler2D TextureSampler;
void main(void)
{
gl_FragColor = texture2D( TextureSampler, TexCoord ) * DestinationColor;
}
Usando la siguiente textura png de 64x64 que contiene un canal alfa, renderizado con glEnable (GL_BLEND):
El rendimiento cae a 47 FPS solo debido a este cambio único {simplemente por multiplicación con UN vector} (FPS medido usando instrumentos xcode y detective OpenGL). Alguna idea de lo que está pasando ?
Gracias.
Editar:
También he intentado eliminar por atributo de color de vértice:
struct Vertex {
float Position[2];
float Texture[2];
};
Y modificando el sombreador de fragmentos de la siguiente manera:
precision lowp float;
varying lowp vec2 TexCoord;
uniform sampler2D TextureSampler;
void main(void)
{
gl_FragColor = texture2D( TextureSampler, TexCoord ) * vec4(1.0,0.0,0.0,1.0);
}
Está funcionando a 52 FPS para 700 sprites (una ganancia de solo 5 FPS). Entonces esto no es interpolación, parece que la multiplicación es extremadamente costosa. ¿Solo esta UNA multiplicación?
Respuestas:
No creo que el problema de rendimiento esté sucediendo en la multiplicación, sino en la interpolación de
DestinationColor
los triángulos, entre los sombreadores de vértices y fragmentos. Tienes cuatrofloat
s para interpolar entre los vértices de los árboles, para cada fragmento para cada sprite.Para 700 sprites de 64x64 píxeles cada uno, esto es 11468800 operaciones adicionales por fotograma que le está pidiendo a la GPU que realice. Es muy posible que te falten algunos vsyncs y, por lo tanto, caigas a 40 FPS.
Si quieres que cada vértice tenga un color diferente, para que puedas tener gradientes para cada sprite, no tienes suerte. También hay otros trucos que quizás quieras probar, pero creo que este no es el caso.
Dado que lo que parece estar haciendo es teñir cada sprite, puede degradarlo
DestinationColor
a auniform
, usarlo directamente en el sombreador de fragmentos y cambiarlo para cada llamada. De esa manera no se realizarán interpolaciones. Perderá el lote completo, pero es posible que pueda procesar un poco si los ordena por color.fuente