Avoid overdraw on advanced parallax scrolling

Hello guys,

Recently i started develope (2d) games with unity (before i did with libgdx / corona) for mobile devices. I think unity has a very nice workflow. So do not blame me if this is a stupid question :frowning:

Since i develope for mobile devices, i am really trying to make game as efficient as possible.

For my next (2D) project however i have a complex parallax background with 4 layers. As you expect, there is a lot of alpha channel in those sprites. Since there are 4 layers, i am forced to overdraw a lot. This brings a big problem. On older devices the fill rate is not very high and i got really performance drops.

I have been searching a lot for solutions but cannot really find a good one. I am new to unity so I do not know how to create custom shaders or to modify them.

The solutions i can only think off are:

  • Reduce texture resolution (however the background still fills the whole screen 4 times, so does it really help?)
  • Using atlasses: I already do this for every layer (every layer has 4 parts)
  • Using Spritemode-> Mesh Type: Tight (this will increase verts but decrease overdraw, and will increase performance in my case)
  • Create custom meshes for textures? (however i do not really know how to do this with sprites…)

Picture of my workflow:

I hope someone knows any better solutions or have any tips & hints.

Thanks,

Ilija

Using a tight mesh type for sprites is all you need, surely? Reducing overdraw is the whole point of that feature.

–Eric

I know, but are there more techincs? since tight mesh is not reducing overdraw by a lot

If it’s for iOS then simply ensuring that the bulk of it is using an opaque shader and the edges are using a transparent shader will eliminate all overdraw for the opaque portions at the gpu level, since that’s what tile deferred gpus do.

But if not then like eric says, you can just use Unity’s sprite feature to create sprites that have a mesh that fits it closely (I think this is a pro feature) and save fill.

It’s not actually all that expensive on any recent mobile to fill the screen a few times. You should be able to get 3 layers + sprites at 60fps providing the shader itself isn’t expensive.

Agreed. Section off the main interior of the background elements to be rendered with a simple solid non-blending shader, then do the smooth/variegated edges with blending.

You can do the thing with the closely-fitting geometry, which will help, since you’re discarding a lot of empty space that doesn’t have to be tested for visibility. But even then with lots of layers you can get lots of overdraw.

Overdraw is really a matter of having to WRITE to the same pixel more than once. You can alleviate this in a custom shader somewhat, by having all of the textures input to that one shader, choosing which telex is ‘closest to the front’, then outputting only one pixel. If you have alpha blending in your layers you could alpha blend inside the shader itself to cross-fade the layer contributions. This at least minimizes how much writing you need to do but it may still require that telexs from every texture are unconditionally read, regardless of whether they are visible… shaders if I recall don’t really do proper branching, they follow all possible paths and discard results, so I think it’d still read 4 layers even if only 1 layer is obscuring the rest. But 4 reads + 1 write is better than 4 reads + 4 writes. … adding the alpha blending cross-fade will be a little bit more overhead though. This kind of shader would be ideal for quite dense parallax layers with lots of content… lots of time wasted if there are lots of gaps, because your geometry has to cover the entire screen with no tight-fitting i.e. a single quad. And I imagine your background might comprise multiple sprites so this might make it hard for you to be flexible in your arrangement of parts.

At the moment i am aiming for android devices.

I am currently just using the default sprite renderer shader.

I do not fully understand what you mean by “the bulk”. Are there any tutorials about the opaque & transparent shaders since i do not really understand the difference between them and when&how they can be used on sprites.

I also wonder if there are any tools where you just can create custom meshes of a texture and just import into unity (i have only trial for pro).

Ilija

I suggest you simply benchmark it first. Worry if it’s slow since unity is pretty fast, probably faster than most engines for 2D on mobile.

I don’t doubt that, but i want to support some old devices too (4 years) and i am pretty sure this overdrawning causing to much performance lost

4 years ago is ancient in android land. You sure customers exist for it? :slight_smile:

Pretty sure ;), for example samsung galaxy s2. Somehow i take for example jetpack joyride. This games just rocks on older devices somehow.

Anyway i found a nice tool: http://www.spriteuv.com/, if you dont have pro version