photonmapping

Photon Mapping

Photon Mapping is an extension to ray tracing that allows for caustics, color bleeding, and soft shadows. During the first pass through the algorithm, photons are emitted randomly from a light source into the scene. As they bounce off each surface, their intersection point is stored in a kd-tree structure (the "photon map"), which allows for fast look-up time. The color of the light is stored as well as the incident direction of the photon ray.

During the second pass, the scene is ray traced as usual except at each point in the ray cast, a radiance value is calculated from the photon map which is added to the color. The radiance value is what allows for global illumination, and is calculated by taking the N nearest photons from the point of intersection and averaging their individual radiance.

In the first screenshot, color bleeding is demonstrated. The red floor, although entirely diffuse, adds a hue to the surrounding gray walls. The second screenshot shows a variety of caustics, as the light reflects and refracts off of the cylinders in the center. About 250 thousand photons were emitted for each render.

Raytracer

Raytracer

A ray tracing engine was implemented over my final semester at DigiPen. It supports a a few basic shapes (sphere, box, cylinder, cone), three types of lights (point, direction, spotlight), and uses the Phong shading equation. Features include reflection, refraction, and adaptive supersampling. Photon mapping, a relatively recent technique which allows for other interesting effects, was implemented as a independent research project.

Bump

The level editor

Bump (Junior Game Project)

Bump was a junior project that was developed over a 3-semester period with a team of 4 programmers. I was responsible for much of the backbone of the game, including the entity manager and component system. I also designed the level editor, which allowed the rest of the team to rapidly generate all of our levels. As development went on, more features were added to editor, such as soft selection and ramp creation. The goal of the game is to collect balls and bring them back to your goal before the opponent does, and includes over fifteen levels.

navmesh

ai2

ai3

Arbitrary Navmesh Generation

This was implemented as a final AI project over one semester. The program takes any triangulated mesh as input and performs a systematic technique to calculate the final navmesh (shown in yellow). The user can click anywhere on the mesh and have the character perform A* to that point (the red line represents the cheapest path taken). Ogre3D was used as the graphical backend, and the Bullet physics library was used to test the character controller (although the navmesh creation was done without any third-party libraries).

The navmesh is generated only by examining the geometry of the mesh, although other parameters can be tweaked depending on the size of the character, the maximum slope, or the level of detail. The algorithm is divided into several different stages, which I'll describe briefly here. First, each triangle in the world is tessellated into smaller triangles, and then a single node is placed in the center. Black nodes are placed on triangles that our considered to be unwalkable (such as ceilings, walls, or steep inclines).

After all of the nodes have been generated (and any unreachable nodes have been removed, such as those that are inside geometry), the second step is to merge all of the "walkable" nodes into more manageable bounding box regions. We do this so that each bounding box represents an area that the character can walk freely in (i.e, no gaps or walls that would prevent the character from moving across any two points). Essentially, a random node is selected that hasn't been merged yet, and then a bounding box is "grown" out form the center by expanding each of the six sides at a time. Each time we expand a side, a check is performed to make sure that the region is still valid, and that no holes or walls have been covered.

Once the entire world has been cut and sliced into walkable bounding box regions, the last step is to create the navmesh by searching for connections between two or more boxes. If two boxes are close enough to one another, and there is nothing preventing the character from transitioning between them, then a node is placed in the navmesh at the connecting location.