2023-02-05 21:52:42 -06:00
|
|
|
---
|
|
|
|
geometry: margin=2cm
|
|
|
|
output: pdf_document
|
|
|
|
---
|
|
|
|
|
2023-02-16 01:14:22 -06:00
|
|
|
# Raytracer part B
|
|
|
|
|
2023-02-15 02:36:53 -06:00
|
|
|
This project implements a raytracer with Blinn-Phong illumination implemented.
|
|
|
|
The primary formula that is used by this implementation is:
|
|
|
|
|
2023-02-16 01:14:22 -06:00
|
|
|
\begin{equation}
|
|
|
|
I_{\lambda} =
|
|
|
|
k_a O_{d\lambda} +
|
|
|
|
\sum_{i=1}^{n_\textrm{lights}} \left(
|
|
|
|
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 object
|
|
|
|
- $k_a$ is the material's ambient reflectivity
|
|
|
|
- $k_d$ is the material's diffuse reflectivity
|
|
|
|
- $k_s$ is the material's specular reflectivity
|
|
|
|
- $n_\textrm{lights}$ is the number of lights
|
|
|
|
- $IL_{i\lambda}$ is the intensity of light $i$
|
|
|
|
- $O_{d\lambda}$ is the object's diffuse color
|
|
|
|
- $O_{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 light $i$
|
|
|
|
- $\vec{H_i}$ is halfway between the direction to the light $i$ and the
|
|
|
|
direction to the viewer
|
|
|
|
- $n$ is the exponent for the specular component
|
2023-02-15 02:36:53 -06:00
|
|
|
|
2023-02-05 21:52:42 -06:00
|
|
|
## Varying $k_a$
|
|
|
|
|
2023-02-16 01:14:22 -06:00
|
|
|
$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.
|
|
|
|
|
|
|
|
{width=360px}
|
|
|
|
\
|
2023-02-05 21:52:42 -06:00
|
|
|
|
|
|
|
## Varying $k_d$
|
|
|
|
|
2023-02-16 01:14:22 -06:00
|
|
|
TODO
|
|
|
|
|
|
|
|
{width=360px}
|
|
|
|
\
|
2023-02-05 21:52:42 -06:00
|
|
|
|
|
|
|
## Varying $k_s$
|
|
|
|
|
2023-02-16 01:14:22 -06:00
|
|
|
TODO
|
|
|
|
|
|
|
|
{width=360px}
|
|
|
|
\
|
2023-02-05 21:52:42 -06:00
|
|
|
|
|
|
|
## Varying $n$
|
|
|
|
|
2023-02-16 01:14:22 -06:00
|
|
|
$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 more focused but covers a smaller area as $n$ increases.
|
|
|
|
|
|
|
|
{width=360px}
|
|
|
|
\
|
|
|
|
|
|
|
|
## 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:
|
|
|
|
|
|
|
|
{width=360px}
|
|
|
|
\
|
|
|
|
|
|
|
|
## 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:
|
|
|
|
|
|
|
|
{width=360px}
|
|
|
|
\
|
|
|
|
|
|
|
|
## 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.
|
|
|
|
|
|
|
|
{width=360px}
|
|
|
|
\
|
|
|
|
|
|
|
|
## Shortcomings of the model
|
|
|
|
|
|
|
|
The model cannot be used to represent TODO
|
2023-02-05 21:52:42 -06:00
|
|
|
|
|
|
|
# Arbitrary Objects
|
|
|
|
|
2023-02-16 01:14:22 -06:00
|
|
|
{width=360px}
|
|
|
|
\
|
|
|
|
|