1
\$\begingroup\$

I tried sampling equirectangular texture as a reflection. It simply does not work as intended. The texture is moving with my camera in a weird manner. Here is what I tried to do.

Fragment shader:

#version 460 core
#extension GL_ARB_bindless_texture : require
#extension GL_ARB_gpu_shader_int64 : require
layout ( location = 0 ) out vec4 FragColor;


const float one_o_2pi = 0.1591;
const float one_o_1pi = 0.3183;


in vec3     normal;
in vec3     eye;
in vec3     frag_pos;

uniform sampler2D   tex_pref;

vec2 uv_from_vec3(vec3 t_direction)
{
    float theta = acos(t_direction.y);
    float phi = atan(t_direction.z, t_direction.x);

    float u = phi * one_o_2pi + 0.5;
    float v = theta * one_o_1pi + 0.5;

    if (phi < 0.0)
    {
        u += 1.0;
    }
    
    return vec2(u, v);
}

vec3 pref_env_map(vec3 w_i, float t_roughness)
{
    vec2    pref_tex_coords = uv_from_vec3(w_i);
    vec3    result = textureLod(tex_pref, pref_tex_coords, 6.0 * t_roughness).rgb;
    return  result;
}

void main( void )
{   
    vec3    w_o = normalize(eye - frag_pos);
    vec3    n = normal;
    if (gl_FrontFacing)
        n = - n;
    vec3    w_i = normalize(reflect(-w_o, n));
    // The roughness is in the code, this is just a snippet
    FragColor = vec4(pref_env_map(w_i, roughness), 1.0);
}

Vertex shader:

#version 460 core

// vertex attributes
layout ( location = 0 ) in vec4 in_position_ms;
layout ( location = 1 ) in vec3 in_normal_ms;


//out vec4 outcol;

// uniform variables
//uniform mat4 P; // Model View Projection
uniform mat4 view; // Model View Projection
uniform mat4 proj; // Model View Projection
uniform vec3 uEye;

out vec3 normal;
out vec3 eye;
out vec3 frag_pos;



void main( void )
{
    mat4 P = proj * view;
    vec4 position = P * (in_position_ms);
    gl_Position = position;
    normal = in_normal_ms;
    eye = uEye;
    frag_pos = position.xyz;
}

```
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$
vec3    w_o = normalize(eye - frag_pos);

This line assumes frag_pos is expressed in the same space as eye — probably world space. (Also: note that eye coming from a uniform uEye, so you should just read the uniform directly instead of wasting an interpolator slot by passing it through as a varying/in-out variable)

vec4 position = P * (in_position_ms);
frag_pos = position.xyz;

These lines store frag_pos in post-projection space. That space is only valid to work with after you divide xyz by w, and the result you get is in normalized device coordinates — i.e. it's a point on the screen now, not in the 3D space of your world.

What you need to do is pass the world space position in frag_pos — one that has not been transformed by the view or projection matrices.

\$\endgroup\$
1
  • \$\begingroup\$ +1 to you, sir. You truly are right and I know you never want to multiply frag_pos by your projection/view matrices and I have never ever done that. I have written this program quickly without taking care of what is what so I have forgotten that P matrix is not in fact my model matrix. \$\endgroup\$
    – Eskimo Joe
    Apr 11, 2023 at 22:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .