web-dev-qa-db-ja.com

フラグメントシェーダーは、ピクセルの色に使用する変数をどのように知るのですか?

さまざまなフラグメントシェーダーがありますが、

#version 130

out vec4 flatColor;

void main(void)
{
    flatColor = vec4(0.0,1.0,0.0,0.5);
}

そして、それらはすべて「out color」に異なる変数を使用します(この場合はflatColor)。それでは、OpenGLはあなたがやろうとしていることをどのように知るのでしょうか?

flatColoroutとして定義されている唯一の変数であるため、これが機能すると推測していますが、さらにout変数を追加できますよね?それとも、単にクラッシュしますか?


実際、テストとして、私はこれを実行しました:

#version 330

in vec2 TexCoord0;

uniform sampler2D TexSampler;

out vec4 x;
out vec4 y;

void main()
{
    y = texture2D(TexSampler, TexCoord0.xy);
}

xを使用してもyを使用しても正常に機能しました。


さらに、定義済みのgl_FragColor。違いは何ですか?また、なぜ人々は通常、独自の変数を使用することを主張しますか?

76
mpen

さらに、定義済みのgl_FragColorがあります。

これから始めましょう。いいえ、事前定義済みのgl_FragColorを持っていませんない。これは、OpenGL 3.1以降のコアから削除されました。互換性を使用している場合を除き(この場合、3.30シェーダーは#version 330 compatibilityを上部に表示する必要があります)、これを使用しないでください。

次に、ユーザー定義のフラグメントシェーダー出力に戻ります。しかし、最初に、簡単なアナロジー。

頂点シェーダーで入力をどのように覚えているか覚えていますか?そして、これらの入力は頂点属性インデックス、glVertexAttribPointerおよびglEnableVertexAttribArrayなどに渡す数字を表しますか?どの入力がどの属性からプルされるかを設定します。 GLSL 3.30では、次の構文を使用します。

layout(location = 2) in color;

これにより、color頂点シェーダー入力が属性位置2から来るように設定されます。3.30より前(またはARB_explicit_attrib_locationなし)では、リンクする前に glBindAttrbLocation で明示的に設定する必要があります。または、 glGetAttribLocation を使用して属性インデックスのプログラムを照会します。属性の場所を明示的に指定しない場合、GLSLは場所を任意に割り当てます(つまり、実装定義の方法で)。

ほとんどの場合、シェーダーで設定する方が良いオプションです。

いずれの場合でも、フラグメントシェーダーの出力はほぼ同じように機能します。フラグメントシェーダーは 複数の出力色 に書き込むことができ、それ自体は フレームバッファー内の複数のバッファー にマッピングされます。したがって、どの出力がどのフラグメント出力カラーに行くかを示す必要があります。

このプロセスは、フラグメント出力場所の値から始まります。頂点シェーダーの入力位置と非常によく似た設定になっています。

layout(location = 1) out secColor;

API関数 glBindFragDataLocation および glGetFragDataLocation もあり、これらはglBindAttribLocationおよびglGetAttribLocationに類似しています。

明示的な割り当てを行わない場合、通常、実装は出力変数の1つをロケーション0に割り当てます。ただし、OpenGL規格では、これをrequireしません。動作なので、それに依存するべきではありません。

公平を期すために、異なる出力場所を取得しない2つの出力を使用した場合、プログラムにはfailedをリンクする必要があります。おそらくあなたのコンパイラはあなたが書いていないものを最適化したので、リンカエラーをチェックする時が来たときにそれをちょっと忘れていました。

134
Nicol Bolas

GLSL_ES_3.10 link を使用するOpenGLES 3.1でこれを指定したいと思います。

§4.4.2

[フラグメントシェーダーに]出力が1つしかない場合、場所を指定する必要はありません。その場合、デフォルトはゼロになります。

8
Lorenzo Belli