GLSL Tessellation Displacement Mapping - opengl

in my recent project I am working with hardware side tessellation. The pipeline I want to implement should take a low poly mesh, tessellate it and apply a displacement map.
The Tessellation works fine and just as I expected it to look like. However, when I apply the displacement map in the tessellation evaluation shader I get an output which is somewhat random.
This is the output without displacement (I used the heightmap as a texture to verify whether my texCoords are accurate)
This is what I get when I enable my displacement (using the same texture for both coloring and displacement):
The shader code is as follows:
//VERTEX SHADER
#version 430
layout(location = 0) in vec4 vertex;
layout(location = 1) in vec4 normal;
layout(location = 2) in vec2 texCoord;
out vec3 vPosition;
out vec3 vNormal;
out vec2 vTexCoord;
void main() {
vPosition = vertex.xyz;
vNormal = normal.xyz;
vTexCoord = texCoord;
}
//TESS CONTROL
#version 430
layout(vertices = 3) out;
in vec3 vPosition[];
in vec3 vNormal[];
in vec2 vTexCoord[];
out vec3 tcPosition[];
out vec3 tcNormal[];
out vec2 tcTexCoord[];
uniform float innerTessLevel;
uniform float outerTessLevel;
void main(){
float inTess = innerTessLevel;
float outTess = outerTessLevel;
tcPosition[gl_InvocationID] = vPosition[gl_InvocationID];
tcNormal[gl_InvocationID] = vNormal[gl_InvocationID];
tcTexCoord[gl_InvocationID] = vTexCoord[gl_InvocationID];
if(gl_InvocationID == 0) {
gl_TessLevelInner[0] = inTess;
gl_TessLevelInner[1] = inTess;
gl_TessLevelOuter[0] = outTess;
gl_TessLevelOuter[1] = outTess;
gl_TessLevelOuter[2] = outTess;
gl_TessLevelOuter[3] = outTess;
}
}
//TESS EVAL
#version 430
layout(triangles, equal_spacing, ccw) in;
in vec3 tcPosition[];
in vec3 tcNormal[];
in vec2 tcTexCoord[];
out vec3 tePosition;
out vec2 teTexCoord;
uniform mat4 ModelViewProjection;
uniform mat4 ModelView;
uniform sampler2D texHeight;
void main(){
vec3 p0 = gl_TessCoord.x * tcPosition[0];
vec3 p1 = gl_TessCoord.y * tcPosition[1];
vec3 p2 = gl_TessCoord.z * tcPosition[2];
vec3 pos = p0 + p1 + p2;
vec3 n0 = gl_TessCoord.x * tcNormal[0];
vec3 n1 = gl_TessCoord.y * tcNormal[1];
vec3 n2 = gl_TessCoord.z * tcNormal[2];
vec3 normal = normalize(n0 + n1 + n2);
vec2 tc0 = gl_TessCoord.x * tcTexCoord[0];
vec2 tc1 = gl_TessCoord.y * tcTexCoord[1];
vec2 tc2 = gl_TessCoord.z * tcTexCoord[2];
teTexCoord = tc0 + tc1 + tc2;
float height = texture(texHeight, teTexCoord).x;
pos += normal * (height * 0.2f);
gl_Position = ModelViewProjection * vec4(pos, 1);
tePosition = vec3(ModelView * vec4(pos,1.0)).xyz;
}
//GEOMETRY
#version 430
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
uniform mat4 ModelView;
in vec3 tePosition[3];
in vec3 tePatchDistance[3];
in vec2 teTexCoord[3];
out vec3 gFacetNormal;
out vec2 gTexCoord;
void main() {
vec3 A = tePosition[2] - tePosition[0];
vec3 B = tePosition[1] - tePosition[0];
vec4 N = vec4( normalize(cross(A, B)) , 0.0);
gFacetNormal = N.xyz;
gTexCoord = teTexCoord[0];
gl_Position = gl_in[0].gl_Position; EmitVertex();
gTexCoord = teTexCoord[1];
gl_Position = gl_in[1].gl_Position; EmitVertex();
gTexCoord = teTexCoord[2];
gl_Position = gl_in[2].gl_Position; EmitVertex();
EndPrimitive();
}
//FRAGMENT
#version 430
layout(location = 0) out vec4 fragColor;
in vec3 gFacetNormal;
in vec2 gTexCoord;
uniform float lit;
uniform vec3 light;
uniform sampler2D texHeight;
void main() {
#ifndef ORANGE_PURPLE
vec3 color = gl_FrontFacing ? vec3(1.0,0.0,0.0) : vec3(0.0,0.0,1.0);
#else
vec3 color = gl_FrontFacing ? vec3(1.0,0.6,0.0) : vec3(0.6,0.0,1.0);
#endif
if (lit > 0.5) {
color = texture(texHeight, gTexCoord).xyz;
vec3 N = normalize(gFacetNormal);
vec3 L = light;
float df = abs(dot(N,L));
color = df * color;
fragColor = vec4(color,1.0);
}
else {
fragColor = vec4(color,1.0);
}
}
It would be nice if someone could help me on that one.

Thanks to #AndonM.Coleman I solved the matter
In fact: the output gFacetNormal is only defined for your first vertex in the geometry shader. Outputs have to be set after every EmitVertex (...) as-per the GLSL specification, or they will be undefined. Many implementations re-use the last value set, but you cannot rely on that behavior if you want this to work portably. You need to set gFacetNormal once before every EmitVertex. void EmitVertex () - "Emits the current values of output variables to the current output primitive. On return from this call, the values of output variables are undefined."
Stupid of me not to notice that, but here is the working code:
//VERTEX
#version 430
layout(location = 0) in vec4 vertex;
layout(location = 1) in vec4 normal;
layout(location = 2) in vec2 texCoord;
out vec3 vPosition;
out vec3 vNormal;
out vec2 vTexCoord;
void main() {
vPosition = vertex.xyz;
vNormal = normal.xyz;
vTexCoord = texCoord;
}
//TESSELLATION CONTROL
#version 430
layout(vertices = 3) out;
in vec3 vPosition[];
in vec3 vNormal[];
in vec2 vTexCoord[];
out vec3 tcPosition[];
out vec3 tcNormal[];
out vec2 tcTexCoord[];
uniform float innerTessLevel;
uniform float outerTessLevel;
void main(){
float inTess = innerTessLevel;
float outTess = outerTessLevel;
tcPosition[gl_InvocationID] = vPosition[gl_InvocationID];
tcNormal[gl_InvocationID] = vNormal[gl_InvocationID];
tcTexCoord[gl_InvocationID] = vTexCoord[gl_InvocationID];
if(gl_InvocationID == 0) {
gl_TessLevelInner[0] = inTess;
gl_TessLevelInner[1] = inTess;
gl_TessLevelOuter[0] = outTess;
gl_TessLevelOuter[1] = outTess;
gl_TessLevelOuter[2] = outTess;
gl_TessLevelOuter[3] = outTess;
}
}
//TESSELLATION EVALUATION
#version 430
layout(triangles, equal_spacing, ccw) in;
in vec3 tcPosition[];
in vec3 tcNormal[];
in vec2 tcTexCoord[];
out vec3 tePosition;
out vec2 teTexCoord;
out vec3 teNormal;
uniform mat4 ModelViewProjection;
uniform mat4 ModelView;
uniform sampler2D texHeight;
void main(){
vec3 p0 = gl_TessCoord.x * tcPosition[0];
vec3 p1 = gl_TessCoord.y * tcPosition[1];
vec3 p2 = gl_TessCoord.z * tcPosition[2];
vec3 pos = p0 + p1 + p2;
vec3 n0 = gl_TessCoord.x * tcNormal[0];
vec3 n1 = gl_TessCoord.y * tcNormal[1];
vec3 n2 = gl_TessCoord.z * tcNormal[2];
vec3 normal = normalize(n0 + n1 + n2);
vec2 tc0 = gl_TessCoord.x * tcTexCoord[0];
vec2 tc1 = gl_TessCoord.y * tcTexCoord[1];
vec2 tc2 = gl_TessCoord.z * tcTexCoord[2];
teTexCoord = tc0 + tc1 + tc2;
float height = texture(texHeight, teTexCoord).x;
pos += normal * (height * 0.5f);
gl_Position = ModelViewProjection * vec4(pos, 1);
teNormal = vec3(ModelView * vec4(normal,0.0)).xyz;
tePosition = vec3(ModelView * vec4(pos,1.0)).xyz;
}
//GEOMETRY
#version 430
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
uniform mat4 ModelView;
in vec3 tePosition[3];
in vec2 teTexCoord[3];
in vec3 teNormal[3];
out vec3 gFacetNormal;
out vec2 gTexCoord;
void main() {
gFacetNormal = teNormal[0];
gTexCoord = teTexCoord[0];
gl_Position = gl_in[0].gl_Position; EmitVertex();
gFacetNormal = teNormal[1];
gTexCoord = teTexCoord[1];
gl_Position = gl_in[1].gl_Position; EmitVertex();
gFacetNormal = teNormal[2];
gTexCoord = teTexCoord[2];
gl_Position = gl_in[2].gl_Position; EmitVertex();
EndPrimitive();
}
//FRAGMENT
#version 430
layout(location = 0) out vec4 fragColor;
in vec3 gFacetNormal;
in vec2 gTexCoord;
uniform float lit;
uniform vec3 light;
uniform sampler2D texHeight;
void main() {
#ifndef ORANGE_PURPLE
vec3 color = gl_FrontFacing ? vec3(1.0,0.0,0.0) : vec3(0.0,0.0,1.0);
#else
vec3 color = gl_FrontFacing ? vec3(1.0,0.6,0.0) : vec3(0.6,0.0,1.0);
#endif
if (lit > 0.5) {
color = texture(texHeight, gTexCoord).xyz;
vec3 N = normalize(gFacetNormal);
vec3 L = light;
float df = abs(dot(N,L));
color = df * color;
fragColor = vec4(color,1.0);
}
else {
fragColor = vec4(color,1.0);
}
}

Related

Specular light erratic in OpenGL

I am working on a shader where the fragment shader should work in the tangent space. It works just as expected for both the ambient and diffuse light, but the specular light is just plain weird. It seems that nearby fragments can have a lot or no light with no obvious reasons.
The vertex shader is:
#version 330 core
layout (location = 0) in vec3 inVertex;
layout (location = 1) in vec3 inNormal;
layout (location = 2) in vec2 inTexture;
layout (location = 3) in vec3 inTangent;
layout (location = 4) in vec3 inBitangent;
out vec3 FragmentPosition;
out vec2 TextureCoordinate;
out vec3 TangentLightDirection;
out vec3 TangentViewPosition;
out vec3 TangentFragmentPosition;
void main()
{
FragmentPosition = vec3(inVertex);
vec3 normal = normalize(inNormal);
gl_Position = vec4( inVertex, 1 );
TextureCoordinate = inTexture;
vec3 tangent = normalize(inTangent);
vec3 biTangent = normalize(inBitangent);
mat3 toTangentSpaceTransformation = transpose(mat3(tangent,biTangent,normal));
TangentFragmentPosition = toTangentSpaceTransformation * FragmentPosition;
TangentLightPosition = toTangentSpaceTransformation * vec3(0,1,1);
TangentFragmentPosition = toTangentSpaceTransformation * vec3(0,0,3);
}
And the fragment shader is:
#version 330 core
out vec4 FragColor;
in vec3 FragmentPosition;
in vec2 TextureCoordinate;
in vec3 TangentLightDirection;
in vec3 TangentViewPosition;
in vec3 TangentFragmentPosition;
uniform sampler2D Texture;
uniform sampler2D normalTexture;
void main() {
vec3 normal = vec3(0,0,1);
float shininess = 4;
vec3 phongVector = vec3(0.3,0.7,1);
vec4 color = texture(Texture,TextureCoordinate);
vec4 ambientLightColor = vec4(1,1,1,1);//vec4(normalOffset,1);
// Calculation of ambient light
vec4 sunLightColor = vec4(1,1,1,1);
vec3 sunLightDirection = normalize(TangentLightPosition);
vec4 ambientLight = phongVector[0] * ambientLightColor;
// Calculation of diffuse light
float diffuseConst = max(dot(normal,sunLightDirection),0.0);
vec4 diffuseLight = phongVector[1] * diffuseConst * sunLightColor;
// Calculation of specular light
vec3 viewDirection = normalize(TangentViewPosition - TangentFragmentPosition);
vec3 reflectionDirection = reflect(-sunLightDirection,normal);
float spec = pow(max(dot(reflectionDirection,viewDirection),0),shininess);
vec4 specularLight = phongVector[2] * spec * sunLightColor;
FragColor = (specularLight)*color;
}
It was a typo. tangentFragmentPosition was initialized twice, while tangentViewPosition was not initialized at all. Initizalizing tangentViewPosition gave the desired result.

How can I make a smoother my heightmap? (Perlin noise, openGL)

I generate 2D perlin noise and I'm doing it terrain. But I have a problem with this. It's too gradual.
I tried x,z coordinates are divided or multiplied but doesn't work. How can I solve this problem without tessellation shader?
EDIT:
fragment shader code:
#version 430
in vec3 pos;
in vec2 text;
in vec3 norm;
layout(binding=3) uniform sampler2D texture_1;
layout(binding=4) uniform sampler2D texture_2;
layout(binding=5) uniform sampler2D texture_3;
vec3 lightPosition = vec3(-200, 700, 50);
vec3 lightAmbient = vec3(0,0,0);
vec3 lightDiffuse = vec3(1,1,1);
vec3 lightSpecular = vec3(1,1,1);
out vec4 fragColor;
vec4 theColor;
void main()
{
vec3 lightVector = normalize(lightPosition) - normalize(pos);
float cosTheta = clamp(dot(normalize(lightVector), normalize(norm)), 0.5, 1.0);
if(pos.y <= 120){
fragColor = texture2D(texture_2, text*0.05) * cosTheta;
}
if(pos.y > 120 && pos.y < 150){
fragColor = (texture2D(texture_2, text*0.05) * (1 - (pos.y-120)/30) + texture2D(texture_3, text*0.05) * ((pos.y-120)/30))*cosTheta;
}
if(pos.y >= 150)
{
fragColor = texture2D(texture_3, text*0.05) * cosTheta;
}
}
vertex shader code:
#version 430
in layout(location=0) vec3 position;
in layout(location=1) vec2 textCoord;
in layout(location=2) vec3 normal;
out vec3 pos;
out vec2 text;
out vec3 norm;
uniform mat4 transformation;
void main()
{
gl_Position = transformation * vec4(position, 1.0);
norm = normal;
pos = position;
text = position.xz;
}
It looks like you're using an 8bit heightmap which only gives you 256 different elevations. You could try using 16bit greyscale or encode the height in rgb.

Flicker artifacts in texture with tessellation

I encountered a problem when using tessellation.
Please refer to the link below
You may see some grey area after the rendering. If I rotate camera, they also changed (like a shinning effect.)
Could any one help me to figure out what is the reason? Thanks in advance.
Here is my code:
Vertex Shader:
in vec3 vertex_position;
in vec2 vertex_texcoord;
void main()
{
v_pos = vec3(vertex_position);
v_texcoord = vertex_texcoord;
}
TC shader:
layout(vertices = 3) out;
in vec3 v_pos[];
in vec2 v_texcoord[];
out vec3 tc_pos[];
out vec2 tc_texcoord[];
#define ID gl_InvocationID
#define TESS_LEVEL_INNER 3.0
#define TESS_LEVEL_OUTER 2.0
void main()
{
tc_pos[ID] = v_pos[ID];
tc_texcoord[ID] = v_texcoord[ID];
if (ID == 0)
{
gl_TessLevelInner[0] = TESS_LEVEL_INNER;
gl_TessLevelOuter[0] = TESS_LEVEL_OUTER;
gl_TessLevelOuter[1] = TESS_LEVEL_OUTER;
gl_TessLevelOuter[2] = TESS_LEVEL_OUTER;
}
}
Te shader:
layout(triangles, equal_spacing, cw) in;
in vec3 tc_pos[];
in vec2 tc_texcoord[];
out vec3 te_pos;
out vec2 te_texcoord;
void main()
{
vec3 p0 = gl_TessCoord.x * tc_pos[0];
vec3 p1 = gl_TessCoord.y * tc_pos[1];
vec3 p2 = gl_TessCoord.z * tc_pos[2];
vec2 t0 = gl_TessCoord.x * tc_texcoord[0];
vec2 t1 = gl_TessCoord.y * tc_texcoord[1];
vec2 t2 = gl_TessCoord.z * tc_texcoord[2];
te_pos = p0 + p1 + p2;
te_texcoord = t0 + t1 + t2;
vec4 p_t = vec4(te_pos-cam_pos.xyz,1.0) * cam_ori;
gl_Position = perspective_mat * p_t;
}
geometry shader:
layout (triangles) in;
layout (triangle_strip, max_vertices=3) out;
in vec3 te_pos[3];
in vec2 te_texcoord[3];
out vec2 g_texcoord;
void main()
{
gl_Position = gl_in[0].gl_Position;
g_texcoord = te_texcoord[0];
EmitVertex();
gl_Position = gl_in[1].gl_Position;
g_texcoord = te_texcoord[1];
EmitVertex();
gl_Position = gl_in[2].gl_Position;
g_texcoord = te_texcoord[2];
EmitVertex();
EndPrimitive();
}
Fragment:
in vec2 g_texcoord;
out vec4 frag_color;
void main()
{
frag_color = texture(tex_unit, g_texcoord);
}
Rendering Result

Shadow not rendered correctly

I am trying create shadow using shadow maps. I believe that shadow map is rendered well.
It seems that sphere's shadow is not in the correct place, so how would I go about fixing that? Also why is there a black ring around the sphere and how to eliminate it?
In the shadow map vertex shader
gl_Position = u_depthMatrix * worldCoord;
In the shadow map fragment shader
fragmentdepth = gl_FragCoord.z;
vs.glsl
uniform mat4 u_Model;
uniform mat4 u_View;
uniform mat4 u_Persp;
uniform mat4 u_InvTrans;
uniform vec3 u_LightColor;
uniform vec3 u_LightDirection;
uniform vec3 u_EyePos;
uniform mat4 u_depthBiasMatrix;
in vec3 Position;
in vec3 Normal;
in vec2 Texcoord;
out vec3 v_Normal;
out vec2 v_Texcoord;
out vec3 v_Position;
out vec3 v_PositionMC;
out vec4 shadowCoord;
void main(void)
{
v_Normal = (u_InvTrans*vec4(Normal,0.0)).xyz;
vec4 world = u_Model * vec4(Position, 1.0);
vec4 cameraCoord = u_View * world;
v_Position = cameraCoord.xyz;
shadowCoord = u_depthBiasMatrix * world;
gl_Position = u_Persp * cameraCoord;
}
fs.glsl
uniform sampler2D shadowMap;
uniform vec3 u_LightColor;
uniform vec3 u_LightDirection;
uniform vec3 u_EyePos;
uniform vec3 u_Ka;
uniform vec3 u_Kd;
uniform vec3 u_Ks;
in vec3 v_Normal;
in vec2 v_Texcoord;
in vec3 v_Position; //coordinate of vertex in camera coordinate system
in vec4 shadowCoord;
void main(void)
{
vec3 v_Normal1 = normalize(v_Normal);
//Diffuse Lighting
vec3 diff = normalize(u_LightDirection - v_Position);
float diffuse = max(dot(diff , v_Normal1) , 0);
vec3 diffuseColor = diffuse * u_Kd * u_LightColor;
//Specular Lighting
vec3 v = normalize(vec3(u_EyePos - v_Position));
vec3 h = normalize(diff + v);
float sl = pow(max(dot(h, v_Normal1) , 0.0), 50);
if ( diffuse <= 0 ) sl = 0;
vec3 specularColor = sl * u_Ks * u_LightColor;
vec3 v_Color;
v_Color = u_Ka + diffuseColor + specularColor ;
//Shadow Part
vec3 shadowCoord3;
float shadowFactor = 1.0;
if(shadowCoord.w > 0 )
{
shadowCoord3 = shadowCoord.xyz / shadowCoord.w ;
if ( texture2D( shadowMap, shadowCoord3.xy ).z < shadowCoord3.z)
{
shadowFactor = 0.2;
}
}
gl_FragColor = shadowFactor * vec4(v_Color , 1);
}

GLSL Shader Lighting not working

Can someone please help me review my glsl shader program. The Issue I am having is that despite the location of the light, the far edges of my mesh is black when it should not be.
To help illustrate, i provide this picture (Note the red,green, blue with white dot is the light position):
VertexShader:
#version 330
struct Matrix {
mat4 mvp;
mat4 mv;
mat4 view;
mat4 projection;
};
struct Light {
vec3 position; //Supplied in eye space(camera view )
vec3 color;
vec3 direction;
float intensity;
vec3 ambient;
};
attribute vec3 inputPosition;
attribute vec3 inputNormal;
attribute vec2 inputTexture;
attribute ivec2 number_influence;
attribute ivec4 boneIDs;
attribute vec4 boneWeights;
//--------------------------------------------
// UNIFORM:INPUT Supplied Data from C++ application
//--------------------------------------------
uniform Matrix matrix;
uniform Light light;
uniform vec3 cameraPosition; //position of viewer
// Bone deformation matrices
uniform mat4 boneFinalMatrix [30];
uniform mat4 boneInvBindPosition[30];
uniform mat4 boneTranslation [30];
//Output Variables
out vec3 oFragNormal;
out vec2 oTexCoord;
out vec3 oFragPosition;
void main() {
mat3 Normal_Matrix = mat3( transpose(inverse(matrix.view)) );
//PLACE HOLDER
vec4 INPUT= vec4(inputPosition , 1.0);
vec4 vertex= vec4(0.0,0.0,0.0,0.0);
vec3 normal= vec3(0.0,0.0,0.0);
int id = 0;
mat4 im;
vec4 O;
float weight;
mat4 locTrans;
mat4 invMatrix;
mat4 transform;
mat4 iBindMatrix;
mat4 FinalTranform;
mat4 Ttrans;
for( int i = 0; i < number_influence.x; i++ ){
id = boneIDs[i];
weight = boneWeights[id];
if(weight <= 0.0) weight = 1.0;
invMatrix = boneInvBindPosition[id];
locTrans = boneTranslation[id];
transform = boneFinalMatrix[id] ;
FinalTranform += transform * weight;
iBindMatrix+= (invMatrix)*weight;
Ttrans += locTrans * weight;
}
vertex = ( FinalTranform )* ( iBindMatrix * (INPUT )) ;
normal = mat3(FinalTranform) * mat3(iBindMatrix) * inputNormal ;
// output the transformed vertex
gl_Position = matrix.projection * matrix.view * vertex;
oFragPosition = vec3(matrix.view * vertex);
oFragNormal = Normal_Matrix * normal;
//store the texture data
oTexCoord = inputTexture.xy;
}
FragmentShader
#version 330
const vec4 AMBIENT = vec4(0.452, 0.452, 0.479, 1.0); //0.2 for all component is a good dark value
struct Light {
vec3 position;
vec3 diffuse;
vec3 direction;
float specularExponent;
vec3 ambient;
vec3 specular;
};
//the image
uniform sampler2D textureSampler;
uniform sampler2D normalSampler;
uniform vec3 cameraPosition;
uniform vec3 materialDiffuse;
uniform vec3 materialSpecular;
uniform Light light[10];
uniform int numberLights;
out vec4 finalOutput;
in vec2 oTexCoord;
in vec3 oFragNormal;
in vec3 oFragPosition;
void main() {
int i=0;
vec3 N = normalize( oFragNormal );
//V = frag to viewier vector
vec3 V = normalize( cameraPosition - oFragPosition );
vec4 texColor = texture2D(textureSampler, oTexCoord);
vec3 mDiffuse = vec3(0.0);
vec3 mSpecular = vec3(0.0);
float N_dot_L = 0.0;
float N_dot_H = 0.0;
vec3 L;
vec3 H;
for( i= 0; i < numberLights; i++){
L = normalize( oFragPosition - light[i].position );
//Diffuse: CmaterialDiffuseColor = max( Normal * LightDir, 0) * CmaterialColor * ClightColor
N_dot_L = max ( dot ( N, L), 0.0 ) ;
mDiffuse += materialDiffuse * light[i].diffuse * N_dot_L ;
//Specular: CmaterialSpecularColor = max(Normal * HalfAngleLightandViewVector, 0) ^ exp * CmaterialColor * ClightColor
H = normalize( (L + V)/2.0 );
N_dot_H = max( dot ( N , H ), 0.0 ) ;
mSpecular += materialSpecular * light[i].specular * vec3(pow(N_dot_H, light[i].specularExponent) );
}
finalOutput = texColor * vec4(mDiffuse,1.0 ) ;
finalOutput.a=1.0;
}
I found the solution to my problem: in the vertex shader I was transforming the vertex position and normal using my cameras view matrix. I removed it and now all works well.
Vertex Shader:
#version 330
struct Matrix {
mat4 mvp;
mat4 mv;
mat4 view;
mat4 projection;
};
struct Light {
vec3 position; //Supplied in eye space(camera view )
vec3 color;
vec3 direction;
float intensity;
vec3 ambient;
};
attribute vec3 inputPosition;
attribute vec3 inputNormal;
attribute vec2 inputTexture;
attribute ivec2 number_influence;
attribute ivec4 boneIDs;
attribute vec4 boneWeights;
//--------------------------------------------
// UNIFORM:INPUT Supplied Data from C++ application
//--------------------------------------------
uniform Matrix matrix;
uniform Light light;
uniform vec3 cameraPosition; //position of viewer
// Bone deformation matrices
uniform mat4 boneFinalMatrix [30];
uniform mat4 boneInvBindPosition[30];
uniform mat4 boneTranslation [30];
//Output Variables
out vec3 oFragNormal;
out vec2 oTexCoord;
out vec3 oFragPosition;
void main() {
//PLACE HOLDER
vec4 vertex= vec4(0.0,0.0,0.0,0.0);
vec3 normal= vec3(0.0,0.0,0.0);
int id = 0;
mat4 im;
vec4 O;
float weight;
mat4 locTrans;
mat4 invMatrix;
mat4 transform;
mat4 iBindMatrix;
mat4 FinalTranform;
mat4 Ttrans;
for( int i = 0; i < number_influence.x; i++ ){
id = boneIDs[i];
weight = boneWeights[id];
if(weight <= 0.0) weight = 1.0;
invMatrix = boneInvBindPosition[id];
locTrans = boneTranslation[id];
transform = boneFinalMatrix[id] ;
FinalTranform += transform * weight;
iBindMatrix+= (invMatrix)*weight;
Ttrans += locTrans * weight;
}
mat4 BoneFinal = ( FinalTranform )* ( iBindMatrix );
vertex = BoneFinal * vec4(inputPosition , 1.0) ;
mat3 transInvView = mat3( transpose(inverse(matrix.view )) );
mat3 transInvBone = mat3( transpose ( inverse (BoneFinal)) );
normal = vec3( normalize ( BoneFinal * vec4(inputNormal,0.0) ) );
mat3 Normal_Matrix = mat3( transpose(inverse(matrix.view )) );
// output the transformed vertex
gl_Position = matrix.projection * matrix.view * vertex;
oFragPosition = vec3( vertex);
oFragNormal = normal;
//store the texture data
oTexCoord = inputTexture.xy;
}
Fragment Shader:
#version 330
const vec4 AMBIENT = vec4(0.452, 0.452, 0.479, 1.0); //0.2 for all component is a good dark value
struct Light {
vec3 position;
vec3 diffuse;
vec3 direction;
float specularExponent;
vec3 ambient;
vec3 specular;
};
//the image
uniform sampler2D textureSampler;
uniform sampler2D normalSampler;
uniform vec3 cameraPosition;
uniform vec3 materialDiffuse;
uniform vec3 materialSpecular;
uniform vec3 materialAmbient;
uniform Light light[10];
uniform int numberLights;
out vec4 finalOutput;
in vec2 oTexCoord;
in vec3 oFragNormal;
in vec3 oFragPosition;
void main() {
int i=0;
vec3 N = normalize( oFragNormal );
//V = frag to viewier vector
vec3 V = normalize( vec3(0.0) - oFragPosition );
vec4 texColor = texture2D(textureSampler, oTexCoord);
vec3 mAmbient = vec3(0.0);
vec3 mDiffuse = vec3(0.0);
vec3 mSpecular = vec3(0.0);
float N_dot_L = 0.0;
float N_dot_H = 0.0;
vec3 L;
vec3 H;
for( i= 0; i < numberLights; i++){
L = normalize( oFragPosition - light[i].position );
mAmbient = materialAmbient * light[i].ambient;
//Diffuse: CmaterialDiffuseColor = max( Normal * LightDir, 0) * CmaterialColor * ClightColor
N_dot_L = max ( dot ( N, L), 0.0 ) ;
mDiffuse += materialDiffuse * light[i].diffuse * N_dot_L ;
//Specular: CmaterialSpecularColor = max(Normal * HalfAngleLightandViewVector, 0) ^ exp * CmaterialColor * ClightColor
H = normalize( (L + V));
N_dot_H = max( dot ( N , H ), 0.0 ) ;
mSpecular += materialSpecular * light[i].specular * vec3(pow(N_dot_H, light[i].specularExponent) );
}
finalOutput = texColor * (vec4(mDiffuse,1.0 ) + vec4(mAmbient, 1.0) );
finalOutput.a=1.0;
}
Thank you all for your help.