ステンシルテストでいくつの断片が作成されたかを調べることはできますか?


11

私はステンシルテストを非常に広範囲に使用して不規則な形状をレンダリングするOpenGLアプリケーションを持っています(単純な2D CSGと少し似ています)。ステンシルテストに合格して実際にレンダリングされたフラグメントの数を確認できれば、これは一部の計算を簡略化するのに非常に役立ちます。具体的には、後でモンテカルロシミュレーションで近似する必要がなく、レンダリングされた形状の領域を無料で決定できます。

ジオメトリシェーダーから放出されるプリミティブにも、変換フィードバックと呼ばれる同様の概念があることを知っています。同様のコンセプトがフラグメントとステンシルテストに存在するかどうか知りたいのですが。


大まかな解決策は、ステンシルを介して対照的な1つの色を別の色にペイントし、そのバッファーを保存して、変更されたピクセルの数を数えることです。
TheBuzzSaw 2015

うーん、仕様ではオクルージョンクエリ深度テストに合格したフラグメントの数をカウントするようになっていますが、頭の上のところでは、ステンシルテストとどのように相互作用するのか今はわかりません。
Chrisは、2015

@ChristianRau深度テストに合格したフラグメントのみがカウントされるようですが、ステンシル、破棄、アルファテストは無視されます。
モーリスラヴォー2015

2
@ChristianRauとMauriceの元のARB_occlusion_query仕様では、深度テストステンシルテストの両方に合格したサンプルをカウントしていると明示されています。このStackOverflowの質問も参照してください。
ネイサンリード、

@NathanReed答えを書こうとしているようですね。
クリスは、モニカを2015

回答:


10

1つの可能なアプローチは、ハードウェアオクルージョンクエリの使用です。

仕様上、ステンシルテストは深度テストの前に実行され、深度テストに合格したフラグメントのみがオクルージョンクエリによってカウントされるという事実を使用できます。

簡単な例(テストされていません)は次のようになります。

    GLuint samples_query = 0;
    GLuint samples_passed = 0;
    glGenQueries(1, &samples_query);
    // Initialize your buffers and textures ...
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_STENCIL_TEST);

    // Set up the values on the stencil buffer ...

    // Now we count the fragments that pass the stencil test
    glDepthFunc(GL_ALWAYS); // Set up the depth test to always pass
    glBeginQuery(GL_SAMPLES_PASSED, samples_query);
    // Render your meshes here
    glEndQuery(GL_SAMPLES_PASSED);
    glGetQueryObjectuiv(samples_query, GL_QUERY_RESULT, &samples_passed);
    // samples_passed holds the number of fragments that passed the stencil test (if any)

    // Release your resources ...
    glDeleteQueries(1, &samples_query);

サンプル数を取得するための呼び出しは、パイプラインのフラッシュを強制的に呼び出し、クエリが完了するまで待機することに注意してください。より非同期のアプローチが必要な場合は、以下を使用して、オクルージョンクエリが実行されるかどうかを照会できます。

    GLuint query_done = 0;
    glGetQueryObjectuiv(samples_query, GL_QUERY_RESULT_AVAILABLE, &query_done);
    if (query_done != 0)
        // Your query result is ready
    else
        // Maybe check the next frame?

2

興味があるのが領域である場合は、1ピクセルに達するまでステンシルバッファーのサイズを小さくし、その色からその領域を推定できます。

手順は次のとおりです。

  • 十分な精度を持つフォーマットを使用して、ステンシルをテクスチャにコピーします。
  • 指定された色のテクセルの数に比例する色を出力するシェーダーをロードします。
  • フレームバッファにピンポンして、1ピクセルに達するまでサイズを半分に減らします。
  • ピクセルの色は、エリアで覆われているビューポートのパーセンテージです。ビューポートのエリアを掛けるだけです。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.