Reputation: 117
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
//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
Upvotes: 2
Views: 1062
Reputation: 1632
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)
Upvotes: 1