0

OpenGL のジオメトリ シェーダー - C++ プログラミングで立ち往生しています。1つの回転した壁を描くことを6回繰り返して単純な立方体を作りたいです。これが私の頂点シェーダーです (すべてのプリアンブルに #version 330 コアがあります):

uniform mat4 MVP;
uniform mat4 ROT;
layout(location=0) in vec3 vertPos;
void main(){
    vec4 pos=(MVP*ROT*vec4(vertPos,1));
    pos.x/=1.5;
    pos.y/=1.5;
    gl_Position=pos;
}

現在のジオメトリ シェーダー:

layout (triangles) in;
layout (triangle_strip, max_vertices = 6) out;
out vec4 pos;
void main(void)
{
    pos=vec4(1,1,1,1);
    for (int i = 0; i < 3; i++)
    {
        vec4 offset=vec4(i/2.,0,0,0);
        gl_Position = gl_in[i].gl_Position+offset;
        EmitVertex();
    }
    EndPrimitive();
}

そして今、フラグメントシェーダー:

uniform mat4 MVP;
in vec4 pos;
out vec3 color;
void main(){
    vec3 light=(MVP*vec4(0,0,0,1)).xyz;
    vec3 dd=pos.xyz-light;
    float cosTheta=length(dd)*length(dd);
    color=vec3(1,0,0);
}

うーん、がらくたがいくつかあります。キューブにシェーディングも入れたかったのですが、座標の送信に問題があります。主な問題は、ここで (MVP マトリックスによって) スケーリングされた正方形を取得し、基本的なインターフェイス (ROT マトリックス) で回転させることもできますが、「+offset」行のコメントを外すと混乱します。きれいな 6 回繰り返しを作成するにはどうすればよいですか?

4

1 に答える 1

2

ジオメトリ シェーダーで、ここにエラーがあるようです。

gl_Position = gl_in[i].gl_Position+offset;

これによりオフセットが追加されます...しかし、クリップ空間にオフセットが追加されますが、これはおそらくあなたが望むものではありません。頂点シェーダーにオフセットを追加するか、ジオメトリ シェーダーで透視投影を行います。

/* Passthrough vertex shader */
layout(location=0) in vec3 vertPos;
void main(){
    gl_Position = vec4(vertPos, 1.0);
}

/* Geometry shader */
...
    gl_Position = MVP * (ROT * (gl_in[i].gl_Position + offset));
    EmitVertex();
...

また、頂点シェーダーに異常があることに気付きました。

pos.x/=1.5;
pos.y/=1.5;

これは、行列乗算の直後の線形変換であるため、異常です。おそらく、MVP マトリックスに次のマトリックスを掛けた方が簡単でしょう。

1/1.5     0     0     0
    0 1/1.5     0     0
    0     0     1     0
    0     0     0     1

これにより、より少ないシェーダー コードで同じ結果が得られます。

于 2015-01-09T00:17:34.767 に答える