典型的な「ナイーブな」頂点シェーダーを考えてみましょう。
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つすべてはどうですか?
もちろん、それはすべてベンチマークに関するものです...しかし、誰かが基本的な、現在の世代のハードウェア実装ベースの洞察を持っていることを望んでいました。 「または「事前乗算なしの現在のシェーダーはまったくの狂気になるので、必ずそれを実行してください」 ...考えますか?