OpenGL skybox in Space Nerds In Space

September 9, 2013 –
I’ve added an OpenGl skybox to Space Nerds In Space.

A skybox is a cube in which the interior faces have been wallpapered with images (texture) to represent the distant environment. The cube is rendered without lighting, so if you are careful about how the images are constructed so that at the seams, everything matches up, and if your environment is kind of “smooth enough”, you can position the camera within this cube, and no matter which way it is pointed, things will look pretty good.

If you think about a cube, such a scheme will require six square images, each constructed so as to match it’s four neighboring square images at the edges. How to construct such an image? Why with a computer program of course.

So, I set about to make such a skybox creating program. Since Space Nerds In Space is, surprisingly enough, set in outer space, a good start is a purely black cube depicting the utter blackness of space. So my program started out like this:

PImage[] img = new PImage[6];
int xdim = 256;
int ydim = 256;

void draw_all_images()
{
	image(img[0], 0, ydim);
	image(img[1], xdim, ydim);
	image(img[2], xdim * 2, ydim);
	image(img[3], xdim * 3, ydim);
	image(img[4], xdim * 2, 0);
	image(img[5], xdim * 2, ydim * 2);
}

void setup()
{


	size(xdim * 4,  ydim * 3);


	for (int i = 0;  i < 6; i++) {
		img[i] = createImage(xdim, ydim, ARGB);
	}

	img[0].loadPixels();

	for (int i = 0; i < 6; i++) {
		for (int j = 0; j < img[i].pixels.length; j++) {
			img[i].pixels[j] = color(0, 0, 0, 255);
		}
		img[0].updatePixels();
	}

	draw_all_images();
}

I’m using the language Processing as it is well suited to these types of problems. The program above simple creates six square images, fills them with the utter blackness of zeroes, and then draws them in an unfolded, flattened cube shape.
(Note: quite likely wordpress has butchered these images. You can see an album here.)

The next step was to add some kind of plotting function which is cognizant of the topological wrapping rules so that I can pretend to draw on one image square, and when I stray off the edge, be automatically transported to the correct location on the correct other square, recursively. Additionally, I don’t want to just plot points, I want to allow transparency, so I want to do some alpha blending. So, for that, I looked up a formula on wikipedia.

Here is the code change for recursively locating the correct location to plot, and for alpha compositing.

Now that I can plot things on my unfolded cube, I should totally plot some stars. To draw a star, a few things must be decided. How big should the star be? What color should it be? These are questions best answered randomly, by my favorite function (not my favorite author), rand. For the color, mostly white, but with some random tinting. Size, well, I picked a reasonable range. Stars smaller than some threshold are drawn as points, with the opacity (alpha channel) being lower for smaller stars than for higher stars. Stars bigger than this threshold are drawn as a kind of union of a large plus sign and a small muliplication sign. That is, a vertical and horizontal line, and two shorter diagonal lines, all crossing at a common intersection, the star’s center. The lines are drawn such that the opacity is greatest at the center, and lessens proportionally to the distance from the center. This turns out to make quite good looking stars.

Here is the code for drawing stars.

The next thing to do is to add some sort of nebula. As a first step, I thought I should add a partially transparent circle that fades on the edges outward to total transparency.

The code to do that is here. This however has a small problem. Some areas are drawn twice.

How to solve this? I don’t know. But maybe I know a way around it. Make it smaller.

Ok, but a circle is not a very convincing nebula. Perlin Noise to the rescue. Luckily, Processing has a library function for Perlin noise, so we don’t even have to write that. Just call noise(x, y). We pick an offset into the perlin noise randomly (this is akin to setting the random seed for the perlin noise) and scale our x and y to get a kind of noise we like. Then, we can scale the opacity of our circle by the square of the perlin noise at each coordinate (scaled and offset).

Here is the code change to render the nebula opacity as a function of Perlin noise. Not too bad.

But, might be nice to have some color other than blue — but still with a blue bias. We can use Perlin noise to offset the colors based on
scaled coordinates as well. Code change to
set colors via Perlin noise
.

Then all that’s left is to scale the image up to something larger, and save the images out to files.

The results in game look like this:

~ by scaryreasoner on September 10, 2013.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
Follow

Get every new post delivered to your Inbox.

Join 39 other followers

%d bloggers like this: