2011-12-14 8 views
19

私はthis記事を読んでいた、と著者は書いている:OpenGLではプログラムのパフォーマンスが低下しますか?

ここでは、2つの簡単な手順で、すべてのプラットフォーム上で高性能なアプリケーションを作成する方法は次のとおりです。[...]

は、ベストプラクティスに従ってください。 AndroidやOpenGLの場合、これには「バッチ描画呼び出し」、「フラグメントシェーダーで破棄を使用しない」などが含まれます。

このような破棄はパフォーマンスなどに悪影響を及ぼし、詳細なアルファが必要ない場合はブレンドを避けるために使用しています。

なぜ誰かが廃棄物を使用するのが悪い習慣とみなされ、discard + depthtestがalpha + blendと比較される理由を説明できますか?

編集:この質問に対する回答を受け取った後、テクスチャ付きのクワッドを背景グラウンドグラウンドでレンダリングしてテストしました。 GL_DEPTH_TESTとライン "if( gl_FragColor.a < 0.5){ discard; }" で終わるフラグメントシェーダを用い

  • は約32 FPSを与えました。
  • フラグメントシェーダからif/discardステートメントを削除すると、 のレンダリング速度が約44 fpsに増加しました。ブレンド機能付きGL_BLENDを使用
  • "(GL_SRC_ALPHA、 GL_ONE_MINUS_SRC_ALPHA)" は代わりGL_DEPTH_TESTの周りにも44 FPSもたらしました。
+0

非常に興味深い質問ですが、誰かがそれに答えることができれば幸いです。 – bvd

答えて

16

ハードウェアによって異なります。 PowerVRハードウェア、およびタイルベースのレンダリングを使用する他のGPUの場合、discardを使用すると、TBRは描画されたすべてのフラグメントがピクセルになると想定できなくなります。この仮定は、TBRがすべての深さを最初にと評価し、最上位フラグメントのフラグメントシェーダーのみを評価できるため、重要です。ハードウェアを除いて、一種の遅延レンダリング手法。

アルファテストを有効にすると同じ問題が発生することに注意してください。

+1

ああ、そうだ。 廃棄を使用すると、それはすべてのタイル、またはフラグメントが破棄されたタイルにのみ影響しますか? 1つのタイルにしか影響しない場合は、アルファ/ブレンディングを使用するより効率的でなければなりません。 – Jave

+1

「アルファ/ブレンディング」とはどういう意味ですか?いずれにしても、実際に呼び出すかどうかにかかわらず、 'discard'キーワードを使用するフラグメントシェーダを実行するすべてのタイルに影響します。 –

+0

アルファ/ブレンディングとは、現在のフラグメントの可視性を決定するアルファマップ付きのテクスチャを使用することを意味します。私が正しく覚えていれば、GL_BLENDを有効にしてGL_DEPTH_TESTを有効にしないと正しく動作しません(たとえば、別のオブジェクトの前にオブジェクトをレンダリングする場合)? – Jave

17

"discard"はすべてのメインストリームグラフィックアクセラレーション手法(IMR、TBR、TBDR)で悪いです。断片(したがって、深さ)の視認性等早期-ZまたはのPowerVRのHSR(隠面消去)の間だけフラグメント処理後の決定としないので、これはさらに除去に対する効果を示す傾向がある前に何かが取得グラフィックスパイプラインダウンパフォーマンス。この場合、フラグメントの処理+他のポリゴンの深さ処理の中断=悪影響

破棄を使用する必要がある場合は、必要なトリスだけが含まれているシェーダでレンダリングされ、全体的なレンダリングパフォーマンス、不透明、破棄、ブレンドの順序でオブジェクトをレンダリングします。

なお、唯一のPowerVRハードウェアが遅延ステップでの視認性を判断する(したがってそれは「TBDR」と呼ぶだけGPU'S)。他のソリューションはタイルベース(TBR)でも構いませんが、依然としてIMRのように提出順に応じて早期Z技術を使用しています。 TBRとTBDRはチップ内でブレンディングされます(高速で、メインメモリへの電力供給よりも消費電力が少ない)ので、透過性のためにブレンディングが優先されます。ブレンドされたポリゴンを正しくレンダリングするための通常の手順は、ブレンド操作が順序に依存しない場合を除いて、深さの書き込み(テストではなく)を無効にし、トリスを前後の深度順にレンダリングすることです。多くの場合、おおよそのソートは十分です。ジオメトリは、完全に透明な断片の大きな領域を避けるようなものでなければなりません。この方法では、複数のフラグメントがピクセルごとに処理されますが、HWの深さの最適化は破棄されたフラグメントと同様に中断されません。

+0

"フラグメントの可視性(したがって深度)はフラグメント処理後のみであり、Early-ZまたはPowerVRのHSR(隠面除去)などの間では不可能です。それは完全に真実ではありません。 Early-Zまたはdiscardは、フラグメントが描画されないようにすることができます。それで、1つを実行し、次にもう1つを実行することは非常に可能です。あなたと私が述べた理由から、PowerVRはできません。しかし、従来のレンダリングは確かに可能です。そうでない場合は、破棄ロジックが深さテストロジックにバンドルされているためです。これはハードウェア設計の問題であり、アルゴリズム的な必要性ではありません。 –

+0

私は、破棄フラグメントが既存のジオメトリの「背後」にレンダリングされるケースを逃しました:S - それはあなたの意味ですか?初期のZとHSRの両方は、その状況でフラグメント処理を行わずにフラグメントを拒否します。それでも早期Zでは、不明瞭なフラグメントをレンダリングしてから破棄する必要があります。また、破棄シェーダを実行して深みを判断する必要があります。 HSRはこの場合、提出順序に依存しません。フレームの終わりに、破棄されたフラグメントが不透明なフラグメントの後ろにある場合、それらはPowerVRによって処理されません。 – gmaclachlan

+0

フラグメントは、多くの理由でレンダリングに失敗する可能性があります。深さテストは1つ、破棄はもう1つです。 Early-Zは最初に深度テストを実行するだけです。捨てられたロジックがハードウェアの深さテストロジックに結びつけられた場合、捨てる理由はこれを妨害する唯一の理由です。何かが深さテストに合格しただけですべてが合格するというわけではありません。深さと破棄が結合されている場合は、ハードウェアがそうした方法で構築されているだけであり、アルゴリズムによってそのように*されているためではありません。あなたはEarly-Zテストを行うことができ、後でまだ廃棄することができます。 –

1

オブジェクトAはオブジェクトBの前にあります。オブジェクトAには「破棄」を使用するシェーダがあります。このように、オブジェクトBのどのセクションがオブジェクトAを通して見えるかを知る必要があるので、私は「Early-Z」を適切に行うことができません。これは、オブジェクトAが処理パイプラインを通ってほとんど最後までオブジェクトBが実際に見えるかどうかを判断する前に(フラグメント処理が実行されるまで)

これは、潜在的に隠されたオブジェクトが座って、処理される前に奥行き情報が更新されるのを待つため、HSRと 'Early-Z'には悪いことです。上で述べたように、それは誰にとっても悪く、友好的なやり方では「友人は友人がDiscardを使用させません」。

2

また、フラグメントシェーダーに「if」ステートメントがあるだけでは、ハードウェアによっては大幅な減速が発生する可能性があります。 (具体的には、パイプラインが多いGPU、または単一の命令/複数のデータを扱うGPUは、分岐ステートメントから大きなパフォーマンス上の不利益を被ります。)したがって、テスト結果は、if文と他の人が言及した効果の組み合わせかもしれません。

(私のGalaxy Nexusでのテストでは、半透明のオブジェクトを深度ソートし、無作為にレンダリングしてフラグメントを破棄するのではなく、先頭に戻していました)

関連する問題