|
Notes for Monday September 14 class -- Intro to ray tracing
Images
An image is essentially just an array of pixels.
Conceptually, the pixels are organized into
a two dimensional grid of rows and columns.
But in reality, the entire image is generally
stored as a contiguous one dimensional array of pixels.
Each pixel stores a color, which
usually contains
a red, a green and a blue component.
|
|
Color perception
The human eye can see a spectrum of light
within the range of about 400 nanometers
to 700 nanometers in wavelength.
As you can see in the figure, our red receptor
cells sensitve to mostly longer wavelengths, and
a little bit of very short wavelengths.
Our green receptors are sensitive to somewhat
shorter wavelengths than our red receptors.
Our blue receptors are sensitive to shorter wavelengths.
In practice, we approximate the color
at each pixel of an image
by a vector of three numbers:
[red, green, blue].
|
|
Shooting a ray at a pixel
Rendering an image by ray tracing
consists of shooting a mathematical ray from
an eye point through each pixel of the image
into the 3D scene,
as shown in the figure.
To render the pixel, we need to find
out what object, if any, the ray hits first.
For each pixel, we need to form a different ray.
A ray consists of an origin point V
and a unit length direction vector W.
A point P along the ray is
defined by P = V + t * W,
where t, the distance along the ray, is
a non-negative number.
Given a pixel with (x,y) coordinates,
and a distance f from the eye to the image plane,
V is given by [0,0,f],
and W is given by normalize([x,y,-f]).
|
|
Ray tracing to a sphere
As shown in the image below,
we intersect a ray with a sphere
by considering two equations:
- P = V + t * W (a point along a ray)
- x*x + y*y + z*z = r*r (a point on a radius r sphere at the origin)
(Continued below the figure)
We can do this much more easily if we
use dot products:
dot(A, B) = Ax * Bx + Ay * By + Az * Bz
If vectors are encoded as arrays, then
the Javascript code code to implement this is:
function dot(A, B) {
return A[0] * B[0] + A[1] * B[1] + A[2] * B[2];
}
Given a sphere with center C and radius r,
we ray trace to it as follows:
Move the sphere to the origin
by shifting coordinates.
Essentially, this means subtracting
the sphere center from ray origin V:
V = V - C
Now we combine the definition of a point along a ray:
[x,y,z] = V + t * W
with the definition of a point on a sphere of radius r at the origin:
x*x + y*y + z*z = r*r
If we look at the individual x,y,z coordinates of points along the ray:
[x,y,z] = [Vx + t * Wx, Vy + t * Wy, Vz + t * Wz]
Then we can substitute the terms in the ray equation into the sphere equation:
(Vx + t * Wx) * (Vx + t * Wx) +
(Vy + t * Wy) * (Vy + t * Wy) +
(Vz + t * Wz) * (Vz + t * Wz) = r * r
or:
( Wx * Wx + Wy * Wy + Wz * Wz ) * t2
+ 2 * ( Vx * Wx + Vy * Wy + Vz * Wz) * t
+ ( Vx * Vx + Vy * Vy + Vz * Vz - r * r ) = 0
Now we can compute t by considering the quadratic formula:
t = ( -B +- sqrt(B2 - 4AC) ) / 2A
= ( -B/2 +- sqrt((B/2)2 - AC) ) / A
We can use the definition of dot product to
find our A,B and C terms to plug into the quadratic formula.
A = W•W = 1
B/2 = V•W
C = V•V - r2
And that gives us the answer:
t = -V•W - sqrt((V•W)2 - V•V + r2)
Now we can move the origin back to where is belongs:
V = V + C
and use t to compute the point of intersection of the ray with the sphere:
P = V + t * W
We can also compute the normal vector
perpendicular to the sphere surface, which
we will need in order to shade the sphere:
N = normalize(P - C)
|
| |