Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm drawing a name above the player's head in a 2D top-down view game. The code to draw the string looks like this:

Vector2 textPos = new Vector2(
  (positionX * 2 * world.Map.TileWidth + (16 -(SmallFont.MeasureString(mName).X / 2))),
  (positionY * 2 * world.Map.TileWidth - 32));

spriteBatch.DrawString(SmallFont, mName, textPos, Color.White, 0, Vector2.Zero,
  1, SpriteEffects.None, 1);

The text is drawn to the position right above the player's head just fine, and it follows the player as he moves just fine as well. But the problem is that when the player moves, the text kind of gets thicker and ugly. I tried screen capping it but the screenshot doesn't capture the problem (because it's just taking a single frame, I presume).

How can I fix this?

share|improve this question
5  
Like I've mentioned in the chat, you should either floor, round or ceil the values. When it attempts to draw between pixels, it'll do some sort of interpolating effect that doesn't work with things that need crisp lines. –  William 'MindWorX' Mariager May 27 '12 at 20:48
    
I tried casting the vector values to int, but the problem still occurs. I've removed them since. –  JMRboosties May 27 '12 at 21:25
1  
Try to draw it with SamplerState.PointClamp –  Blau May 28 '12 at 11:40
    
I would store the text location in a Point structure and then pass it to a Vector2 in the DrawString call. Point is specific for 2D space location using integers. –  ChrisC Dec 15 at 21:16

1 Answer 1

XNA is based on D3D9, which has the dreaded "half-pixel offset problem." Pixels are dots, not squares, even though we like to think of them as the latter. In D3D9 you can visualize pixel coordinates as referring to the center of the cell they would illuminate; however we often consider origin of our coordinate systems to be at the "upper left" (or a similar corner) and thus there is a delta between the coordinate frame's origin at the pixel coordinate.

The D3D documentation has a decent write-up on the topic:

enter image description here

The preceding diagram correctly shows each physical pixel as a point in the center of each cell. The screen space coordinate (0, 0) is located directly at the top-left pixel, and therefore at the center of the top-left cell. The top-left corner of the display is therefore at (-0.5, -0.5) because it is 0.5 cells to the left and 0.5 cells up from the top-left pixel. Direct3D will render a quad with corners at (0, 0) and (4, 4), as shown in the following illustration.

enter image description here

The above shows the mathematical frame of the quad, but D3D can't fill only a portion of a pixel, it must approximate. When you have textures quads rendered thusly (as you do when drawing text), the approximations D3D does to filter the results looks unpleasant. In the MSDN link, they provide an example where the above 4x4 quad has a unique set of pixel colors but still ends up looking mushy:

enter image description here

This could be what it happening to your text. Note that if true, it would be possible to eventually capture a screenshot of your text in it's blurry form, although you may have a hard time getting that to happen normally depending on the resolution at which your players end up moving in the world; you might have to set up a contrived example rendered at fixed coordinates to do so.

The solution is, fortunately, rather simple: subtract 0.5 units from the components of your vertex positions in transformed screen space.

Another good write-up of the issue can be found here.


Now, you also mentioned that you had difficulty capturing a screenshot of the blur. While I noted this could be due to how your characters move in the world, if you really can't reproduce the blur even with a fixed, contrived example then it's quite possible there's actually nothing wrong at all. You could simply be seeing motion blur, or other similar visual artifacts related to your eyes and persistence of vision.

However, I'm inclined to believe the issue is in the placement of the quad vertices in screen space and/or your texture filtering options (as has been previously noted in the comments).

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.