Hello again!
I have created a basic phong model but I noticed that inside faces are getting lighted too. It seems to me like Normals (their direction) are the same outside-inside and this is why this is happening. Take a look at the following video.
Outside it seems alright, but when I look inside the cube, the front face which is getting lighted from the outside, is also getting lighted from the inside. I believe that 99% this is because the inside face is actually using the same normals as the outside one, since in my vertex data normals are being initialised for each face (6 in total) not for 12. Do I have to create 72 vertices? 36 for the outside 6 faces and 36 for the inside with different normals.
In the specular calculations don't be suprised by this:
vec3 viewDirection = normalize(fragPosition - viewPos);
The viewPos is actually the Front of the camera not the position, which is relative to the view coordinate system no the world (I'm doing lighting calculations in the word coordinate system). Instead of transforming the viewPos (Front of the camera) into the word coordinate system, i just moved it with my mind from view to word (like we learned in maths) and came out with the above calculation which gives me the appropriate vector to get the correct angle between the view direction and the reflection of the light.
This is my vertex data:
//Vertex Data.
float vertices[] = {
// positions // normals // texture coords
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
This is my fragment shader:
#version 330 core
//Framgent Output.
out vec4 aPixelColor;
//Normals and TexCoordinates.
in vec3 fragNormal;
in vec2 fragTexCoord;
in vec3 fragPosition;
//Light Source.
struct LightSource
{
vec3 position;
vec3 ambient;
vec3 color;
};
//Material.
struct Material
{
sampler2D diffuse;
sampler2D specular;
int shininess;
};
//Uniforms.
uniform LightSource light;
uniform Material material;
uniform vec3 viewPos;
//Declare Functions.
vec3 GetAmbientColor();
vec3 GetDifffuseColor();
vec3 GetSpecularColor();
//-_-_-_-_-_-_-_-_-_-_-_-_-_-_-Main Function-_-_-_-_-_-_-_-_-_-_-_-_-_-_-//
void main()
{
float alpha_value = texture(material.diffuse, fragTexCoord).w;
vec3 ambient_color = GetAmbientColor();
vec3 diffuse_color = GetDifffuseColor();
vec3 specular_color = GetSpecularColor();
vec3 final_color = ambient_color + diffuse_color + specular_color;
//Set the final color.
aPixelColor = vec4(final_color, alpha_value);
}
//-_-_-_-_-_-_-_-_-_-_-_-_-_-_-Main Function-_-_-_-_-_-_-_-_-_-_-_-_-_-_-//
vec3 GetAmbientColor()
{
return light.ambient * vec3(texture(material.diffuse, fragTexCoord));
}
vec3 GetDifffuseColor()
{
vec3 light_direction = normalize(light.position - fragPosition);
vec3 normal = normalize(fragNormal);
float diffuse_factor = max(dot(light_direction, normal), 0);
return (light.color * diffuse_factor) * vec3(texture(material.diffuse, fragTexCoord));
}
vec3 GetSpecularColor()
{
vec3 light_direction = normalize(fragPosition - light.position);
vec3 normal = normalize(fragNormal);
vec3 viewDirection = normalize(fragPosition - viewPos);
vec3 refrection = normalize(reflect(light_direction, normal));
float spec_factor = pow( max(dot(refrection, viewDirection), 0) , material.shininess );
return light.color * spec_factor * vec3(texture(material.specular, fragTexCoord));
}
This is the vertex shader:
#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aNormal;
layout(location = 2) in vec2 aTexel;
uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;
out vec3 fragNormal;
out vec2 fragTexCoord;
out vec3 fragPosition;
void main()
{
gl_Position = proj * view * model * vec4(aPos, 1.0f);
fragNormal = mat3(transpose(inverse(model))) * aNormal;
fragTexCoord = aTexel;
fragPosition = vec3(model * vec4(aPos, 1.0f));
}