Firewatch-Style Sky & Fog

After seeing this presentation from Jane Ng about her work on Firewatch, I fell in love with their backgrounds and tried to build a similar sky and fog shader. Their blog entry on the topic helped me get started by defining the parameters they use for their system, but it was a little light on implementation details.

I started by just generating simple gradients for the sky, set from user-defined colors. From there I projected the sun as a circle onto the sky from a position on the unit circle (to allow the user to the time of day) and added some exponential falloff from the sun's base color to the sky near the sun's position. The fog itself is a simple exponential function, with the density of the fog increasing with distance from the camera and with decreasing height. Scattering effects from sunlight into the fog are handled with a similar exponential decay function to the halo around the sun in the sky.

The coolest idea Campo Santo had, though, was their adjustment of the fog's color from a gradient map. This was easy to implement, but makes a huge difference. We just sample from a 1D texture based on the distance from the camera for each point (normalized to the 0..1 range based on the max draw distance) and use the color from the texture in the fog calculation instead of using a constant color value.

Using these gradient textures for the fog makes it really easy to create some very nice silhouettes off in the distance, and by adjusting the fog's density & height parameters you can still maintain a great deal of detail in the foreground, which lets the system provide photo-realistic rendering for objects near the user, and more stylistic rendering for distant objects.

It also lets you do some crazy things, like this rainbow map I used to debug some distance calculations.

There are GUI controls for all of the fog, sky, and sun parameters, which should be fairly self-explanatory. The fog uses a constant color by default (also settable in the GUI), but to use a gradient image instead just drag and drop any image onto the scene. Your gradients should be 1px tall, and some power-of-two px wide. Here are some examples:

If you have a Leap Motion and a VR HMD, you can also view the sky in VR and controll some of the sun & fog parameters through hand gestures:

  1. With your right hand: Make a fist, and move your hand vertically to move the sun. Pinch your thum & forefinger and move your hand side-to-side to change the size of the sun.

  2. With your left hand: Pinch your thumb and forefinger together, then move your hand vertically to adjust the fog height, or horizontally to adjust the fog density.

Play online here
NOTE: It will render at the size of your browser window! If you have performance issues, try resizing your browser.

Fluid Visualization

I helped build a small fluid visualization application in OpenGL over the summer. Our main goal was to produce something specifically for fluids, with the hope of making something more intuitive than ParaView for at least a limited set of scenarios (ParaView is amazing, but very complex).

At the moment the project supports most of the basic types of glyph and line rendering used for many fluid visualization scenarios, and we have plans to extend it with more interesting features like volume rendering and particle tracing.

It also provides a small plugin API which can be used to integrate the visualizer directly with a fluid simulator. At the moment we include a simple Lattice-Boltzmann Method simulator with the visualizer to demonstrate this, and to show off some LBM-specific rendering capabilities for displaying the distributions in each cell, which could be helpful for debugging your simulator.

The project is completely free and open source and available on github. If you find any issues or fork it and want to contribute changes, feel free to let us know!

The project dependencies are fairly minimal, with CEGUI being the hardest to set up. A manual is included in the repo which explains all of the GUI controls for the different rendering primitives.

Cyrano the Hothead

A short game made with a friend in one week for the Public Domain Jam. You take on the role of Cyrano de Bergerac just after he joins the military, and before he has gained the great amount of respect and panache that he is shown to have in the play.

Combat in the game is handled much like a card game, with different cards representing different types of actions that can be combined to form an attack. Some of these actions are physical, which will damage your opponent's health, and some are verbal which will lower their morale. Some card combinations will also allow you to execute a special move, which may differ from the specific cards you played to produce it. Physical damage is augmented based on the morale of you and your opponent, so maintaining your morale and combining verbal and physical attacks is the key to success.

The theme for this jam was "Paper", so we decided to make the characters as paper cutouts. To further drive this home in the game, characters (and many scene objects) are rendered on flat planes, and have normal maps applied which were made from high-res scans of rough paper.

Play online here, or take it with you for:
    -OS X (20 MB)
    -Linux (24 MB)
    -Windows (20 MB)

The game source and all related assets are also freely available:
    -Game Source & Assets (130 MB)
    -Additional Art Resources (332 MB)


PRESS: Browser Pick
    PCGamer: The Best Free Games of the Week


A Tetris-like game in which some pieces release water into the play area when they are cleared. As the water level rises, wooden blocks will float, separating them from metal and water blocks. This creates a two-tiered play area in which one must plan rows both at the surface and at the bottom of the water. The water level itself is managed by the player by submerging fireballs, which causes the water to evaporate.

Play online here

Triangular Crystal Growth

A small simulation which begins from a "seed" set of triangles, growing new ones from each available vertex while taking care than any newly-added triangles do not overlap any existing triangles.

Because the set of triangles grows exponentially, several optimizations were tested to keep the simulation running as close to real-time as possible. First, the triangles are grown one-by-one rather than growing all triangles from a whole iteration at once. This ensures that the actual rendering of new triangles is always done in constant-time and that the program never takes on a work load large enough to prevent a user from closing the application.

The next problem is collision detection. As can be seein in the image to the right, newer (smaller) triangles even after many iterations may still be in a position near the original seed triangles (the largest). This means we can't cull existing triangles from the set we need to compare against based on their age or size. Several spatial data structures were used before I finally settled on inserting each new triangle into an R-Tree and using it to manage the data for collisions. With the tree, performance remains acceptable up until well after new triangles are being created with a width of just 1 or 2 pixels. At this point, the overal shape does not change much, so there is little point in running the simulation further. A better optimization if it becomes necessary to run the simulation even longer would probably be to render every triangle to a bitmap, and then test new triangles against the pixels on a sub-region of the bitmap. With such an approach, the simulation could probably run indefinitely on a fixed-size bitmap (but it's not as much fun as using R-Trees!).

Play online here

Object Tracking for Interactive Installations

Simple object tracking prototypes in one and two dimensions using a cheap webcam. The tracking data is used to control the state of an LED array (via USB connection to an Arduino which manages the LED driver).

The eventual goal from this project is to develop a cheap, robust, system for tracking multiple people as they move through a space, allowing the room to react to their presence and movement. Essentially, to provide an easy and cost-effective means for developing installations like this one, which tend to be quite expensive to produce. To keep the cost as low as possible these early prototypes used the cheapest USB webcam I was able to find, which wound up costing less than the circuitry needed to control the LEDs. For a large-scale installation, the cost of LED controllers, lights, etc., easily outstrips the cost of the cameras, so future prototypes will use RGB-D sensors which allow for much more accurate object detection and tracking than a normal webcam.

The cost of driver chips, however, is non-negligible for a project large enough to fill a room. The cheaper drivers tend to only come in surface-mount packages, so prototyping is going a little slowly as I make breakout boards to use in testing. I'm currently focusing on using the TLC5947 driver for LED arrays, which seems to be quite cost-effective.

Raymarching with Refraction

A little hacky but working. The sky is actually just a hollow textured sphere, which unfortunately required me to bump the iteration count on the march up to avoid getting a seam on one side (should probably have just used a cubemap).

TODO: Caustics for the shadows, and reworking the hacks into something more robust (e.g. in the current implementation transparent objects will occlude other transparent objects).

Play online here
NOTE: It will render at the size of your browser window! If you have performance issues, try resizing your browser.


A simple animated raymarching exercise. Supports procedural and bitmap textures, both of which go through the same lighting process, as well as soft shadows and ambient occlusion.

Play online here
NOTE: It will render at the size of your browser window! If you have performance issues, try resizing your browser.

(Mobile users should use this ShaderToy link, instead)

HTML5 Julia Explorer

More or less "Hello World" for HTML5 and WebGL. On the left-hand side of the page you can see the color gradient used to render the fractal, and by clicking on the labels along the gradient you can configure it to render in any colors you like. (it will also randomly regenerate the gradient if the page is reloaded, but this doesn't usually produce pleasant color combinations)

Play online here
NOTE: It will render at the size of your browser window! If you have performance issues, try resizing your browser.

2D Sprite Engine

2D layered sprite engine for a never-finished action RPG. The engine was written in Python with the help of PyGame, and the map editor/animation viewer was written in C#.

The project began as a simple tile-based engine, but a strict grid and tile size felt too restrictive. Since fixed-size tilesets weren't necessary for performance, the engine was rewritten to simply render layers of arbitrarily-sized and placed tiles. The alpha layer for each bitmap contained metadata for collision detection, etc., and the tiles even supported animation (for things like water).

A level editor was written for the game in C#. It was modeled after a basic tile editor, and intended to be intuitive and easy to use for anyone who had worked on a fixed-tile game, but allowed the grid size used for snapping to resized at any time. This allowed multiple tilesets of different sizes to be used seamlessly together in the same scene, and special objects like trees, characters, etc, could be precisely positioned on or off the grid.

The tiles themselves were described in metadata files which defined "sets" of tiles. Each set could be composed of tiles from one or more images, and after loading only the relevant sections of each referenced image were retained in memory. This ensured that an artist could easily create a "set" of related tiles to be used together without worrying about performance beyond the number of unique tiles in a given set (and the number of sets used in a given map).