512x512 のテクスチャは、タイリングにもかかわらず iPhone に大きな GPU ストレスを引き起こします
-
22-08-2019 - |
質問
iPhone で単純な OpenGL ES 実装 (2D ゲーム) をテストしています。 レンダリング使用率が高いことに気づきました プロファイラーを使用しているとき。これらは事実です:
- 表示してます プリロードされた大きなテクスチャが 1 つだけ (512×512ピクセル) 60fps で、レンダリング使用率は約 40% です。
- 私のテクスチャは以下を使用してブレンドされています
GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
, 私が使用している唯一のGL関数. - テクスチャ作ってみた 小さくてタイル張り それ、どれ 違いはありませんでした.
- 1024x1024 ピクセルの PNG テクスチャ アトラスを使用しています
これは非常に奇妙だと思います 1 つのテクスチャが非常に激しい GPU 使用率を引き起こしています。
これは期待できることですか? 私の何が間違っているのでしょうか?
編集: 私のコード:
// OpenGL setup is identical to OpenGL ES template
// initState is called to setup
// timer is initialized, drawView is called by the timer
- (void) initState
{
//usual init declarations have been omitted here
glEnable(GL_BLEND);
glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
glEnableClientState (GL_VERTEX_ARRAY);
glVertexPointer (2,GL_FLOAT,sizeof(Vertex),&allVertices[0].x);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer (2,GL_FLOAT,sizeof(Vertex),&allVertices[0].tx);
glEnableClientState (GL_COLOR_ARRAY);
glColorPointer (4,GL_UNSIGNED_BYTE,sizeof(Vertex),&allVertices[0].r);
}
- (void) drawView
{
[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLfloat width = backingWidth /2.f;
GLfloat height = backingHeight/2.f;
glOrthof(-width, width, -height, height, -1.f, 1.f);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
[self checkGLError];
}
編集: いくつか改善を加えましたが、どれもレンダリング使用率を下げることはできませんでした。テクスチャを 32x32 の部分に分割し、座標のタイプとテクスチャ座標を GLfloat から GLshort に変更し、縮退三角形の頂点を追加しました。
更新内容は次のとおりです。
初期状態:(頂点とテクスチャ ポインタは GL_SHORT になりました)
glMatrixMode(GL_TEXTURE);
glScalef(1.f / 1024.f, 1.f / 1024.f, 1.f / 1024.f);
glMatrixMode(GL_MODELVIEW);
glScalef(1.f / 16.f, 1.f/ 16.f, 1.f/ 16.f);
描画ビュー:
glDrawArrays(GL_TRIANGLE_STRIP, 0, 1536); //(16*16 parts * 6 vertices)
解決
512×512は、おそらくiPhoneがに対処するための楽観余りでます。
EDITます:
私はあなたがすでにこれを読んでいると仮定ではなく、場合は、りんごをチェックiPhone上でのOpenGL ESのパフォーマンスを最適にするために導く。に
他のヒント
私はGL_SRC_ALPHA、GL_ONE_MINUS_SRC_ALPHAを使用して、2D環境で互いの上に5つの512x512のテクスチャを表示するアプリを書いている、と私は14fps程度得ることができます。あなたは本当に60fpsのが必要なのでしょうか?ゲームのために、私は24-30は大丈夫だろうと思うだろう。すべての可能であればまた、PVRのテクスチャ圧縮を使用します。それはSDKに含まれない例があります。
- 無効にすることを忘れていないことを願っています
GL_BLEND
まだ必要ないとき。 - 16 bpp 形式または PVRTC を使用して、メモリ帯域幅の最適化を試みることができます。テクスチャサイズのテクスチャキャッシュに関する私見では、まったく役に立ちません。
- フレームバッファが iPhone UI によってテクスチャとして使用されていることを忘れないでください。32 ビット RGBA として作成された場合は、もう一度アルファ ブレンドされます。最適なパフォーマンスを得るには、16 ビット 565 フレームバッファが最適です (ただし、グラフィックスの品質は低下します)。
キャッシュ サイズなどの詳細はすべてわかりませんが、おそらくテクスチャ ピクセルはビデオ メモリにアップロードされたときにすでにスウィズルされており、三角形は PVR タイル エンジンによって分割されていると思われます。したがって、独自の分割は冗長であるように見えます。
そして最後に。これは単なるモバイルの低電力 GPU であり、巨大な画面や高いフィルレート向けに設計されていません。アルファ ブレンディングにはコストがかかり、PowerVR チップではおそらく 3 ~ 4 倍の違いがあります。
正確に問題は何であるか?
あなたは滑らかで絹のようである、あなたの60fpsのを取得している。
誰が気に?
問題は、iPhoneのテクスチャキャッシュサイズのものであってもよいです。それは単にあなたが状態を設定している方法に応じて、個々の三角形、クワッド、またはトリストリップ上でどのくらいのテクスチャーのに降りてくることがあります。
これを試してください:あなたのクワッドを細分化し、テストを繰り返します。ですから、1つのクワッドしている場合、その後16というように、それ4.作り、それが助けかどうかを確認します。キーは、各プリミティブの参照画素の実際の数を減らすことです。
テクスチャキャッシュが溶断を取得したときに、は、ハードウェアは、の各画素のためのテクスチャ・バッファのために確保されているものVRAMにメインメモリからテクスチャルックアップをスラッシュであろう。これは強大な速いパフォーマンスを殺すことができます。
OR - 私は実際にiPhoneのハードウェアを知らないので、私は完全に間違っている、と私はまた、PVRチップは、私が(PS2、PSP)に慣れているものに比べて、奇妙な獣であることを知っています。まだそれは試して簡単にテストだし、それが助け場合、私は興味があります。