2D tile rendering

Making tiles for orthogonal 2D games.


This article is deprecated. You'll find the updated version HERE.



Introduction

Gaming on mobile devices is very common these days. You can play on your mobile phone, your PDA, even on an mp3 player. These gadgets are ideal platform for 2D tile based games like Bomberman or FinalFantasy 1-6. This article is about rendering and retouching 2D othogonal tiles.
(Note: I use Modo and PaintShopPro, but I think the workflow is pretty similar when using other 3D/2D applications.)

Example

Let's start by setting up the 3d scene and the camera. We have to decide on two important parameters of the tiles: how many we want to render in one texture, and the angle we want to look at them. In this example my target is a texture containing 8x8 tiles with the view angle of 45 degrees. We need a reference grid: make a 256x256 plane on the XZ plane, with 8x8 segments and centered in the origin. The tile objects will be located in the cells of the plane. I'm using "game units" as system unit: the "power of two" based grid helps to keep everything ^2 based. This means that on the final render (dimensions based on ^2 as well) each pixel is associated with exactly one tile, no bleeding will occur between cells. On the left you can see a zoomed in view of three adjacent cells.

Now let's take care of the camera. Set the position to for example [0,0,135.8]. Set the action center to "origin" and rotate the camera on X by 45 degrees. It will arrive at [0,96,96], but to be honest [0,7.14,7.14] would be just as good. :) Set the Projection type to "Orthographic". Set focal length, Film width/heigth all 1. Focus distance to 256, or whatever the dimension of your plane is.

Now the camera sees something like on the image on the left. The width of the reference grid is all right, but since we are looking at an angle, it doesn't fill the frame vertically. We have to scale up the grid item by 1/(sin(45°)) on the Z axis. In this case it's 1.4142.

Now the plane covers the whole screen. The next step is to extend this grid to visualize the camera projection. Use the extend tool and extrude by [0,96,96] or whatever coordinates the camera is at. Now we have an idea where each tile should go, and where the camera is looking from, so everything is ready to model actual content.

When modeling, use the reference object as a guide in the background. Each object should be inside its designated cell. It is a 3D volume now, so look out for height as well. To be on the safe side, make stuff just a little bit (1-2%) smaller.

Another thing is sorting the tiles into "black" and "white" groups. Like it's a chessboard: tiles on the white squares are one group and the rest is another. This separation will help us much later in the retouch phase.

All right, we have all the objects in place, we are almost ready to render the first group of tiles. Let's set up render settings:
Although the final texture will be 256x256 pixels, set the frame to 512x512. It is always better to work on higher resolutions.
Antialiasing: 1 or 2 samples/pixel. Too high value will result in a too soft image in the end. (We are going to downscale the image anyway.)

Okay, render both object groups and save the images in .PNG to keep transparency information. Now comes the retouching part.

On the left you can see the layer setup I ended up with. Let me explain the main parts of it, starting from the top.

The "Additional" layer contains stuff not coming from modo. In this case that's two smoke puffs, made with one of my FilterForge filters.

The collapsed "White group" contains half of the objects. The structure inside is exactly the same as in the expanded "Black group", only the data is different.

At the bottom of the "Black group" is the image rendered in modo. It's all right, but too "renderish", lacks the style of classic pixel art. To make the tiles look more like it, let's make a black outline around the tiles.
Duplicate this layer (that's the "Outline"), and use the "Threshold" operation with a value of 1-3. This makes all non black pixels totally white. (If you have black inside a tile you have to clean that up manually.)
In the "Canvas size" dialog, increase the canvas size by 1 pixel on each side. (Make sure the background is transparency, not a color.) Now if we apply "erode" twice, we are going to have a black outline sneaking in at the edge of the texture as well. (By separating the objects earlier, we made sure that even tiles covering the whole cell get an outline from all sides.)
Set the layer's blending mode to multiply.

Repeat these steps at the other group as well, and then crop the image back to its original size. To do that "select all", contract the selection by 1 pixel, select the crop tool, and click on the "Crop to current selection" button.

Almost done. The outline may look very aliased, but downscaling the image will take care of it. Unfortunately that will also cause some bleeding around tiles which extend to the borders of their cell. To prevent that we put the "Render" and "Outline" layers into a group, and apply a checkboard texture to it as a mask. The same goes to the "White group", only the checkboard is inverted.

We are pretty much done. You may want to experiment with "Edge preserving smooth" and "Sharpen", if you feel the image is too CG like and/or too blurry.

Here are my results: