CSCI 441 - Computer Graphics

Fall 2020

|     Home   |   Assignments  |   Leaderboard  |   Schedule  |   Resources    |

Masao Asanaka
まさお朝中


Lab 00

2 triforces    2 triforces

This lab was first focused on making sure OpenGL and all libraries were installed and working correctly, by drawing a handful of triangles to the screen, including some transformations. The second half of the lab was to draw our track using OpenGL primatives. This half of the lab had some interesting implementation details, even if it only transforms, translates, and colors triangle primatives.
Because I wanted to use a large number of triangles to both have more detail in the image as well as some texture (so it wasn't just green), I needed a more dynamic way to register triangles with the GPU, translate them, and draw them than hard-coding each triangle myself. As such, I created a set of vectors to store information on triangles that I was able to loop through in the draw call to draw all the vectors. This meant that I could then use for loops to draw the background and the track shapes with an arbitrary number of triangles, thanks to also pulling some information in from C++'s rand() function to add some variance. Overall, I think it resulted in a good looking track, with quite a bit of detail.

Assignment 1

2 triforces

2 triforces

This assignment was to create a sign displaying my hero's name, as well a crest for their hometown. Since I built this assignment on top of the codebase from lab 00, I was able to leverage the more dynamic shape-registration system I had created to more easily create the sign without needing as much boilerplate (even if a lot of positioning and vertex data is still hard-coded).

The shape-registration system was expanded in this implementation to support any OpenGL primative rather than just triangles, as well as scaling, which while only used with small variances in this assignment, helped me to get a "built out of wood" look for the sign.
The most interesting implementation detail, however, from this project is how the crest is drawn, as none of the shape data is included in the program itself. Rather, it is loaded in from an external file, crest.txt. The formatting for this file is custom to this program, but it does allow the specification of an arbitrary number of OpenGL triangle primatives and their colors to be defined and modified without recompilation. However, it is far from a perfect system. It does not support per-vertex coloring (only per-shape), is fairly difficult to read (since everything is numeric), and requires verticies to be duplicated if they are used in more than one shape. However, these could all be improved or fixed with a revision to the file format to make it more capable and easier to work with.

Lab 2

Buildings

I wanted to include this lab in the website since for the first time, we've made the jump from 2D into 3D space. The particularly interesting detail from this lab to share is how this lab very clearly demonstrates some of the risks of the theta-phi method to store rotations, namely that they can cause gimbal lock. I just found this to be the best demonstration of that concept I've seen.

Assignment 2

Masao Asanaka at his track     Going exploring

This assignment was to create a model of my hero, and make it so they can walk around the park. While the animation, callbacks, and other related functions to actually do the animations and walking around and screen wrap and such were interesting, my favorite detail is my expanded "load from file" system.
Now, rather than needing to provide a number of shapes and verticies, I can simply provide a list of verticies and then reference these verticies in each shape that I define to draw them. I'm also now able to individually color verticies to get some nice gradients of color to make everything just a little bit less bland. Overall, the system is now a lot easier to use, and is coded in a separate header file to make reuse and modification (to add more functionality) quite easy.
The other improvement is that the shapes are loaded heirarchically, making it very easy to transform and move compound shapes, since the heirarchy and transformation stacks are abstracted into the file with very simple syntax rather than needing to be worried about elsewhere. The fact that these shapes are objects also makes instantiating each shape much easier than it was before, so I can create many instances of a model, or simply load one and continue to reference it. This is much cleaner than global vectors to store data, and resulted in some very nice code that was extremely easy to work with.

Assignment 3

Overlooking the valley     By a tree

This assignment was to create a people mover and make it move around a 3D world that also has some height variation and other objects (though collision was not required). I decided to create a basic rocket-ship type people mover, where the middle of the ship slowly spins and fire spits out the back while moving (aka the diamond spazzes out).
One interesting part of this assignment was how I was able to, relatively easily, update my "load from file" code to use a 3D shape rather than a 2D shape, and still have the heirachical drawing system fully functional. This made adding the animations and such to my model very simple.
The other interesting aspect is the heightmap. This is generated semi-randomly to create the shape I want, and is then stored in an array used to draw the grid, place rocks and trees at the correct height, and to ensure that the player snaps to the ground. Since the heightmap has no interpolation, it is a bit jagged when moving, but the people mover always stays on top of the ground normally.

Assignment 4

Overlooking the valley 1     Overlooking the valley 2
People Mover MK2

This assignment was to take the results of the previous assignment and write a shader to light up the world using a handful of different colored point lights. I also took this opportunity to upgrade the people mover (it's now a cube orbited by spheres), make the ground a bunch of solid cubes (Minecraft ripoff, anyone?), and generally make the world look better.
The lighting is diffuse lighting only, with Gourad shading computed by the interpolation between the vertex and fragment shaders. This isn't anything special, but it did take a while to work out all the bugs (the hardest to solve being remembering to multiply the normal by the normal matrix to get the shading to actually look normal).

Midterm Project

The gang's all here!     Overlooking the valley!

The assignment was to take three of our heros and put them into the same world, with the different camera models also available (arcball, freecam, and first person as an insert). We were then to implement the full Phong Reflectance Model alongside Gourad Shading (diffuse, specular, and ambient lights interpolated linearly between verticies) - with different colors as well.
This project took a bit of work to get the different lighting equations to all work, transition everything to running our own shader code, and make switching cameras and heros a smooth process. There wasn't a singular hard implementation detail so much as just lots of small things to get the entire lighting model working correctly.

Assignment 5

That curve looks crazy!     Did one side of the valley get taller?

The assignment was to both create a "mascot" that moves around the player using a bezier curve, as well as to finally put the world into a skybox rather than the black void of space. The plotting of the bezier curve's control points, cage, and curve itself is also supported.
The most interesting implementation detail of this assignment is that rather than using 6 quads with different textures to create the skymap, I elected to use a cubemap to draw the textures, which saves having to key in all the UVs for the textures (as it uses model space cube coordinates to determine what part of the texture to apply). I also made the skybox static, so you don't see it moving strangely as you move around the world.

Assignment 6

Fountains!     Rain clouds?     Particle spam.

The assignment was to add particle systems to the world. I opted to allow the user to spawn these particle systems (defined in a file) as they explore the world. The particles exhibit gravity, and have a finite lifespan (and change as they age - getting smaller). Both a fountain and a raincloud particle system were implemented. Particle systems themselves also despawn after an amount of time.
An interesting implementation detail is that particles are stored as a single point and then expanded into a quad with a size based on the age in the geometry shader. Not only does this save on bandwidth sending particles to the GPU, but it also makes the particles shrinking as they age much easier.
Another interesting implementation detail is drawing the particles in such a way that they don't occlude each other. Even if I sort particles by distance to the camera, particles that are either in different systems or at the same depth still sometimes occlude each other. To fix this, rather than drawing transparent fragments to screen, I simply discard the transparent fragments. Not only does this fix the problem, it also cuts the number of fragments drawn by a particle to be much less, making the app run faster as well. It also technically renders the sorting obsolete, but I kept it in for the assignment.

Assignment 7

RUN! THE INTERNS ARE COMING!     ... slowly and agressively

The assignment was to create a basic game with collision detection and a goal to complete (in my game's case - just to survive long enough). I chose to also go ahead and create an entire game engine surrounding the game to get it to work, while also removing all the references to the class libraries - so this runs entirely using my code (and some standard libraries - GLFW for windows, GLEW for OpenGL calls, glm for some math stuff, and stbimage for texturing). All player-enemy and enemy-enemy collsions send both of them flying off - not a great thing when the goal is to stay on the platform!
One interesting detail is the collision system. Since axis-aligned bounding boxes don't work for things like the rotated ground plane, I elected to use transforming a unit box in one collider's space into another object's space and checking overlap with a unit box in that space. I'm not sure if this method is common, or has a proper name, but it works for collision cubes with arbitrary translational, rotational, and scaling transformations and isn't too slow, especially since I only compute the space transformation matricies when a collider changes (such as the player or an enemy moving).
Another interesting detail is that object rotations use a quaternion object I created. They function like normal quaternions, but it's still an interesting detail. They work very well for 3D rotations, which is why I use them. Quaternions are cool.

Final Project

When Cubes Attack     At least they seem to be made out of paper.

This was a pretty open ended assignment to make anything we wanted as a team (my team was me and 3 other people), to show off some of the stuff we learned this semester - including shaders, lighting, and all the other fun stuff in computer graphics. My team chose to make a simple first person shooter where you basically played skeet with a bunch of cubes whose only goal in life is to fly directly at you and launch you into the air. This was pretty fun to work on and I'm pretty happy with the final project
There are a lot of near implementation details, so I'll just talk about some of the big ones. This is built using the game engine I made back for A7, which is a neat demo of how you can use it to pivot to a different type of game entirely. The lights are dynamic (the main scene light fades to black over time, and both the particle shower when you kill an enemy as well as the muzzle flash light up as well). The ground quad implements Phong shading rather than Gourad shading, meeaning only 4 verticies are needed for a very nice lighting effect on it. When you pick up a powerup, the screen starts a fairly tripping rainbow recolor effect that fades over time using a second pass shader.
Overall, this was a pretty fun project and has a neat outcome.