Ho un gioco che funziona abbastanza bene (55-60 fps) su un display retina. Desidero aggiungere una sovrapposizione a schermo intero che si fonde con la scena esistente. Tuttavia, anche quando si utilizza una piccola trama, il successo delle prestazioni è enorme. Esiste un'ottimizzazione che posso eseguire per renderlo utilizzabile?Il successo delle prestazioni dalla fusione di quadratini grandi
Se utilizzo una trama 80x120 (la texture è renderizzata al volo, motivo per cui non è quadrata), ottengo 25-30 FPS. Se riduco la trama, le prestazioni aumentano, ma la qualità non è accettabile. In generale, tuttavia, la qualità della sovrapposizione non è molto importante (è solo illuminazione).
L'utilizzo del renderer è del 99%.
Anche se utilizzo una trama quadrata da un file (.png), le prestazioni non sono buone.
Questo è come mi creo la trama:
[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);
E qui è la resa ...
/* 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);
Ecco alcuni punti di riferimento che ho preso quando si cerca di circoscrivere il problema. 'Nessuna mescolanza' significa che non posso (GL_BLEND) prima di disegnare il quad. 'Nessuna commutazione del buffer' significa che non passerò avanti e indietro dal buffer fuori dallo schermo prima di disegnare.
(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
Qualsiasi aiuto è apprezzato. Grazie!
UPDATE
Invece di miscelazione tutta lightmap dopo, ho finito per scrivere uno shader per fare il lavoro al volo. Ogni frammento di campioni e miscele dalla mappa di luce (tipo di multitexturing simile). All'inizio, il guadagno di prestazioni era minimo, ma poi ho usato un sampler2d lowp per la mappa di luce, e poi ho avuto circa 45 FPS.
Ecco lo shader frammento:
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;
Ho il sospetto che il buffer 'glView' gli interruttori sono probabilmente il colpevole qui. Cosa sta succedendo in questi metodi? Perché non usare 'glBindRenderBuffer'? – Justicle
Aggiungerò questi metodi per chiarimenti. – whooops
Ok per debuffare il problema di perf, provate il pre-rendering dell'overlay (lasciatelo solo statico per ora) e poi copiandolo nel buffer principale ogni frame. Almeno questo ti dirà se i buffer switch sono lenti (cioè facendo due chiamate a glBindFrame, glBindRender, glViewport a ogni frame). – Justicle