辅导案例-CSE 167-Assignment 2
CSE 167 Assignment 2

Due: Feb 14 12:59 PM


From the two previous assignments we have got somewhat familiar with an OpenGL program.
Now it's the time to really get to the fun part of lighting and shading!

From this point we're no longer using the rasterizer code you wrote for assignment 1. We will be
using OpenGL for all our rendering in later homeworks. Welcome to the shader world!

In this homework you will learn how to:
1. Modify parser to support triangle meshes (10 pts)
2. Center and scale the 3D models (10 pts)
3. Render polygons (triangle meshes) in modern OpenGL (10 pts)
4. Control objects using the mouse (30 pts)
a. rotating (20/30 pts)
b. translating (10/30 pts)
5. Set material properties (10 pts)
6. Set up light sources (20 pts)
a. directional light (5/20 pts)
b. point light (15/20 pts)
7. Enable Light Interaction Controls (15 pts)
PURE FUN: ​Spot lights

A video demo of this assignment will be posted later this week. Refer to Piazza for more
information!

Part One ​Complete the Model Loader

You already know how to load point clouds from assignment one. Now it is time to modify the
parser you've written to support the triangle meshes by loading the connectivities of vertices.
In the OBJ file format, the connectivity is defined by lines starting with an 'f' for face. Just as how
you parsed for vertices and normals, now parse for face and store properly.
Example line of face:
f 31514//31514 31465//31465 31464//31464
In this example, the 31514​th​ vertex, 31465​th​ vertex, and the 31464​th​ vertex forms a triangle in a
counterclockwise manner.
Notice​: Make sure the stored faces values are 0-based because they are 1-based in the OBJ
file.

What to render:
- All 3 objects (dragon, bunny, bear) individually to the screen
- Switch among three models by pressing F1, F2, and F3 keys

Part Two​ Scaling and Centering

In order to make mouse control work well, we want those models to be centered in the window
and have similar scale on the screen. To achieve this goal, you will have to process the vertices
of each of the models, translate and scale them.
An easy way to do this is to process the vertices value, find such scale factor and translation
once when parsing the values, and store transmation matrix in the memory (see below).

What to render:
- Center the model such that the geometric center of the model resides in the center of the
rendering window. This can be done by looking at each dimension (x, y, z)
independently, calculate the maximum and minimum coordinates along each dimension,
and use the midpoint between them as the centering point of the model.
- Scale all the models to the same size: fit them within an imaginary 2x2x2 cube centered
around the origin. In other words: the vertices position values should be in range of
[-1,1].
Part Three​ Rendering in Modern OpenGL

In the starter code, you have been switching between your own rasterizer an with modern
OpenGL. Now it's time to unleash the power of OpenGL: use VAO (Vertex Array Object), VBOs
(Vertex Buffer Object), and EBOs (element buffer object). Refer to here if you want to learn
more about these OpenGL objects: ​https://learnopengl.com/Getting-started/Hello-Triangle
Rasterizer mode is no longer needed for this and later homeworks, so feel free to deprecate it :)

What to render:
- properly generate such buffer like you did for assignment one
- bind them to the model vao and properly pass to OpenGL
- Render the model with triangle mesh faces

Part Four​ Mouse Control

Now everything looks nice and good on the screen. It's time to add some interaction function to
your program. You are going to disable the spin function in your code, and substitute it with
some real update function.
What to render:
- Rotation​:
While the left mouse button is pressed and the mouse is moved, rotate the model about
the center of your graphics window. We will refer to this operation as "trackball rotation".
A video will be posted on Piazza about how it should work.
- Translation in x-y plane​:
When the right mouse button is pressed and the mouse is moved, move the model in the
plane of the screen (similar to translation by keyboard operation in assignment 1). Scale
this operation so that when the model is in the screen space z=0 plane, the model
follows your mouse pointer as closely as possible. If you don't have a right mouse
button, use your mouse button along with a function key (Shift, Control, Alt, etc.) to enter
this mode.
- Translation along z-axis​:
Use the mouse wheel to move the model along the screen space z axis (i.e., in and out
of the screen = push back and pull closer).
- Scale​:
Retain the functionality of the 's'/'S' keys to scale the model about its object space origin.
The other keyboard functions for the control of the 3D models are no longer needed, but
it does not hurt to keep them supported.

Details on the Trackball Rotation
The figure below illustrates how to translate mouse movement into a rotation axis and angle. m​0
and m​1​ are consecutive 2D mouse positions. These positions define two locations v and w on
an invisible 3D sphere that fills the rendering window. Use their cross product as the rotation
axis ​a = cross(v,w) ​ and the angle between v and w as the rotation angle.


Horizontal mouse movement exactly in the middle of the window should result in a rotation just
around the y-axis. Vertical mouse movement exactly in the middle of the window should result in
a rotation just around the x-axis. Mouse movements in other areas and directions should result
in rotations about an axis a which is not parallel to any single coordinate axis, and is determined
by the direction the mouse is moved in.
Once you have calculated the trackball rotation matrix for a mouse drag, you will need to
multiply it with the object-to-world transformation matrix of the object you are rotating. For step
by step instructions, take a look at ​this tutorial​. Note that the tutorial was written for Windows
messages, instead of GLFW mouse events. This means that you'll need to replace the
"CSierpinskiSolidsView::OnLButtonDown", "CSierpinskiSolidsView::OnMouseMove", etc. with
an appropriate GLFW equivalent.
To help you better picture what to do, here is a line by line commented version of the
trackBallMapping function:



Part Five​ Define Materials

In order to render the 3D models as realistically as possible, write shaders to render them with
the Phong illumination model and per pixel lighting. Per pixel lighting means that you have to do
all of your light reflection calculations in the fragment shader.
For the shader to work, you will have to define light sources as well as different materials for
each of your 3D models. Write vertex and fragment shaders to support the features listed below.
In this part of the project, you should use fixed positions for the lights and all other lighting
parameters. But know that later you're going to have to make some of these parameters user
modifiable, so you may want to already introduce variables instead of using constant values.

Assign each of the 3D model files different material properties, following the instructions below.
Each object should have a different color of your choice.

What to define:
- One model with very shiny, no diffuse reflection
- One model with only diffuse reflection, with no shininess
- One model with significant diffuse ​and​ specular reflection component
- Enable switch between normal coloring and Phong illumination model with key 'n'

Rendering Mode Switch
Support keyboard key 'n' to switch between the rendering modes of normal coloring and your
new Phong illumination model.
- Normal coloring is useful to keep around so that you can check if your surface normals
have been calculated correctly. Normal coloring should work just as you implemented it
in assignment one, except now you render the entire 3D model (all triangles, not just the
vertices) with normal shading.
- In Phong render mode, you render your 3D models more realistically, determined by
their materials and the type of light source shining on them.


Part Six​ Define Lights

You will need to create two separate light sources: a directional light and a point light. Use two
C++ classes to define the parameters for the two types of light sources. Your class
implementation is very flexible, but should at least contain these variables:

What to define:
Directional Light Properties
- color (vec3)
- direction (vec3)
Point Light Properties
- color (vec3)
- position (vec3): world coordinate of the light source
- Notice: use ​linear​ attenuation when calculating the light intensity

Part Seven ​Interactive Light Controls

To test out the effect of your light sources, make the light sources movable with the mouse, and
add keyboard commands for certain illumination parameters as described below.

You will have the following components implemented:
- Light Scene Selection
- Light Representation (indicate the location of point light)
- Light Movements

Light Selection
Make the lights selectable with the number keys.
What to render:
- Keys ‘1’, ‘2’ and ‘3’ are used to switch among 3 scenes.
- Key '1': Directional light(rotating) only. Mouse movement does not apply to anything.
- Key '2': Directional light(rotating) + point light. Mouse movement applies to point light.
- Key '4': Toggling directional light on/off on all scenes.
- Key '0': switch the control between the 3D model and spot light.

Light Representation
What to render:
- Directional light​: No representation needed.
- Point light​: Draw the sphere model provided in the color of that point light.
Representation Notices:
- The sphere needs to be scaled down on screen, just big enough to be clearly visible.
Use a uniform scale matrix to scale it down as part of the model matrix transformation.
- To draw sphere in the color of the light source. You should use the light color as the
light's ​ambient​ reflection value, and ​DO NOT​ use diffuse or specular reflection (they
wouldn't work properly because the light source is inside of the light source geometry).
Or somehow tell the shader you're rendering light source representation, and output that
color directly.

Light Movements
What to render:
- Directional Light
- The mouse does not affect this light source. The directional light should be
“hovering” over the object, i.e rotating around positive y-axis.

- Point Light
- Mouse control: same as ​rotation ​in ​Part four​. For your convenience, here is a
copy: ​Rotation​: While the left mouse button is pressed and the mouse is moved,
rotate the light about the center of your graphics window (origin of world
coordinate). We will refer to this operation as "trackball rotation".
- Notice that light intensity should be visibly different on the model as the light is
moved closer and farther from the model surface.

PURE FUN​ Spot light

Notice: this part is only provided to those who want to work a little bit more with lighting.
Completing ​this part of work will NOT give you any extra credit, and you will NOT be
graded​ on this part.
Try to enable key interactions for a spot light as well. This time you get to choose whatever key
you want to work with!

Spotlight
- Should do everything the point light does, plus:
- Somekey should make the spot wider/narrower.
- Some other key should make the spot edge sharper/blurrier.

Notice: The light intensity should be visibly different on the model as the light is moved closer
and farther from the model surface, with an even more visible effect than with the point light (it
uses linear vs. quadratic attenuation).
Notes and Tips

Learn OpenGL​ provides vertex and fragment shader code, as well as the corresponding C++
code for different lighting parameters. The shader does almost exactly what you need. Find out
how it differs from the equations given on the discussion slides for this homework project and
make necessary modifications.

Lighthouse 3D also provides excellent tutorials for the necessary shaders: for directional lights,
point lights and spot lights.

This tutorial​ provides very useful information on light parameters in chapters 6 and 7. An
additional tutorial on different light types is provided in chapter 8.

This table of material properties​ may inspire you to select interesting material parameters. But
note that there are specific requirements for the materials you use, which make it necessary to
eliminate one or more reflection components (ambient, diffuse, specular) when you define your
own materials.

Submission

DUE DATE: Feb 14 12:59 pm
Please zip all your source code files and submit the zip file on Gradescope before the due date.
Source code files are all .h files and .cpp files, plus the vertex shader and fragment shader.
Please ​do not​ include any OBJ files, .xcodeproj, or .sln file.

Friendly reminder, the due date is ​before​ the grading session from 1:00 pm to 3:00 pm on the
same day. Otherwise there will be a 30% penalty for late submission. Notice that if you submit
the code on time, but did not attend the grading session on Feb 14, there will be that 30%
penalty as well. Please attend the grading session on time.
51作业君 51作业君

扫码添加客服微信

添加客服微信: IT_51zuoyejun