Difference between revisions of "Project2S16"
(→4. Lights and materials) |
(→Notes) |
||
(22 intermediate revisions by 3 users not shown) | |||
Line 20: | Line 20: | ||
Besides vertices and vertex normals you are going to have to parse the files for connectivity. It is defined with the letter 'f' for face. Each line starting with the letter 'f' lists three sets of indices to vertices and normals, which define the three corners of a triangle. The numbers are indices into the vertex and vertex normal lists. Example: <br><pre>f 31514//31514 31465//31465 31464//31464</pre> | Besides vertices and vertex normals you are going to have to parse the files for connectivity. It is defined with the letter 'f' for face. Each line starting with the letter 'f' lists three sets of indices to vertices and normals, which define the three corners of a triangle. The numbers are indices into the vertex and vertex normal lists. Example: <br><pre>f 31514//31514 31465//31465 31464//31464</pre> | ||
− | Modify your OBJ loader so that it also parses the face lines, then modify your code to display triangles instead of vertices for the OBJ objects. | + | ===Parsing the faces (2 Points)=== |
+ | Modify your OBJ loader so that it also parses the face lines, then modify your code to display triangles instead of vertices for the OBJ objects. Ensure stored faces values are 0-based. | ||
+ | ===Centering the model (4 Points)=== | ||
+ | In order to make mouse controls you are about to implement work well, you will need to center your OBJ models and standardize their sizes. Write function calls to do both of these things whenever a new model is selected with the function keys F1, F2 and F3. Center each model such that the center of the model resides at the origin (0.0,0.0,0.0). | ||
+ | ===Scaling the model (4 Points)=== | ||
+ | Scaled all models to the same size, such that they fit within an imaginary 2x2x2 cube centered around the origin. Afterwards, the vertex position values should be in the range of [-1,1]. | ||
− | ==2. Rendering using modern OpenGL== | + | ==2. Rendering using modern OpenGL (20 Points)== |
[[BasecodeCSE167S16|The starter code]] has been modified so that the Cube now gets rendered with modern OpenGL, through the use of a VAO (Vertex Array Object), VBOs (Vertex Buffer Object), and EBOs (element buffer object). In order to make the use of the programmable pipeline possible, a shader class was added to the starter code, along with a sample vertex and fragment shader. At the moment, the sample fragment shader causes all objects to be colored light orange. You will be fixing this later when you begin working with lights. | [[BasecodeCSE167S16|The starter code]] has been modified so that the Cube now gets rendered with modern OpenGL, through the use of a VAO (Vertex Array Object), VBOs (Vertex Buffer Object), and EBOs (element buffer object). In order to make the use of the programmable pipeline possible, a shader class was added to the starter code, along with a sample vertex and fragment shader. At the moment, the sample fragment shader causes all objects to be colored light orange. You will be fixing this later when you begin working with lights. | ||
Line 36: | Line 41: | ||
It is time to support the mouse to control your 3D models. Add functionality to allow the following operations on the displayed 3D model: | It is time to support the mouse to control your 3D models. Add functionality to allow the following operations on the displayed 3D model: | ||
− | + | ===Rotating the model (6 Points)=== | |
− | + | While the left mouse button is pressed and the mouse is moved, rotate the model about the center of your graphics window. This is an extension of the orbit function ('o' key), but it should orbit the model around a sphere, not just a circle. We will refer to this operation as "trackball rotation". [[Media:cube.mpg|This video]] shows how this should work. | |
− | + | ||
− | + | ===Translation in the x-y plane (6 Points)=== | |
+ | When the right mouse button is pressed and the mouse is moved, move the model in the plane of the screen (similar to what the 'x' and 'y' keys did). 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 the z-axis (6 Points)=== | ||
+ | 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). | ||
+ | |||
+ | ===Retain reset and scale (2 Points)=== | ||
+ | Retain the functionality of the 's'/'S' keys to scale the model about its object space origin, as well as 'r' to reset the model to the 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. | ||
===Notes on the Trackball Rotation=== | ===Notes on the Trackball Rotation=== | ||
Line 71: | Line 83: | ||
</pre> | </pre> | ||
− | ==4. Lights and Materials ( | + | ==4. Lights and Materials (50 Points)== |
+ | <!---\sum_{n=0}^{lights-1} [k_aL_a + \frac{1}{cd^2}(k_dL_d(\overrightarrow{n} \cdot \overrightarrow{l}) + k_sL_s(\overrightarrow{r} \cdot \overrightarrow{v})^\alpha )]--> | ||
+ | ===Separate materials for each model (5 Points)=== | ||
Select different material properties for each of the 3D model files: make some more shiny, others more diffuse. Use colors other than white. The differences in shininess must be obvious - use extreme settings if you need to. Instead of being determined by the vertex normals, your 3D models' colors will now be determined by their materials and the amount of light shining on them. | Select different material properties for each of the 3D model files: make some more shiny, others more diffuse. Use colors other than white. The differences in shininess must be obvious - use extreme settings if you need to. Instead of being determined by the vertex normals, your 3D models' colors will now be determined by their materials and the amount of light shining on them. | ||
− | |||
+ | ===Light sources=== | ||
+ | You will need to create three separate light sources: a directional light, a point light, and a spotlight. Create C++ structs that hold data relevant to these light types, such as position, intensity, attenuation, etc. Make sure your lights are implemented in modern OpenGL, which requires them to be implemented in GLSL shaders. You'll also have to make the parameters user controllable, as described below. | ||
+ | |||
+ | Use per pixel lighting for all three types of light sources. | ||
+ | |||
+ | ====Attenuation==== | ||
+ | Add an attenuation value which applies to all point lights and spotlights. Each light does not need to have a separate value for attenuation. Legacy OpenGL required three values for various types of attenuation (constant, linear, and quadratic). For this assignment, we will only require quadratic attenuation. | ||
+ | |||
+ | ====Directional light properties (5 Points)==== | ||
+ | *Direction | ||
+ | *Ambient | ||
+ | *Diffuse | ||
+ | *Specular | ||
+ | ====Point light properties (10 Points)==== | ||
+ | *Position | ||
+ | *Ambient | ||
+ | *Diffuse | ||
+ | *Specular | ||
+ | ====Spotlight properties (15 Points)==== | ||
+ | *Direction | ||
+ | *Position | ||
+ | *Spot-cutoff | ||
+ | *Spot exponent | ||
+ | *Ambient | ||
+ | *Diffuse | ||
+ | *Specular | ||
+ | |||
+ | ===Light control (15 Points)=== | ||
Give the user control of the lights: make them selectable with the number keys '1', '2', and '3' (for the directional, point and spot lights, respectively). Use the '0' key to de-select and return to controlling the 3D model. Note that only one light source should be active at any given time. | Give the user control of the lights: make them selectable with the number keys '1', '2', and '3' (for the directional, point and spot lights, respectively). Use the '0' key to de-select and return to controlling the 3D model. Note that only one light source should be active at any given time. | ||
When a light source is selected, your mouse controls should only affect this particular light source. You need to support the following functions, depending on the type of light source: | When a light source is selected, your mouse controls should only affect this particular light source. You need to support the following functions, depending on the type of light source: | ||
− | + | ====Directional light==== | |
− | + | *Rotations change the direction of the light | |
− | + | ||
− | + | ====Point light==== | |
+ | *Rotations rotate the light around the origin of the world coordinate system (=center of window). | ||
+ | *Scaling with the mouse wheel changes the distance of the light from the origin of the world coordinate system. | ||
+ | *Light intensity should be visibly different on the model as the light is moved closer and farther from the model surface. | ||
− | '''Notes: | + | ====Spotlight==== |
− | * Lighthouse 3D provides excellent tutorials for | + | *Should do everything the point light does, plus: |
+ | **When the right mouse button is held down, up/down should make the spot wider/narrower | ||
+ | ** 'e'/'E' should make the spot edge sharper/blurrier. | ||
+ | **Make sure the spot keeps pointing at the center of your window coordinate system even when its position is changed. | ||
+ | *Light intensity should be visibly different on the model as the light is moved closer and farther from the model surface. | ||
+ | |||
+ | ====Notes==== | ||
+ | |||
+ | * [http://learnopengl.com/#!Lighting/Multiple-lights Learn OpenGL] provides [http://learnopengl.com/code_viewer.php?code=lighting/lighting_maps&type=vertex vertex] and [http://learnopengl.com/code_viewer.php?code=lighting/multiple_lights&type=fragment fragment] shader code, as well as the [http://learnopengl.com/code_viewer.php?code=lighting/multiple_lights-exercise2 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 the few modifications. | ||
+ | * Lighthouse 3D also provides excellent tutorials for the necessary shaders: for [http://www.lighthouse3d.com/tutorials/glsl-tutorial/directional-lights-per-pixel/ directional lights], [http://www.lighthouse3d.com/tutorials/glsl-tutorial/point-lights/ point lights] and [http://www.lighthouse3d.com/tutorials/glsl-tutorial/spotlights/ spot lights]. | ||
* [http://www.tomdalling.com/blog/modern-opengl/06-diffuse-point-lighting/ 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. | * [http://www.tomdalling.com/blog/modern-opengl/06-diffuse-point-lighting/ 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. | ||
+ | |||
+ | '''Grading:''' | ||
+ | * +5 if all that's done is passing the normals | ||
+ | * -10 if all code is there but lighting doesn't work | ||
+ | |||
+ | <!--next time: add a toggle to switch between normal coloring and lighting --> | ||
==5. Optional: Mouse Controlled Parameter Editor (10 Points)== | ==5. Optional: Mouse Controlled Parameter Editor (10 Points)== | ||
− | For extra credit, create a visual editor to allow the custom modification of the colors and shading parameters of your light source and surface materials. Use the ' | + | For extra credit, create a visual editor to allow the custom modification of the colors and shading parameters of your light source and surface materials. Use the 'c' key to display the color editor. The editor needs to be exclusively mouse controlled. You can either write your own OpenGL code to generate GUI widgets such as buttons or sliders, or you can use an existing open source library for it, such as [https://github.com/wjakob/nanogui NanoGUI]. |
You'll get points for the modification of the following parameters: | You'll get points for the modification of the following parameters: |
Latest revision as of 11:38, 22 April 2016
Project 2: 3D Models
From this point on we're no longer using the rasterizer code. In all future homework projects we're going to use OpenGL for all our rendering.
In this homework assignment you're going to learn how to:
- load polygonal OBJ files
- render polygons in modern OpenGL
- automatically center and scale 3D models
- control objects using the mouse
- set up light sources
- set material properties
1. 3D Model Loader (10 Points)
You already know how to load point clouds. It turns out that the 3D model files from project 1 (Bunny, Bear, Dragon) contain surface descriptions as well, by means of triangle connectivity.
Besides vertices and vertex normals you are going to have to parse the files for connectivity. It is defined with the letter 'f' for face. Each line starting with the letter 'f' lists three sets of indices to vertices and normals, which define the three corners of a triangle. The numbers are indices into the vertex and vertex normal lists. Example:f 31514//31514 31465//31465 31464//31464
Parsing the faces (2 Points)
Modify your OBJ loader so that it also parses the face lines, then modify your code to display triangles instead of vertices for the OBJ objects. Ensure stored faces values are 0-based.
Centering the model (4 Points)
In order to make mouse controls you are about to implement work well, you will need to center your OBJ models and standardize their sizes. Write function calls to do both of these things whenever a new model is selected with the function keys F1, F2 and F3. Center each model such that the center of the model resides at the origin (0.0,0.0,0.0).
Scaling the model (4 Points)
Scaled all models to the same size, such that they fit within an imaginary 2x2x2 cube centered around the origin. Afterwards, the vertex position values should be in the range of [-1,1].
2. Rendering using modern OpenGL (20 Points)
The starter code has been modified so that the Cube now gets rendered with modern OpenGL, through the use of a VAO (Vertex Array Object), VBOs (Vertex Buffer Object), and EBOs (element buffer object). In order to make the use of the programmable pipeline possible, a shader class was added to the starter code, along with a sample vertex and fragment shader. At the moment, the sample fragment shader causes all objects to be colored light orange. You will be fixing this later when you begin working with lights.
Using Cube's example of the modern OpenGL approach, add the ability to render your OpenGL using modern OpenGL. Since you are no longer using the Rasterizer, you no longer need to support the 't' key to toggle between modes.
Notes:
- This is a good resource for learning modern OpenGL.
3. Mouse control (20 Points)
Since we'll be allowing the mouse to rotate the object, if you had your spin while idle code, now would be the time to disable it.
It is time to support the mouse to control your 3D models. Add functionality to allow the following operations on the displayed 3D model:
Rotating the model (6 Points)
While the left mouse button is pressed and the mouse is moved, rotate the model about the center of your graphics window. This is an extension of the orbit function ('o' key), but it should orbit the model around a sphere, not just a circle. We will refer to this operation as "trackball rotation". This video shows how this should work.
Translation in the x-y plane (6 Points)
When the right mouse button is pressed and the mouse is moved, move the model in the plane of the screen (similar to what the 'x' and 'y' keys did). 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 the z-axis (6 Points)
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).
Retain reset and scale (2 Points)
Retain the functionality of the 's'/'S' keys to scale the model about its object space origin, as well as 'r' to reset the model to the 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.
Notes on the Trackball Rotation
The figure below illustrates how to translate mouse movement into a rotation axis and angle. m0 and m1 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 = v x 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 understand the code better, here is a line-by-line commented version of the trackBallMapping function:
Vec3f CSierpinskiSolidsView::trackBallMapping(CPoint point) // The CPoint class is a specific Windows class. Either use separate x and y values for the mouse location, or use a Vector3 in which you ignore the z coordinate. { Vec3f v; // Vector v is the synthesized 3D position of the mouse location on the trackball float d; // this is the depth of the mouse location: the delta between the plane through the center of the trackball and the z position of the mouse v.x = (2.0*point.x - windowSize.x) / windowSize.x; // this calculates the mouse X position in trackball coordinates, which range from -1 to +1 v.y = (windowSize.y - 2.0*point.y) / windowSize.y; // this does the equivalent to the above for the mouse Y position v.z = 0.0; // initially the mouse z position is set to zero, but this will change below d = v.Length(); // this is the distance from the trackball's origin to the mouse location, without considering depth (=in the plane of the trackball's origin) d = (d<1.0) ? d : 1.0; // this limits d to values of 1.0 or less to avoid square roots of negative values in the following line v.z = sqrtf(1.001 - d*d); // this calculates the Z coordinate of the mouse position on the trackball, based on Pythagoras: v.z*v.z + d*d = 1*1 v.Normalize(); // Still need to normalize, since we only capped d, not v. return v; // return the mouse location on the surface of the trackball }
4. Lights and Materials (50 Points)
Separate materials for each model (5 Points)
Select different material properties for each of the 3D model files: make some more shiny, others more diffuse. Use colors other than white. The differences in shininess must be obvious - use extreme settings if you need to. Instead of being determined by the vertex normals, your 3D models' colors will now be determined by their materials and the amount of light shining on them.
Light sources
You will need to create three separate light sources: a directional light, a point light, and a spotlight. Create C++ structs that hold data relevant to these light types, such as position, intensity, attenuation, etc. Make sure your lights are implemented in modern OpenGL, which requires them to be implemented in GLSL shaders. You'll also have to make the parameters user controllable, as described below.
Use per pixel lighting for all three types of light sources.
Attenuation
Add an attenuation value which applies to all point lights and spotlights. Each light does not need to have a separate value for attenuation. Legacy OpenGL required three values for various types of attenuation (constant, linear, and quadratic). For this assignment, we will only require quadratic attenuation.
Directional light properties (5 Points)
- Direction
- Ambient
- Diffuse
- Specular
Point light properties (10 Points)
- Position
- Ambient
- Diffuse
- Specular
Spotlight properties (15 Points)
- Direction
- Position
- Spot-cutoff
- Spot exponent
- Ambient
- Diffuse
- Specular
Light control (15 Points)
Give the user control of the lights: make them selectable with the number keys '1', '2', and '3' (for the directional, point and spot lights, respectively). Use the '0' key to de-select and return to controlling the 3D model. Note that only one light source should be active at any given time.
When a light source is selected, your mouse controls should only affect this particular light source. You need to support the following functions, depending on the type of light source:
Directional light
- Rotations change the direction of the light
Point light
- Rotations rotate the light around the origin of the world coordinate system (=center of window).
- Scaling with the mouse wheel changes the distance of the light from the origin of the world coordinate system.
- Light intensity should be visibly different on the model as the light is moved closer and farther from the model surface.
Spotlight
- Should do everything the point light does, plus:
- When the right mouse button is held down, up/down should make the spot wider/narrower
- 'e'/'E' should make the spot edge sharper/blurrier.
- Make sure the spot keeps pointing at the center of your window coordinate system even when its position is changed.
- Light intensity should be visibly different on the model as the light is moved closer and farther from the model surface.
Notes
- 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 the few 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.
Grading:
- +5 if all that's done is passing the normals
- -10 if all code is there but lighting doesn't work
5. Optional: Mouse Controlled Parameter Editor (10 Points)
For extra credit, create a visual editor to allow the custom modification of the colors and shading parameters of your light source and surface materials. Use the 'c' key to display the color editor. The editor needs to be exclusively mouse controlled. You can either write your own OpenGL code to generate GUI widgets such as buttons or sliders, or you can use an existing open source library for it, such as NanoGUI.
You'll get points for the modification of the following parameters:
- The object's colors and other parameters for ambient, diffuse and specular reflectivity. (5 points)
- The light's color and other properties: if using a spot light: cone angle, edge falloff; else: attenuation mode (constant, linear, quadratic). (5 points)