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