Jon Baker, Graphics Programming

    home

    writings

Voraldo Spaceship Generator

green

  Motivation

  This was the concieved as an application for the font glyphs I collected as part of this project. With a collection of 50k+ glyphs, some of which are pretty exotic shapes, I thought that there might be some cool potential for form synthesis here. The basic concept is that by stamping these shapes into a voxel space, and applying a few different randomly selected operations to them, these interesting, sometimes symmetrical shapes can be produced.

first result

 As I mentioned at the end of that article, I have always found the toy problem of a 'spaceship generator' interesting, creating some type of structure that the mind might imagine to represent some kind of a spaceship. This was written as a header, and included in the Voraldo codebase, alongside the optimized glyph collection. The finished model is put into the loadbuffer, the same way as in the previous CPU-side shape gen code, and then copied with the same logic, allowing for the mask values of the existing data to be respected.

green card

  Data Layout

  With the help of Clepirelli on the Graphics Programming Discord, I decided that std::unordered_map, a hashmap impelementation, was a good fit for this operation ( at some point I want to implement my own replacement for this functionality, in the future ) - I had initially been trying to do this with an array, clipped to the size of the desired volume, but iteration became difficult, slow, and not very functional for the operations I was trying to implement. By using a representation consisting of a std::unordered_map< glm::ivec3, rgba >, I was able to handle only occupied voxels, not needing to even think about any voxels which were left empty - it ended up being a much more efficient way to do it. This carries with it a number of benefits - namely, trivial negative indexing of voxels through the use of glm::ivec3 keys and very efficient storage and iteration as part of the std::unordered_map implementation.

red

  In order to generate some kind of coherent color scheme, I used Inigo Quillez's palette logic. The process is relatively simple, using 4 vec4 control points, you can create some nice, smooth gradients. I found some instability when randomly generating these control points, but he provides some configs that produce very nice gradients. The original implementation uses vec3's, but it's a simple extension to add an alpha channel. If you do randomly generate these values, it makes sense to clamp each channel in the output to the desired range because it can create too large or too small ( negative ) values.

				vec4 palette( in float t, in vec4 a, in vec4 b, in vec4 c, in vec4 d ) {
					return a + b * cos( 6.28318 * ( c * t + d ) );
				}
			

  Operations

corruption

  Each of the manipulation operations creates a new hashmap and writes the new values into it. This is to overcome some strange corruption issues I was having using the .clear() method, like you can see in the picture here. In order to randomly generate a shape, these operations are applied iteratively, in a randomly selected order. There is relatively heavy use of std::random within this list. Operations are as follows:


blok

  I feel that this turned out well, and produced some interesting results. At some point I want to return to this and write my own hashmap to hold the data, potentially find some ways to tune it for this particular application. Adding more operations to manipulate the data might be an interesting thing to get into, as well.

deck

  I think there is some real potential in this, for automated procedural generation in the space game that I eventually want to make - by using a given color scheme and maybe constraining to small set of glyphs, to get some visual sense shared across multiple randomly generated spaceships. By picking a set of parameters like this, you could have some consistent style shared across ships from a given faction, make it look like they had colors and some geometric features in common. This could be made very flexible, with near-infinite variation, even when constrained to a very small set of glyphs.

teeth

Last updated 11/28/2021