GLSL几何着色器矩阵

时间:2015-08-11 12:15:11

标签: glsl shader

我有以下顶点着色器:

#version 150 core

attribute vec4 vertex;
varying vec3 vert;
varying float zdepth;

uniform mat4 projMatrix;
uniform mat4 mvMatrix;

void main() {
   vert = vertex.xyz;
   zdepth = -(mvMatrix * vertex).z;
   gl_Position = projMatrix * mvMatrix * vertex;
}

和几何着色器:

#version 150 core


uniform mat4 projMatrix;
uniform mat4 mvMatrix;

layout(lines_adjacency) in;
layout(triangle_strip, max_vertices = 4) out;

void main() {



    vec4 p0 = gl_in[0].gl_Position;
    vec4 p1 = gl_in[1].gl_Position;
    vec4 p2 = gl_in[2].gl_Position;
    vec4 p3 = gl_in[3].gl_Position;

    vec4 v0 = normalize(p1-p0);
    vec4 v1 = normalize(p2-p1);
    vec4 v2 = normalize(p3-p2);

    vec4 n11 = normalize(v1-v0);
    vec4 n12 = -n11;

    vec4 n21 = normalize(v2-v1);
    vec4 n22 = -n21;

    gl_Position = p1+n11*0.2;
    EmitVertex();
    gl_Position = p1+n12*0.2;
    EmitVertex();
    gl_Position = p2+n21*0.2;
    EmitVertex();
    gl_Position = p2+n22*0.2;
    EmitVertex();

    EndPrimitive();
}

几何着色器的任务是将线条转换为三角形条带。 这就是我对线条螺旋所得到的:

spiral triangle strip

我希望三角形条正常始终指向观察者方向并获得均匀的厚度。当然,它必须远远不那么厚。

我需要旋转n11,n12,n21,n22,使它们与视平面平行: normals

我可能需要用projMatrix和mvMatrix操纵v0,v1,v2? 谢谢!

2 个答案:

答案 0 :(得分:1)

投影矩阵不应该应用于顶点着色器,我会在视图空间中执行此操作,然后将最终结果转换为几何着色器中的剪辑空间。 这样可以避免在几何着色器中将所有内容除以W。

您希望对每个三角形进行屏幕对齐,这在几何着色器中非常容易(这实际上是广告牌)。将右/上向量从ModelView矩阵中拉出,然后使用它们计算X和Y中的偏移量。

Geometry Shader Pseudo-code:

// Right = Column 0
vec3 right = vec3 (mvMatrix [0][0], 
                   mvMatrix [1][0], 
                   mvMatrix [2][0]);

// Up = Column 1
vec3 up = vec3 (mvMatrix [0][1], 
                mvMatrix [1][1], 
                mvMatrix [2][1]);


//
// Screen-align everything, and give a width of 0.4
//

gl_Position = projMatrix * ((p1+n11*0.2) - vec4 ((right + up) * 0.2, 0.0));
EmitVertex();
gl_Position = projMatrix * ((p1+n12*0.2) - vec4 ((right - up) * 0.2, 0.0));
EmitVertex();
gl_Position = projMatrix * ((p2+n21*0.2) + vec4 ((right - up) * 0.2, 0.0));
EmitVertex();
gl_Position = projMatrix * ((p2+n22*0.2) + vec4 ((right + up) * 0.2, 0.0));
EmitVertex ();

答案 1 :(得分:0)

使用此代码我无法获得良好的效果。我猜这与在顶点着色器中应用的mvMatrix有关,然后在右向上向量中再次使用它。

我提出了一个相对较好的新代码:

顶点着色器:

#version 150 core

attribute vec4 vertex;
varying vec3 vert;


uniform mat4 projMatrix;
uniform mat4 mvMatrix;
uniform vec3 camPos;

void main() {
   vert = vertex.xyz;

   gl_Position = vertex;
}

几何着色器:

#version 150 core


uniform mat4 projMatrix;
uniform mat4 mvMatrix;
uniform vec3 camPos;

layout(lines_adjacency) in;
layout(triangle_strip, max_vertices = 6) out;

void main() {


    vec4 p0 = gl_in[0].gl_Position;
    vec4 p1 = gl_in[1].gl_Position;
    vec4 p2 = gl_in[2].gl_Position;
    vec4 p3 = gl_in[3].gl_Position;

    vec3 forward1 = normalize(camPos - p1.xyz);
    vec3 forward2 = normalize(camPos - p2.xyz);

    vec3 v0 = normalize(vec3(p1-p0));
    vec3 v1 = normalize(vec3(p2-p1));
    vec3 v2 = normalize(vec3(p3-p2));

    vec3 v0p1 = normalize(v0-(dot(v0,forward1))*forward1);
    vec3 v1p1 = normalize(v1-(dot(v1,forward1))*forward1);

    vec3 v1p2 = normalize(v1-(dot(v1,forward2))*forward2);
    vec3 v2p2 = normalize(v2-(dot(v2,forward2))*forward2);


    vec3 n0p1 = normalize(cross(v0p1,forward1));
    vec3 n1p1 = normalize(cross(v1p1,forward1));

    vec3 n1p2 = normalize(cross(v1p2,forward2));
    vec3 n2p2 = normalize(cross(v2p2,forward2));


    vec3 n11 = normalize(n0p1+n1p1);
    vec3 n12 = -n11;

    //if (n11[0]<0){
        //n11 = n12;
        //n12 = -n11;
   // }

    vec3 n21 = normalize(n1p2+n2p2);
    vec3 n22 = -n21;

    //if (n21[0]<0){
       // n21 = n22;
        //n22 = -n21;
   // }

    gl_Position =  projMatrix * mvMatrix * vec4(p1.xyz+n11*0.2,1.0);
    EmitVertex();
    gl_Position =  projMatrix * mvMatrix * vec4(p1.xyz+n12*0.2,1.0);
    EmitVertex();

//    EndPrimitive();

    gl_Position =  projMatrix * mvMatrix * vec4(p2.xyz+n21*0.2,1.0);
    EmitVertex();
    gl_Position =  projMatrix * mvMatrix * vec4(p2.xyz+n22*0.2,1.0);
    EmitVertex ();

    EndPrimitive();

//    gl_Position =  projMatrix * mvMatrix * p1;
//    EmitVertex();
//    gl_Position =  projMatrix * mvMatrix * p2;
//    EmitVertex ();

//    EndPrimitive();


}

我在没有应用矩阵的情况下工作。我基本上只包括眼睛到点矢量。所以屏幕上的一切似乎都转向了眼睛。