使用均一バッファ(すなわち一定のバッファ D3Dの用語では)。
すべてのシェーダーがそのような各バッファーのレイアウトとバインディングポイントに同意している限り、更新は簡単です。モデルは、シェーダーについて何も知る必要はありません。それらは定数バッファー内のモデルビューマトリックスを更新するだけでよく、レンダリングパイプラインはそれを自動的に使用します。
少なくとも、そのようなバッファが2つあるべきだと主張します。1つ目は、射影行列、カメラ行列、連結されたカメラ射影行列、ビューポート情報、錐台の詳細、逆行列を格納する必要があります。このバッファを更新する必要があるのは、シーンごとに1回だけです。
次に、各モデルに別のバッファーを与えて、モデルビューマトリックス、法線マトリックス、逆行列、および材料特性を保存します。これはモデルごとに1回更新され、別の更新パスで実行できます(該当する場合/該当する場合)。複数のオブジェクト間でマテリアルを共有する機能がある場合は、マテリアル情報を3番目のマテリアル固有のバッファに移動できます。
フォワードシェーディングセットアップでは、すべてのライトを別のバッファーに配置することには意味があり、ディファードシェーディングでは、同様にライトパスにライトごとのバッファーを使用することも意味があります(モデルで使用されるモデル/マテリアルバッファーの代わりに)ジオメトリパス)。
均一なバッファーを使用するには、適度に最新のバージョンのGL(3.1または拡張機能、一部の古いがまだ稼働中のラップトップを除いて今日は十分に一般的)が必要であり、かなり最近のバージョンが必要です。シェーダーコード内から特定のバインディングロケーションに均一なバッファーをバインドできます(4.2;まだ一般的ではありませんが、改善されています)。とにかく指すので、それは深刻な問題というよりもAPIの匂いです。OpenGL | ESは3.0までは均一なバッファーを追加しませんでしたが、残念ながら、ほとんどの一般的なモバイルプラットフォームではまだサポートされていません。
バッファーがオプションではない場合、アクティブなシェーダーのインデックスの場所を格納するためのグローバルな場所が必要になります。glGetUniformLocation
シェーダーを読み込んだ後でを使用して、既知の名前(ModelViewMatrix
など)のインデックスを検索し、これらのインデックスを保存できます。レンダーはMODEL_VIEW
、SetUniform
ラッパー関数に渡されるような列挙値をマップして、バインドされたシェーダーを調べ、インデックスを見つけ、glUniform
適切に呼び出すことができます。すべてをうまくまとめた場合に各ユニフォームを個別に設定する必要があることを除いて、バッファからのクライアントコードの使用法に大きな変更はありません。
GLSLインターフェースブロックとUniform Bufferオブジェクトを参照してください。