首页 > 解决方案 > GLSL 点积问题

问题描述

所以我尝试使用 OpenGL 实现基本的漫反射照明。我编写了一个简单的着色器,它将采用法线向量和光向量,并使用所述向量的点积计算像素的亮度。这是我的输出:

正如你所看到的,它在前两种情况下工作得很好,但在第三种情况下就完全崩溃了。顺便说一句,[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);
}

我认为这个问题与点积有关,但我找不到原因。

标签: c++openglglsl

解决方案


漫射光是使用公式计算的max(dot(-lightDir, normal), 0.0f);。因此,如果dot (-lightDir, normal)小于 0,则场景完全是黑色的。2 个单位向量
点积是 2 个向量之间夹角的余弦值。因此,如果角度 > 90° 且 < 270°,则结果小于 0。 这意味着,当物体背面被照亮时,它会显示为完全黑色。


光的方向是世界空间中的一个向量。dot(-lightDir, normal)只有当法线也是世界空间中的向量时才有意义。
从模型空间转换normal到世界空间:

normal = inverse(transpose(mat3(model))) * normalize(aNormal);

为什么用模型视图矩阵的逆转置来转换法线?


推荐阅读