GLSL 点积问题
Trouble with GLSL dot product
所以我尝试使用 OpenGL 实现基本的漫反射照明。我写了一个简单的着色器,它接受一个法向量和一个光向量,并使用所述向量的点积计算像素的亮度。这是我的输出:
- 来自左侧的光([1, 0, 0] 作为光矢量)
- 光线落下([0, -1, 0] 作为光线矢量)
- 从后面射来的光([0, 0, 1] 作为光向量)
如您所见,它在前两种情况下工作得很好,但在第三种情况下就完全崩溃了。顺便说一句,[0, 0, -1] 也不起作用,[0, 1, 1] 给出的输出与光亮时相同 ([0, 1, 0])。这是我的着色器:
- 顶点着色器:
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform vec3 lightDirection;
out vec3 normal;
out vec3 lightDir;
void main()
{
normal = normalize(aNormal);
lightDir = normalize(lightDirection);
gl_Position = projection * view * model * vec4(aPos, 1.0f);
}
- 片段着色器:
#version 330 core
in vec3 normal;
in vec3 lightDir;
out vec4 FragColor;
void main()
{
float grey = max(dot(-lightDir, normal), 0.0f);
FragColor = vec4(grey, grey, grey, 1.0f);
}
我认为这个问题与点积有关,但我找不到原因。
漫射光使用公式max(dot(-lightDir, normal), 0.0f);
计算。所以如果dot (-lightDir, normal)
小于0,场景全黑。
Dot product of 2 Unit vector 是两个向量之间夹角的余弦值。因此,如果角度 > 90° 且 < 270°,则结果小于 0。
这意味着,当物体从后面被照亮时,它会呈现全黑。
光线方向是世界中的矢量space。 dot(-lightDir, normal)
仅当法线也是世界中的矢量时才有意义 space.
将 normal
从模型 space 转换为世界 space:
normal = inverse(transpose(mat3(model))) * normalize(aNormal);
(Why transforming normals with the transpose of the inverse of the modelview matrix?)
所以我尝试使用 OpenGL 实现基本的漫反射照明。我写了一个简单的着色器,它接受一个法向量和一个光向量,并使用所述向量的点积计算像素的亮度。这是我的输出:
- 来自左侧的光([1, 0, 0] 作为光矢量)
- 光线落下([0, -1, 0] 作为光线矢量)
- 从后面射来的光([0, 0, 1] 作为光向量)
如您所见,它在前两种情况下工作得很好,但在第三种情况下就完全崩溃了。顺便说一句,[0, 0, -1] 也不起作用,[0, 1, 1] 给出的输出与光亮时相同 ([0, 1, 0])。这是我的着色器:
- 顶点着色器:
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform vec3 lightDirection;
out vec3 normal;
out vec3 lightDir;
void main()
{
normal = normalize(aNormal);
lightDir = normalize(lightDirection);
gl_Position = projection * view * model * vec4(aPos, 1.0f);
}
- 片段着色器:
#version 330 core
in vec3 normal;
in vec3 lightDir;
out vec4 FragColor;
void main()
{
float grey = max(dot(-lightDir, normal), 0.0f);
FragColor = vec4(grey, grey, grey, 1.0f);
}
我认为这个问题与点积有关,但我找不到原因。
漫射光使用公式max(dot(-lightDir, normal), 0.0f);
计算。所以如果dot (-lightDir, normal)
小于0,场景全黑。
Dot product of 2 Unit vector 是两个向量之间夹角的余弦值。因此,如果角度 > 90° 且 < 270°,则结果小于 0。
这意味着,当物体从后面被照亮时,它会呈现全黑。
光线方向是世界中的矢量space。 dot(-lightDir, normal)
仅当法线也是世界中的矢量时才有意义 space.
将 normal
从模型 space 转换为世界 space:
normal = inverse(transpose(mat3(model))) * normalize(aNormal);
(Why transforming normals with the transpose of the inverse of the modelview matrix?)