视图空间中的 openGL 立方体贴图反射是错误的

Hir*_*sam 4 opengl shader glsl coordinate-systems coordinate-transformation

我正在关注本教程,并设法将立方体贴图添加到我的场景中。然后我尝试向我的对象添加反射,与教程不同,我在视图空间中制作了我的 GLSL 代码。然而,反射似乎有点偏离。无论您面对什么角度,它们总是反射同一侧,在我的情况下,您总是在反射对象上看到一块岩石,但岩石仅在我的立方体贴图的一侧。这是一个显示效果的视频:

.

我尝试了其他形状的物体,如立方体,效果是一样的。我还发现了这本书,它显示了一个视图空间反射的例子,看起来我正在做类似的事情,但它仍然不会产生预期的效果。我的顶点着色器代码:

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 aTexCoord;

uniform mat4 Model;
uniform mat4 View;
uniform mat4 Projection;

out vec2 TexCoord;
out vec3 aNormal;
out vec3 FragPos;

void main()
{
    aNormal = mat3(transpose(inverse(View * Model))) * normal; 
    FragPos = vec3(View * Model * vec4(aPos,1.0));
    gl_Position = Projection * vec4(FragPos,1.0);
    TexCoord = aTexCoord;
}
Run Code Online (Sandbox Code Playgroud)

我的顶点代码:

#version 330 core

out vec4 FragColor;

in vec3 FragPos;
in vec3 aNormal;

uniform samplerCube skybox;


void main(){
    vec3 I = normalize(FragPos);
    vec3 R = reflect(I,normalize(aNormal));
    FragColor = vec4(texture(skybox,R).rgb,1.0);
}
Run Code Online (Sandbox Code Playgroud)

Rab*_*d76 8

由于您在片段着色器中进行计算,因此在视图空间中,反射向量 ( R) 也是视图空间中的向量。立方体skybox贴图( ) 表示世界空间中的环境贴图。您必须将R表单视图空间转换为世界空间。这可以通过逆视图矩阵来完成逆矩阵可以通过 glsl 内置函数计算inverse

#version 330 core

out vec4 FragColor;

in vec3 FragPos;
in vec3 aNormal;

uniform samplerCube skybox;
uniform mat4 View;

void main() {
    vec3 I      = normalize(FragPos);
    vec3 viewR  = reflect(I, normalize(aNormal));
    vec3 worldR = inverse(mat3(View)) * viewR;
    FragColor   = vec4(texture(skybox, worldR).rgb, 1.0);
}
Run Code Online (Sandbox Code Playgroud)

注意,视图矩阵从世界空间转换到视图空间,这个逆视图矩阵从视图空间转换到世界空间。另见可逆矩阵