1

遅延レンダリング コンテキストでのステンシル バッファの使用に関して 1 つ疑問に思っているのは、スクリーン スペース上のすべてのフラグメント シェーダが「オクルード」領域内で使用されているかということです。

Web サイトhttp://www.learnopengl.com/#!Advanced-OpenGL/Stencil-testingの例を次に示します(ステンシル バッファーのトピックのみで、遅延レンダリングとは関係ありません)。

ここに画像の説明を入力

質問: ここで「他は捨てる」という表現は何を意味していますか? これは、マスク サンプラーで値が 0 の場合、ピクセル シェーダーが呼び出されないことを意味します。または、画面上の各フラグメントに対してピクセル シェーダーが呼び出されますが、値が 0 の場合、ピクセルの塗りつぶしを破棄する条件が適用されます。

左の最初の画像が、ステンシル バッファリングなしの結果であるとします。情報のサポートは、2 つの三角形で構成されるクワッドです (遅延レンダリング手法を適用するため、画面空間で作業しています。画面の寸法は 500x500 です)。そのため、ラスタライズ後、500 * 500 のフラグメント シェーダーが呼び出されてフレーム バッファーが満たされ、光のない暗い領域でもそれらのすべてが使用されます。これは、ブリンフォン シェーディング モデルを適用すると、この最後のモデルが画面のどこにでも適用され、暗い領域でも適用されることを意味し、パフォーマンスの無駄だと思います。

したがって、この場合に行う論理的なことは、マスクを作成し (ステンシル バッファーを使用するか、他のフレーム バッファーを使用してマスクを塗りつぶす外部カスタム マスク レンダー パスを使用して)、最後に blinn-phong シェーディング モデルのみを使用することです。ここで、スクリーン スペースのマスク サンプラーのピクセルの値は 1 です。このようにして、フォン シェーディング モデルは、この例でのみ 2 つのボックスとプレーンに適用されます。

最初のアプローチでジョブを正しく行うための秘訣は、フラグメント シェーダーに条件を追加して、現在のフラグメントのブリンフォン シェーディングを計算する必要があるかどうかを、サンプリングされたマスク テクスチャの値に従って判断することです。

void main(void)
{
    if (texture(MaskSampler, TexCoord.xy).r == 1.0f)
    {
         //Execute here Blinn-Phing shading model...
    }
    //Else nothing
}

しかし、(上の 3 番目の図を見ると) 色付きの領域のみに関係するフラグメント シェーダーを呼び出すように OpenGL API に指示できるかどうか疑問に思っています! (つまり、フラグメント シェーダーのメインには入らないということです)。この場合、使用されるフラグメント シェーダーの数が大幅に削減され、パフォーマンスが向上します。または、上記のようにフラグメント シェーダーに条件を入れることが唯一の解決策ですか?

4

1 に答える 1

1

ほとんどの場合、ステンシル テストはフラグメント シェーダーの前に実行され、その実行はスキップされます。フラグメントシェーダーの前に実行されない理由についての条件とともに、ここで詳細に説明されていますが、これらは説明されている設定ではありそうにありません. これは、フラグメント シェーダーにブランチ/サンプルを追加するよりもはるかに優先されます。また、実装と保守がはるかに簡単です。

ただし、分岐の場合、はるかに単純なシェーダーを実行する提案された方法でも、速度が向上する場合があります (各ピクセルに対して完全なシェーダーを実行するよりも)。これは、ほとんどの最新のドライバーが空間コヒーレンスで分岐予測を最適化するためです。つまり、局所領域内のすべてのピクセルが常に同じ分岐を取る場合、これを最適化できます。GPU Gemsの章で、このプロセスについて説明しています。もちろん、これはシェーダーの複雑さ、領域、およびドライバーの実装に大きく依存します。ステンシル方式のアプローチは、それほどあいまいではありません。

于 2015-06-06T02:01:56.510 に答える