Ухудшение производительности при смешивании большого четырехугольника

У меня есть игра, которая довольно хорошо работает (55-60 кадров в секунду) на дисплее Retina. Я хочу добавить полноэкранный оверлей, который сочетается с существующая сцена. Однако даже при использовании небольшой текстуры падение производительности огромно. Могу ли я выполнить оптимизацию, чтобы сделать это полезным?

Если я использую текстуру 80x120 (текстура визуализируется на лету, поэтому она не квадратная), я получаю 25-30 кадров в секунду. Если я сделаю текстуру меньше, производительность возрастет, но качество будет неприемлемым. Но в целом качество наложения не очень важно (это просто освещение).

Использование модуля рендеринга составляет 99%.

Даже если я использую квадратную текстуру из файла (.png), производительность будет плохой.

Вот как я создаю текстуру:

    [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);

А вот рендеринг ...

/* 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);

Вот несколько тестов, которые я взял, пытаясь сузить проблему. «Без смешивания» означает, что я отключил glDisable (GL_BLEND) перед тем, как нарисовать четырехугольник. «Без переключения буфера» означает, что я не переключаюсь назад и вперед из закадрового буфера перед рисованием.

(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

Любая помощь приветствуется. Спасибо!

ОБНОВЛЕНИЕ

Вместо того, чтобы впоследствии смешивать всю карту освещения, я закончил тем, что написал шейдер, который будет выполнять работу на лету. Каждый фрагмент сэмплирует и смешивает карту освещения (что-то вроде мультитекстурирования). Сначала прирост производительности был минимальным, но затем я использовал lowp sampler2d для карты освещения, а затем я получил около 45 кадров в секунду.

Вот фрагментный шейдер:

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;
9
задан whooops 22 November 2011 в 04:29
поделиться