Saturday, October 6, 2012

Sprite Atlas Tool - Part I: Creating the atlas

Sprite Atlas - why bother?

  When creating even small game you usually have to deal with lot of single sprites. Putting them into separate files may help you to organize them somehow but loading plenty of textures and switching between them will not make openGL happy as well as it will probably eat more of your memory.

 It is where sprite atlas comes into play. Sprite atlas is just a one big image created from all the individual sprite images. Of course, as the number of sprites increases its maintenance and changes require more and more overhead. More, creating it by hand is pretty boring and be sure that decent computer algorithm can do the job better than you. "Better" means it will be faster and sprites will be placed in atlas in such a way that the memory consumption is minimized.

 Unfortunately, most of the sprite atlas tools I came across on web are not optimizing anything. It just glues several images into one big by putting one after each other.

 All these problems can be solved when using our tool SBC PicOpt. It will help you to keep single files with your sprite assets and create optimized sprite atlases from them. Even more! You can create animations in it or add custom properties to sprites. The result you get may look like this:
GUI sprite sheet form our Mahjong Tris game

SBC PicOpt Tool

 The SBC PicOpt tool is Java desktop application. After you run it with "java -jar SBC_PicOpt.jar" or simply with clicking on provided .bat file you will get this screen:
SBC PicOpt main screen
  Next you will need to create your sprites. The tool can process .png files created like this:
example of sprite animation frames enclosed in grid
 Note the 1 pixel thin grid. The grid can have any color but this color should not be used elsewhere as it may confuse the tool when looking for particular sprites. Of course you can have may of such  images because with the tool you will add them to project. The grid can be also vertical or combination but each line in the grid must preserve its starting height. So, here are examples of good and bad grid:
good and bad grid for sprite frames
 OK, back to the tool. Select File->New Project and name your project. Next select Bitmap->Add bitmap and open your first picture with grid. Add another bitmap and you should have something similar to this:
SBC PicOpt main view after importing some gird based sprites
 In upper left combo box there are all imported images with grid. Selecting one changes content of combo box below it where particular sprites are already extracted from the grid. Your project is thus pile of grids that may contain one or more sprites enclosed in grid (even single sprite must be enclosed).
 The red dot in the editor is center which the sprite is relative to. You may drag the sprite on the screen end see how its Offset property is changing (more on properties later). How is the offset initialized? Yes, it is another feature of the grid. Actual start of the sprite is measured against top left pixel within the grid. Next time when loading your project it will be taken from saved property data.

Handling properties

  So far on the left side is only one property - Offset. Beside this there are also properties that are currently hidden and that will be present in data export after optimization. These are position of sprite within final atlas and also its size. But you are not limited only to these. What about creating rectangular collision box and some kind of point marker? Select Sprite->Sprite Properties and change it like this:
property dialog
 After clicking on OK you will be returned to main screen where all the new properties are placed over single red central point. So drag them with mouse to desired positions:
main view with custom properties


 You can also create animations with imported sprites. On the top right side of main screen you can add animations and below it you can manage animation frames. Try changing the screen so it look similar to this:
adding animations

Optimization and export

 Finally we got to creating the atlas. Choose Optimize->Best Place and the optimization starts. "Best Place" is the name for optimization method used. There was also alternative genetic algorithm but it was terribly slow so it is now removed. Ok, my result looks like this:
example of final atlas
 It merged two grid base sprite images in my project into one optimized sprite atlas. The result can be found in directory "export' that was created along with additional files with .dat and .anm extensions. These files contains all the data with properties and animations. Their format will be explained next time in Part II.

 You probably noticed some controls on the top of the main screen:
controls used to modify export
  these can affect the export you are generating:
Little endian - tells the exporter how the data should be saved - which byte order to use,
POT Texture - whether the final atlas should have its dimensions as power of 2. It is helpful when working with openGL ES textures,
Padding - says how much pixels is minimal space between sprites stored in final atlas. If you ever encountered ugly artifacts around your sprite when working with atlases and openGL you will appreciate it (it is related to way how pixels are interpolated when drawn)
Sprite Border - in connection with Padding says how many times the first and last row and column will be repeated instead of padding with empty space. Again, very useful - prevents artifacts and also fading out of the image in the rim.

Closing words

 This was my first blog post. I hope the tool will be useful for you and in Part II I will describe the output format. The tool is still far from perfect, so you may encounter situations where it throws some exception or so. But four games were already made using it.

No comments:

Post a Comment