混合大型四核的性能受到影响

who*_*ops 9 iphone opengl-es ios

我有一个在视网膜显示器上运行得很好(55-60fps)的游戏.我想添加一个与现有场景融合的全屏叠加层.然而,即使使用小的纹理,性能也很大.我可以进行优化以使其可用吗?

如果我使用80x120纹理(纹理是动态渲染,这就是为什么它不是正方形),我得到25-30FPS.如果我使纹理变小,性能会提高,但质量是不可接受的.但一般来说,叠加的质量不是很重要(它只是照明).

渲染器利用率为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);
Run Code Online (Sandbox Code Playgroud)

这是渲染......

/* 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);
Run Code Online (Sandbox Code Playgroud)

以下是我在尝试缩小问题时采取的一些基准测试.'无混合'意味着在我绘制四边形之前我是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
Run Code Online (Sandbox Code Playgroud)

任何帮助表示赞赏.谢谢!

UPDATE

我没有在之后混合整个光照贴图,而是最终编写了一个着色器来动态地完成工作.每个片段都会从光照贴图中进行采样和混合(类似于多重纹理).起初,性能增益很小,但后来我使用了lowp sampler2d作为光照贴图,然后我得到了大约45FPS.

这是片段着色器:

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;
Run Code Online (Sandbox Code Playgroud)

Jus*_*cle 3

好吧,我认为你已经遇到了硬件的限制。对于基于图块的硬件来说,在整个场景中混合屏幕大小的四边形可能是一个特别糟糕的情况。PowerVR SGX(在 iPhone 上)针对隐藏表面去除进行了优化,以避免在不需要时绘制东西。它具有较低的内存带宽,因为它针对低功耗设备进行了优化。

因此,屏幕大小的混合四边形正在读取然后写入屏幕上的每个片段。哎哟!

加速glClear是相关的 - 因为你告诉 GL 你在渲染之前不关心后备缓冲区的内容,这可以节省将之前的内容加载到内存中的时间。

这里有一个关于 iOS 硬件的很好的概述:http://www.imgtec.com/factsheets/SDK/POWERVR%20SGX.OpenGL%20ES%202.0%20Application%20Development%20Recommendations.1.1f.External.pdf

至于实际的解决方案 - 我会尝试直接在游戏场景上渲染叠加层。

例如,您的渲染循环应如下所示:

[EAGLContext setCurrentContext:context];

// Set up game view port and render the game
InitGameViewPort();
GameRender();

// Change camera to 2d/orthographic, turn off depth write and compare
InitOverlayViewPort()

// Render overlay into same buffer 
OverlayRender()
Run Code Online (Sandbox Code Playgroud)