6.4 KiB
geometry | output |
---|---|
margin=2cm | pdf_document |
Raytracer part B
This project implements a raytracer with Blinn-Phong illumination and shadows implemented. The primary formula that is used by this implementation is:
\begin{equation} I_{\lambda} = k_a O_{d\lambda} + \sum_{i=1}^{n_\textrm{lights}} \left( f_\textrm{att} \cdot S_i \cdot IL_{i\lambda} \left[ k_d O_{d\lambda} \max ( 0, \vec{N} \cdot \vec{L_i} ) + k_s O_{s\lambda} \max ( 0, \vec{N} \cdot \vec{H_i} )^n \right] \right) \end{equation}
Where:
I_{\lambda}
is the final illumination of the pixel on an objectk_a
is the material's ambient reflectivityk_d
is the material's diffuse reflectivityk_s
is the material's specular reflectivityn_\textrm{lights}
is the number of lightsf_\textrm{att}
is the light attenuation factor (1.0 if attenuation is not on)S_i
is the shadow coefficient for lighti
IL_{i\lambda}
is the intensity of lighti
O_{d\lambda}
is the object's diffuse colorO_{s\lambda}
is the object's specular color\vec{N}
is the normal vector to the object's surface\vec{L_i}
is the direction from the intersection point to the lighti
\vec{H_i}
is halfway between the direction to the lighti
and the direction to the viewern
is the exponent for the specular component
In this report we will look through how these various factors influence the
rendering of the scene. All the images along with their source .txt
files,
rendered .ppm
files, and converted .png
files can be found in the examples
directory of this handin.
Varying k_a
k_a
is the strength of ambient light. It's used as a coefficient for the
object's diffuse color, which keeps a constant value independent of the
positions of the object, light, and the viewer. In the image below, I varied
k_a
between 0.2 and 1. Note how the overall color of the ball increases or
decreases in brightness when all other factors remain constant.
Varying k_d
k_d
is the strength of the diffuse component. It also affects an object's
diffuse color, but at a strength that's affected by how much of it faces the
light. Much like the dark side of the moon, the parts of the object that aren't
pointed at the light will not receive as much of the light's influence. In the
image below, I varied k_d
between 0.2 and 1. Note how the part pointed to the
light changes the strength of the brightness as all other factors remain
constant.
Varying k_s
k_s
is the specular strength. It uses the object's specular color, which is
like its reflective component. When there is a large specular k_s
, there's a
shine that appears on the object with a greater intensity. In the image below, I
varied k_s
between 0.2 and 1. Note how the whiteness of the light is more
reflective in higher k_s
values as other factors remain constant.
Varying n
n
is the exponent saying how big the radius of the specular highlight should
be. In the equation, increasing the exponent usually leads to smaller shines. In
the image below, I varied n
between 2 and 100. Note how the size of the shine
is the same intensity, but more focused but covers a smaller area as n
increases.
Multiple lights
Multiple lights are handled by multiplying each light against an intensity level, and then added together. Unfortunately, this means that the intensity of each light can't be too bright. We rely on the image to not use lights that are too bright. Because this may result in color values above 1.0, the final value is clamped against 1.0. Below is an example of a scene with two lights; one to the left and one to the right:
Shadows
Shadows are implemented by pointing a second ray between the intersection point of the original view ray and each light. If the light has something obstructing it in the middle, the light's effect is not used.
The soft shadow effect is realized by jittering rays across an area. In my implementation, a jitter radius of about 1.0 is used, and 75 rays are shot into uniformly sampled points within that radius. This also has the side effect that rays that are closer to the original ray are sampled more frequently. Each of these rays produces either 0 or 1 depending on if it was obstructed by the object. Taking the proportion of rays that hit as a coefficient for the shadow, we can get some soft shadow effects like this:
Light attenuation
Light attenuation is when more of the light is applied for objects that are closer to a particular light source. The function that's applied is an inverse quadratic formula with respect to the distance the object is from the light:
\begin{equation} f_\textrm{att}(d) = \frac{1}{c_1 + c_2 d + c_3 d^2} \end{equation}
Where:
f_\textrm{att}
is the attenuation factord
is the distance the object is from the lightc_1
,c_2
, andc_3
are user-supplied coefficients
As you can see below, the effect of the light drops off with the distance from the light (light coming from the left):
Depth Cueing
Depth cueing is when the objects further from the viewer have a lower opacity to "fade" into the background in some sense. A good example of this can be seen in the image below; note how the objects are less and less bright the further they are away from the eye.
Shortcomings of the model
The Phong formula is just a model of how light works, and doesn't actually represent reality. There's not actually rays physically escaping our eyes and hitting objects; it's actually the other way around, but computing it that way would not be efficient since we would be factoring in a lot of rays that don't ever get rendered.
Also, one needs to take care to use reasonable constants. For example, if using a different specular light color than the diffuse color, then it may produce some bizarre lighting effects that may not actually look right compare to reality.
Arbitrary Objects
Here is an example scene with some objects that demonstrates some of the features of the raytracer.