I’ve released my iOS App, Pulse Racer on the app store!
Pulse Racer is a rhythm based score-attack game, which requires the player to travel along a generated course and collect “notes” which are synchronized to music. Players are rated based on their ability to string together notes, and their final percentage at the end of each course.
I’m really quite happy with how the project turned out and, for me, having a polished app on the store is a huge accomplishment.
Technically this app was a big endeavor as well. I’ve had the idea floating around for a year or so, but was never able to properly execute it until now. Building courses based on music is more difficult than it seems at first glance. Perhaps the most challenging part was determining the positions of notes on the course. I used a spectral-flux based onset detection algorithm, which ran a Fourier transform over audio samples, converting them to the frequency domain. Next I calculated a net difference in each spectral band between samples using a rolling average. From this, I determined the change in acoustic energy for each sample window. From there, it was simply a matter of finding local maxima (locations where the energy peaked), and I had a reasonably reliable system. Other aspects of the course are generated from the intermediate steps. For instance, the large-scale contour of the course is based on the acoustic energy graph. The radius of the cylinder is based on the spectral flux over time, and so forth. Using these techniques together produced a fun, and challenging course for almost any song input into the game. This also allowed for tracks to be pre-processed, so that no complex calculations were done during the game, allowing for the absolute maximum frame rate.
The music I used was made by an awesome artist I found online, F-777. He was kind enough to let me use a few of his songs as included sample tracks in the game, so that users did not need to generate their own to play. My experience working with him was a blast, and I’d highly recommend him to other developers looking for some good electro music.
Pulse Racer was a blast to work on, and was a wonderful learning experience for me. It is currently available on the App Store for $1.99 should you wish to play.
Pulse Racer Website
App Store Link
I know webGL already exists, and serves as a fantastic solution to integrating 3D into web pages, but I wanted to know what is actually involved in a simple 3D rendering architecture. I’ve used OpenGL quite extensively, but I thought it would be interesting to try and write it all from scratch… so I did!
Currently the worst part of the system is the rasterization code. I attempted a per-pixel rasterization system, which iterated through all points on each triangle, and colored a frame buffer based on the calculated color values for each pixel. I did this primarily because it allowed me to perform simple depth tests using a depth buffer, and the opportunity to use custom pixel shading programs. The rasterization system is COMPLETELY unoptimized at this point, and as a result, it is painfully slow. Rendering using the built in polygonal drawing tools in HTML5 Canvas is far faster, however I could not find a way to draw polygons to a second buffer or context, and as a result, depth testing quickly became impossible.
It might not be a visual marvel, but it works, and I’d say it does its job fairly well, considering the tools used.
The project is available on Github here and is free to download and use!
I was playing more with OpenGL, and decided that I could re-write my existing 3D back-end to be far more flexible! After looking over asset libraries for quite some time, I decided that it would be a good idea to try and incorporate a flexible, reliable framework for reading asset data. I eventually settled on Assimp. A cross-platform library for loading dozens of different 3D assets, animations, skeletons, and some texture formats! It was admittedly a bit of a pain to work through, but once compiled, it was easily incorporated. Pretty soon, I got my system loading .Md5 models (The format used in older versions of the Quake engine).
After I managed to get models loading, my next goal was animation. Skeletal animation is something I had never tried before, and frankly, I was a little afraid of it. It seems like a daunting task to begin with, especially considering the seemingly infinite number of possible skeletons and numerous model formats that could be loaded. Some model formats store their joint orientations in quaternion values, so I ended up having to write a quaternion to matrix conversion system on the back end in order to allow these formats to work! Eventually though, I got simple .Md5Anim files loading, and playing (sort of). With hours of struggle, and frustration, I finally figured it was a simple problem with multiplication order of matrices. In the end, I got these models playing arbitrary animations successfully!
This system supports almost any effect, shader, or camera setup imaginable, and is flexible enough to implement a number of simple effects incredibly easily. So far, it does not support more advanced lighting features, such as shadows, but they can be added in quite simply.
I was disappointed when I found out that the Unity terrain engine did not work properly on mobile devices, so I experimented with a number of different custom solutions. Over time, this project began to evolve into a fractal terrain generator, using simple noise algorithms to produce a randomly generated landscape. Next, I wrote custom shaders to blend between a stony texture and a grassy texture depending on the slope of the terrain. This worked well, but lacked the depth I felt it needed. The final step was implementing the custom shell model used to represent grass. The terrain is rendered multiple times with various vertex offsets in a multi-pass shader, with time and location based fluctuations to emulate wind, and a grass height based on slope, and some user specified parameters.
The system works fairly well, and allows for a simple procedural terrain that can be dropped into any scene.
A simple landscape generated by the script.
A close-up of the rendered grass, implemented in the base terrain shader.
A view of the generated terrain from within the Unity engine.
You can experiment with this script by running the Unity Player here
In 2009 I began experimenting with OpenGL. I found it cumbersome and unwieldy, but incredibly versatile and powerful as a rendering engine. As a result, I wrote a simple wrapper library in order to streamline the OpenGL programming process, creating a series of wrapper classes and internal formats to dramatically simplify project workflow and make the entire OpenGL rendering framework much easier to use.
This unnamed library supports a number of distinct features, such as near instantaneous mesh file loading, custom texture import functions for a number of formats, support for GLSL shaders, per-pixel lighting with a large number of dynamic lights, and multi-buffered post-processing effects.
Custom per-pixel lighting model, tested on a 250,000 polygon mesh.
Multisample post-process effect, rendering a simple Gaussian blur in real-time.
Depth of field post-processing effect with automatically calculated focal distance using depth-buffer sampling.
A brief video demonstrating the library.