OPenGL--几何着色器的应用(法线向量可视化)

简述

几何着色器可以多次调用EmitVertex()输出多种数量的图元,它产生的输出图元比输入的图元更多,这种方法叫扩充。使用这种方法可以显示任意物体顶点的法线向量。首先需要创建两个着色器程序,一个不适应几何着色器正常绘制物体,另一个通过几何着色器生成法线向量,然后输出直线(法线向量)。

顶点着色器

在顶点着色器中可以得到模型每个顶点的法线向量,为了适配模型缩放和旋转,我们在将法线变换到裁剪空间坐标之前,先使用法线矩阵变换一次。

mat3 normalMatrix = mat3(transpose(inverse(view * model)));

vs_out.normal = normalize(vec3(projection * vec4(normalMatrix * aNormal, 1.0)));

几何着色器

设置输入类型为triangles类型,所以每次输入一个三角形,即三个顶点。输出类型设置为line_strip类型,每个顶点都自己的需要显示法线向量,所以输出点为6。从内置变量gl_in获得输入点的个数。

for(i = 0; i < gl_in.length(); i++)

{

gl_Position = gl_in[i].gl_Position;

EmitVertex();

gl_Position = gl_in[i].gl_Position + vec4(gs_in[i].normal, 0.0) * 10;

EmitVertex();

EndPrimitive();

}

应用程序

在程序中,绘制完正常的模型后还需要绘制法线向量。

//--------基本模型绘制-------

//激活基本着色器

shader.use();

//模型矩阵变换

.....  

//绘制模型

draw();

 

//--------法线向量绘制-------

//激活输出法线向量的着色器

shader.use();

//模型矩阵变换

.....  

//绘制法线向量

draw();


着色器源码

geometry_shader.vs

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;

out VS_OUT {
    vec3 normal;
} vs_out;

uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;

void main()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0); 
	
    mat3 normalMatrix = mat3(transpose(inverse(view * model)));
    vs_out.normal = normalize(vec3(projection * vec4(normalMatrix * aNormal, 1.0)));
}

geometry_shader.gs

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

in VS_OUT {
    vec3 normal;
} gs_in[];

void main()
{
	int i;
	for(i = 0; i < gl_in.length(); i++)
	{
		gl_Position = gl_in[i].gl_Position;
		EmitVertex();
		gl_Position = gl_in[i].gl_Position + vec4(gs_in[i].normal, 0.0) * 10;
		EmitVertex();
		EndPrimitive();
	}

}

geometry_shader.fs

#version 330 core
out vec4 FragColor;

in vec2 TexCoords;

uniform sampler2D texture_diffuse1;

void main()
{
    FragColor = vec4(1.0, 1.0, 0.0, 1.0);
}

结果

OPenGL--几何着色器的应用(法线向量可视化)_第1张图片
参见:《OpenGL编程指南》第八版第2章

           LearnOpenGL教程

你可能感兴趣的:(OpenGL笔记,OpenGL笔记)