# 翻译:探索GLSL-用几何着色器(着色器库)实现法线可视化

• 译者: FreeBlues

## 顶点法线可视化

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

• 片段着色器
#version 150
in vec4 vertex_color;
out vec4 Out_Color;
void main()
{
Out_Color = vertex_color;
}


## 面法线可视化

layout(triangles) in;


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


• 几何着色器
#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

## 相关文章

posted on 2016-07-26 12:16  自由布鲁斯  阅读(3538)  评论(2编辑  收藏  举报