「モダン」環境では、「NVオクルージョンクエリ」拡張機能により、深度テストに合格したフラグメントの数を取得する方法が提供されます。ただし、OpenGL ESを使用するiPad / iPhoneでは、拡張機能は利用できません。
フラグメントシェーダーで同様の動作を実装するための最もパフォーマンスの高いアプローチは何ですか?
私のアイデアのいくつか:
オブジェクトを完全に白でレンダリングし、次に2パスシェーダーを使用してすべての色を一緒にカウントします。最初に垂直線がレンダリングされ、各フラグメントについて、シェーダーは行全体の合計を計算します。次に、フラグメントが最初のパスのすべての部分和を合計した単一の頂点がレンダリングされます。非常に効率的ではないようです。
オブジェクトを黒の背景の上に完全に白でレンダリングします。合理的に小さい解像度になるまで、テクスチャ間のハードウェア線形補間を悪用して、再帰的にダウンサンプリングします。これは、対応する領域内の白いピクセルの数に応じてグレースケールレベルを持つフラグメントにつながります。これでも十分正確ですか?
ミップマップを使用して、単純に1x1レベルのピクセルを読み取ります。繰り返しになりますが、精度の問題と、2のべき乗ではないテクスチャを使用しても可能かどうかという問題です。
これらのアプローチの問題は、パイプラインが停止し、パフォーマンスに大きな問題が発生することです。したがって、私の目標を達成するためのよりパフォーマンスの高い方法を探しています。
EXT_OCCLUSION_QUERY_BOOLEAN拡張の使用
Apple はiOS 5.0 for iPad 2でEXT_OCCLUSION_QUERY_BOOLEANを導入しました。
"4.1.6 Occlusion Queries Occlusion queries use query objects to track the number of fragments or samples that pass the depth test. An occlusion query can be started and finished by calling BeginQueryEXT and EndQueryEXT, respectively, with a target of ANY_SAMPLES_PASSED_EXT or ANY_SAMPLES_PASSED_CONSERVATIVE_EXT. When an occlusion query is started with the target ANY_SAMPLES_PASSED_EXT, the samples-boolean state maintained by the GL is set to FALSE. While that occlusion query is active, the samples-boolean state is set to TRUE if any fragment or sample passes the depth test. When the occlusion query finishes, the samples-boolean state of FALSE or TRUE is written to the corresponding query object as the query result value, and the query result for that object is marked as available. If the target of the query is ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, an implementation may choose to use a less precise version of the test which can additionally set the samples-boolean state to TRUE in some other implementation dependent cases."
最初の文は、まさに私が探している振る舞いのヒントです:パフォーマンスを大幅に低下させることなく、深度テストに非同期で合格したピクセル数を取得します。ただし、ドキュメントの残りの部分では、ブール結果を取得する方法についてのみ説明します。
この拡張機能を利用してピクセル数を取得することは可能ですか?ピクセル数にアクセスするための隠しAPIがあるように、ハードウェアはそれをサポートしていますか?
悪用される可能性のあるその他の拡張機能は、フラグメントシェーダーが呼び出された回数などのデバッグ機能です(DirectXのPSInvocations-OpenGL ESで類似のものが利用可能かどうか不明)。ただし、これによりパイプラインがストールすることもあります。