Space Game v0.1.3 Released!

A new version of Space Game is now available for download! This is not a major update, but it includes many performance fixes and gameplay improvements over the previous versions. The main performance update corrects the sphere vertex distribution (as explained in Cube-to-Sphere Projection) for a consistent and uniform frame rate. The bounding box algorithm now uses Oriented Bounding Boxes (OBB) to reduce selection in planet “corners.”

Shadow mapping is off by default in this release. Since this feature is still experimental and has a big performance impact, I think it is better at this point to have the player manually enable it. To enable shadow mapping, open config.ini and append the following lines:

shadow_mapping = 1

Known Limitations:

The new frustum-OBB culling algorithms are not yet perfected. There are cases where terrain will not render though it is visible on-screen. I am currently looking into a fix for this issue.

Cube-to-Sphere Projection

As the release of Space Game v0.1.3 approaches, I thought I would discuss one of the more challenging obstacles that was blocking its release. I first noticed something was wrong when traveling to certain “corners” of the demo planet in the game. Performance would drop, and the simulation would attempt to request and render thousands of terrain nodes. Towards the spawn region — and most of the rest of the planet — I never noticed this performance hit. For a while, this seemed like a minor issue and I just left it on the backburner. Well, it turns out that the issue was a bit more sinister.

To give some background, the planet renderer originally used the naïve cube-to-sphere projection of simply normalizing the quadtree cube coordinates and scaling to the planet radius. This method can be seen in the image below. The red dots indicate vertices placed at equal intervals on the cube’s surface. These vertices are then “pushed” along their normals relative to the center point until they reach the sphere surface (marked with green dots). Notice the green dots are no longer at equal intervals on the sphere surface. This introduces a distortion with more vertex density towards the face edges.

In the terrain renderer, each pair of dots constitutes a renderable tile. This means that as the player approaches the edges of the former cube faces, more terrain tiles would be required and performance would drop. To solve this, I implemented a projection scheme that would warp the position of the cube face coordinates such that when they were projected, they would create (nearly) equal area regions on the sphere surface. Terrain tile density would remain mostly constant and gameplay should stay smooth. The desired projection is shown below.

The cube face coordinates (red) are now warped towards the center of the face such that after the sphere projection they are at equal area intervals (green). As it turns out, this is a projection that is easy to compute an exact solution for in 2D, but difficult in 3D. My goal was to find a projection that minimized computation, but also provided an equal area solution to an acceptable margin of error.

After some research, I found a paper that went over several options for cube-to-sphere projection. The approach outlined in the paper that I found most desirable is the Odd Polynomial Univariate method. It had minimal area error, but was also very fast to compute. The method forms a 5th order polynomial with 3 coefficients that are optimized to minimize distortion.

    \[ K_1 x + K_2 x^3 + K_3 x^5 + \ldots \]

This method further reduces the error beyond the similar tangent function, and it is a simple computation. So with this equation in place, I thought I had a sphere with nearly equal area distribution. I start up the game, head to a planet corner and… performance dropped to a slow crawl! After investigating for a few days, I found that the warping scheme was applied on my UV coordinates which were in the range [0, 1]. This caused the projection to push vertices into the (0, 0) corner of each face, resulting in extreme terrain tile counts in this region. After remapping the UVs to a [-1, 1] range, my performance was as I had predicted.

This was another one of those issues that seems simple in hindsight, but the processing of discovering the problem and tracing back its cause can be exceedingly difficult. The resulting mapping is now fairly uniform and has good performance all over the planet. Now that I’m done wasting time fiddling with renderer basics, I’m hoping I can get Space Game v0.1.3 out soon!

Space Game v0.1.1 Released!

I am excited to announce the first public demo release of the Space Game engine! The goal of this demo is predominantly to start testing the game on a wide variety of hardware. There are many quirks to the GPU-side double-emulation code that have been exposed on new hardware in the past. It is better to eliminate these issues now while the code base is relatively small, than to discover them later when many more lines have been written based on the current assumptions.

There are a few new features relative to the previous update. I had mentioned adding HDR and exposure support. Well, I jumped the gun and implemented a basic system without eye adaptation. The atmosphere and sun are now at more realistic brightness levels relative to the rest of the scene, although this will still require some tweaking in future updates. The output is also now gamma-corrected for completeness.

The Space Game engine still has a long way to go, and has plenty of yet undiscovered bugs. But this first release is a big milestone in its development. I hope you enjoy experimenting with it! Please feel free to share any ideas, and don’t get too upset at the many deficiencies at this point.

Skybox Update

I have been holding off on this one for quite some time. The graphics, especially in space scenes, have always seemed to be devoid of…. soul. There were only two visible bodies: the star and the main planet. Not a star to be seen in the sky!

I have held off on adding a background for a few reasons. Firstly, it’s not totally unrealistic to have the background empty when viewing very bright objects in the foreground. Just like how there were no stars in the background in the moon landing images, there should not be visible stars in these scenes. However, it turns out that the blackness of space is very unwelcoming. The game feels friendlier when you can see some stars.

Now with 100% more dust!

Second, the game will ultimately support a whole universe of stars, galaxies, and nebulaes that the player will be able to visit. Once this feature is in place, the background will be the true sky around the player rather than a skybox. Any star in view would be a potential destination for the player. But, this feature is some ways off. So in the meantime, I have decided to breathe some life into the game with a static skybox.

Atmospheric scattering and color blending.

In the future, I hope to add an “eye exposure” that may help replicate your eye adjusting to the light level. This will help strike a balance with realism without making the universe seem boring. Stay tuned for developments with this feature.

Particle System

I have added many features to the space project over the last few months. But one feature that I have been looking forward to adding for a long time has finally come to fruition. It’s a feature that adds a small touch of life to the game and is useful for countless dynamic graphics effects. By now you probably have guessed it (not to mention the blog title)… Particles!

Set the controls for the heart of the sun!

The space project’s Particle System faces many of the same precision issues that have made conventional approaches more difficult. These particles must be able to be emitted at very high relative speeds, and in many different reference frames and coordinate systems. By making use of double precision on the CPU-side, and emulated double precision on the GPU-side, I am able to accurately render many billboard particles at a wide range of velocities and distances throughout the entire Star System.

The Particle System itself is based on a pool (underlying deque) of IDs that point to Particle objects in a constant-size array. Active particles are moved from the pool to a list where they are updated every frame. An active particle has a life cycle that is directly related to its current “alive time,” which measures how long in seconds the particle has been alive. During this life cycle, particle parameters can be adjusted based on functions or simple interactions to create interesting graphical effects. Once a particle has reached its end-of-life, it is transferred back into the pool where it can flag that it is available for use again.

On the graphical side of the house, the particle position and parameters are stored in a dynamic Vertex Buffer Object (VBO) which is updated after any change is made. Like other graphical objects in the game, positions are assumed to be relative to eye (or camera) to conserve precision close to the viewpoint at the expense of precision far from it. This results in a very stable simulation with minimal apparent jitter. The Particles are sorted by the square of their relative to eye position for correct alpha blending of translucent objects.

This is the most stable and efficient launch profile for this spacecraft.

The Particle System is far from compete and currently only supports smoke trails. However, the bulk of the implementation is out of the way. New Particle types can be rapidly added to support all kinds of graphical effects. But for now, what other than smoke does a space game need to support? Yeah, yeah, fire and… explosions of course! Stay tuned.

Solid Rocket Software

In the spring of 2017, just before I graduated from school, I began a small C++/Allegro project to predict solid rocket motor performance. This project started as a simple 0-D ballistic model based on basic primitives, but quickly grew into something more as I continued adding features. By the end of the summer, I had a program that could take arbitrary 2-D solid rocket propellant and case geometry, and simulate ballistic performance in real time.

The software takes an input file that defines the geometry and solid propellant characteristics. The initial as-cast propellant boundary is input by a series of coordinates and indices. This will define the bounding volume that the gaseous products will initially burn into. Propellant parameters can be found with a thermochemistry code such as NASA CEA. The final section of the input file defines nozzle throat and expansion data that is used for thrust and pressure calculations. These assume the 1-D isentropic nozzle flow equations for simplicity.

After the program reads in an input file, it computes a level-set that represents the data. This level-set is internally held as a non-uniform signed distance field. To speed computation, the level-set is maintained as a quadtree with the highest resolution clustered about the burning “interface” between the solid propellant and free volume. The level-set is recalulcated as it diverges from the typically slow-moving interface. This does not usually need to be performed every time step, which saves some computer cycles.

For each time step, the level-set is recalculated using a Lagrangian scheme. A burning “flow field” is computed against the level-set using the interface normals. The next interface is extracted from the current level-set using an algorithm based on Dual-Contouring. The surface area can then be found by computing the length of the lines composing the contour, and then scaling that value by the input length of the motor. Moving to a 3-D regression simulation, the surface area of the triangles that compose the contour will be used instead.

From the current burning surface area, which is found via the previously described algorithm, the internal ballistics of the motor may now be calculated. The mass flow rate of the propellant grain, and therefore the pressure of the motor, can be found using parameters from the last time step. The current burn rate can be found using the chamber pressure and St. Robert’s burning rate law. Once the motor pressure is known, it is a trivial task to compute the current thrust using the isentropic nozzle relations.

This brief blog post does not cover all of the features of this software, or all of the details of its implementation. I would like to go into detail about some of its inner workings, and maybe even one day extend the functionality to 3-D. I have included some sample output clips from two solid rocket performance runs: an 11-point star, and a double anchor shape. I hope that these make some of the methodology described in this post a little more clear. Thanks for reading!

Space Simulator Progress

Over the last few weeks I have made significant progress on the core parts of the space simulator engine. Although some changes were made under the hood (more sensible organization and rendering), the most noticeable are the addition of model material support and shadow mapping.

Model materials are a feature that have been a long time coming. Models used to support only one mesh and a clunky and simplistic shading model. With this latest update, models can have an arbitrary number of meshes (performance-limited) and can compile flexible shaders on the fly. Although the current demo shader continues to use the Phong shading model, I am looking into implementing a more complex Physically Based Rendering (PBR) model. Textures are also implemented, but have a few bugs associated with them. Check out a rendered scene with multiple materials below!

A new system was needed to provide high fidelity shadows both on the ground and at altitude. I had started the skeleton of Cascaded Shadow Maps (CSM) nearly a year ago and was finally able to get the feature implemented. Although it still has some bugs that will need to be ironed out, shadows give the rendered scene a greater sense of depth.

These are just a few of the most obvious updates. A rudimentary cockpit system is in place that will allow the player to have a first person view from the spacecraft. I am currently working on improving the rendering model a bit, and then I will move on to adding fidelity to the planet and surrounding solar system. Stay tuned for some exciting updates and a possible official public demo release soon!


After migrating from my previous host, I’ve reset the blog again. I’m thinking this time around I will make this blog a lot more free-form, and not strictly related to certain topics. I’ll be posting my thoughts, adventures, or software development updates here.

For now, the focus will likely mostly be on my space simulator that has been in development for a long time. And likely will be that way for a while.