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)
好吧,我认为你已经遇到了硬件的限制。对于基于图块的硬件来说,在整个场景中混合屏幕大小的四边形可能是一个特别糟糕的情况。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)
| 归档时间: |
|
| 查看次数: |
1488 次 |
| 最近记录: |