I'm working on a ray tracer using C++ and OpenGL (glDrawPixels), and it is going well so far. However, my shading seems to be a bit off. I want my spheres to look a little smoother without having the blatant lines between intensities. At the moment, I am just trying to implement Lambertian shading, which is Intensity = Id * pd * (N dot L). I know how I need to calculate the (N dot L) by normalizing the normal vector and light vector, but what about the Id and pd (intensity diffuse and factor of proportionality)? I am just using a constant value of 2.5 to achieve the following:
(Here is a picture of what my shading looks like)
Obviously, 2.5 is completely arbitrary, and I'm only using it because my other attempts did not even resemble proper shading. The equation above seems to suggest that I should multiply the color by the intensity. This is my method:
Color simpleIlluminate(Vector3D normal, Vector3D light, Color color) {
float intensity = dotProduct(normal, light)*2.5f;
color = Color((unsigned int)intensity*color.r, (unsigned int)intensity*color.g, (unsigned int)intensity*color.b);
return color;
}
Assume that the normal vector and the light vector are correct. Color is just a color struct I made that has an unsigned int for each of the RGB values. The parameter Color color is the color of the sphere I want to shade, e.g. red = Color(255,0,0). To modify the intensity of the color, I simply multiply each value by the intensity I calculated, but it doesn't look right when I run it.
Can someone explain what I am missing and show me what the correct function should look like given the vectors and sphere color? I've looked everywhere, but I can't find a good solution. I might also be doing my float to unsigned int conversion wrong, but I'm not sure. Any help is appreciated.