私は、網膜ディスプレイ上で非常によく走るゲーム(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);
そして、ここでは、レンダリングです...ここで
/* 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)を意味します。 'No buffer switching'は、描画する前にオフスクリーンバッファから前後に切り替わらないことを意味します。
(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
助けていただければ幸いです。ありがとう!代わりに、その後全体のライトマップをブレンドする
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;
私は 'glView'バッファを疑いますスイッチがおそらくここでの犯人です。これらの方法では何が起こっていますか? 'glBindRenderBuffer'を使わないのはなぜですか? – Justicle
私はこれらの方法をインラインで説明します。 – whooops
これでperf問題を解決するには、オーバーレイをプリレンダリングしてください(ちょうど今は静的にしておきます)、それをフレームごとにメインバッファにコピーしてみてください。それは、バッファスイッチが遅いかどうかを少なくとも教えてくれます(つまり、フレームごとにglBindFrame、glBindRender、glViewportを2回呼び出す)。 – Justicle