5

典型的な「ナイーブな」頂点シェーダーを考えてみましょう。

in vec3 aPos;

uniform mat4 uMatCam;
uniform mat4 uMatModelView;
uniform mat4 uMatProj;

void main () {
    gl_Position = uMatProj * uMatCam * uMatModelView * vec4(aPos, 1.0);
}

もちろん、従来の知識では、「頂点ごとに3つのmat4が乗算され、そのうちの2つは現在のシェーダープログラム内の後続の複数のglDrawX()呼び出しでも均一です。少なくとも、これら2つはCPU側で事前に乗算する必要があります。 3つすべてでも。」

現代のGPUがこのユースケースを最適化して、CPU側の事前乗算がパフォーマンス上のメリットではなくなったのではないかと思います。もちろん、純粋主義者は「エンドユーザーのOpenGL実装に依存する」と言うかもしれませんが、このユースケースでは、その実装を提供する現世代のOpenGL4.2対応のnVidiaまたはATIドライバーであると安全に想定できます。

あなたの経験から、UseProgram()パスごとに100万程度の頂点を「描画」する可能性があることを考えると、UseProgram()ごとに少なくとも最初の2つ(パースペクティブプロジェクションとカメラ変換行列)を事前に乗算すると、パフォーマンスが向上します。かなりの程度?Draw()呼び出しごとの3つすべてはどうですか?

もちろん、それはすべてベンチマークに関するものです...しかし、誰かが基本的な、現在の世代のハードウェア実装ベースの洞察を持っていることを望んでいました。 「または「事前乗算なしの現在のシェーダーはまったくの狂気になるので、必ずそれを実行してください」 ...考えますか?

4

1 に答える 1

4

現代のGPUがこのユースケースを最適化して、CPU側の事前乗算がパフォーマンス上のメリットではなくなったのではないかと思います。

GPUは、並列操作で最適に機能します。「GPU」がこのように3つの連続するベクトル/行列の乗算を最適化できる唯一の方法は、シェーダーコンパイラがそれらが均一であることを検出し、描画呼び出しを発行したときにどこかで乗算を実行し、シェーダーに結果を渡す場合です。

したがって、どちらの場合でも、3つの行列の乗算はシェーダーで1になります。あなたはそれらの掛け算を自分ですることもできないこともできます。また、ドライバーはこの最適化を実装することも実装しないこともできます。可能性の図は次のとおりです。

            | GPU optimizes  | GPU doesn't optimize
------------|----------------|---------------------
You send 3  |   Case A       |        Case B
matrices    |                |
---------------------------------------------------
You multiply|   Case C       |        Case D
on the CPU  |                |
------------|----------------|---------------------

ケースAでは、コードが示唆するよりも優れたパフォーマンスが得られます。ケースBの場合、パフォーマンスは向上しません。

ケースCとDはどちらも、ケースAと同じパフォーマンスを保証します。

問題は、ドライバーがこの最適化を実装するかどうかではありません。問題は、「そのパフォーマンスはあなたにとってどのような価値があるのか​​」ということです。そのパフォーマンスが必要な場合は、自分で行うことをお勧めします。それがそのパフォーマンスを確実に達成する唯一の方法です。そして、あなたがパフォーマンスを気にしないのなら...それは何が重要ですか?

つまり、この最適化に関心がある場合は、自分で行ってください。

あなたの経験から、UseProgram()パスごとに100万程度の頂点を「描画」する可能性があることを考えると、UseProgram()ごとに少なくとも最初の2つ(パースペクティブプロジェクションとカメラ変換行列)を事前に乗算すると、パフォーマンスが向上します。かなりの程度?Draw()呼び出しごとの3つすべてはどうですか?

かもしれない; そうではないかもしれません。それはむしろ、頂点変換がレンダリングシステムのボトルネックになっている状況に依存します。実際のレンダリング環境でテストを行わずに知る方法はありません。

また、投影とカメラマトリックスを組み合わせることは、カメラ空間ではなくワールド空間で照明を行うことを意味するため、最善のアイデアではありません。また、値を引き出すための純粋な射影行列がないため、遅延レンダリングが非常に難しくなります。

于 2012-10-17T18:14:27.107 に答える