2D tile rendering

The mobile platform is ideal for 2D tile based games like Bomberman or FinalFantasy 1-6. This article is about rendering and retouching 2D orthogonal tiles.
(Note: I use Modo and PaintShopPro, but the workflow is similar with any other 3D/2D packages. In Modo the XYZ axes translate to width/height/depth.)

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 8×8 tiles with the view angle of 45 degrees. We need a reference grid: make a 256×256 ground plane, with 8×8 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 will be part of exactly one tile, no bleeding will occur between cells. On the left you can see a zoomed in view of three adjacent cells.

Color bleeding between cells 2D tile rendering 2D tile rendering image1

Now let’s take care of the camera. Set the position to for example [0, 0, 135.8]. The reason why its exactly 135.8 is that when rotated 45° around the origin, the camera will arrive at [0, 96, 96], which is a nice number. But it doesn’t really matter as long as you use the X as rotation axis and the origin as the center.

Set the Projection type to Orthographic. Set focal length, Film width/height all 1. Focus distance to 256, or whatever the dimension of your plane is.

Now the camera sees something like on this image. 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.

Reference grid 2D tile rendering 2D tile rendering image2

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.

The cells from the side 2D tile rendering 2D tile rendering image3

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 later in the retouch phase.

The two mesh groups 2D tile rendering 2D tile rendering image4

All right, we have all the objects in place, we are almost ready to render the first group of tiles. Let’s set up the render parameters:
Although the final texture will be 256×256 pixels, set the frame to 512×512. 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 to a .PNG file to keep transparency information.

Now comes the retouching part.


On the right 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 that, 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 (minimum filter) 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 checkerboard texture to it as a mask. The same goes to the White group, only the checkerboard 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.

The layer setup for retouching 2D tile rendering 2D tile rendering image5

I recommend recording macros for the most straightforard/tedious steps as they will make the workflow faster and help to keep the results consistent.

Anyways, here are my results:

The final tile set 2D tile rendering 2D tile rendering image6
The tile set used in a level 2D tile rendering 2D tile rendering image7