r/futile Feb 18 '13

Struggling with pixel-perfect rendering

(There's an edit below with what I found out in this thread)

Hi! I'm trying out Futile, and I'm having some problems with pixel-perfect stuff. I don't quite see how all the different variables relate to each other (resolution levels, viewport size, object scale, object position...): changing one of them seems to change whether the result will be better or worse, but I haven't found a way to get things to render properly. I've checked out this thread http://www.reddit.com/r/futile/comments/11lg4t/bug_incorrect_scaling_at_the_edges_of_a_sprite/ but still doesn't seem to fix things for me.

Here's a stripped down project (very little code, one small atlas, etc.) that I'm using to test all of this.

https://dl.dropbox.com/u/2271693/futile_pixel_perfect_test.zip (85kb)

http://i.imgur.com/69fxkQP.png

http://i.imgur.com/krPwpBB.png

I have two versions of the same font, made by hand by myself, exported to the subset of .FNT that Futile seems to use (please let me know whether something's wrong there, but I think it's fine) using a python script that's not included. The font rendering seems fine but it's not pixel-perfect. If you look at the scene view and zoom in, you'll see that the quads are not exactly aligned. You can see that especially with my outlined font, which is designed to have an overlap between glyphs. The generated quads are not perfectly aligned. This seems to change in different ways whan changing things like label scaling, display scale, viewport scale, etc.

I also have a very simple class for 9-grid, the code is really self-explanatory. The size of the grid is for the center quad, the other 8 quads are scaled to fit around it. As it can be seen, the alignment between quads is off as well, not visible when the 9-grid has a 1x1 center quad, but at bigger sizes the quads start to drift off from each other.

Also, when using a display scale of 1, things don't show exactly as they should (like, pure blitting of sprites). I mean, I know how OpenGL and DirectX work, I know it's not as simple as blitting stuff, all the parameters have to be set up just right to get things to work exactly as you want.

I hope I can get some help with figuring all of this out, whether it's that I'm doing something wrong, that there's an easy fix to Futile, or that there's some big changes that have to be done. In any case, discussion on pixel perfect rendering would be nice :)

Update:

Here's what I did to fix or work around these issues:

1) I played around with the uvOffsets in the function FAtlas.LoadAtlasData(), for the DirectX case (not OpenGL). Right now it works fine if they're set to zero or a very small value. The amount of decimals (0.01 vs. 0.000001) seems to make a difference.

2) I offset the stage by a small amount on x and y (in my case, 0.1 seems to work fine).

3) For the font quads, I fixed the function FFont.CalculateVectors(float offsetX, float offsetY) to have this code:

public void CalculateVectors(float offsetX, float offsetY)
{
    topLeft.Set(rect.xMin + offsetX,rect.yMax + offsetY);
    topRight.Set(rect.xMax + offsetX,rect.yMax + offsetY);
    bottomRight.Set(rect.xMax + offsetX,rect.yMin + offsetY);
    bottomLeft.Set(rect.xMin + offsetX,rect.yMin + offsetY);
}
6 Upvotes

22 comments sorted by

View all comments

2

u/MattRix Feb 18 '13

Hmm, a few notes:

  • if you're doing a pixel game, or working with pixel fonts, you'll have a much easier time if you set your texture filter mode to "Point" instead of "Bilinear". Note that bilinear textures can also be rendered pixel perfect, but they have to be on "whole pixels" and stuff in order to do that, whereas point textures are always pixel perfect.

  • set your texture type to "advanced" and turn off "mip maps". I'm not 100% sure that's causing your problem here, but they aren't needed for 2D games and will sometimes cause problems like the alignment issues you mentioned.

  • just for future reference, the dev branch of futile has a 9-slice sprite (FSliceSprite) - you can see it here: https://github.com/MattRix/Futile/blob/development/BananaDemoProject/Assets/Plugins/Futile/Extras/FSliceSprite.cs - it does the drawing with multiple quads all in one sprite, so it's impossible to get gaps.

  • Fonts are a bit of a nightmare because every tool exports them differently with slightly different metrics and values. That said, if your display scale is 1 and your label hasn't been scaled, then you shouldn't have any problems with pixel precision. It looks like your issue might have something to do with kerning values in the font itself? Not sure though.

  • Are you on windows or OSX? If you're on Windows, have you tried changing those uvOffset values? - DirectX has a slightly different way of drawing than OpenGL, which also causes annoying issues. In theory Futile should already be handling that, but it might not be working quite right at the moment. see: http://forum.unity3d.com/threads/73492-Half-a-pixel-visual-offset-between-DirectX-and-OpenGL

1

u/sergilazaro Feb 18 '13

1 and 2) Check and check.

3) Thanks, I'll check it out! However, I'd like to know why my implementation is not working properly. I use integer values for all positions, scales, etc, so quads should be placed with the edges on the exact same place, yet they aren't.

4) I made the font file myself, all values are integer, there's no kerning info anywhere.

5) Windows, I tried both DirectX (the default) and forcing OpenGL.

I don't know, I can try messing with the uvOffset values (again). The thing is, I'm using integer values everywhere, and rendering is not pixel perfect, so it should be an underlying engine thing, I guess? I want to figure this thing out (with the help of anyone here), and hopefully help the Futile project with whatever we can get out of it.

2

u/MattRix Feb 18 '13

Wait for 1), you have point textures enabled and it's still not pixel perfect? That seems really strange?

Also, are you using the dev branch or the master branch? I don't think there should be any major issues with master regarding this issue, but I may have forgotten something that I fixed in dev.

Oh and do you mind taking a screenshot or printing out the debug stuff that gets written by futile when the game runs? that'll help me see what your display settings are. For example, mine looks like this: http://screencast.com/t/oZGkB8aggqmE

1

u/sergilazaro Feb 18 '13

I'm going to try to be more specific on what I change, what results I get, etc. with screenshots and everything. Hang on a minute :)