1

vec4がNULLかどうかをシェーダー(GLSL)内で確認しようとしています。これが必要な理由はいくつかあります。主に、特定のグラフィックカードに互換性を持たせるためです。これは、gl_FragColorで以前の色を渡すものと、渡さないもの(上書きする必要のあるnull vec4を提供するもの)があるためです。まあ、かなり新しいMacで、誰かがこのエラーを受け取りました:

java.lang.RuntimeException: Error creating shader: ERROR: 0:107: '==' does not operate on 'vec4' and 'int'
ERROR: 0:208: '!=' does not operate on 'mat3' and 'int'

これは、フラグメントシェーダーの私のコードです。

void main()
{
    if(gl_FragColor == 0) gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); //Line 107
    vec4 newColor = vec4(0.0, 0.0, 0.0, 0.0);

    [...]

    if(inverseViewMatrix != 0) //Line 208
    {
        [do stuff with it; though I can replace this NULL check with a boolean]
    }

    [...]

    gl_FragColor.rgb = mix(gl_FragColor.rgb, newColor.rgb, newColor.a);
    gl_FragColor.a += newColor.a; 
}

ご覧のとおり、最初にgl_FragColorの0 / NULLチェックを行います。これは、グラフィックカードの中には貴重な情報を渡すものもあれば、渡さないものもあるためです。さて、その特別なマックでは、それは機能しませんでした。調査を行いましたが、GLSLで適切なNULLチェックを行う方法に関する情報が見つかりませんでした。1つでもありますか、それともここで個別のシェーダーを作成する必要がありますか?

4

3 に答える 3

9

読み取り用のすべての変数、つまり入力変数は常に適切な値を提供します。出力変数であるgl_FragColorことは、これらの変数の 1 つではありません!

このコードでは

void main()
{
    if(gl_FragColor == 0) gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); //Line 107
    vec4 newColor = vec4(0.0, 0.0, 0.0, 0.0);

最初に行うことは、から読み取ることですgl_FragColorGLSL 仕様では、出力変数の値がそのままでgl_FragColorは、フラグメント シェーダー ステージに入ったときに未定義であることが明確に述べられています(ポイント1 )。

出力変数の値は、次の 3 つのケースのいずれかで未定義になります。

  1. 実行の開始時。
  2. 各同期点で、
    • 値が前回の同期点の後に明確に定義されていて、それ以降の呼び出しによって書き込まれていない、または
    • 値は、前回の同期ポイント以降に 1 回のシェーダー呼び出しによって書き込まれたか、または
    • この値は、前回の同期ポイント以降の複数のシェーダー呼び出しによって書き込まれ、そのようなすべての呼び出しによって実行された最後の書き込みで同じ値が書き込まれました。
  3. シェーダー呼び出しによって読み取られる場合、
    • 値が前の同期ポイントで未定義であり、それ以降、同じシェーダー呼び出しによって書き込まれていない、または
    • 出力変数は、読み取りに続くコードでその割り当てが発生した場合でも、前の同期ポイントと次の同期ポイントの間の他のシェーダー呼び出しによって書き込まれます。

出力変数の要素が最初に書き込まれた後でのみ、その値が定義されます。したがって、そこで行うすべてのことは意味がありません。「うまくいかなかった」ということは完全に許容され、あなたの側のエラーです。

未定義の動作を呼び出しています。技術的には、これに対する代替反応として、コンピューターが知覚的になり、通りを追いかけ、すべてのデータを消去することは許容されます。


GLSL では、vec4は int と同様に通常のデータ型です。nullポインターである可能性のある配列へのある種のポインターではありません。せいぜい glUniformの呼び出しによって上書きされないデフォルト値があります。

于 2013-01-13T15:35:47.320 に答える
1

GLSL シェーダーの変数は常に定義されています (そうしないと、リンカー エラーが発生します)。これらの値にデータを提供しない場合 (適切なユニフォームをロードしないかまたは属性変数に属性をバインドしないことにより)、それらの変数の値は未定義 (つまり、ガベージ) になりますが、存在します。

于 2013-01-13T15:40:01.043 に答える