Goals
|
![]() |
Oh no! Mike Wazowski has been banished to the Himalayas again. We need to find him with our (virtual) airplane, but unfortunately, the aircraft controls are frozen. Our first task is to fix the controls. The next task is to make the terrain look colorful.
The third objective of this lab relates to the idea of working within a larger codebase and figuring out what already exists and where you need to add code to implement some functionality and/or fix bugs. This is an important skill to develop as you continue in computer science. The code has been labeled with comments such as PART XY
to identify where you should add code for certain parts.
Please start by opening up the template for this lab (link on our discussion board). Mike has been placed at the highest point in the terrain, which is defined by a grid in which the height at each grid point is computed using Perlin noise.
You might be able to see Mike (original model found here, which was simplified using MeshLab). The flight simulator UI allows you to overlay the cockpit controls and adjust the speed of the airplane. You can also adjust the terrain using the dropdown.
The arrow keys are supposed to maneuver the airplane by adjusting the pitch, roll and yaw of the aircraft. But these are currently broken.
The scene is rendered from the viewpoint of the cockpit, and the flight simulator works by adjusting the gaze and up directions at each time step in the simulation. In contrast to previous labs and exercises, the up direction changes with time. This means that the view-matrix (vertexShaderSource
at the top of simulator.js
. Notice that the u_ViewMatrix
and u_ProjectionMatrix
have been hard-coded, which is why the controls are frozen.
There are two models in our simulation which are stored in this.objects
(a map/dictionary) of the FlightSimulator
class. These are written to the GPU in the write
method of this class. At every time step, the animate
method updates the position
, gaze
and up
vector of the aircraft, subsequently calling the draw
method. Note that the vertices defining Mike Wazowski have been directly transformed when the simulation loads, and the terrain does not need to be transformed, so there is no need for a model matrix. The model matrix is always the identity matrix in this lab.
JavaScript
and pass them (and use them) in the shader program.We are assuming that the forward direction of the aircraft aligns exactly with the gaze direction. Therefore, whenever the arrow keys are pressed, the gaze is updated, as well as the up vector. Please calculate a "look at" point and calculate a view matrix using mat4.lookAt
. Search for PART 1A
, which is where this should be calculated. As mentioned earlier, this.up
,this.gaze
, and this.position
are all updated at each step in the simulation. You will need these to calculate the view matrix.
Next, write this view matrix to a uniform and use it in the vertex shader (PART 1B
). Please do the same for the perspective projection matrix (using mat4.perspective
instead). Use a field-of-view of aspectRatio
variable of the draw
method. Use a near plane of 0.001
and a far plane of 1000
.
When this works, you should be able to navigate the airplane with the arrow keys.
JavaScript
and pass it (and use it) in the shader program.The normal vector at every vertex of the mesh (in world space) is calculated and saved in each model as an array called normals
. Each mesh (in this.objects
) has a normalBuffer
which is created and written to in the FlightSimulator
write
method. Also note that the a_Normal
attribute is enabled right after the program is created and that the normalBuffer
of each mesh is associated with this attribute whenever a mesh is drawn.
Please search for PART 2A
, then calculate and set the normal matrix in the shader program. We would like to transform normals into the frame of reference of the airplane (camera space). Remember the model matrix is always the identity matrix in this lab.
For PART 2B
, declare (1) a uniform for the normal matrix and (2) an output varying
for transformed normals. Then use this normal matrix to transform the incoming a_Normal
attribute into camera space to compute the transformed normal (PART 2C
), which will be assigned to the varying
you declared in PART 2B
.
For PART 2D
, declare the incoming (varying
) normal vector for the fragment shader, and then use it instead of the constant normal vector (n
) that is currently used in the shading algorithm (PART 2E
).
When this works, the terrain should look shaded, but everything has the same base color.
For PART 3A
, please push
color values to the colors
array of each mesh object (a 1d array with a stride of 3). For Mike Wazowski, you can set any color you want. I would recommend starting by setting a constant color for Mike Wazowski, for example, (0.5, 0.7, 0.5). Although this is a constant color, we will still assign it to every vertex in the mesh. You can make this vertex-dependent later if you want.
For the terrain (PART 3A (continued)
), please push
color values according to the height of the vertex:
h (height) |
color to push |
description |
---|---|---|
h > 0.8 | 1, 1, 1 | snow |
h > 0 | 0.5, 0.5, 0.5 | rock |
else | 0.2, 0.5, 0.2 | trees |
For PART 3B
, add some code to the write
method which creates a buffer for the colors, and buffer each mesh color data to this color buffer. Make sure to save the variable for this buffer in each mesh object (just like we already have for positionBuffer
and normalBuffer
). You will need this variable below.
For PART 3C
, declare a new attribute in the vertex shader for the color of each vertex. Then enable this attribute in the constructor of the FlightSimulator
(at PART 3C (continued)
).
For PART 3D
, add some code to the loop in the draw
method to associate the previously created color buffer (from PART 3B
) with the color attribute.
Finally, for PART 3E
, declare a varying
in the vertex shader and assign the incoming color attribute to it (PART 3E (continued)
). Then use this color as the km
in the fragment shader, instead of the constant color which is currently there.
When this works, the terrain should look more realistic.
The initial submission for the lab is due on Thursday 5/1 at 11:59pm EDT. Feel free to add some extensions if you want. For example, you can add Sulley somewhere in the mountains (see the sulley.obj
mesh included in the template as well as the preprocessWazowski
function in utils.js
).
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 9 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