Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

openGL cubemap reflections in view space are wrong

I am following this tutorial and I managed to add a cube map to my scene. Then I tried to add reflections to my object, differently from the tutorial, I made my GLSL code in view space. However, the reflections seem a bit off. They are always reflecting the same side whatever angle you are facing, in my case, you always see a rock on the reflected object, but the rock is only on one side of my cube map. Here is a video showing the effect:

.

I tried with other shaped objects, like a cube, and the effect is the same. I also found this book, that shows an example of a view space reflections, and it seems I am doing something similar to it, but it still won't result in the desired effect. My vertex shader code:

#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;
}

My vertex code:

#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);
}
like image 585
Hirosam Avatar asked Dec 22 '22 18:12

Hirosam


1 Answers

Since you do the computations, in the fragment shader, in view space, the reflected vector (R) is a vector in view space, too. The cubemap (skybox) represents a map of the environment, in world space. You have to transform R form view space to world space. That can be done by the inverse view matrix The inverse matrix can be computed by the glsl built-in function 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);
}

Note, the view matrix transforms form world space to view space, this the inverse view matrix transforms form view space to world space. See also Invertible matrix.

like image 174
Rabbid76 Avatar answered Jan 14 '23 15:01

Rabbid76