In terms of new concepts and code to write, this lab will be shorter than previous labs. However, it's our first lab with GLSL
and WebGL
so it can be hard to debug because we cannot "print/log" in a shader. Please read and try to interpret the cause of the error messages in the Console
when your shader does not compile. When an error is reported on line X, try to pinpoint which line this is by starting at the first line of the fragmentShaderSource
string and moving to an offset of X lines.
(Almost) All of the code you will write in this lab will be in the fragmentShaderSource
variable at the top of renderer.js
. Feel free to look at the other stuff, which will be covered next week. I said "almost" because there is one small change we will make on the JavaScript
side with the WebGL
context used by the Renderer
.
Before proceeding, let's look at how the template is set up. The rightmost dropdown in the HTML
file selects the shading algorithm to use. Try changing this to "Phong". You should see the model in blue now. When the selected option in this dropdown changes, it changes a variable in our WebGL
program called u_shader
. Notice that when u_shader == 0
(the first option in the dropdown, i.e. "None"), then the fragment shader defined in fragmentShaderSource
sets the final color (gl_FragColor
) to red and returns. Otherwise, it sets gl_FragColor
to blue. We'll talk about the details of the u_shader
variable next week, but please note the relationship between u_shader
and the color we want to set from the following table:
u_shader |
color to use |
---|---|
$\hspace{30pt}$1 | Phong (Part 1 + Part 3) |
$\hspace{30pt}$2 | Toon (Part 3 + Part 4) |
$\hspace{30pt}$3 | Cool-Warm (Part 3 + Part 5) |
The fragment shader defined in fragmentShaderSource
currently sets a constant color to the fragment (pixel). Please implement the Phong reflection model in the fragment shader. Use a light that is positioned exactly at the eye (camera) location (please ask yourself: what are the coordinates of the eye in the camera coordinate system?). Note that the coordinates of the surface point being processed in the fragment shader (relative to the camera coordinate system) is available in the variable point
. The surface normal is available in the variable normal
which has already been normalized. Remember to use a unit vector for the direction to the light gl_FragColor
(use a transparency of 1 to make the result opaque).
This part will look a bit strange at first because we need to fix a few things in Part 2 (left-most image below after rotating the model a bit).
WebGL
context.In the Renderer
draw
method, note that the gl
context is used to set some attributes. Every time we draw, we need to clear the existing buffer of color and depth values. Add the following line after the gl.clearColor
call:
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
This will clear the buffers used to store the color and depth of each pixel. When you rotate the model, you should no longer see a cascading effect. However, it still doesn't look quite right (middle image above). This is because we need to enable depth testing. Please see the following documentation and add the appropriate line to enable depth testing.
https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/enable
Your rendering should then look like the right-most image above.
A silhouette is a black border where the model surface normal starts to point away from the observer. This can be added by checking the dot product between the surface normal normal
) and the vector point
) to the eye (gl_FragColor
to black and return
from the fragment shader. Use
Toon shading can be implemented by "banding" the result of the diffusion term in the Phong reflection model into discrete values. There are various ways to do this. Here we will band the color by resetting the diffusion term according to the following table:
value used | |
---|---|
0 - 0.25 | 0 |
0.25 - 0.5 | 0.25 |
0.5 - 0.75 | 0.5 |
0.75 - 1.0 | 0.75 |
The color returned for toon shading would then be the ambient + diffuse contributions (no need for specular reflection, but you can discretize that as well if you want). You should still use a silhouette for this effect.
Another artistic shading technique is to use a "cool-to-warm" shading model. The idea here is to, again, use the diffusion term to influence the final color. For this technique, please return (store in gl_FragColor
):
where normal
) and
The initial submission for the lab is due on Thursday 4/24 at 11:59pm EDT.
Please see the Setup page for instructions on how to commit and push your work to your GitHub repository and then submit your repository to Gradescope (in the Lab 8 assignment). I will then provide feedback within 1 week so you can edit your submission.
Remember, if you see a git
error when you try to sync changes, you might need to run the following two commands in the Terminal before being able to sync (push) your changes:
git config --global pull.rebase true
git pull