Friday, September 30, 2005
Friday, September 02, 2005
Finally some Phong shading :)
This is the model I used for phong shading. Soon I will be using different models. It is a geosphere and backface culling is done. The green lines show the face normals and the red the avg normal. Note.. the normals are not culled and therefor those that are behind can also be seen!
However only the face normals are now used and therefor you can see the outlines of the triangles.. I will be using the average normals soon.
- The light source is the eye itself.
- The light color is (1, 1, 1).
- The diffuse material color is (0.6, 0.6, 0.6) which is gray.
- The specular material color is (1, 0, 0) which is red.
- The specular light color is (1, 1, 1)... same as the diffuse light color.
With no specular reflection and only diffuse component.
With shininess set to 1.
With shininess set to 10.
Note: Since only the face normals were used... the shading is not smooth and therefor the individual triangles are easily visible :)
Thursday, September 01, 2005
Refreshing memory... diffuse light (red book)
RGB Values for Lights and Materials
The color components specified for lights mean something different than for materials. For a light, the numbers correspond to a percentage of full intensity for each color. If the R, G, and B values for a light's color are all 1.0, the light is the brightest possible white. If the values are 0.5, the color is still white, but only at half intensity, so it appears gray. If R=G=1 and B=0 (full red and green with no blue), the light appears yellow.
For materials, the numbers correspond to the reflected proportions of those colors. So if R=1, G=0.5, and B=0 for a material, that material reflects all the incoming red light, half the incoming green, and none of the incoming blue light. In other words, if an OpenGL light has components (LR, LG, LB), and a material has corresponding components (MR, MG, MB), then, ignoring all other reflectivity effects, the light that arrives at the eye is given by (LR*MR, LG*MG, LB*MB).
Similarly, if you have two lights that send (R1, G1, B1) and (R2, G2, B2) to the eye, OpenGL adds the components, giving (R1+R2, G1+G2, B1+B2). If any of the sums are greater than 1 (corresponding to a color brighter than the equipment can display), the component is clamped to 1.
The ultimate diffuse light equation..
(max { L ยท n , 0} ) * diffuselight * diffusematerial
Where L = Normalised vector from vertex to light source.
n = Normal of the polygon at the vertex.
OR
where I is the reflected intensity, Ld is the light's diffuse color (gl_LightSource[0].diffuse), and Md is the material's diffuse coefficient (gl_FrontMaterial.diffuse).
The color components specified for lights mean something different than for materials. For a light, the numbers correspond to a percentage of full intensity for each color. If the R, G, and B values for a light's color are all 1.0, the light is the brightest possible white. If the values are 0.5, the color is still white, but only at half intensity, so it appears gray. If R=G=1 and B=0 (full red and green with no blue), the light appears yellow.
For materials, the numbers correspond to the reflected proportions of those colors. So if R=1, G=0.5, and B=0 for a material, that material reflects all the incoming red light, half the incoming green, and none of the incoming blue light. In other words, if an OpenGL light has components (LR, LG, LB), and a material has corresponding components (MR, MG, MB), then, ignoring all other reflectivity effects, the light that arrives at the eye is given by (LR*MR, LG*MG, LB*MB).
Similarly, if you have two lights that send (R1, G1, B1) and (R2, G2, B2) to the eye, OpenGL adds the components, giving (R1+R2, G1+G2, B1+B2). If any of the sums are greater than 1 (corresponding to a color brighter than the equipment can display), the component is clamped to 1.
The ultimate diffuse light equation..
(max { L ยท n , 0} ) * diffuselight * diffusematerial
Where L = Normalised vector from vertex to light source.
n = Normal of the polygon at the vertex.
OR
where I is the reflected intensity, Ld is the light's diffuse color (gl_LightSource[0].diffuse), and Md is the material's diffuse coefficient (gl_FrontMaterial.diffuse).
DOT product... i keep forgetting it :(
Vector1 (x1, y1, z1) and Vector2 (x2, y2, z2).
DotProduct = (x1*x2 + y1*y2 + z1*z2)
The value is the cosine of the angle between the two input vectors, multiplied by the lengths of those vectors.
So, you can easily calculate the cosine of the angle by either, making sure that your two vectors are both of length 1, or dividing the dot product by the lengths.
Cos(theta) = DotProduct(v1,v2) / (length(v1) * length(v2))
Backface culling
When deciding if a polygon is facing the camera, you need only calculate the dot product of the normal vector of that polygon, with a vector from the camera to one of the polygon's vertices. If the dot product is less than zero, the polygon is facing the camera. If the value is greater than zero, it is facing away from the camera.
DotProduct = (x1*x2 + y1*y2 + z1*z2)
The value is the cosine of the angle between the two input vectors, multiplied by the lengths of those vectors.
So, you can easily calculate the cosine of the angle by either, making sure that your two vectors are both of length 1, or dividing the dot product by the lengths.
Cos(theta) = DotProduct(v1,v2) / (length(v1) * length(v2))
- Values range from 1 to -1.
- If the two input vectors are pointing in the same direction, then the return value will be 1.
- If the two input vectors are pointing in opposite directions, then the return value will be -1.
- If the two input vectors are at right angles, then the return value will be 0. So, in effect,
Backface culling
When deciding if a polygon is facing the camera, you need only calculate the dot product of the normal vector of that polygon, with a vector from the camera to one of the polygon's vertices. If the dot product is less than zero, the polygon is facing the camera. If the value is greater than zero, it is facing away from the camera.
Problems with normals... sucks
I was having lots of problems with normals. The back face culling was not working properly and the color was not distributed along the object properly. It took me one whole day to find out where the problem was...there was a small error in calculating the cross product of two vectors!! The y component of the normal was not correct. I had to render the normals of each face in order to find that the problem was with normals..Now its fixed and the pictures below show normals correctly :)
A geosphere showing average normals. I found a very easy way of calculating the average normals after the face normals have been calculated. The average normals are required when I want shade smooth object with phong shading... such as this geosphere will be rendered like a true sphere. If face normals (shown below) are taken then the edges of the polygon will be visible and it will not be a perfect sphere!! However average normals are not always desirable... for example a box should be rendered with the face normals instead of the average normals. Applying phong shading with avg normals will make the corners of the box look curved instead of being pointed... and therefor the shading would make the box look like a sphere (something else).
The face normals of each triagle drawn from the vertex.
A geosphere showing average normals. I found a very easy way of calculating the average normals after the face normals have been calculated. The average normals are required when I want shade smooth object with phong shading... such as this geosphere will be rendered like a true sphere. If face normals (shown below) are taken then the edges of the polygon will be visible and it will not be a perfect sphere!! However average normals are not always desirable... for example a box should be rendered with the face normals instead of the average normals. Applying phong shading with avg normals will make the corners of the box look curved instead of being pointed... and therefor the shading would make the box look like a sphere (something else).
The face normals of each triagle drawn from the vertex.