幾何着色器


 

  一般我們只使用了頂點和片段着色器,這也是基本和必須的兩個着色器,而幾何着色器是一個可選的着色器,其位於頂點和片段着色器之間。

  幾何着色器接收來自頂點着色器的一個片元的一組頂點,然后可以對其進行變換,可以輸出新的不同類型的片元,也可以增加頂點數,其功能非常強大。

  一般寫法如下:

#version 330 core
layout (points) in;
layout (line_strip, max_vertices = 2) out;

void main() {    
    gl_Position = gl_in[0].gl_Position + vec4(-0.1, 0.0, 0.0, 0.0); 
    EmitVertex();

    gl_Position = gl_in[0].gl_Position + vec4( 0.1, 0.0, 0.0, 0.0);
    EmitVertex();

    EndPrimitive();
}

  可以看到首先定義了輸入和輸出布局修飾符。

  輸入修飾符:

layout (points) in;

  括號中的輸入片元類型一般應該與頂點着色器接收的頂點數據一致,有以下幾種片元類型(后面的括號中的數字表示此片元包含的最少頂點數):

  • points:繪制GL_POINTS圖元時(1)。
  • lines:繪制GL_LINESGL_LINE_STRIP時(2)
  • lines_adjacencyGL_LINES_ADJACENCYGL_LINE_STRIP_ADJACENCY(4)
  • trianglesGL_TRIANGLESGL_TRIANGLE_STRIPGL_TRIANGLE_FAN(3)
  • triangles_adjacencyGL_TRIANGLES_ADJACENCYGL_TRIANGLE_STRIP_ADJACENCY(6)

  輸出修飾符:

layout (line_strip, max_vertices = 2) out;

  max_vertices=2 表示:對應頂點着色器輸出的每個片元,幾何着色器每次處理的最大頂點數量,超出的頂點就不再處理了。

  可供選擇的輸出修飾符有:

  • points
  • line_strip
  • triangle_strip

  

  效果展示:

  1、輸入片元為points,渲染“房子”

#version 430 core
layout (points) in;
layout (triangle_strip, max_vertices=5) out;

in VS_OUT{
    vec3 color;
}gs_in[];

out vec3 fColor;

void build_Quad(vec4 p){
    fColor=gs_in[0].color;
    gl_Position=p+vec4(-0.2,-0.2, 0, 0);
    EmitVertex();
    gl_Position=p+vec4( 0.2,-0.2, 0, 0);
    EmitVertex();
    gl_Position=p+vec4(-0.2, 0.2, 0, 0);
    EmitVertex();
    gl_Position=p+vec4( 0.2, 0.2, 0, 0);
    EmitVertex();
    gl_Position=p+vec4( 0.0, 0.4, 0, 0);
    fColor=vec3(1.0,1.0,1.0);
    EmitVertex();
    EndPrimitive();
}

void main(){
    build_Quad(gl_in[0].gl_Position);
}

 

  2、nanosuit模型爆炸效果

#version 430 core
layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;

in VS_OUT{
    vec3 FragPos;
    vec2 TexCoords;
    vec3 Normal;
}gs_in[];

out vec2 TexCoords;

uniform float time;

vec3 GetNormal(){
    vec3 a=vec3(gl_in[0].gl_Position) - vec3(gl_in[1].gl_Position);
    vec3 b=vec3(gl_in[2].gl_Position) - vec3(gl_in[1].gl_Position);
    return normalize(cross(a,b));
}

vec4 explode(vec4 position, vec3 normal){
    float magnitude=2.0;
    vec3 direction=normal*((sin(time)+1.0)/2.0)*magnitude;
    return position+vec4(direction,0.0);
}

void main(){
    vec3 normal = GetNormal();

    gl_Position=explode(gl_in[0].gl_Position,normal);
    TexCoords=gs_in[0].TexCoords;
    EmitVertex();
    gl_Position=explode(gl_in[1].gl_Position,normal);
    TexCoords=gs_in[1].TexCoords;
    EmitVertex();
    gl_Position=explode(gl_in[2].gl_Position,normal);
    TexCoords=gs_in[2].TexCoords;
    EmitVertex();
    EndPrimitive();
}

 

  3、nanosuit模型的法線可視化

#version 430 core
layout (triangles) in;
layout (line_strip, max_vertices = 6) out;

in VS_OUT{
    vec3 FragPos;
    vec2 TexCoords;
    vec3 Normal;
}gs_in[];

void GenerateLine(int index){
    gl_Position=gl_in[index].gl_Position;
    EmitVertex();
    gl_Position=gl_in[index].gl_Position + vec4(gs_in[index].Normal,0.0) * 0.4;
    EmitVertex();
    EndPrimitive();
}

void main(){
    GenerateLine(0);
    GenerateLine(1);
    GenerateLine(2);
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM