The next step in the rendering process would be to find the local light intensity of a given point. Numerous lighting models exist to complete this task, but we will choose the Phong Reflection model as it is one the simpler ones.
The Phong model was developed by Bui Tuong Phong in the mid 70's[2]. It basically computes the illumination of a point by a combination of 3 different types of light; Ambient, diffuse and specular. As a first step, we will describe these light types in further detail.
Ambient: The ambient light is considered to illuminate an object completely and evenly. It is this light, in opposition the diffuse and specular, that gives the object its colour.
Diffuse: The diffuse light is obtained from reflecting a light source onto a rough surface. The diffuse light will vary according to the roughness of the reflective surface and the angle of the incident rays. The colour of this light is independent from that of the object that reflects it.
Specular: The specular light is the small highlights obtained from the reflection of shiny surfaces. A high specular level will create a small specular reflection as opposed to a lower specular level which will increase the size of the highlight. The following illustration compares the three types of lights. The specular light, is also independent from the diffuse and ambient lights.
Image courtesy of Wikipedia |
The basic Phong reflection formula: The light intensity I at point p is given by
- Ka, Kd ans Ks are the reflection ratio of incoming light of type ambient, diffuse and specular respectively.
The Phong Reflection model equation (Courtesy of Wikipedia) |
ia, im,d, im,s are the ambient, diffuse and specular light intensity. The subscript m relates to a specific light m element of all light sources involved in the scene.
Lm, is a unit vector originating at the point with a direction towards the light source m
N is the unit vector normal at the point
Rm is a unit vector of a perfectly reflected Lm vector for a light source m
V is a unit vector from the point towards the viewpoint
α is a brightness factor, where a higher value means a smaller but precise specular reflection
It is interesting to notice that only the ambient portion is independent to the number of light sources.
RGB colours and light:
The light values follow an established RGBA model where A is a transparency parameter. We must apply our Phong Reflection to the three RGB channels separately. This is easily done, as each intensity data type is built as a size three array. As a convention, the intensity indices will represent the following RGB values
intensity[0] = red
intensity[1] = green
intensity[2] = blue
Linear Algebra: Normals and dot products
One of the main pedagogical aspects of implementing the ray tracer lies in the practical use of diverse vector operations; Some of these operations being so common and used repeatedly in the program, they will have their own methods.
The normal
Finding the normal of different of different objects like planes or spheres varies according to the object. Glassner (pp37) defines the normal of a sphere at a given point on its surface.The RayTracer class implements the following method:
public double[] get_normal_for_sphere(Sphere sphere, double[] point){
double[] normal = new double[3];
for(int i = 0 ; i < 3 ; i++)
normal[i] = (sphere.centre[i] - point[i]) / sphere.radius;
return normal;
}
This normal is needed to find the Rm reflection vector. All we need to find a perfectly reflected vector is the vector of incidence and the normal at that point. Finding this reflected vector makes use of another linear algebra concept, the dot product.
The dot product
The dot product returns a scalar value equal to the magnitude of each component multiplied by the cosine of the angle between the two vectors. It is easily calculated by adding the multiplication of each vector's components. The RayTracer class implements the following:
The LightSource class creates light objects. Each light has a single coordinate point, and an intensity_diffuse and intensity_specular size 3 array that contain the RGB intensity values. These values, implemented as doubles (floating point) control the color of the diffuse and specular reflections. The user can control the displayed colour by setting each array's values by a range of 0 to 1. If all the values of a specific array are set equally, the resulting display would be a shade of grey. We will now display the outcome of different parameter values.
Examples
Changing the Alpha value changes the size of the specular reflection
Another question the author would raise pertains to the colour of the diffuse light and its specular counterpart. The Phong Reflection model enables the implementer to select different colours for the diffuse components and for the specular components. The fundamental question raised here would be if in the real world, a light source can have the diffuse and specular components to be of a different colour. The author's answer here would be no, as the diffuse light component originates from the same light source that create the specular portion, the diffuse aspect being created by the texture or roughness of the object exposed to the light. The dot product
The dot product returns a scalar value equal to the magnitude of each component multiplied by the cosine of the angle between the two vectors. It is easily calculated by adding the multiplication of each vector's components. The RayTracer class implements the following:
public double dot_product(double[] u, double[] v){
double product = 0.0;
for(int i = 0 ; i <3 ; i++)
product = product + u[i] * v[i];
return product;
}
- Evaluating the complexity of the reflection model The dot products of Lm and N and Rm and V are responsible for changing light's intensity at a point according to the angle it makes with the normal and the viewpoint. This has been a difficult aspect of dot products to visualize; We only have to understand that, as the angle of the rays change in relation to the fixed normal, and specular and diffuse intensity will change accordingly.
- VisibleObject and Sphere class members related to the Phong model
- The VisibleObject and Sphere class contain members to control some parameters of the Phong Reflection equation:
- The reflection constant member is an size 3 array for the ambient, diffuse and specular reflection values of the object. These values are implemented as doubles and can range from 0.0 to perhaps 1000. A higher value would suggest for instance a larger area of diffused light, or a larger specular area. The VisibleObject class also contains an ambient_intensity member, which contains a size 3 array to store RGB values. It is through this parameter, by changing the respective RGB values, that we can control the ambient colour of the object.
The LightSource class creates light objects. Each light has a single coordinate point, and an intensity_diffuse and intensity_specular size 3 array that contain the RGB intensity values. These values, implemented as doubles (floating point) control the color of the diffuse and specular reflections. The user can control the displayed colour by setting each array's values by a range of 0 to 1. If all the values of a specific array are set equally, the resulting display would be a shade of grey. We will now display the outcome of different parameter values.
Examples
Sphere created only with ambient light. The ambient B and G values are 0.0 while the R is 0.3 |
Same sphere but with diffuse light added. The light source in the image is located somewhere in close upper right of the sphere. |
Specular lighting has been added |
Here the Alpha value has been reduced to 1.0 |
Alpha value of 1000 |
Ambient reflection almost to 0. Alpha value of 10.0. Specular and diffuse lights are not the same colour as they are independent. |
Multiple lights and multiple objects
Once the Phong reflection model has been successfully implemented, we should consider multiple light sources potentially lighting multiple objects. This add nothing much to the complexity of the implementation; Sphere objects are created and inserted into an array so as different light sources are instantiated and inserted into another array. Each rendering process saves the partial intensity values created and then adds them up to the final value which will be displayed at the pixel. The problem multiple light sources create is that the light intensity at a given point being built by adding all light source intensities could potentially result in creating an intensity value which goes beyond the 255 limit. The solution for this problem resides into implementing a ceiling value of 255 for all light intensities prior to rendering. If the addition of multiple light sources add to a value of more than 255, they will appear white on the display. This simple code snippet does just that.
for(int j = 0 ; j < 3 ; j++)
if(intensity[j] > 255)
intensity[j] = 255;
Rendered scene with multiple spheres and 2 light sources |
Author's observations on the results
Stepping into the world of ray tracing has proven to be most challenging but also incredibly satisfying; The joy of being able to create images that somehow display the illusion of three dimensions simply by implementing geometrical and algebraic concepts is something the author had never experienced before. The results, simple in comparison to those produced by more advanced ray tracers, still have tremendous pedagogical value.
The principal evaluation of the rendering results would lie in the success of creating the illusion of 3 D. As the image above seems to well display this intention, the author's attention has been drawn to what appears to be limitations or flaws in the rendering process; One of the main elements which makes the scene look 'artificial' is the diffuse light of the large sphere appears to be too well defined for the top light source. The author cannot help thinking if a light source could actually create such light / shadow delimitation.
The principal evaluation of the rendering results would lie in the success of creating the illusion of 3 D. As the image above seems to well display this intention, the author's attention has been drawn to what appears to be limitations or flaws in the rendering process; One of the main elements which makes the scene look 'artificial' is the diffuse light of the large sphere appears to be too well defined for the top light source. The author cannot help thinking if a light source could actually create such light / shadow delimitation.
These exposed weaknesses of the model are easy to control and alleviate; One has to simply make the diffuse light colour the same as its specular counterpart. This would add an extra degree to of realism to the scene.
The author notes that these are minor flaws; It is obvious ray tracing can achieve an astonishing level of realism in its rendered scenes. The author is merely stating that having done the first steps in image rendering, he has acquired a better sense of where these limitations might lie.