2016/07/26 12:19

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

• 译者: FreeBlues

## 顶点法线可视化

``````V0 = Pi
V1 = pi + (normal_length * N)
``````
• `i` 是顶点索引(范围`0~2`是因为`几何着色器`的输入是一个三角形).
• `Pi``Ni` 是第`i` 个顶点的`位置``法线`.
• `V0``V1` 是新线条的顶点.

`顶点法线``几何着色器`输入顶点的一部分. 下面是完整的原来渲染顶点法线的 `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

1
0 收藏

0 评论
0 收藏
1