If you're running a 2D game on mobile,
chances are that you care a great deal
about rendering performance.
But one of your biggest perf problems
could be coming from a weird combination of alpha blending,
overdraw, and how you create your texture atlases.
But let's start at the top.
Modern 2D games are awash in awesome graphics
to create the visuals for their scene.
But when you start to break it down,
you realize that drawing your environment
is actually a complex dance involving
drawing multiple layers of graphics.
For example, the background layer, ground info,
sprites, and, finally, UI data.
Every now and again, though, we'll
see some weird additional layers pop up
that don't end up contributing to the final scene.
In reality, these extra draws create
a lot of wasted performance, which
is a scarce resource on mobile platforms.
There's really two ways to look at how
you render your graphics and your scene.
The first is back to front order and generally involves
drawing geometry farther from your camera
before geometry that's closer to your camera.
The end result is the last drawn pixel with the closest distance
to the camera.
Front to back order, on the other hand,
draws images closer to the camera
first and then progressively gets further away.
Although the rendering order of both of these techniques
produces the same final pixel color,
back to front produces 2x more work
that doesn't contribute to the final scene,
or, as we prefer to call it, overdraw.
The reason for the performance difference
has to do with how modern graphics APIs work.
You see OpenGL ES and all of its desktop brethren
support a mode called depth testing, which
allows you to avoid processing any pixels that
don't contribute to the final image.
Here's how it works.
When a pixel on the screen is updated with color information,
we also store its depth from the camera.
When the rasterizer attempts to draw another pixel
at that location, we first test the depth of the incoming pixel
against that of the existing pixel.
If it's farther from the camera, then we discard it,
saving cycles since we don't have
to compute any of the color.
Now if the incoming pixel is closer to the camera,
on the other hand, then we continue on,
compute its color information, and write it back
to the color buffer.
Overdraw is a term used to describe
how many times a pixel on the screen
has been redrawn in a single frame.
For example, drawing a large background image like this,
and then drawing a box on top of it, another one on top of that,
and then finally putting some font on top of that.
When you turn on your profiler's overdraw mode,
you can see the parts of your screen
that have been processed the most times.
If your screen is super red like this one down here,
then chances are you've got performance problems.
Any work you do on a pixel that doesn't contribute
to the final scene is wasted work.
Now for 2D games, alpha blending is the single biggest source
of overdraw.
Generally, a majority of the scene
has to be rendered with alpha blending turned on,
because those textures use some geometry that
have an alpha channel component in them.
When you render your objects in your game with alpha turned on,
you're forced, forced to render your scene in back
to front order.
This is because during each draw, the alpha operation needs
existing pixels in the color buffer to blend against,
which increases the number of times
a given pixel on the screen gets redrawn.
The truth is, the order in which you draw your game geometry
has a profound impact on the performance of your game.
In an ideal world, what you want to do
is render all of your opaque geometry
in front to back order, which will
reduce the amount of overdraw that
occurs, while rendering all transparent geometry in back
to front order, which we're forced to do anyway in order
to get the look we're after.
But this is easier said than done, trust me.
I read an analysis of over 1,000 games from Google Play
and found the majority of them are packing
both transparent and opaque images into a single texture
atlas.
Typically, this is a bad idea.
Texture atlasing software that's used to do this operation
doesn't always export the type of per image information that
allows you to know what was originally transparent
and what was originally opaque.
The result is that you're forced to assume
everything in your scene is transparent
and render everything in front to back order regardless
of the performance problems involved.
To fix this in your game, it's actually pretty simple.
When creating your atlases, split your alpha and opaque
objects into separate textures.
This will allow you at run time to sort geometry
based on what type of texture it has before
rendering them to the final scene.
The new process will help reduce overdraw
and will help make your scene render faster.
Oh, and one more thing.
Once you've separated your opaque textures
into their own atlas, make sure that you properly compress them
with GP texture formats.
ETC, PVR, and DXT are supported all by various levels
of hardware and will reduce distribution and GPU residency
sizes of your textures, which is something
everybody loves, right?
Anyway, the truth is that you shouldn't
take alpha blending lightly.
Besides giving you the look you're interested in,
there's a load of performance issues you may not be aware of.
So think twice, alpha once, and as always,
remember, perf matters.