In class we looked at material models that can be used to generate physically-based, photorealistic images. However, these models can be very expensive to evaluate. For real-time, interactive applications, one often uses simpler, more efficient models. These models are a bit crude and are not physically based, but still capture some of the basic visual phenomena that show up in real materials.
For this mini-hw, you will implement a simple real-time shader via an interactive web interface. The basic inputs will be:
- N --- the unit surface normal
- L --- the unit direction from the point on the surface toward the light source
- V --- the unit direction from a point on the surface toward the camera
- R --- the reflection of the view direction V in a surface with normal N
Your material will be built up from four simple components (here the angle brackets denote the usual dot product of U and V):
- Diffuse <N,L> --- Approximates a rough material that scatters light equally in all directions.
- Specular <L,R>^k --- Approximates a bright light source reflecting off a slightly glossy surface. The power k controls the "glossiness" of the surface.
- Fresnel (1-<V,N>)^p --- Approximates the behavior of light that hits the surface at "grazing angles" (i.e., very shallow angles). The parameter p controls the "sharpness" of the fresnel term.
- Ambient (constant) --- Approximates all other light bouncing around the scene. Simply a constant that is added to the final color value to increase the overall brightness.
Part 1: Reflect a vector
Consider a plane with unit normal N. Two vectors are "reflected in N" if they both make the same angle with N, and if their projections onto the plane are equal in magnitude and opposite in direction. Show that one can reflect a vector U by computing
V = 2 <U,N>N - U.
In the code below, you will already be provided with the reflection
R of the view vector
Part 2: Implement the shader!
Almost all the code for this shader has already been written for you, in this ShaderToy, which lets you easily try out OpenGL shader code (known as GLSL) on the web. All you have to do is plug in a few basic expressions corresponding to the four terms above. Click on the black triangle at the bottom of the editor to refresh the code.
You should compute the cosine of the angle between any two unit vectors u and v via the dot product. In GLSL, a dot product can be computed as
dot(u,v). Be careful of the fact that dot products can be negative, and think about how to modify these negative values in a meaningful way.
In general, GLSL is more or less like C, with a few minor differences. For instance, there is a
vec3 type that lets you specify 3D vectors. You can find a quick reference at this link, though you shouldn't need many of these functions.
IMPORTANT: You may get confusing errors if you type constants without decimal points, e.g., zero and one should be entered as
1. rather than
When everything is working properly, it should look like the image above. Print out your code and include it in your handin.
Part 3: Matching Parameters
Now that your shader has been implemented, try to pick the intensities
ka, the four colors
ambientColor, and the tuning parameters
p that match the images below as closely as possible. For each image, write the values you picked.
For our simple specular model (called the "Phong" model of specular reflection), what happens as the power
k approaches infinity? What kind of real-world material does this start to look like?