Difference between revisions of "Project6SP15"

From Immersive Visualization Lab Wiki
Jump to: navigation, search
(1. Terrain)
(4. Terrain Colors (25 Points))
 
(42 intermediate revisions by 2 users not shown)
Line 14: Line 14:
 
The goal of this project is to create a highly interactive 3D visualization tool to show the effects of different water levels on San Diego. You will have to load and render a [http://en.wikipedia.org/wiki/Heightmap height map] and allow the user to change the water level in real-time.
 
The goal of this project is to create a highly interactive 3D visualization tool to show the effects of different water levels on San Diego. You will have to load and render a [http://en.wikipedia.org/wiki/Heightmap height map] and allow the user to change the water level in real-time.
  
==1. Terrain==
+
==1. Terrain (40 Points)==
  
In the first step you need to generate and display a 3D mesh out of [[Media:sd-terrain.ppm | this 2D height map image of San Diego]]. The image has a resolution of 1024*1024 pixels and covers an area of about 37*37 miles (60*60 kilometers). The image is in PPM format so that you can read it with your PPM reader from Project 5. The information in the red, green and blue channels is identical for each pixel - you can interpret any one of them as elevation. A gray value of zero translates to an elevation of zero (sea level), a value of 255 translates to an elevation of about 3,500 feet (1,000 meters).
+
In the first step you need to generate and display a 3D mesh out of [[Media:SanDiegoTerrain.zip | this 2D height map image of San Diego]]. The image has a resolution of 1024*1024 pixels and covers an area of about 37*37 miles (60*60 kilometers). The image is in PPM format so that you can read it with your PPM reader from Project 5. The information in the red, green and blue channels is identical for each pixel - you can interpret any one of them as elevation. A gray value of zero translates to an elevation of zero (sea level), a value of 255 translates to an elevation of about 3,500 feet (1,000 meters).
 +
 
 +
For this project we recommend that you start with your code from project 5 and implement the terrain as a scene graph node. You will not need any of the 3D models from the previous projects. Feel free to keep the sky box - everything looks better with a sky box. You will need your mouse and keyboard routines to rotate, translate and scale the object space.
  
 
The steps to generate the height map are as follows:
 
The steps to generate the height map are as follows:
  
 
* Load the height map image and store the elevation data in an unsigned char array of size 1024*1024.
 
* Load the height map image and store the elevation data in an unsigned char array of size 1024*1024.
* Create a 1024*1024 array of vertex coordinates (Vector3). Populate the array as follows: the x and y coordinates should equal the array indices (Vector3[x][y].x = x, Vector3[x][y].y = y). The z value should be the corresponding value from the height map array (Vector3[x][y].z = heightmap[x][y]). Feel free to scale each of the values to a range more convenient for you. In a professional application one would decide on a physical unit for the vertex coordinates, for instance feet or meters.
+
* Create a 1024*1024 array of vertex coordinates (Vector3). Populate the array as follows: the x values should correspond to the array's x index, the z values to the y index. For example: Vector3[x][y].x = x, Vector3[x][y].z = y. The y value should be the corresponding value from the height map array (Vector3[x][y].y = heightmap[x][y]).  
* To render the height map, create a triangle mesh with 1023*1023*2 triangles, using the vertex array created above. Make yourself familiar with [http://en.wikipedia.org/wiki/Triangle_strip triangle strips] (glBegin(GL_TRIANGLE_STRIP)) and use them to create the triangle mesh - this way it will render much faster than separate triangles.
+
* To render the height map, create a triangle mesh with 1023*1023*2 triangles, using the vertex array created above. Make yourself familiar with [http://en.wikipedia.org/wiki/Triangle_strip triangle strips] and use them to create the triangle mesh - this way it will render much faster than separate triangles.
 
* For the vertex colors, use the same gray values as in the PPM file with the height map. We will add color later.
 
* For the vertex colors, use the same gray values as in the PPM file with the height map. We will add color later.
 +
* Support your mouse or keyboard commands to rotate, translate and scale the terrain.
 +
* Add an additional mouse control: when the user clicks within about 100 pixels from the left end of the window, vertical mouse movements should control an exaggeration factor for the elevation. It is often desirable to exaggerate terrain elevation in order to get a better idea of elevation differences.
  
 
'''Notes:'''
 
'''Notes:'''
 
* [http://www.chadvernon.com/blog/resources/directx9/terrain-generation-with-a-heightmap/ The tutorial at this link] may be helpful for this part of the project.
 
* [http://www.chadvernon.com/blog/resources/directx9/terrain-generation-with-a-heightmap/ The tutorial at this link] may be helpful for this part of the project.
 +
* The description above uses a "z up" coordinate system - feel free to use a "y up" coordinate system instead.
 +
* Feel free to scale each of the coordinate axes to a range more convenient for you. It may be useful to center the x/y values around the origin; or decide on a physical unit for the vertex coordinates, for instance feet or meters, so that you can display the terrain elevation at the correct height in relation to distances on the ground.
 +
* You need to calculate your own normals for the vertices, and update them every time the elevation exaggeration factor changes.
  
<!--
+
'''Grading hints:'''
- create tessellated rectangle, with triangle strips
+
* Missing or incorrect normal vectors (-10 points)
- load height map into GPU as texture
+
* Errors in the triangle mesh (-10 points)
- set up GLSL shaders
+
* Missing (-10 points) or incorrect (-5 points) elevation exaggeration
- pass uniform variable between 0 and 1 for elevation scale
+
* Inability to rotate or zoom in/out of terrain (-10 points)
- render triangles with shaders
+
* Tessellation without triangle strip (-5 points)
- vertex shader: offset vertices based on elevation scale
+
- fragment shader: pick draw color based on elevation
+
- render sun with parabolic path: east to west over south end of terrain
+
- scalable elevation multiplier
+
- colors need to shift with sea level
+
  
==1. Add Per-Pixel Lighting (20 Points)==
+
==2. Illumination (20 Points)==
  
The starter code in the Git repository has been updated with code templates for the integration of GLSL shaders.
+
Next we want to control the illumination of our terrain. Add a point light source to your scene and remove all other lights in it. Draw a sphere in the location of the point light. Move the point light gradually along a path described by a 2nd order polynomial, an upside down parabola. Put start and end points of the parabola in the southwest and southeast corners of your scene. The parabola can be vertical or slightly tilted. This path imitates the path the sun goes along during the course of a day. When the sun reaches one end point of the parabola, turn its direction around so that it oscillates slowly between the end points (i.e., sunrise and sunset).
  
Up until now, the spot light's outline on the surface of the 3D models has been rather fuzzy. Add per pixel lighting for the spot light to your application. To accomplish this, you need to add a vertex and a fragment shader to your application and enable them. In this project, you are free to copy-paste the shader code into your application from a source of your choice, for instance [http://www.lighthouse3d.com/tutorials/glsl-tutorial/spot-light-per-pixel/ Lighthouse3D]. You do not need to understand the shader code, just make it work.
+
Use the parabola's blending functions to control the color of the point light and its spherical representation: when the sun is in the apex make the light white, at the lowest points it should be yellow. Your shader needs to support ambient and diffuse shading.
  
Toggle this per-pixel lighting mode on and off with the 'p' key. When it is enabled, you do not need to render the effect of the point light, because this would require modifying the shader.
+
The light needs to be in the same coordinate system as the terrain: when the user rotates the terrain, the sun should rotate with it.
  
For Windows and Linux users, in order to use the OpenGL extensions for shaders, you should [https://www.opengl.org/sdk/libs/GLee/ download GLee] and add the glee.h and glee.c files to your project files, or tell the linker to link with the GLee library (glee.lib or glee.dll for Windows, or libglee.a/libglee.so for Linux). OSX users will not need GLee, as the OpenGL extensions are available by default. In case the GLee server is down, you can find the files [[Media:GLee5_4.zip | in this ZIP file.]]
+
'''Grading hints:'''
 +
* Sun not moving: -5 points
 +
* No color change as sun moves: -5 points
 +
* No sphere for the sun: -5 points
 +
* Not a parabola: -5 points
 +
* Sun not oscillating: -2 points
  
'''Notes'''
+
==3. Water Level (15 Points)==
* While most CSE lab computers do, some older computers or simpler graphics cards do not support GLSL. Be aware that this might be a problem with your personal computer.
+
* We provide a [[Media:shader-class.zip|sample shader class]] and [[Media:shaders.zip|three sample combinations of vertex and fragment shaders]] for you to familiarize yourself with GLSL shader programming more, if you find additional examples to the code on Lighthouse3D to be useful.
+
* The Lighthouse3D example assumes that your spot light is your first light (light #0), so if your spot light is actually light #1 you need to change that in the shader.
+
  
==3. Optional Project: Height Map (10 points)==
+
Now it is time to increase the water level. We simplify the effect of the increasing sea level by assuming that the water reaches every point on the terrain which is lower than the new water level. In computer graphics terms, all vertex elevations below the new water level need to be modified to match the new water level.
  
http://www.chadvernon.com/blog/resources/directx9/terrain-generation-with-a-heightmap/
+
While you could simply modify the vertex coordinates and re-send them to the GPU, in this part of the project you will need to use GLSL vertex shaders to accomplish the task. The starter code in the Git repository has been updated with code templates for the integration of GLSL shaders.
  
Generate and display a 3D mesh out of a 2D height map image. Wikipedia has a great [http://en.wikipedia.org/wiki/Heightmap description of this topic]. Allow the user to interactively fly over the height map, similar to a simple flight simulator. You can use the height map image from the Wikipedia page, which you will also find below, or create your own with a paint program or another method of your choice.  
+
To control the water level you should create a GLSL Uniform variable for the water level in your C++ code and pass it on to the vertex shader. The vertex shader then needs to compare every vertex's y-coordinate to this value and if it is smaller, it needs to match the vertex coordinate with the water level.
  
<center>
+
Add a mouse routine to control the water level: when the left mouse button is clicked within 100 pixels or so from the right edge of the screen, translate vertical mouse movement to changes of the water level.
[[Image:Heightmap.png]]<br>
+
 
''Height map image from Wikipedia''
+
'''Notes:'''
</center>
+
* [http://www.lighthouse3d.com/tutorials/glsl-tutorial/spot-light-per-pixel/ Lighthouse3D] has excellent tutorials for GLSL shaders.
 +
* For Windows and Linux users, in order to use the OpenGL extensions for shaders, you should [https://www.opengl.org/sdk/libs/GLee/ download GLee] and add the glee.h and glee.c files to your project files, or tell the linker to link with the GLee library (glee.lib or glee.dll for Windows, or libglee.a/libglee.so for Linux). OSX users will not need GLee, as the OpenGL extensions are available by default. In case the GLee server is down, you can find the files [[Media:GLee5_4.zip | in this ZIP file.]]
 +
* While most CSE lab computers do, some older computers or simpler graphics cards do not support GLSL. Be aware that this might be a problem with your personal computer.
  
To get full credit you need to implement the following features:
+
'''Grading hints:'''
 +
* Water level not flat across terrain: -5 points
 +
* No or incorrect mouse control: -5 points
  
* Load the height map image and create a 3D mesh out of it. You can either read the Wikipedia PNG image file with your own reader, or read [[Media:Heightmap.pgm|this PGM image file]] with [[pgm-loader.cpp|this piece of C code]]. Note that this code returns a one dimensional array, which you have to interpret as a two-dimensional array based on the width of the image. Add the mesh to your 3D viewer and allow switching to it with the 'F8' key ('F7' is for the soccer ball if you have it). ('''5 points''')
+
==4. Terrain Colors (25 Points)==
  
* Color the terrain polygons in blue (water), yellow (sand), green (grass), grey (rock) or white (snow), depending on their height. Feel free to add more colors as you see fit. ('''2 points''').
+
Write a GLSL fragment shader to color the terrain blue (water), yellow (sand), green (grass), grey (rock) or white (snow), depending on their height. Make sure that as the water level rises the elevation thresholds for the color boundaries are being updated so that the areas just above the water level are sand, while the highest elevations remain to be snow covered (San Diegans will still want to be able to go skiing).
  
* Add support for an airplane flight mode, in which the user can use the cursor keys to rotate the camera left or right and tilt it up or down, and change the velocity of the flight ('-' for slower, '=' for faster) ('''3 points''').  
+
Make sure the terrain's diffuse reflection works correctly with your colors.
  
If you use the Wikipedia height map, the resulting terrain should look similar to this, except that it needs to be colored as described above:
+
'''Grading hints:'''
 +
* Diffuse lighting incorrect: -10 points
 +
* Incorrect adjustment of color gradient on water level changes: -5 points
 +
* Missing colors: -5 points each
  
<center>
+
==5. Extra Credit: Flight Simulator==
[[Image:Heightmap_rendered.png]]<br>
+
''3D terrain generated from height map''
+
</center>
+
  
-->
+
Add support for an airplane flight mode, in which the user can use the mouse to control the camera as if flying an airplane: left button and forward/backward should control the pitch of the airplane, left/right controls the roll. The heading is implicitly controlled by the roll. Right mouse button and forward/backward should control the speed.

Latest revision as of 15:39, 14 May 2015

Contents

Project 6: Global Warming

In this project you will need to render a terrain with GLSL shader programs.

This project is due on Friday, May 15th, 2015 at 1:00pm. You need to present your results in the CSE basement labs as usual, grading starts at 12:15pm. Please upload your source code including your shaders to the Ted system by 1pm. You do not need to upload any binaries, including textures, 3D models, etc.

The discussion for this project will be on Monday, May 11th in CSB 002 (note the room change due to construction).

The total score for this project is 100 points, plus 10 for extra credit.

It is widely believed that as a consequence of Global Warming the sea level is going to rise. San Diego has many low lying areas, which would get severely affected even with a moderate increase of the sea level. There are web apps such as this one, which can give you an idea of which areas will be affected, but they are not as interactive as they could be.

The goal of this project is to create a highly interactive 3D visualization tool to show the effects of different water levels on San Diego. You will have to load and render a height map and allow the user to change the water level in real-time.

1. Terrain (40 Points)

In the first step you need to generate and display a 3D mesh out of this 2D height map image of San Diego. The image has a resolution of 1024*1024 pixels and covers an area of about 37*37 miles (60*60 kilometers). The image is in PPM format so that you can read it with your PPM reader from Project 5. The information in the red, green and blue channels is identical for each pixel - you can interpret any one of them as elevation. A gray value of zero translates to an elevation of zero (sea level), a value of 255 translates to an elevation of about 3,500 feet (1,000 meters).

For this project we recommend that you start with your code from project 5 and implement the terrain as a scene graph node. You will not need any of the 3D models from the previous projects. Feel free to keep the sky box - everything looks better with a sky box. You will need your mouse and keyboard routines to rotate, translate and scale the object space.

The steps to generate the height map are as follows:

  • Load the height map image and store the elevation data in an unsigned char array of size 1024*1024.
  • Create a 1024*1024 array of vertex coordinates (Vector3). Populate the array as follows: the x values should correspond to the array's x index, the z values to the y index. For example: Vector3[x][y].x = x, Vector3[x][y].z = y. The y value should be the corresponding value from the height map array (Vector3[x][y].y = heightmap[x][y]).
  • To render the height map, create a triangle mesh with 1023*1023*2 triangles, using the vertex array created above. Make yourself familiar with triangle strips and use them to create the triangle mesh - this way it will render much faster than separate triangles.
  • For the vertex colors, use the same gray values as in the PPM file with the height map. We will add color later.
  • Support your mouse or keyboard commands to rotate, translate and scale the terrain.
  • Add an additional mouse control: when the user clicks within about 100 pixels from the left end of the window, vertical mouse movements should control an exaggeration factor for the elevation. It is often desirable to exaggerate terrain elevation in order to get a better idea of elevation differences.

Notes:

  • The tutorial at this link may be helpful for this part of the project.
  • The description above uses a "z up" coordinate system - feel free to use a "y up" coordinate system instead.
  • Feel free to scale each of the coordinate axes to a range more convenient for you. It may be useful to center the x/y values around the origin; or decide on a physical unit for the vertex coordinates, for instance feet or meters, so that you can display the terrain elevation at the correct height in relation to distances on the ground.
  • You need to calculate your own normals for the vertices, and update them every time the elevation exaggeration factor changes.

Grading hints:

  • Missing or incorrect normal vectors (-10 points)
  • Errors in the triangle mesh (-10 points)
  • Missing (-10 points) or incorrect (-5 points) elevation exaggeration
  • Inability to rotate or zoom in/out of terrain (-10 points)
  • Tessellation without triangle strip (-5 points)

2. Illumination (20 Points)

Next we want to control the illumination of our terrain. Add a point light source to your scene and remove all other lights in it. Draw a sphere in the location of the point light. Move the point light gradually along a path described by a 2nd order polynomial, an upside down parabola. Put start and end points of the parabola in the southwest and southeast corners of your scene. The parabola can be vertical or slightly tilted. This path imitates the path the sun goes along during the course of a day. When the sun reaches one end point of the parabola, turn its direction around so that it oscillates slowly between the end points (i.e., sunrise and sunset).

Use the parabola's blending functions to control the color of the point light and its spherical representation: when the sun is in the apex make the light white, at the lowest points it should be yellow. Your shader needs to support ambient and diffuse shading.

The light needs to be in the same coordinate system as the terrain: when the user rotates the terrain, the sun should rotate with it.

Grading hints:

  • Sun not moving: -5 points
  • No color change as sun moves: -5 points
  • No sphere for the sun: -5 points
  • Not a parabola: -5 points
  • Sun not oscillating: -2 points

3. Water Level (15 Points)

Now it is time to increase the water level. We simplify the effect of the increasing sea level by assuming that the water reaches every point on the terrain which is lower than the new water level. In computer graphics terms, all vertex elevations below the new water level need to be modified to match the new water level.

While you could simply modify the vertex coordinates and re-send them to the GPU, in this part of the project you will need to use GLSL vertex shaders to accomplish the task. The starter code in the Git repository has been updated with code templates for the integration of GLSL shaders.

To control the water level you should create a GLSL Uniform variable for the water level in your C++ code and pass it on to the vertex shader. The vertex shader then needs to compare every vertex's y-coordinate to this value and if it is smaller, it needs to match the vertex coordinate with the water level.

Add a mouse routine to control the water level: when the left mouse button is clicked within 100 pixels or so from the right edge of the screen, translate vertical mouse movement to changes of the water level.

Notes:

  • Lighthouse3D has excellent tutorials for GLSL shaders.
  • For Windows and Linux users, in order to use the OpenGL extensions for shaders, you should download GLee and add the glee.h and glee.c files to your project files, or tell the linker to link with the GLee library (glee.lib or glee.dll for Windows, or libglee.a/libglee.so for Linux). OSX users will not need GLee, as the OpenGL extensions are available by default. In case the GLee server is down, you can find the files in this ZIP file.
  • While most CSE lab computers do, some older computers or simpler graphics cards do not support GLSL. Be aware that this might be a problem with your personal computer.

Grading hints:

  • Water level not flat across terrain: -5 points
  • No or incorrect mouse control: -5 points

4. Terrain Colors (25 Points)

Write a GLSL fragment shader to color the terrain blue (water), yellow (sand), green (grass), grey (rock) or white (snow), depending on their height. Make sure that as the water level rises the elevation thresholds for the color boundaries are being updated so that the areas just above the water level are sand, while the highest elevations remain to be snow covered (San Diegans will still want to be able to go skiing).

Make sure the terrain's diffuse reflection works correctly with your colors.

Grading hints:

  • Diffuse lighting incorrect: -10 points
  • Incorrect adjustment of color gradient on water level changes: -5 points
  • Missing colors: -5 points each

5. Extra Credit: Flight Simulator

Add support for an airplane flight mode, in which the user can use the mouse to control the camera as if flying an airplane: left button and forward/backward should control the pitch of the airplane, left/right controls the roll. The heading is implicitly controlled by the roll. Right mouse button and forward/backward should control the speed.