10

そこで、オレンジブック (第 3 版) を読んでいて、第 9 章で不変修飾子に関する一節に出くわしました。そしてそれは言います:

不変修飾子は、出力の計算に直接関係のない式と関数を無視するようにコンパイラとリンクに指示します。

この一節は、2 つの類似したコード スニペットの後に続きます。

uniform mat4 MVPmatrix;
// ...

in vec4 MCVertex;
// ...

a(); // does not modify gl_Position, MVP or MCVertex

// ...
// Transform vertex to clip space
gl_Position = MVP * MCVertex;

uniform mat4 MVPmatrix;
// ...

invariant gl_Position;
in vec4 MCVertex;
// ...

a(); // does not modify gl_Position, MVP or MCVertex

// ...
// Transform vertex to clip space
gl_Position = MVP * MCVertex;

その後、本は次のように述べています。

最初のケースでは、シェーダーにリンクされている関係のない関数または式に関係なく、まったく同じ方法で変換された位置を計算する場合と計算しない場合があります。マルチパス アルゴリズムを使用して同じジオメトリを複数回レンダリングすると、レンダリングで問題が発生する可能性があります。

これは私を混乱させました。変換された位置の計算に関与する変数にまったく影響しない場合a()、計算はどのように変化しますか? (そして、追加はそれをどのようにinvariant助けますか?)。そして、最初の引用を参照すると、「無関係な機能を無視する」とは正確にはどういう意味ですか? 彼らは処刑されないだけですか?

4

2 に答える 2

12

の目的はinvariant、シェーダー オプティマイザーがシェーダーに対して何を行うかに関係なく (特に複数のシェーダー コンパイル間で)、実行中の計算が常に同じ結果になるようにすることです。

オレンジ色の本の言い回しは貧弱だと思います (そして、あなたが指摘したように誤解を招きます)。GLSL 仕様 (言語 1.2) セクション 4.6 はより明確です。

このセクションでは、分散とは、異なるプログラムで同じ式から異なる値を取得する可能性を指します。たとえば、異なるプログラムで 2 つの頂点シェーダーがあり、それぞれが両方のシェーダーで同じ式を使用して gl_Position を設定し、両方のシェーダーが実行されたときにその式への入力値が同じであるとします。2 つのシェーダーの独立したコンパイルが原因で、2 つのシェーダーが実行されたときに gl_Position に割り当てられた値が正確に同じではない可能性があります。この例では、これがマルチパス アルゴリズムでのジオメトリの位置合わせに問題を引き起こす可能性があります。一般に、シェーダー間のこのような差異は許容されます。そのような分散が特定の出力変数に存在しない場合、その変数は不変であると言われます。

invariantさらに、修飾子がこの問題を回避する保証を得ると説明しています。

于 2013-09-25T11:24:43.300 に答える
4

invariantキーワードは、(要するに、Bahbarのより詳細な回答とは対照的に)、あなたが言及したように、複数のジオメトリパスに現れる可能性のある非常に微妙な計算上の違いに関するものです。

以下に例を示します。画面上に任意の奇妙な三角形を (より難しくするために) 描画します。ラスタライザーは正規化された頂点を取得し、占有するすべてのフラグメントを計算してから、フラグメント シェーダーを実行します。ここで、三角形の真上に別の三角形を描きたいとしますが、3 時間後、PC が水没している間に温度が下がり、その間に昼食をとります。次に、シェーダーを再コンパイルすると、バム...

これらはすべて、ラスタライザーに影響を与える可能性があります。シェーダーの最適化が開始され、出力にわずかな変更が加えられる場合があります。技術的には正しいですが、結果は必ずしも最初の三角形とまったく同じである必要はなく、「問題」は最初の三角形の残りのピクセルになります。

invariant潜在的に遅いアプローチが取られることを保証します。私はドライバー アーキテクトではありませんが、一般的には、いくつかの追加の状態リセット、クリーンアップ、または状態スタックのプッシュ/ポップを意味する場合があります。そうして初めて、「クリーン」な計算状態が残り、ハードウェアが正常である限り、結果はまったく同じになるはずです。

于 2013-09-25T12:57:11.060 に答える