翻譯:探索GLSL-用幾何着色器(着色器庫)實現法線可視化


翻譯:探索GLSL-用幾何着色器(着色器庫)實現法線可視化

翻譯自: Exploring GLSL – Normal Visualizer with Geometry Shaders (Shader Library)

  • 譯者: FreeBlues

概述

親愛的讀者們, 我回來了! 已經三周沒發表新文章了... 很多事情需要去做, 再加上跟明媚的天氣 -- 導致沒有新文章給 Geek3D.

今天我們來看看一個簡單而有用的幾何着色器(geometry shaders)的應用: 法線可視化(normal visualizer). 我已經在文章Simple Introduction to Geometry Shaders in GLSL (Part 1)Simple Introduction to Geometry Shaders in GLSL (Part 2 中討論過 GLSL幾何着色器.

一個 幾何着色器 允許創建一個新的幾何圖形(一個頂點, 一條線, 或者一個多邊形) on the fly. 我們將會利用這個特性生成一個三角形網格的頂點和面的可視化法線的線條.

本文的示例用GLSL Hacker編寫, 你可以在 Code Sample PackGLSL_Geometry_Shader_Normal_Visualizer/ 目錄中找到全部的源碼. 你可以來這里下載(我建議使用最新的 DEV 版本).

一般而言, GLSL 程序並不特定於 GLSL Hacker. 你可以在任何 OpenGL/WebGL 應用中使用它們, 只需要做一些小小的修改(着色器輸入).

頂點法線可視化

截圖:

頂點法線的生成很簡單. 每個法線都是由兩個頂點構成的一條線. 第一個頂點就是輸入的頂點(屬於當前的網格-mesh). 第二個頂點就是第一個頂點沿着它的法線方向做一段位移后的新頂點.

V0 = Pi
V1 = pi + (normal_length * N)
  • i 是頂點索引(范圍0~2是因為幾何着色器的輸入是一個三角形).
  • PiNi 是第i 個頂點的位置法線.
  • V0V1 是新線條的頂點.

頂點法線幾何着色器輸入頂點的一部分. 下面是完整的原來渲染頂點法線的 GLSL 程序(頂點+幾何+片段).

  • 頂點着色器

這是一個簡單的透傳頂點着色器. 這里沒有任何變換(譯者注:指矩陣變換), 頂點將在幾何着色器中被變換用於最終的顯示.

#version 150
in vec4 gxl3d_Position;
in vec4 gxl3d_Normal;
 
out Vertex
{
  vec4 normal;
  vec4 color;
} vertex;
 
void main()
{
  gl_Position = gxl3d_Position;
  vertex.normal = gxl3d_Normal;
  vertex.color =  vec4(1.0, 1.0, 0.0, 1.0);
}
  • 幾何着色器

幾何着色器 做了大部分的工作: 它把頂點從本地空間(譯者注: 也叫模型空間)變換到窗口空間(裁剪空間)(gxl3d_ModelViewProjectionMatrix)並且創建了那些線條.

#version 150
layout(triangles) in;
 
// Three lines will be generated: 6 vertices
layout(line_strip, max_vertices=6) out;
 
uniform float normal_length;
uniform mat4 gxl3d_ModelViewProjectionMatrix;
 
in Vertex
{
  vec4 normal;
  vec4 color;
} vertex[];
 
out vec4 vertex_color;
 
void main()
{
  int i;
  for(i=0; i<gl_in.length(); i++)
  {
    vec3 P = gl_in[i].gl_Position.xyz;
    vec3 N = vertex[i].normal.xyz;
    
    gl_Position = gxl3d_ModelViewProjectionMatrix * vec4(P, 1.0);
    vertex_color = vertex[i].color;
    EmitVertex();
    
    gl_Position = gxl3d_ModelViewProjectionMatrix * vec4(P + N * normal_length, 1.0);
    vertex_color = vertex[i].color;
    EmitVertex();
    
    EndPrimitive();
  }
}
  • 片段着色器
#version 150
in vec4 vertex_color;
out vec4 Out_Color;
void main()
{
  Out_Color = vertex_color;
}

面法線可視化

截圖:

頂點法線的生成很簡單. 讓我們看看如何在幾何着色器中生成面法線. 我們所需要的是定義一個三角形的三個頂點. 幸運的是這些頂點是幾何着色器的輸入, 感謝這一行代碼:

layout(triangles) in; 

如果 P0, P1P2是面頂點的位置, 面法線就是下面的叉積(cross product)的結果:

V0 = P0-P1
V1 = P2-P1
N = cross (V1, V0)

截圖:

現在我們已經有了編寫面法線可視化的所有理論. 下面就是單獨的 幾何着色器 的代碼, 因為跟前面的 GLSL 程序相比, 只有 幾何着色器 做了更新. 這個 幾何着色器 生成 3 條頂點法線(黃色), 1 條面法線(紅色): 4 條線或者 8 個新頂點.

  • 幾何着色器
#version 150
layout(triangles) in;
layout(line_strip, <b>max_vertices=8</b>) out;
 
uniform float normal_length;
uniform mat4 gxl3d_ModelViewProjectionMatrix;
 
in Vertex
{
  vec4 normal;
  vec4 color;
} vertex[];
 
out vec4 vertex_color;
 
void main()
{
  int i;
  
  //------ 3 lines for the 3 vertex normals
  //
  for(i=0; i&lt;gl_in.length(); i++)
  {
    vec3 P = gl_in[i].gl_Position.xyz;
    vec3 N = vertex[i].normal.xyz;
    
    gl_Position = gxl3d_ModelViewProjectionMatrix * vec4(P, 1.0);
    vertex_color = vertex[i].color;
    EmitVertex();
    
    gl_Position = gxl3d_ModelViewProjectionMatrix * vec4(P + N * normal_length, 1.0);
    vertex_color = vertex[i].color;
    EmitVertex();
    
    EndPrimitive();
  }
  
 
  //------ One line for the face normal
  //
  vec3 P0 = gl_in[0].gl_Position.xyz;
  vec3 P1 = gl_in[1].gl_Position.xyz;
  vec3 P2 = gl_in[2].gl_Position.xyz;
  
  vec3 V0 = P0 - P1;
  vec3 V1 = P2 - P1;
  
  vec3 N = cross(V1, V0);
  N = normalize(N);
  
  // Center of the triangle
  vec3 P = (P0+P1+P2) / 3.0;
  
  gl_Position = gxl3d_ModelViewProjectionMatrix * vec4(P, 1.0);
  vertex_color = vec4(1, 0, 0, 1);
  EmitVertex();
  
  gl_Position = gxl3d_ModelViewProjectionMatrix * vec4(P + N * normal_length, 1.0);
  vertex_color = vec4(1, 0, 0, 1);
  EmitVertex();
  EndPrimitive();
}

參考

OpenGL Superbible, fifth edition, chapter 11

相關文章

Mesh Exploder with Geometry Shaders
Simple Introduction to Geometry Shaders in GLSL (Part 2)
Particle Billboarding with the Geometry Shader (GLSL)
(Shader Library) Bumpy Sphere Env Normal Mapping
Simple Introduction to Geometry Shaders in GLSL (Part 1)


免責聲明!

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



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