web-dev-qa-db-ja.com

GLSLマルチシェーダープログラムVSユニフォームスイッチ

私はシェーダーマネージャーアーキテクチャに取り組んでおり、より高度な人々にいくつか質問があります。私の現在の選択は、次の2つの設計に反対しています。


1.マテリアルシェーダープログラムごと

潜在的な短所:

  • すべてのオブジェクトが独自のマテリアルを持っている可能性があることを考えると、多くのglUseProgram呼び出しが含まれます。
  • 多くのshaderprogramオブジェクトの作成を意味します。
  • #2よりも複雑なアーキテクチャ。

長所:

  • シェーダーコードは、マテリアルで使用される「オプション」ごとに特別に生成できます。
  • 私が間違っていなければ、ユニフォームは一度だけ設定する必要があります(シェーダープログラムの作成時)。


2.グローバルシェーダープログラム

潜在的な短所:

  • ユニフォームはフレームごとに何度も交換する必要があります。

長所:

  • シェーダープログラムの数が少なくなります。
  • 少ないSPスイッチ(glUseProgram)。


私の現在の傾向が#1であることに気付くかもしれませんが、それについてのあなたの意見を知りたいと思いました。

  • 初期のユニフォーム設定はglUseProgram呼び出しのオーバーヘッドを相殺しますか(私は特にスピードフリークではありません)?
  • ケース#1の場合、メモリやパフォーマンスを考慮して、SPの作成時にglLinkProgramを1回だけ呼び出す必要がありますか、それともglUseProgramを呼び出すたびにリンクを解除/リンクする必要がありますか?
  • より良い解決策はありますか?

ありがとう!

39
Profet

#1を見てみましょう。

すべてのオブジェクトが独自のマテリアルを持っている可能性があることを考えると、多くのglUseProgram呼び出しが含まれます。

これはそれほど大したことではありません。プログラムの交換は難しいですが、テクスチャも交換することになるので、重要な状態をまだ変更していないわけではありません。

多くのshaderprogramオブジェクトの作成を意味します。

これは痛いです。確かに、#1の主な問題は、シェーダーの爆発的な組み合わせです。 ARB_separate_program_objectsは役に立ちますが、それでも、多くのシェーダーを作成するか、多くのシェーダーを作成しない方法を考え出す必要があることを意味します。

または、 遅延レンダリング を使用することもできます。これは、これを軽減するのに役立ちます。その多くの利点の中には、材料データの生成を、この材料データを光の反射率(色)に変換する計算から分離することがあります。そのため、使用するシェーダーがはるかに少なくなります。マテリアルデータを生成するシェーダーのセットと、マテリアルデータを使用して照明の計算を行うセットがあります。

したがって、遅延レンダリングで#1を使用すると言います。

11
Nicol Bolas

それは本当にあなたのハードウェアとあなたのアプリの特定の要求に依存します。

#2のもう1つの欠点は、渡したユニフォームに基づいて条件付き分岐を実行する必要があるため、通常、シェーダーの効率が低下することです。したがって、基本的に、状態の切り替え時間の短縮とシェーダーのスループットの低下との間でトレードオフを行っています。 。どちらが悪いかによります。

シェーダーごとに1回だけglLinkProgramを呼び出す必要があります。シェーダーのコンパイルは、コンパイル済みのシェーダーを切り替えるよりもはるかに時間がかかります。

これ以上の解決策はありません。レンダリングエンジンを作成するほとんどすべての人が、直面している決定を下さなければなりません。

9

モバイルデバイスでは、シェーダーで分岐すると、レンダリングにかかる​​時間が大幅に長くなります。プログラムを切り替える時間と、頂点ごと/テクセルごとの繰り返し操作での分岐に関連する描画率の低下を測定する必要があります。方法1をお勧めし、GPUImageが優れたオブジェクト指向シェーダーアーキテクチャ用にどのように設定されているかを見てみましょう。

https://github.com/BradLarson/GPUImage

1
Slynk