【问题标题】:GLSL geometry shader matricesGLSL 几何着色器矩阵
【发布时间】:2015-08-11 12:15:11
【问题描述】:

我有以下顶点着色器:

#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();
}

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

我想让三角形条带法线始终指向观察者方向并获得均匀的厚度。当然,它必须在更远的地方不那么厚。

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

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

【问题讨论】:

    标签: glsl shader


    【解决方案1】:

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

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

    几何着色器伪代码:

    // 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 ();
    

    【讨论】:

      【解决方案2】:

      我没有用这段代码得到好的结果。我想这与在顶点着色器中应用的 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();
      
      
      }
      

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

      【讨论】:

        猜你喜欢
        • 2011-09-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多