Ok, so I think I’ve got the tangent calculation down. (Or not)
But upon rendering, well it doesn’t look right.
It could be down to the tangents, or the shaders, I don’t know.
On top of that, any books you guys could recommend for understanding glsl and lighting techniques and the math behind it?
Here’s some images:
(Note the actual vector values for the light position, doesn’t change)
(With normal texture coords scaled several times and small changes)
As you can see, not quite right, also, how can I smooth out the lighting, I assume it’s because I have a tangent per vertex, and not per polygon.
The shaders:
Vertex
#version 430 core
in vec4 in_Position;
in vec2 in_TexCoord;
in vec3 in_Normal;
in vec3 in_Tangent;
out VS_OUT {
vec2 pass_TexCoord;
vec3 eyeDir;
vec3 lightDir;
} vs_out;
uniform mat4 proj_matrix;
uniform mat4 view_matrix;
uniform mat4 model_matrix;
uniform vec3 lightPos = vec3(5.0, 0.0, 10.0);
void main(void) {
// EDITED // "mv_matrix" is used in the book, I assume this is how it's calculated
// Didn't know that the order of matrix multiplication would change things, reversing the order, made
// the specular stop moving, one step closer to it looking better.
mat4 mv_matrix = view_matrix * model_matrix;
// Calculate vertex position in view space
vec4 P = mv_matrix * in_Position;
// Calculate normal (N) and tangent (T) vectors in view space from incoming
// object space vectors
vec3 N = normalize(mat3(mv_matrix) * in_Normal);
vec3 T = normalize(mat3(mv_matrix) * in_Tangent);
// Calculate the bitangent vector (B) from the normal and tangent vectors
vec3 B = cross(N, T);
// I think it was a little mistake, in the book, this part was calculate just above the
// "eyeDir" calculation
vec3 V = -P.xyz;
// The light vector (L) is the vector from the point of interest to the light.
// Calculate that and multiply it by the TBM matrix
vec3 L = lightPos - P.xyz;
vs_out.lightDir = normalize(vec3(dot(V, T), dot(V, B), dot(V, N)));
// The view vector is the vector from the point of interest to the viewer,
// which in view space is simply the negative of the position.
// Calculate that and multiply it by the TBN matrix
vs_out.eyeDir = normalize(vec3(dot(V, T), dot(V, B), dot(V, N)));
// Pass the texture coordinate through unmodified so that the fragment shader
// can fetch from the normal and color maps
vs_out.pass_TexCoord = in_TexCoord;
// Calculate clip coordinates by multiplying our view position by
// the projection matrix
//gl_Position = proj_matrix * P;
// The above "gl_Position" just brings back the refresh color without any geometry
gl_Position = proj_matrix * view_matrix * model_matrix * in_Position;
}
Fragment
#version 430 core
// Textures
uniform sampler2D albedo_Tex;
uniform sampler2D normal_Tex;
uniform sampler2D reflect_Tex;
uniform sampler2D micro_Tex;
// Environment Map
uniform sampler2D envMap_Tex;
in VS_OUT {
vec2 pass_TexCoord;
vec3 eyeDir;
vec3 lightDir;
} fs_in;
out vec4 out_Albedo;
out vec4 out_Normal;
out vec4 out_Reflect;
out vec4 out_Micro;
void main(void) {
// Normalize our incoming view and light direction vectors
vec3 V = normalize(fs_in.eyeDir);
vec3 L = normalize(fs_in.lightDir);
// EDITED // Read the normal from the normal map and normalize it
// Scaling the texture coords made the base normal map much easier to see, as it is a
// 2048x2048 normal map with 4 squares, and a crease in between each square.
// It now looks perfect on the cube, but not the sphere due to the noticeable triangles.
// How do I go about smoothing it out? Would I have to "smooth" it before the
// data is sent to opengl? Or can I do that with the shaders?
vec3 N = normalize(texture2D(normal_Tex, fs_in.pass_TexCoord * 4.0).rgb * 2.0 - vec3(1.0));
// Calculate R ready for use in Phong lighting
vec3 R = reflect(-L, N);
// Fetch the diffuse albedo from the texture
vec3 diffuse_albedo = texture2D(albedo_Tex, fs_in.pass_TexCoord).rgb;
// Calculate diffuse color with the simple N dot L
vec3 diffuse = max(dot(N, L), 0.0) * diffuse_albedo;
// Uncomment this to turn off diffuse shading
// diffuse = vec3(0.0);
// Assume that specular albedo is white - it could also come from a texture
vec3 specular_albedo = vec3(1.0);
// Calculate Phong specular highlight
vec3 specular = max(pow(dot(R, V), 5.0), 0.0) * specular_albedo;
// Uncomment this to turn off specular highlights
// specular = vec3(0.0;
// Finale color is diffuse + specular
out_Albedo = vec4(diffuse + specular, 1.0);
}
This is pretty much what’s in the book itself
Also, when implementing basic Phong shading using the books code, it looks the way it’s supposed to, the sphere and dragon are smooth where as the Suzanne and the cube are not.