View Full Version : [GLSL] Normalmap shader in XZY space

12-20-2014, 05:42 PM

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.