The goal of this lab is explore ways of defining customized lights using shaders.
In this lab, you will build a shader that models a spotlight used in the theater and cinema. As in the previous lab, you will develop your shader in phases, with each phase adding an additional feature to the light shader.
The three phases are as follows:
BASIC: Basic definition of the spotlight cone
INTERMEDIATE: Focus control
ADVANCED: Use of textures to simulate the use of gobos
For each submission you should include the shader code and an example image which illustrates the effect. It should be clear that the later submissions are extensions of the code written for the earlier submissions of this lab.
As with previous assignments, two ZIP archives have been provided for you:
lab5files.zip
expands into a folder named lab5files which contains "starter"
code for your GLSL and RenderMan®
implementations.
lab5template.zip
expands into a folder named lab5results which is a framework
into which you should place your solutions and resulting images.
As with previous assignments, please place your solutions in the
lab5results folder, as follows:
Place your source code (not object files or binaries) in the appropriate
subfolder (e.g., your GLSL basic source files in the
GLSL/Basic folder, your RenderMan intermediate source
files in the RenderMan/Intermediate folder, etc.).
Place your result images in the Results subfolder, with
names of the form
lang-task.suffix.
For lang, use glsl or
rman,
as appropriate; for task, use basic,
intermediate. or advanced;
suffix should match the type of the image file
you created (typically, tiff, png,
gif,
etc.
For example, the result image for the Basic RenderMan task might
be named rman-basic.tiff, and the Advanced GLSL task result
image might be named glsl-advanced.png.
Create a ZIP archive of your results folder by using the "Compress" entry of the right-click menu for the folder. Submit this ZIP archive on one of the Ubuntu systems with the command
try wrc-grd shading-5 lab5results.zip
For this first part, you are to define a basic spotlight. The intensity of your spotlight will be attenuated in two ways:
Intensity falls off based on the distance from the direction vector of the light (i.e., across the width of the beam).
Optionally, intensity falls off based on the distance from the light to the surface being illuminated (the basic 1/d^2 attenuation factor is fine to use here).
Your shader should expect parameters indicating the position (named "from") and direction ("to") of the light, the color ("intensity") of the light, the field angle ("field") and beam angle ("beam") for the light (specified as degrees), and whether or not to apply distance-based attenuation ("distance") to the light.
As shown below, the beam angle is the angle (measured from the direction vector) at which the intensity of the light has fallen off to 50%. The field angle is the angle at which the intensity falls off to 10%.
The intensity of the light should be interpolated smoothly from 100% down
to 50% for angles between 0 degrees and the beam angle.
For angles between the beam angle and the field angle, the intensity
should be interpolated smoothly from 50% down to 10%.
(You may wish to use the
clamp() or smoothstep()
function for these interpolations.)
Any angle beyond the field angle will have an intensity of 0% (i.e.,
any point outside of the range of the field angle should be considered
to be not illuminated by the light).
To start with, I suggest using a beam angle of 15 degrees and a field angle of 25 degrees. You may want to experiment with these to achieve different lighting effects.
Remember that GLSL does not have "light shaders", so you will need to emulate this functionality in (preferably) the fragment shader.
For both RenderMan and GLSL, use a basic Phong shader for the surface of
objects, or even a simpler Lambertian shader.
I have provided a shader named simpleSurface in the
RenderMan file set which does this.
Submit two images for each language for this part: one with no distance-based attenuation, and one with the standard 1/d^2 distance-based attenuation.
In the real world, many lighting instruments provide a focus control that will enable the light to have a hard beam or a soft beam. For this task, you will add a parameter to your shader named "focus" which will control the width of the region between the beam and field angles.
Focus values will range from 0 to 1. A focus of 0.0 indicates a soft focus; in this case, the field and beam angles should be unaffected (i.e., exactly as in part 1). At the other extreme, a focus of 1.0 indicates a sharp focus; in this case, the effective field angle should be narrowed to equal the beam angle (in essence, removing the field angle effect). Any value between 0 and 1 would move the effective field angle part way into the region between the original field and beam areas.
Submit two images for each language for this part: one with the focus set to 0.5, and one with the focus set to 1.0. To better illustrate the focus effect, do not use distance-based attenuation for this part.
In Part 3, you will be adding a gobo to your lighting instrument. The gobo acts as a filter and is used to shape the beam. You can use a texture image for the representation of the gobo pattern. Unlike previous labs, this texture will not be mapped on any piece of geometry the scene; instead, you will have to determine the s and t values based on the direction of the light and the vector from the light to the surface point being illuminated. The mapping should be set up so that the entire beam fills the texture image as indicated below.
In order to perform this mapping, you need to transform the appropriate points and vectors to the coordinate space of the light source. This is a relatively straightforward process if the position and direction of the light and the position of the point being shaded are all in the same coordinate system (usually world coordinates, as it is intuitive to specify light parameters in world coordinates).
Transferring points and vectors from one coordinate space to another in RenderMan is easy, as there are conversion functions to do this for you. In GLSL, the process is a bit more complicated; the matrix that takes one from model coordinates to world coordinates is not ordinarily maintained by the OpenGL graphics state. This matrix can be derived by multiplying the GL_MODELVIEW matrix by the inverse of the OpenGL view matrix. The view matrix will need to be calculated in the OpenGL program and then passed as a uniform variable so that the GLSL shader can make use of it. This matrix will only change when the camera position and/or orientation changes.
To read in a texture image to use as the gobo, you can make use of the
SOIL library (used in lab 3).
The star image found in
/usr/local/pub/wrc/graphics/textures/images
is suitable for use as the gobo pattern.
If you use this image, please do not submit a copy with your solution.
You are free to experiment with other pattern images; if you
submit results based on other patterns, please do submit
copies of those pattern images.
As with the previous task, to better illustrate the gobo effect, do not use distance-based attenuation for this part.