As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
What is the best size for an individual tile in a 2D sprite sheet?
I am creating a sprite sheet and am trying to figure out what the best resolution is to use for each sprite. Is there a standard size I shouldn't go above or below?
ex. 64px X 64px, 512px X 512px, etc.
I am trying to get HD quality sprites. Think Alien Hominid, Castle Crashers, or World of Goo. Some examples would be nice too, so if you have sprite sheet example please upload them.
This depends on how the sprite is going to be rendered, as well as what you are going to do with them when you render them.
If you are going to avoid scaling the sprites, making them the same as their final rendered resolution as possible will help keep the quality higher. I would definitely stick to power of two texture sizes, since it does seem to help in general.
However, if you're going to be doing a lot of transformations on your sprites, particularly with rotations or scaling, you may want to go slightly larger than the resolution they will render, since the resampling may be slightly better quality. You'll want to consider how many sprites are being composited and displayed at any time, and what hardware you'll be running on (xbox, pc, both?), to determine the best options for balancing performance with texture quality.
If you're not going too crazy with the number of sprites, though, you can probably go at a higher quality, and allow the system to downsize them as needed, and get good results.
This may not directly answer your question, but I wanted to throw in what I've learned when using sprite sheets. Sprite sheets are great because the fewer textures that the GPU has to switch between when drawing to the screen, the better performance.
I would recommend that you take a look at the XNA sprite sheet example, if you haven't already. It offers a couple great benefits:
It automatically packs your sprites (in different files) into one big texture. I thought keeping my artwork in separate files and having the one giant sprite sheet generated automatically would be better than keeping all my art in one file.
For example, what if I decide I want my animations to have an extra frame in the middle? Then I have to shift around a bunch of stuff in the sprite sheet to make room for the new frame. If I'm using one file per frame, it's just a one line change to the XML file listing what goes into the sprite sheet if I want to add a new frame in the middle.
It can be a pain to list every frame file separately, so I can see why this may not work for some people, but it was great for my project. Also, I found that the gain of being able to swap textures in and out of my sprite sheet easily was more than worth it, which will help you as you determine what size of sprites to use.
We ran into a problem when scaling sprites. I believe that link describes the issue pretty well. In any case, this sprite sheet example will automatically add a 1 pixel border (using the color of the pixel that was originally on the edge) around each sprite you add to the sprite sheet, which will protect you from seeing oddly colored borders around your sprites when scaling, because it still only draws the sprite using the original size. It just uses the extra border for interpolation instead of a nearby sprite's pixels or white space.
Reed is correct that there really isn't any standard sprite size you should use. It depends mostly on what type of game you are doing, what type of scaling and rotating you are doing, etc. However, there are specific sizes you need to watch for when using sprite sheets. Sprite sheets are just one giant texture, but there is a limit to how big of a texture GPU's can hold in their memory. The XBOX360 supports up to 4096x4096 (I think) textures. If you're programming for Windows, then it depends on the user's graphics card. From what I've seen, it's probably best to stick with 2048x2048 on Windows, because most graphics cards can support at least that much.
One last note on the sprite sheet example. I don't believe that it will watch for a maximum sprite sheet size, so if you do use it, you may want to add a couple lines to catch when the size of the generate texture is larger than you want to support.
Shawn Hargreaves recently did a series of blog posts on texture resampling and aliasing. See the top of the list of posts for April and the posts for May. The key word here is "Nyquist frequency" (wikipedia).
In particular take a look at this post on texture aliasing. It's got nice diagrams like this:
http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-70-20-metablogapi/6518.image_5F00_1B896E07.png
The very, very short answer is this:
Avoid rendering more than 2x smaller than your source texture (ie: 50% of the source size or smaller). If you do need to render smaller, then use mipmaps. And if you're rotating you've got less margin for scaling downwards. Avoid scaling upwards.
There is no advantage to using power-of-two sized textures in XNA. Just use textures at your target resolution and let XNA handle it under-the-hood.
As an example: If you're making a game for 1080p resolution, then scaling down to 720p is scaling down to 66.66% the size, which is perfectly acceptable.
Related
I'm creating a 3D mobile game where my base reference screen size is the Galaxy S9, with an aspect ratio of 18:37 (portrait). The player controls a box where you can move +/- 5 units along X axis and objects fall down that you have to either avoid or catch.
That part is easy, the hard part is that when I change the aspect ratio or resolution, the game scale changes as well, and now +/- 5 units on the X axis means my box can be cut off, or completely off screen.
My goal is to limit the camera view so that it always shows the same coordinates no matter the aspect ratio or resolution, within reason (being portrait mode on a phone, obviously don't want to care about it working in landscape or on a PC/Mac).
How can I accomplish this with the minimum amount of stretching or distortion to the game objects? I saw some people show a way to accomplish this for orthographic views, but my camera must be in perspective for this. The default FoV I'm using is 60, and I'm thinking I can try scaling the FoV based on aspect ratio, but I'm at a loss for how to start. Any help is appreciated!
Supporting multiple aspect ratios for games is definitely one of the most frustrating things about making a game look professional.
Probably the most common technique is the same technique used by Film, called letterboxing.
TVs had to solve a problem when widescreen first came out: How do you show a 16:9 film on a TV with an aspect of 4:3? There are two options: either add black bars to the top and bottom of the screen to make the aspect 4:3, or you can make sure that everything important is happening in the middle area that will be shown by both aspect ratios and then just cut off part of the view if it doesn't fit within the aspect ratio.
My suggestion is to surround the playable area with something that looks good, but wont affect the game if it gets cut off. Then write a routine that will run when your level loads for your camera to zoom out until all of the play area is visible. Since you zoomed out, this means that devices which do not have the same aspect ratio as your play area will be able to see the area around the play area. As long as you have non-play area that is big enough, there won't be an issue.
Here are some good examples:
Note: Sorry the examples are orthographic, but the same should work for perspective, you just may have to be a little creative with doing a projection from the camera frustrum to determine if your play area is all visible
I'm making a shape matching game for toddlers.
I drew the shapes using gimp on my mac.
The images all seemed stretched out on the android devices.
Is there some mathematical way i could figure out how much shorter I have to make the images on the mac computer so they look correctly on the android devices?
This is a tough question. I have made several Apps for iOS and have pretty much the same problem with graphics for buttons and backgrounds when going between iPhone and iPad, which have different aspect ratios (which I suspect is the problem you are having). Throw orientation into the mix as well.
I use Gimp, Inkscape, Spine, Cocos2d-x, and lots of other tools for reference (see here).
As far as I know, the general options for "different screen geometry" issues are (if there are others, let me know):
Different graphics for each geometry.
Scaling the graphics proportionally for the geometry (I suspect you have this).
Same graphics for all, scale proportionally based on one dimension and then place graphics on screen using percentages for fixed stuff.
Option 1 means extra work...not acceptable for a hobbyist or indie (like me) developer.
Option 2 usually looks like junk. Frustration and sadness usually ensue.
Option 3 is the option I use most often. I find that occasionally I have to add small changes (read: hacks) based on the device or geometry. In the case of iOS, it is not too bad, because there are only two geometries to deal with. In the case of Android, where there are lots of different tablet geometries, you could cut it down by working with ranges of geometries and picking a fixed orientation for your application.
At the end of the day, proportional scaling by a single dimension (height or width) has gotten me the most bang for the buck.
I usually make the graphics a little "bigger" than I will need so I only have to scale down. This consumes a bit more memory, but I re-use a lot, use sprite sheets, etc. There is a definite tradeoff with managing every bit of memory (which you have to do in a large AAA rated game) and what you can get away with in a small independent application. I am not encouraging sloppiness or memory mismanagement; I'm encouraging balancing the resources against the developmental needs of simplicity...making the same graphics for different situations burns a lot of daylight.
ONE MORE NOTE:
For applications where I use a framework for the graphics (i.e. games), I use a "viewport" to let me match up the physics with the graphics...that is to say, dynamically scale the size of the graphics based on how much of the total scene I want the user to see. This lets me put the graphic for the "body" on top of it and match up the size statically or dynamically as needed. The code is in C++ and is only loosely tied to the framework...and the concept is applicable to general situations for games (i.e. scaling the graphics as needed). You can find some description and code here, if you are interested.
Was this helpful?
You need to design your application so that it can function correctly regardless of device resolution as many mobile devices have many different aspect ratios and resolutions.
If your images are being stretched then you need to change the ui design so that they are enlarged and spaced out to make use of whatever space there is.
I am going to play around with making an XNA game.
The windows store has two base resolutions it reccommends you support: 1024x768 and 1366x768
But after that there are no restrictions.
The common advice is to use a ViewBox that will scale your content for you.
But an XNA game does not have a viewbox. It has a draw method where you render your content.
What is the common way for Games (XNA or DirectX) to adapt to different resolutions?
I would rather not have to make images for each and evey resolution out there. It would be a lot of work and I am bound to miss some.
Is there a better way?
GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Widthand.Height will give you the current desktop resolution.
Then you can update Game.GraphicsDevice.Viewport variables to use these settings.
The above code usually goes in Game1.cs constructor
The link provided then documents one technique that makes your sprites, backgrounds etc look correct independently of the resolution(the theory should be sound if the code is not 100% up to date)
http://msdn.microsoft.com/en-us/library/bb447674%28v=xnagamestudio.10%29.aspx
There are two different approachs I read in a tutorial:
Resize everything to the new viewport (even with changing aspect ratio)
Just draw more surroundings around
Of course you can mix both: Resize everything as long as it can still be in the same aspect ratio (e.g. 4:3 or 16:9) and then show more or less background / surroundings.
You can also decide to display black content instead of the more surroundings, if it is important for everyone to have exactly the same sight (e.g. due to fairness), but in such a case it might be a better idea to use fog of war to reduce sight.
I need to speed up my image viewer, and wondering if I should be looking into creating my own DirectX control to do so.
My image viewer displays medical images. They can be pretty large. We're talking 55mb when it comes to mammography. The pixel data is 16bit greyscale stored in a ushort array. Without getting into the gory details, my current approach is loading the pixel data into an ImageSource, and using the WPF Image control.
I've never done anything with DirectX. Is it worth diving into it? Would it be any faster than the native WPF stuff? If so how significantly? Or, should I just forget about DirectX and look into areas where I can improve my current approach?
Before somebody says so, I know WPF utilize DirectX. I'm wondering If removing the WPF layer and writing the DirectX myself will improve performance.
I have some experience drawing multi-gigabyte satellite and chart imagery. Working with imagery around 55MB should probably work okay even without trying to optimize it too much. You haven't really given enough detail to recommend one alternative over the other, so I will give my opinion on the pros and cons.
Using 2D windows APIs will be the simplest to implement and should always be fast enough if you don't need to rotate and simply want to display an image and zoom and pan around. If you treat it as one large image the performance will not be as good when you zoom out if you are drawing with halftoning to give a nice smooth image. This is because it will effectively have to read all 55mb of image every time it draws.
To get around this performance issue you can make multiple bitmaps, effectively mip-mapping your image. As you zoom out you can pick the reduced resolution image closest to the resolution you are trying to draw . If you are not familiar with mip-mapping here is a Wikipedia link:
http://en.wikipedia.org/wiki/Mipmap
Implementing it with DirectX will be 10x as difficult. Different graphics hardware has different maximum texture sizes. Most likely you will need to break your image up in to multiple textures to draw and you will also have to keep track of render states, viewing matrices, etc.
However, if you do use DirectX, you can implement lots of real-time photo adjustments You can do real-time rotation by simply adjusting view matrices. You can do real-time contrast, brightness, gamma, and sharpness easily in a pixel shader.
There are two other API's I might suggest. If you are willing to limit yourself to Vista or later then Direct2D would be a little simpler than Direct3D. Also if you ever will need to implement it on a non-windows platform I would suggest using OpenGL instead. My current project is in Direct3D because a few years ago when we started it OpenGL was falling behind and I didn't forsee the popularity of Android devices. I now wish we had used OpenGL instead.
Try profiling to see where WPF is spending its time. Are you displaying the images at their native resolution? If not it might be worthwhile to do some preprocessing and create 1/2 resolution versions.
In my XNA game, I program and design the entire thing for 1920x1080 resolution and then scale scale and letterbox to fit the running system (XBox or PC).
This has been a great solution as it allows me to only ever worry about one resolution.
However, I'm now wondering if this will come back to bite me in the future as the game becomes more complex.
Since I'm having to scale everything with every draw (I scale SpriteBatch.Begin() with the scale factor only once, do all drawing, then call End()), is this going to have any detrimental effect on performance? I know the XBox already does this for XNA games for you when set to 720p natively (which, I actually am when running on XBox, it just gets the appropriate scaling factor).... so I can't imagine it's too bad, even for the PC.
The xbox does its scale in a specialized scaler in the video output - there is zero performance hit to your app.
The scale factor you pass in to SpriteBatch just translates the vertices of your sprite. Its done with a factor of 1 even if you don't pass in a scale so there is no extra load there.
With different screen sizes there will be different fill rates (more or less pixels) and texture lookups will be different too so that will show some variances.
Just using a 1028x720 backbuffer is the safest to do. The xbox can hardware scale that into ANY resolution or ratio without a single line of code or any perf issues. It will letter box properly and the hardware scaler is very good quality. You cannot claim 1080p support is really the only downside.
If you chose 1020x1080 as your back buffer note that the hardware scaler cannot scale that down to 480i and WILL fail in peer review (well it should if anyone notices)
On WIndows the easiest thing is probably to draw everything to a RenderTarget and then just scale the whole darn thing on one go at the end. See the SpaceWar starterkit for the few lines of code it takes to do that. (All inside #if !XBOX so you dont waste cycles doing it on the 360)
This shouldn't cost you. The scaling is done by he video card.
However, if this does worry you, another option to handle different resolutions is to change the render target to an off screen buffer, render to that, and then draw a square on the screen with the buffer as the texture. More pixels are rendered, but you don't need to do a transform on each vertex.