0

シーンに少なくとも 20 個のライトが必要なため、ディファード シェーディングの実装に取り​​組んでいます。私はそれを十分に速くするのに問題を抱えていました(そして今でもそうです)が、遅くなると思っていた変更を加えましたが、実際にはフレームレートがほぼ2倍になりました.

初期コード:

geometryPassFBO = createFBO(); // position texture, normal texture, colour texture and depth buffer
while (1)
{
    bind geometryPassFBO.
    allObjects.draw();

    bind systemFBO();
    for each light
        send light info
        draw light sphere sampling from position, normal and colour textures.

    blit depth buffer from geometryFBO to systemFBO

    for each light
        light.draw(); // draw a cube to represent the light

    2DObjects.draw(); // frame rate, etc...
}

ジオメトリ パス中にピクセルが設定されている場合 (つまり、法線 = 0,0,0、位置 = 0,0,0、色 = 0 の背景) にのみライティング パスを実行するようにステンシル テストをセットアップしていました。 ,0,0.

ただし、結合された深度/ステンシル バッファーをデフォルトの深度/ステンシル バッファーにコピーするのは困難でした。システムの深度/ステンシル バッファがどのような形式になるかがわからないため、これはうまく機能しないようです。そのため、深度/ステンシル バッファ フォーマットを指定し、これにレンダリングしてから、スクリーン クワッドをブリットまたはレンダリングして画面に出力できる別の FBO をセットアップする方がよいと読んでいました。

そのため、ステンシルを追加する前に、新しい FBO を追加して、そのビットが機能するようにしました。

私の新しいコードは次のようになります。

geometryPassFBO = createGeometryFBO(); // position texture, normal texture, colour texture and depth buffer
lightingPassFBO = createLightingFBO(); // colour texture and depth buffer
while (1)
{
    bind geometryPassFBO.
    allObjects.draw();

    bind lightingPassFBO();
    for each light
        send light info
        draw light sphere sampling from position, normal and colour textures.

    blit depth buffer from geometryFBO to lightingPassFBO

    for each light
        light.draw(); // draw a cube to represent the light

    2DObjects.draw(); // frame rate, etc...

    bind systemFBO;
    render screen quad sampling from colour texture.
}

これは期待どおりに機能します。予想外だったのは、フレーム レートが 25 FPS から 45 FPS に急上昇したことです。

どうしてこれなの?スクリーン クワッドに追加のシェーダー パスを実行しなければならないことは、実行しないよりも効率的ですか?

簡単なフォローアップの質問。シンプルな頂点シェーダーとフラグメント シェーダーを使用して gl_FragCoord に基づいてテクスチャをサンプリングすることと、カラー アタッチメントをシステム FBO に直接ブリットすることのどちらが効率的ですか?

4

1 に答える 1

2

まあ、それはおそらくこれです:

geometryFBO から lightingPassFBO への blit 深度バッファー

ご指摘のとおり、フォーマット変換は遅くなる可能性があります。ただし、このブリット操作の入力バッファーと出力バッファーの両方を定義しているため、おそらく同じ深度形式を使用しています。したがって、ブリッティング操作ははるかに高速に進行する可能性があります。

また、おそらくこのブリットを行うべきではありません。ライト キューブをレンダリングする前geometryFBOに、 の深度/ステンシル バッファを にアタッチするだけです。lightingPassFBOライトをレンダリングした後でアタッチメントを削除することを忘れないでください (そうしないと、遅延パスの深度バッファーから読み取っていると仮定して、遅延パスの動作が未定義になります)。

ブリッティングとフルスクリーン クアッドに関する質問については、もっと良い質問があります。シーンに 20 以上のライトを蓄積し、ハイ ダイナミック レンジ ライティングを使用しないのはなぜですか? 画面にレンダリングする最終パスでも、トーン マッピングを使用して HDR 画像を表示用の LDR に変換する必要があるためです。

しかし、正確な質問に関しては、フォーマット変換が行われないと仮定すると、blit 操作は FSQ よりも遅くはないはずです。フォーマット変換が発生している場合は、頂点シェーダーに移動する方が効率的である可能性があります。

于 2016-01-24T19:35:39.023 に答える