Advertisement

Parallax Mapping view errors

Started by January 03, 2022 03:50 PM
0 comments, last by pavixavi 2 years, 10 months ago

Can anyone guess why this shader is only working from a top down view position (0.0, -1.0, 0.0).

The parallax mapping calculation in the shader below is basically copied directly from learnopengl.com care of Joey Devries and adapted for my first-pass gBuffer shader program.

Video blow which may also help. Normals, Tangent, and Bitangent are viualised toward end of the video. All look correct.

Thanks.

    [VERTEX SHADER]
    #version 330 core
    layout (location = 0) in vec3 aPos;
    layout (location = 1) in vec3 aNormal;
    layout (location = 2) in vec2 aTexcoords1;
    layout (location = 3) in vec2 aTexcoords2;
    layout (location = 4) in vec2 aTexcoords3;
    layout (location = 5) in vec3 aTangent;

    uniform vec3 viewPos;
    uniform mat4 model;
    layout (std140) uniform matrix_block
    {
        mat4 projection;
        mat4 view;
    };
    uniform vec2 tex_scale;
    uniform vec2 tex_offset;

    out VS_OUT {
        vec3 FragPos;
        vec2 TexCoords;
        mat3 TBN;
        vec3 TanView;
        vec3 TanFrag;
    } vs_out;

    void main()
    {
        vs_out.FragPos = vec3(model * vec4(aPos, 1.0));
        vs_out.TexCoords = aTexcoords1 * tex_scale + tex_offset;

        mat3 normalMatrix = transpose(inverse(mat3(model)));
        
        vec3 T = normalize(normalMatrix * aTangent);
        vec3 N = normalize(normalMatrix * aNormal);
        T = normalize(T - dot(T, N) * N);
        vec3 B = normalize(cross(N, T));
        mat3 TBN = mat3(T, B, N);
        
        vs_out.TBN = TBN;

        vs_out.TanView = TBN * viewPos;
        vs_out.TanFrag = TBN * vs_out.FragPos;

        gl_Position = projection * view * model * vec4(aPos, 1.0);
    }

[FRAGMENT SHADER]
#version 330 core
layout (location = 0) out vec3 gPosition;
layout (location = 1) out vec3 gNormal;
layout (location = 2) out vec4 gAlbedoSpec;
layout (location = 3) out vec4 gOther;


struct Material {
    sampler2D texture_diffuse; //1
    sampler2D texture_roughness; // (specular #2)
    sampler2D texture_emmissive; // 4
    sampler2D texture_height; // 5
    sampler2D texture_normal; // 6
    sampler2D texture_occlusion; // 7
    sampler2D texture_metallic; // 8
   
    float shininess;
    //todo add float height_scale
    bool isActive;
};


in VS_OUT {
    vec3 FragPos;
    vec2 TexCoords;
    mat3 TBN;
    vec3 TanView;
    vec3 TanFrag;
} fs_in;

uniform Material material;

vec2 ParallaxMapping(vec2 texCoords, vec3 viewDir);

float height_scale = 0.05;

void main() {
    vec3 v = normalize(fs_in.TanView - fs_in.FragPos); //frag to view position direction vector
    vec2 texCoords = ParallaxMapping(fs_in.TexCoords, v);

    gPosition = fs_in.FragPos;


    vec3 normal = texture(material.texture_normal, texCoords).rgb;
    normal = normal * 2.0 - 1.0;
    normal = normalize(fs_in.TBN * normal);
    gNormal = normal;
    gAlbedoSpec.rgb = texture(material.texture_diffuse, texCoords).rgb;
    gAlbedoSpec.a = texture(material.texture_roughness, texCoords).r;
    gOther.rgb = v;
}


vec2 ParallaxMapping(vec2 texCoords, vec3 viewDir)
{
    const float minLayers = 8;
    const float maxLayers = 32;
    float numLayers = mix(maxLayers, minLayers, abs(dot(vec3(0.0, 0.0, 1.0), viewDir)));  
    float layerDepth = 1.0 / numLayers;
    float currentLayerDepth = 0.0;
    vec2 P = viewDir.yz / viewDir.z * height_scale;
    vec2 deltaTexCoords = P / numLayers;

    vec2  currentTexCoords = texCoords;
    float currentDepthMapValue = texture(material.texture_height, currentTexCoords).r;
     
    while(currentLayerDepth < currentDepthMapValue)
    {
        currentTexCoords -= deltaTexCoords;
        currentDepthMapValue = texture(material.texture_height, currentTexCoords).r;
        currentLayerDepth += layerDepth;
    }
  
    vec2 prevTexCoords = currentTexCoords + deltaTexCoords;
    float afterDepth  = currentDepthMapValue - currentLayerDepth;
    float beforeDepth = texture(material.texture_height, prevTexCoords).r - currentLayerDepth + layerDepth;
    float weight = afterDepth / (afterDepth - beforeDepth);
    vec2 finalTexCoords = prevTexCoords * weight + currentTexCoords * (1.0 - weight);
    return finalTexCoords;
}

This topic is closed to new replies.

Advertisement