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

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

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

  • 譯者: FreeBlues

概述

親愛的讀者們, 我回來了! 已經三週沒發表新文章了... 不少事情須要去作, 再加上跟明媚的天氣 -- 致使沒有新文章給 Geek3D.app

今天咱們來看看一個簡單而有用的幾何着色器(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. 咱們將會利用這個特性生成一個三角形網格的頂點和麪的可視化法線的線條.3d

本文的示例用GLSL Hacker編寫, 你能夠在 Code Sample PackGLSL_Geometry_Shader_Normal_Visualizer/ 目錄中找到所有的源碼. 你能夠來這裏下載(我建議使用最新的 DEV 版本).code

通常而言, GLSL 程序並不特定於 GLSL Hacker. 你能夠在任何 OpenGL/WebGL 應用中使用它們, 只須要作一些小小的修改(着色器輸入).orm

頂點法線可視化

截圖: 索引

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

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

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

  • 頂點着色器

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

#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)

相關文章
相關標籤/搜索