[GLSL] Normalmap shader in XZY space


My friend and I are working on a small openGL project. One of the things we’re attempting to create is a normal map shader. Here is our current shader:


#version 330
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 modelMatrix;
uniform mat3 normalMatrix;
uniform mat3 normalModelMatrix;
uniform vec4 modelColor;
layout (location = 0) in vec3 in_position;
layout (location = 1) in vec3 in_normal;
layout (location = 2) in vec2 in_texCoords;
layout (location = 3) in vec4 in_Color;
out vec3 vNormal;
out vec2 vTexCoords;
out vec4 vColor;
out vec3 vEyePosition;
void main(){
        vEyePosition = (viewMatrix * modelMatrix * vec4(in_position, 1.0)).xyz;
    gl_Position = projectionMatrix * vec4(vEyePosition, 1.0);
        vNormal = normalMatrix * normalModelMatrix * in_normal;
        vTexCoords = in_texCoords;
        vColor = in_Color * modelColor;


#version 150
uniform sampler2D sampler;
uniform sampler2D normalMap;
uniform float specular;
uniform float gloss;
in vec3 vNormal;
in vec2 vTexCoords;
in vec4 vColor;
in vec3 vEyePosition;
mat3 cotangentFrame( vec3 N, vec3 p, vec2 uv ) {
    // get edge vectors of the pixel triangle
    vec3 dp1 = dFdx(p);
    vec3 dp2 = dFdy(p);
    vec2 duv1 = dFdx(uv);
    vec2 duv2 = dFdy(uv);
    // solve the linear system
    vec3 dp2perp = cross( dp2, N );
    vec3 dp1perp = cross( N, dp1 );
    vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
    vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
    // construct a scale-invariant frame
    float invmax = inversesqrt(max(0.00000000000000001, max(dot(T, T), dot(B, B))));
    return mat3( T * invmax, B * invmax, N );
vec3 perturbNormal( vec3 N, vec3 V ) {
    vec3 map = texture( normalMap, vTexCoords ).xyz;
    map = (map * (255.0/127.0)) - (128.0/127.0);
    map.z = sqrt( 1.0 - dot( map.xy, map.xy ) );
    mat3 TBN = cotangentFrame( N, V, vTexCoords );
    return normalize( TBN * map );
void write(vec3 diffuse, vec3 normal, float specular, float glossiness, vec3 emissive);
void main(){
        vec4 textureSample = texture(sampler, vTexCoords) * vColor;
        if(textureSample.a < 0.5){
        vec3 normalNormalized = normalize(vNormal);
        vec3 normalPerturbed  = perturbNormal(normalNormalized, normalize(vEyePosition));
        write(textureSample.xyz, normalPerturbed, specular, gloss, vec3(0, 0, 0));

What happens is as I rotate my camera the shading in the outcome changes; also the shading to begin with isn’t correct. I am almost certain that all of my uniforms are correct (camera and object matrices, samplers, ect).

My friend used this same method in a project of his and had correct normalmap results.

We believe that it is because my project uses the Z vector as the up component in the camera projection, whereas he used Y in his original project.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.