Advertisement

Spritesheet or single-sprite files?

Started by August 27, 2014 03:05 PM
6 comments, last by Ravyne 10 years, 5 months ago

Hey guys, I'm back after a big existential break from programming and now I'm going all-in. 4 Life, brah! biggrin.png

So, I've read that using sprite sheets is usually preferred over making single-sprite files for your sprites, mostly for ease of editing. Apparently, you're not gaining much (process) speed from separating the sprites (perhaps you're actually losing speed?).

But then I saw how some devs do indeed separate some sprites (like special tiles and most entities, etc) because they're adding various maps (dynamic lighting, etc) to the sprite and make a horizontal "film" with the same image repeating, but with different color schemes for those mapping purposes.

So what are the convention that people here are following? Could you perhaps elaborate on when you want to use spritesheets, when you want to keep single sprites in their own files, and why?

Thanks in advance.

Having spritesheet gives you boost mainly for one reason - you can pack geometry for many sprites in single buffer and draw them all with single call.

Otherwise performance gain might be barely noticeable compared to separate textures.

Advertisement

Having spritesheet gives you boost mainly for one reason - you can pack geometry for many sprites in single buffer and draw them all with single call.

Otherwise performance gain might be barely noticeable compared to separate textures.

So basically: spritesheets by default and single sprites when specifically needed. Sounds about right.

Apparently, you're not gaining much (process) speed from separating the sprites (perhaps you're actually losing speed?).


Sprite sheets are a win for performance both in terms of load times (less disk seeks and OS calls) and runtime (data packed into a single texture allows you to greatly reduce GPU state changes and draw calls).

If you're targeting more modern graphics APIs (D3D11, GL4.4) you can use array textures, letting you pack multiple distinct images (of the same size) into different layers of a texture rather than using a classic sprite sheet. This actually has a number of advantages.

You can have runtime sprite sheets (or array textures) and loose individual files, too. It's not all or nothing.

Sean Middleditch – Game Systems Engineer – Join my team!

I think you're a bit confused of what are those things.

A sprite is a 2D image, you usually draw a sprite in some part of the screen without altering it.

A texture is "information" (in 3D programming you can have 1D, 2D or 3D textures, and they don't neccesarilly contain an image), and are mostly used to "paint" polygons, but may be used to store information.

A spritesheet is a collection of sprites in one single file. It's faster to load one image and just draw a portion of the image rather than loading different images. You gain in performance (at least on the disk access, which are almost the slowest things you can do) but you'll need more work (you need at least one extra file with info of width and height of the sprites). Normally a spritesheet has all sprites of the same size, and it's really usefull for 2D animations (and 2D stuff in general).

A collection of 2D textures is called an "atlas", atlas usually contain textures of different sizes for different things. The "film" thing you name is an atlas, it contains different textures that are not used directly like sprites. One texture probably contains the pattern of a surface, and another probably contains information of the normals of that pattern. With those 2 textures of information you can paint a polygon so it looks like a certain surface (the pattern texture) and at the same time do things like dynamic lightning inside the pattern (using the normals information) to get a realistic effect.

Now, using different or unified files for each of those things is up to you, but it's not a bad idea to stick to one. Also, even using spritesheets and/or atlases, you'll eventually have more than one file for them, so you should think of grouping them in some meaningfull way (maybe all textures for GUI could be in one atlas, and textures for one character in another). I'm not sure how common this is, but I worked in a company where atlases where 1024x1024 png files, and we had 3 or 4 of them.

Yeah, that sounds about right. Thanks for clarifying its naming convention, it'll help with looking it up in detail. smile.png

Advertisement

Now, using different or unified files for each of those things is up to you, but it's not a bad idea to stick to one. Also, even using spritesheets and/or atlases, you'll eventually have more than one file for them, so you should think of grouping them in some meaningfull way (maybe all textures for GUI could be in one atlas, and textures for one character in another). I'm not sure how common this is, but I worked in a company where atlases where 1024x1024 png files, and we had 3 or 4 of them.


This is one possible advantage to the array textures. D3D11 class hardware is required to support at least 2048 slices per array (OpenGL implementations may limit, though), so depending on texture sizes you may be able to pack far more sprites into a single array than you can a typical atlas. Using sparse texture support you can keep memory usage down to only what you need out of that array, too.

If you're really crazy you can use a texture array of atlases, too, and completely remove the need to ever bind more than one texture. smile.png

Sean Middleditch – Game Systems Engineer – Join my team!

On thing here is that you're conflating content creation workflow issues and runtime issues.

For runtime performance, you want to minimize the number of draw-calls you have to issue, and a good way to do that is to collect together a bunch of small sprites that have the same or similar properties into a single, large texture -- then, you can feed a list of triangles with different texture coordinates to draw various sprites from it. Same idea with array textures, it just depends on what your hardware supports -- Sometimes you might know at build time what's best for a platform (say, on a console or other fixed platform), sometimes you might know at deploy time (say, from the AppStore where you know (IIRC) what device the package is being deployed to), and sometimes you might not know until runtime (say, on a PC). For best performance, you want to defer the decision of runtime formats until you know what your hardware supports, but you might just pick a good middle-ground like texture atlases, sacrificing some performance to regain some simplicity.

For your content creation workflow, you want to focus on what's the most efficient way for you to work with the art assets, and to get them into your work-in-progress builds. You might prefer to work with individual image files, or there might be technical reasons for doing so -- like image characteristics or version control. Sometimes you might prefer to work with sprite sheets containing tightly-related images -- like a single character, or even a single animation of a single character. How you or your artists work on your game's assets is about 75% preference, tempered with 25% technical considerations.

But the important take away is that these things don't have to be (and probably shouldn't be) the same. That is, just because your game might run best with a texture atlas doesn't mean you have to create your art assets in a texture atlas -- all you need is a little command-line tool to assemble the texture atlas (or, your game could do it on the fly, if you're willing to give up some load time) from smaller files containing fewer images, maybe just one. You can make this a part of your build system, so that the assets are assembled together when you build your game.

I like to think of code, assets, developers and artists as being "on the near side" of the build system, and software builds, "run-time", and end-users as being "on the far side" -- Often what's best for the near side is different from what's best for the far side. The build system is everything that automates the process of going from the near side to the far side.

throw table_exception("(? ???)? ? ???");

This topic is closed to new replies.

Advertisement