I'm implementing a small 3d renderer and I'm stuck at blinn_phong illumination model.
These are the steps that I've made until now.
1- calculate all the vertex normal
for (uint16_t i = 0; i < Cube->m_indices.size() - 2; i+= 3)
{
Vec3 Normal;
Vec3 p1(Cube->m_vertices[Cube->m_indices[i + 1]].position - Cube->m_vertices[Cube->m_indices[i]].position);
Vec3 p2(Cube->m_vertices[Cube->m_indices[i + 2]].position - Cube->m_vertices[Cube->m_indices[i]].position);
Normal = p1.Cross(p2);
Normal.Normalize();
Cube->m_vertices[Cube->m_indices[i]].normal = Cube->m_vertices[Cube->m_indices[i]].normal + Vec4(Normal, 0);
Cube->m_vertices[Cube->m_indices[i + 1]].normal = Cube->m_vertices[Cube->m_indices[i + 1]].normal + Vec4(Normal, 0);
Cube->m_vertices[Cube->m_indices[i + 2]].normal = Cube->m_vertices[Cube->m_indices[i + 2]].normal + Vec4(Normal, 0);
}
for (uint16_t i = 0; i < Cube->m_vertices.size(); ++i)
{
Cube->m_vertices[i].normal.Normalize();
}
2- transform positions and normals into eye-space. Positions with modelview matrix and normals with inverse-transpose of modelview matrix.
3- Calculate normal per pixel using barycentric coordinates.
4- Calculate blinn_phong
Color Rasterizer::BlinnPhongColor(Vertex p_position, Vec3 p_normal, Vertex p_lightPosition, Vec3 p_lightcomp, Color p_color)
{
Vertex position1(Mat4::ScreenToView(p_position.position,
m_rtexture.GetWidth(), m_rtexture.GetHeight()));
Vec3 lightDir(p_lightPosition.position - position1.position);
lightDir.Normalize();
float lambert = std::max(lightDir.dot(p_normal), 0.0f);
float specular = 0.0f;
if (lambert > 0.0f)
{
Vec3 viewDir = (position1.position *-1);
viewDir.Normalize();
Vec3 halfDir = (lightDir + viewDir);
halfDir.Normalize();
float specAngle = std::max(halfDir.dot(p_normal), 0.0f);
specular = pow(specAngle, 14.0);
}
Color amb = p_color * (p_lightcomp.x);
Color diff = p_color * (p_lightcomp.y * lambert);
Color spec = Color(255, 255, 255) * (p_lightcomp.z * specular);
Color total = spec;
return total;
}
*(p_lightcomp.x ,y z => ambient, diffuse, specular light component value).
This is what I get from the calculation.
a- Ambient light only.
b- Diffuse light only.
c- and finalllly a weirdest Specular light only.
I've been trying to solve this since last Sunday and still couldn't find any solution!
Please help!
Thank you -Hans
*P.S!! light position is at (0,0,0) and cube position is at (0,0, -2) and I've made rotation of 45 degree on x and y axis. Sorry for not specifying this!
EDIT: following Rabbid76 's comment, first test with fabs(lightDor.dot(p_normal));
1- no change with ambient and spec.
but Diffuse color changed.
2- test with second line where normal = position. Diffuse color and Specular colors were Black.
I've found the answer to my problem. I did mix clockwise/counterclockwise primitives. This changes all the calculations for normal vectors.
Thank you @Rabbid76