2
votes

I was trying to add a normal map effect to a shader tutorial I have found here but with no luck.

UPDATE 1: I updated the code adding a tangent space matrix

Vertex shader:

#version 330


in vec3 inPosition;
in vec3 vertNormal;
in vec2 vertTexCoord;
in vec4 vertNormalMapping;

out vec3 fragVert;
out vec3 fragNormal;
out vec2 fragTexCoord;
out vec4 fragNormalMapping;
out mat3 TBNMatrix;

uniform mat4 modelViewProjectionMatrix;
uniform mat4 camera;

void main(){    

vec3 tangent; 
vec3 binormal; 

vec3 c1 = cross( vertNormal, vec3(0.0, 0.0, 1.0) ); 
vec3 c2 = cross( vertNormal, vec3(0.0, 1.0, 0.0) ); 

if( length(c1)>length(c2) )
{
    tangent = c1;   
}
else
{
    tangent = c2;   
}

tangent = normalize(tangent);

binormal = cross(vertNormal, tangent); 
binormal = normalize(binormal);

mat3 normalMatrix = transpose(inverse(mat3(camera * modelViewProjectionMatrix )));
vec3 n = normalize(normalMatrix * vertNormal);
vec3 t = normalize(normalMatrix * tangent.xyz);
vec3 b = normalize(normalMatrix * binormal.xyz);
TBNMatrix = mat3(t, b, n);



fragTexCoord = vertTexCoord;
fragNormal = vertNormal;
fragVert = inPosition;
fragNormalMapping = vertNormalMapping;


gl_Position  = camera * modelViewProjectionMatrix * vec4(inPosition, 1.0);



}

Fragment shader #version 330

precision highp float;


uniform vec3 cameraPosition;
uniform mat4 modelViewProjectionMatrix;
uniform mat4 camera;
uniform sampler2D tex;
uniform sampler2D heightMap; 



uniform float materialShininess;
uniform vec3 materialSpecularColor;

uniform struct Light {
   vec3 position;
   vec3 intensities; //a.k.a the color of the light
   float attenuation;
   float ambientCoefficient;
} light;


in vec3 fragNormal;
in vec3 fragVert;
in vec2 fragTexCoord;
in vec4 fragNormalMapping;
in mat3 TBNMatrix;

out vec4 finalColor;

void main() {

vec3 surfacePos = vec3(modelViewProjectionMatrix * vec4(fragVert, 1));
    vec4 surfaceColor = texture(tex, fragTexCoord);
    vec3 surfaceToLight = TBNMatrix * (light.position - surfacePos) ;
    vec3 surfaceToCamera = TBNMatrix * (cameraPosition - surfacePos);



vec3 normal = normalize(texture(heightMap, fragTexCoord).xyz * 2.0 - 1.0);


//ambient
vec3 ambient = light.ambientCoefficient * surfaceColor.rgb * light.intensities;

//diffuse
    float diffuseCoefficient = max(0.0, dot(normal, surfaceToLight));
    vec3 diffuse = diffuseCoefficient * surfaceColor.rgb * light.intensities;

//specular
    float specularCoefficient = 0.0;
    if(diffuseCoefficient > 0.0)
        specularCoefficient = pow(max(0.0, dot(surfaceToCamera, reflect(-surfaceToLight, normal))), materialShininess);
    vec3 specular = specularCoefficient * materialSpecularColor * light.intensities;

    //attenuation
    float distanceToLight = length(light.position - surfacePos);
    float attenuation = 1.0 / (1.0 + light.attenuation * pow(distanceToLight, 2));

//linear color (color before gamma correction)
vec3 linearColor = ambient + attenuation*(diffuse + specular);

    //final color (after gamma correction)
    vec3 gamma = vec3(1.0/2.2);
    finalColor = vec4(pow(linearColor, gamma), surfaceColor.a);

}

The result is better but now the lighting is calculated wrong O.O wrong light

//OLD I have tried with a blank color texture and a correct normal map texture and the result is this: The normal map is calculated correctly but... these lines are not so cool to see :-(

Any idea of what is the cause? thank you everyone for the help =D

1
what this line is suppose to do??? normalMap.g = 1.0-normalMap.g; also why are you multiplying your vertexCoord in the frag shader (for each pixel) while nor matrix nor vertexPos change per fragment?j-p
More over where are your tangent space vectors (T,B,N) which are pixel space coordinate, essential for normal mapping,j-p
THank you @j-p for the optimization =D I changed the code. this 'normalMap.g = 1.0-normalMap.g;' is for reverse the G coordinate... mhm... it's not wokring without reverting it neither, so it's not this the problem. mhm...DaviDeMo
Have a look at a complete normal mapping example and implementing tangent space vectors (T,B,N) in you light equation would surely do the trickj-p
I would have understand another visual errors, like bump mapping not whowing or something else. But here it's working... the bump mapping is showing and calculating correctly. The only problem we have is that it's flickering like crazy :-(DaviDeMo

1 Answers

1
votes

posting here for clarity...

mv = camera * transform;//modelview
mvp = proj * camera * transform;//modelviewprojection
mvi = transpose(inverse(mv))//modelview inverse (=gl_NormalMatrix)

so you should have in place of modelViewProjectionMatrix passed to the shader the modelView and the projection separately, and compute the resulting mvp in the vertex shader.

(or precompute them all on cpu side)