私は、頂点のデータを16バイトの頂点から頂点まで圧縮する操作があることを発見したので、非常に大きい(GPUラムを埋める)オブジェクトの表示パフォーマンスを改善するために、 4バイトの頂点(データは概念的には変形された高さマップと考えることができるので、頂点idからxとyの位置を暗示している)、ここでは2ビットを残して30ビットにZ座標をしっかりとパックすることができますカラーパレットインデックスの場合。それはとにかく考えです。私の質問はコーディネートパッキングではなく、カラーパッキングです。シェーダの切り替えステートメントではなく、カラーパレットにテクスチャを使用する方が効率的ですか?
カラーパレットは、モデルをロードするC++コードによって選択されます。それはまた、シェーダをロードしているので、私は現在、switch文、すなわちとしてカラールックアップコードを記述しようとしている:
int colourIndex = (compressedVertex & Mask) >> bitOffset;
switch (colourIndex)
{
case 0: return vec4(....);
case 1: return vec4(....);
case 2: return vec4(....);
case 3: return vec4(....);
}
モデルは、より多くの色4を有する場合、私は高精度のビットを犠牲に快適ですカラーパレットをより多くのビットに合わせるために(とにかくポイントまで)。私の測定結果では、4つのカラーパレットをバインドするためにswitch文を使用すると、4ピクセルの1Dテクスチャがバインドされ、サンプラを使用して読み込みが遅くなることはありません。
これまでの32色にスケールアップしましたが、少なくともテクスチャを使用する場合と同じくらい速いです。
スイッチを使用して停止してルックアップテーブルのテクスチャを使用し始めると、砂の中の良い行はいつですか?もし私が開発しようとしているアプリケーションがOpenGl 3.3の要求を満たしていれば、データがカードに保存されると、決して変更されません。私はそれを最大256件のステートメントにすることができますか? 1024? 32768?限界はどこですか?
(先制レスポンス:はい試行錯誤と補間を使用して私の単一の現代カードで私の価値あるものを試し続けてもらうことができますが、私はもっと一般的なアイデアに興味がありますベストプラクティスと誰にも似た何かをしようと、それは野生で動作するように知っていたかどうか?)私はシェーダで可能な限り分岐避ける
これに関するベストプラクティスはありません。私はシンプルな定数配列を行うときに明示的なswitch文を避けることを提案しますが。 32色の定数配列であっても、おそらく問題ありません。 –
コンパイルによってswitch文が静的配列に変更されない場合、switch文ではパフォーマンスが非常に悪くなり、古いカードではabysmal(エミュレーションに戻ります)になります。 SIMDとは、何千ものデータポイントが同じ命令で計算されることを意味します。これらのポイントのいずれかが異なる実行パスになる場合、パイプライン全体をフラッシュする必要があります。スイッチステートメントが正当化できるケースはまれです。 http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter17.html –
switchステートメントの実行が異なる(悪い)場合は、テクスチャを読み込むオーバーヘッド(メモリアクセス、スロー)最新のGPUはメモリを読み込める速度よりもはるかに高速に計算できるため、switch/if-else文が高速になる可能性があります。提案として、ルックアップテーブルを一様なバッファに入れ、それにインデックスを付けることができます。テクスチャへのアクセスやスイッチの発散を避けるために、テーブルは定数キャッシュ(レジスタとほとんど同じくらい)にロードされます。 – user2746401