|COMP1011 Assignment 2 - 05s2|
|Computing 1A 05s2||
Thu 13 Oct 2005 11:19
Much of this section is written in mathematical notation, not the notation
that will be used within the Haskell code. We distinguish the two by using
different fonts. Mathematical equations will be denoted using the
italic font while Haskell code will always be in the
typewriter font. We define many terms in this section in a
The world is the setting in which we compose scenes in. A scene can contain two types of objects: spheres and planes which are explained in a subsequent section of this document.
A point within the world is described using three-dimensional cartesian co-ordinates: a triple of values, (x,y,z). The co-ordinate system is left-handed meaning that if we orient the world such that the x-axis points right and the y-axis points up then the z-axis points away from the viewer (or "into the page").
Each scene is contained within a volume element or voxel. This is simply a fancy name for a cube which bounds the scene. A voxel is defined by its left/bottom/front corner, a point, and the length of its side. This can be written as a pair; e.g., ((1.0, 2.1, 3.0), 5).
A computer monitor is composed of a rectangular array of so-called pixels; an abbreviation for picture element. The colour of each pixel is composed of three components; a red, a green and a blue one. In this assignment colours will be represented as a triple of double-precision floating-point numbers of the form (r,g,b) where r,g, and b are between 0.0 and 1.0 inclusive.
For example the brightest possible red a computer can display is (1,0,0), while a very dark blue would have the value (0,0,0.1). (1,1,1) is the colour white, while (0,0,0) is black.
A vector is used to represent a direction and is represented as a triple of floating-point values. For instance, (0,0,1) is a vector pointing in the direction of the z-axis.
Vectors also have a magnitude (or length). For a given vector, (v1,v2,v3), the magnitude is defined as sqrt (v1^2 + v2^2 + v3^2). A unit vector is one that has a magnitude of one. A unit vector can be obtained from a regular vector by dividing each component of the vector by the magnitude. For instance, let m = magnitude (v1,v2,v3). Then a unit vector point in the same direction would be (v1/m, v2/m, v3/m).
In the rest of this section vectors are either written as triples or using a single capital letter. In this case the letter will be in bold; e.g., N
A ray consists of a point, called the origin of the ray, and a vector, called the direction. The origin of a ray should not be confused with the origin of the world which is the point (0,0,0). A ray is a function from time to points. For example: R(t) = (1,2,3) + (4,5,6)t
This ray has an origin of (1,2,3), equal to R(0), and a direction of (4,5,6). Note that the first is a point while the latter is a vector. There is no difference in their representation, yet they are used for very different purposes.
The intersection of a ray with an object is expressed as the time of intersection rather than a point. This makes sense since if we expressed it merely as a point there is no guarantee that it would actually lie on the ray. For example, the ray, R(t) = (0,0,0) + (1,2,3)t has value (2,4,6) at time t=2.
There are two types of objects that can appear in a scene, planes and spheres. The Haskell data type for representing these pure objects is:
data PureObject = Sphere Point Distance | Plane Distance Vector
A close real world example of a plane is a flat piece of paper that extends infinitely in all directions. They can have any orientation and be arbitrarily far way from the origin of the world. However, for the purposes of this assignment they shall only extend as far as the bounds of our world. To put it another way, planes do not extend outside the voxel containing the scene. Planes are represented as a distance and a unit normal vector, which we have not defined as of yet.
A normal vector is one that points in the direction that is perpendicular, or at 90 degrees to, all the points in a plane. It is therefore natural to define a plane in terms of a normal vector. However, as we shall see later they are vitally useful for describing the angle at which a ray strikes and reflects from an object. Another thing that should be mentioned is that a normal vector for a plane can point in two directions, one for each side of the plane. The side of the plane from which the vector emerges is known as the positive half-space of the plane; the other as the negative half-space.
The unit normal vector of the plane points towards the origin of
the world. For example, the plane,
Plane 10 (0,0,-1) is
parallel to the x-y plane but a distance of 10 units along the
Spheres are much easier to conceptualise in the mind. They have a centre (represented as a point) and a radius (a distance). The surface of a sphere is that collection of points that lies uniformly distant from the centre.
Each pure object in the scene has some associated properties:
colour, diffuse reflection coefficient and specular reflection
coefficient. (The meaning of the two reflections coefficients will be
covered in the Reflections section.) These objects are modelled in the
Physics module with the following data structure:
data Object = Object PureObject Double -- diffuse reflection coefficient Double -- specular reflection coefficient Colour -- colour
Lights in a scene have two properties: position and colour. They are assumed to emit light uniformly in all directions.
The position of the eye is fixed at the co-ordinates (0,0,-1) and it points directly down the z-axis. The dimensions of the view plane are determined by an angle known as the field of view. This angle is measured in degrees, not radians, and represents the angle formed between a line from the ray to the left and right hand sides of the view plane. The view plane is measured in terms of world co-ordinates and although this is the case it corresponds to the final image to be rendered (in pixels).
The final image to be rendered is something that will be displayed on a computer display and as such must be measured in terms of pixels. (See the section on Colour for a more in depth explanation.)
Objects in the real world reflect light in different ways. Some objects scatter the light that strikes them uniformly in all direction while others reflect light only at an angle equal to the angle of incidence. The former is known as diffuse reflection while the latter is known specular reflection. Each object within the world has a surface that reflects in a manner that is either diffuse, specular or both.
In the following sections we refer to the following diagram many times. It shows the light from the eye position (labelled as Viewer in the figure), the point of reflection, a vector pointing towards a light source, a normal vector at the point of intersection, a vector half way between the light vector and the one from the eye, and a ray, S, leaving the surface at the same angle at which the ray from the eye hits it.
Ambient light is just a base level of light in a scene. In the real world it is that light which comes from the millions of reflections on all the objects around you. Even if there are no light sources in a scene, each object will be lit to by ambient light.
The diffuse reflection coefficient, kd is a number in the range [0.0, 1.0]. An object that reflected all the light upon it would have kd = 1.0, while one that absorbed it all would have kd = 0.0.
Many real world objects have surfaces that are not entirely smooth and as a consequence reflect light evenly in all directions. A light source that sits directly above an object illuminates it more strongly than one that shines on a surface from an angle. This can be found by taking the dot product of the vectors N and Lj. (This only works if they are unit vectors.)
The intensity of the light, Ij, is attenuated
over distance. But this is not all! It is also possible that
Ij is equal to the colour black. This happens
when the light source is behind the object or there is another object
between the light source and the surface.
Specular reflections are those that occur on shiny, smooth
surfaces. Light rays upon such surfaces reflect off the surface at
precisely the angle they strike the surface. In other words, the
angle of incidence is equal to the angle of reflection. But as for
diffuse reflections we must also work out what the intensity of the
light striking the surface must be. This time, however, we do this by
taking the dot product of the normal and a new vector that lies half
way between the ray from the eye and the ray to the light. We call
this vector Hj.
Light reflected from other objects
It is also possible that an object is illuminated by light from other objects; moonlight striking the surface of the Earth is a good real world example of this. It turns out that this component of the light entering the eye is probably the easiest to calculate. We simply recursively call the ray tracing algorithm upon a ray that leaves the object at precisely the same angle the ray from the eye strikes it. This is ray S in the diagram above. This angle is calculated by finding the angle between the ray from the eye and the normal.
The value returned by recursively calling the ray tracing algorithm is then multiplied by the specular reflection coefficient.