2

現在、3 つの異なるシェーダー (Vertex、Geometry、Fragment) を使用しています。それぞれが異なるプログラムに属し、すべて単一のプログラム パイプラインに集められています。

問題は、Geometry と Fragment の変数がゼロになっていることです。つまり、パイプラインの前のシェーダーによって以前に書き込まれた値が含まれていません。

各シェーダーについて:

glCreateShader(...)
glShadersource(...)
glCompileShader(...)
glGetShaderiv(*shd,GL_COMPILE_STATUS,&status)

各プログラム:

program[index] = glCreateProgram()
glAttachShader(program[index],s[...])
glProgramParameteri(program[index],GL_PROGRAM_SEPARABLE,GL_TRUE)
glLinkProgram(program[index])
glGetProgramiv(program[index],GL_LINK_STATUS,&status)

それから:

glGenProgramPipelines(1,&pipeline_object)

glドローで:

glBindProgramPipeline(pipeline_object)
glUseProgramStages(pipeline_object,GL_VERTEX_SHADER_BIT,program[MY_VERTEX_PROGRAM])
and again for the geometry and fragment programs

頂点シェーダー:

#version 330

//modelview and projection mat(s) skipped
...

//interface to geometry shader
out vec3 my_vec;
out float my_float;

void main() {
    my_vec = vec3(1,2,3);
    my_float = 12.3;
    gl_Position = <whatever>
}

ジオメトリ シェーダ:

#version 330

//input/output layouts skipped
...

//interface from vertex shader
in vec3 my_vec[];
in float my_float[];
//interface to fragment shader
out vec3 my_vec_fs;
out float my_float_fs;

void main() {
    int i;
    for(i=0;i<3;i++) {
        my_vec_fs = my_vec[i];
        my_float_fs = my_float[i];
        EmitVertex();
    }
    EndPrimitive();
}

フラグメント シェーダー:

#version 330

//interface from geometry
in vec3 my_vec_fs;
in float my_float_fs;

void main() {
    here my_vec_fs and my_float_fs come all zeroed
}

プログラム パイプラインのさまざまなステージ間で変化する書き込み/読み取りの重要なステップを見逃していますか?

アップデート:

GLSL仕様に次のように記載されているため、全員が同じベクトルで「話している」ことを確認するために、レイアウトの場所の修飾子を試しました。

layout-qualifier-id location = integer-constant 引数は 1 つだけ受け入れられます。たとえば、vec4 normal; の layout(location = 3) です。シェーダ入力法線がベクトル位置番号 3 に割り当てられることを確立します。頂点シェーダ入力の場合、位置は、入力値が取得される汎用頂点属性の番号を指定します。他のすべてのシェーダー タイプの入力の場合、場所は、そのシェーダーが別のプログラム オブジェクトにある場合でも、前のシェーダー ステージからの出力と照合するために使用できるベクトル番号を指定します。

しかし追加

layout(location = 3) out vec3 my_vec;

コンパイルしない

だから私は glBindAttribLocation() を介して同じことをしようとしましたが、エラーは発生しませんが、動作はまだ変更されていません

更新 2

「#extension GL_ARB_separate_shader_objects: enable」を追加すると

次に、layout(location = n) in/out var; を使用できます。そして、それは機能します。

見つかった:

GLSL 330: Vertex shaders cannot have output layout qualifiers
GLSL 420: All shaders allow location output layout qualifiers on output variable declarations

これは興味深い.. #version 330 を宣言すると、たとえ拡張機能を有効にしたとしても、レイアウトアウト修飾子を使用できないはずです.. ..しかし、拡張機能は次のように述べています:

この ARB 拡張機能は、GLSL 言語のレイアウト修飾子の使用を拡張して、クロスステージ インターフェイスを提供します。

glBindAttribLocation() を使用したり、単純な名前の一致 + ARB 拡張機能を有効にしただけでは機能しない理由を知りたいです!

4

1 に答える 1

0

少なくとも 1 つの実装 (webgl と古いクロムだと思います) でバグが見つかりましglBindAttribLocation() た。問題は、頂点属性を番号順にバインドする必要があることだったと思います。したがって、それを使用しても役に立たないことが判明しました。それを機能させるには、に切り替える必要getAttribLocation()がありました。

于 2012-04-08T07:58:37.607 に答える