对我的法线进行可视化是错误的。
正如你在video中所看到的,法线是错误的并且似乎在移动。 鸭子和球体都加载.dea文件(带有assimp),我自己对立方体进行了硬编码。
以下是我的着色器:
顶点着色器:
#version 430
layout(location = 0) in vec3 inPos;
layout(location = 1) in vec3 inNormal;
out vec4 vertex_normal;
void main(void) {
gl_Position = vec4(inPos, 1.0);
vertex_normal = vec4(inNormal, 1.0f);
}
几何着色器:
#version 430
layout(triangles) in;
layout(line_strip, max_vertices = 6) out;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
uniform mat4 normalMatix;
in vec4 vertex_normal[3];
out vec4 outColor;
void main(void)
{
//The "NormalViewProjection" matrix for the normals
mat4 NVP = projectionMatrix * viewMatrix * normalMatix;
//The ModelViewProjection matrix for the vertices
mat4 MVP = projectionMatrix * viewMatrix * modelMatrix;
//Normals transformed to screen space
const vec4 normals[] = {
normalize(NVP * vertex_normal[0]),
normalize(NVP * vertex_normal[0]),
normalize(NVP * vertex_normal[0]),
};
const float normalLength = 1.2f;
//gl_in.length() = 3, since we are working with triangles
for(int i = 0; i < gl_in.length(); i++)
{
outColor = normals[i];
const vec4 position = MVP * gl_in[i].gl_Position;
//First vertex
gl_Position = position;
EmitVertex();
//Second vertex
gl_Position = position + normals[i] * normalLength;
EmitVertex();
//Send the line to the fragment shader
EndPrimitive();
}
}
Fragment Shader:
#version 430
layout(location = 0) out vec4 fragColor;
in vec4 outColor;
void main(void)
{
fragColor = vec4(outColor.xyz, 1.0f);
}
答案 0 :(得分:1)
这里必须区分两种不同类型的载体:
投影仅为您提供位置矢量的正确结果,但不提供方向矢量。这正是代码中存在的问题所在:您将法线(方向)视为位置。
在我看来,正确的代码必须看起来像这样:
...
for(int i = 0; i < gl_in.length(); i++)
{
const vec4 position = MVP * gl_in[i].gl_Position;
//First vertex
gl_Position = position;
EmitVertex();
//Second vertex
const vec4 position2 = MVP * vec4(gl_in[i].gl_Position.xyz + vertex_normal[i].xyz, 1.0);
gl_Position = position2;
EmitVertex();
}
...
此处,法线尖端的位置首先在模型空间(gl_in[i].gl_Position.xyz + vertex_normal[i].xyz
)中计算,然后进行投影。
编辑:当您在模型矩阵中使用缩放并希望所有法线处于相同的长度时,您可能必须在添加之前将法线和位置转换为世界空间:
mat4 VP = projectionMatrix * viewMatrix;
...
for(int i = 0; i < gl_in.length(); i++)
{
const vec4 position_ws = modelMatrix * gl_in[i].gl_Position;
//First vertex
gl_Position = VP * position_ws;
EmitVertex();
//Second vertex
const vec4 normal_ws = normalize(normalMatrix * vertex_normal[i]);
gl_Position = VP * vec4(position_ws.xyz + normal_ws.xyz, 1.0);
EmitVertex();
}
...