Masao Asanaka まさお朝中
Lab 00
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
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
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
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
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
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 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
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
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
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
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.
|