Tengo un juego que funciona bastante bien (55-60 fps) en una pantalla de retina. Quiero agregar una superposición de pantalla completa que combine con la escena existente. Sin embargo, incluso cuando se usa una textura pequeña, el impacto en el rendimiento es enorme. ¿Hay alguna optimización que pueda realizar para que esto sea utilizable?Golpe de rendimiento de la mezcla de quad grande
Si uso una textura de 80x120 (la textura se representa sobre la marcha, por lo que no es cuadrada), obtengo 25-30FPS. Si reduzco la textura, el rendimiento aumenta, pero la calidad no es aceptable. En general, sin embargo, la calidad de la superposición no es muy importante (solo es iluminación).
La utilización de Renderer es al 99%.
Incluso si uso una textura cuadrada de un archivo (.png), el rendimiento es malo.
Éste es cómo crear la textura:
[EAGLContext setCurrentContext:context];
// Create default framebuffer object.
glGenFramebuffers(1, &lightFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, lightFramebuffer);
// Create color render buffer and allocate backing store.
glGenRenderbuffers(1, &lightRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, lightRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, LIGHT_WIDTH, LIGHT_HEIGHT);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, lightRenderbuffer);
glGenTextures(1, &lightImage);
glBindTexture(GL_TEXTURE_2D, lightImage);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, LIGHT_WIDTH, LIGHT_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, lightImage, 0);
Y aquí es la prestación ...
/* Draw scene... */
glBlendFunc(GL_ONE, GL_ONE);
//Switch to offscreen texture buffer
glBindFramebuffer(GL_FRAMEBUFFER, lightFramebuffer);
glBindRenderbuffer(GL_RENDERBUFFER, lightRenderbuffer);
glViewport(0, 0, LIGHT_WIDTH, LIGHT_HEIGHT);
glClearColor(ambientLight, ambientLight, ambientLight, ambientLight);
glClear(GL_COLOR_BUFFER_BIT);
/* Draw lights to texture... */
//Switch back to main frame buffer
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
glViewport(0, 0, framebufferWidth, framebufferHeight);
glBlendFunc(GL_DST_COLOR, GL_ZERO);
glBindTexture(GL_TEXTURE_2D, glview.lightImage);
/* Set up drawing... */
glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, 0);
Éstos son algunos puntos de referencia que tomé cuando se trata de reducir el problema. 'Sin mezcla' significa I glDisable (GL_BLEND) antes de dibujar el quad. "Sin conmutación de almacenamiento intermedio" significa que no cambio hacia atrás y hacia adelante desde el almacenamiento intermedio fuera de la pantalla antes de dibujar.
(Tests using a static 256x256 .png)
No blend, No buffer switching: 52FPS
Yes blend, No buffer switching: 29FPS //disabled the glClear, which would artificially speed up the rendering
No blend, Yes buffer switching: 29FPS
Yes blend, Yes buffer switching: 27FPS
Yes buffer switching, No drawing: 46FPS
Cualquier ayuda es apreciada. ¡Gracias!
ACTUALIZACIÓN
En lugar de mezclar todo el mapa de luz después, terminé escribiendo un sombreado para hacer el trabajo sobre la marcha. Cada fragmento de muestras y mezclas de la lightmap (tipo de multitextura). Al principio, la ganancia de rendimiento fue mínima, pero luego usé un muestreador lowp2d para el mapa de luces, y luego obtuve alrededor de 45FPS.
Aquí está el fragment shader:
lowp vec4 texColor = texture2D(tex, texCoordsVarying);
lowp vec4 lightColor = texture2D(lightMap, worldPosVarying);
lightColor.rgb *= lightColor.a;
lightColor.a = 1.0;
gl_FragColor = texColor * color * lightColor;
Sospecho que el búfer 'glView' los interruptores son probablemente el culpable aquí. ¿Qué está pasando en esos métodos? ¿Por qué no usar 'glBindRenderBuffer'? – Justicle
Inventaré esos métodos para aclararlos. – whooops
Ok para debuf el problema de perf, intente pre-renderizar la superposición (simplemente déjelo estático por ahora), y luego copie eso en el buffer principal de cada cuadro. Eso al menos le dirá si los interruptores de la memoria intermedia son lentos (es decir, hacer dos llamadas a glBindFrame, glBindRender, glViewport cada fotograma). – Justicle