April 04, 2013

Rendering a skybox for Unity, using Blender

A skybox, is a wrapper around the world of your game, used as a method of creating a sky (or backgrounds in general).
It essentially is, an inward facing cube around the game world, where each of the 6 faces has a texture assigned, that connects seamlessly to the surrounding sides, appearing to the player as a seamless sky.

The theory behind it, is pretty simple, imagine taking a photo of all 6 directions around you (up, down, left, right, front and back), if these would get mapped onto all 6 sides of a cube, you would get a surrounding view in every direction, standing inside it.

Making them can get a bit more complicated, all textures have to be able to connect (without visible seams) to their surrounding sides, and since it is a cube, and not a round object, there is distortion around the edges to deal with.

Painting this by hand, especially when there are objects (mountains, clouds) getting close - or even over - a seam, can be really tedious.

An easy way to do it, is to render it in a 3d application, you can either model your environment/place  volumetric clouds, or just paint it and place your painted objects within your scene. The rendering will take care of aligning the views correctly, handling the distortion.

To do this in blender (2.66a when writing this), first create your environment as you like it (for the demo here, i'm using an empty environment, with just a simple sky gradient and sunlight setup).

Once you like the look of it, position an object in the center of your world (it does not have to be the actual center, but the point from where you like your skybox to be viewed), a primitive object (cube, sphere etc.) will do. Next step is to add a new Material to the object, and create a new Texture > Type: Environment Map.

Unfolding the Environment Map section, you first want to select Cube as the Mapping type, and select your center object, as the Viewpoint Object.

The Clipping value, will set the distance objects will be rendered in, if you have objects far away, make sure to raise this high enough.
The Resolution will set the pixel resolution of your map, since this is displayed in a very big scale in-game, if you have something detailed in it, make sure to go high enough to avoid artifacts.

Once all is set up, render your image.
You'll notice that not much changed once the render is done, however there is an environment map generated now, by clicking the little arrow in the corner of the Environment Map, the image can be exported.

Blender will save this out as a single image, for taking it into Unity, you will need to cut it apart into 6 individual textures.

Blenders map render order (for unity), works like this.

To get it to work in Unity, import the individual textures, and make sure to change their Wrap Mode to Clamp in the Importer.

Using Clamp, instead of Repeat (default) will avoid visible seams..

To actually use it, create a new Material > RenderFX/Skybox, and assign the images to the matching directions. You can enable it through Edit > Render Settings > Skybox Material now.

That's all, pretty simple, and can be a real timesaver compared to manually adjusting the images to match by hand.