We realized lately we had blurry textures between Mac and PC with the same code in our game. The cause seems to be related to an offset between OpenGL and DirectX according to our investigation.
We made a “checker” texture and depending of the Device (DirectX and OpenGL), one will be blurry and the other not. You can notice the difference on the screenshot, the left sprite position’s is aligned to the pixels and the sprite to the right has a 0.5 pixel offset in X and Y. The misaligned image is solid gray because it linearly interpolate the pixels.
You can download this zip, I packaged a build for PC, a batch file to run PC’s build with OpenGL, a Mac build and an Unity3D project with all the source code. The application allows to modify a Sprite on the fly if you want to test the behaviours. http://dl.dropbox.com/u/18185132/SpriteTest_v0.zip
The workaround we imagined is to move the camera slightly (0.5 pixels in X and Y) on DirectX to get the same result as OpenGL until there’s another better solution.
Rasterization rules between OpenGL and Direct3D are offset by “half a pixel”. So yeah, to do pixel-perfect 2D stuff you have to be extra careful. We do handle that behind the scenes for built-in Unity stuff (e.g. UnityGUI, GUIText/GUITexture, also if you call GL.LoadPixelMatrix etc.). But if you do pixel-perfect stuff completely on your own, you will have to take care of the differences yourself.
I know I’m a bit off-topic here, but I have a question about “pixel-perfect stuff on your own”. I"m doing a 2D game and I want to ensure that my GameObjects that contains my 2D text won’t be positioned at half-pixel.
To ensure that, I would have like to be able to override the “myGameObject.transform.localPosition” so that when someone pass a new Vector3 to it, I can round the coordinates before passing it to the actual localPosition. Do you have any idea which way would be the best to handle that?
If your camera can get to a non-aligned pixel position, you’d rather fix that along with game object positions.
We noticed that pixel alignment with moving objects does not look smooth. We decided to align to pixels only when things are not moving (including the the camera). You can experiment that yourself when you find the solution to your issue.
Do not forget that alignment to pixels is different on DirectX and OpenGL like I explained in my first post and like Aras confirmed. So you might have an half pixel somewhere in an equation depending if you are on DirectX or OpenGL.
PS: For your information, with the Sprite Manager, we managed to align Sprites to pixels.
Thank you for your recommandations, it is really appreciated but I’m going to give you a little bit more context about my problem.
Our camera is set to Orthographic (of course) and it can be moved inside a scene towards the left or the right. So, the camera is actually moving at half pixel when I scroll.
However, that doesn’t affect my 2D texture at all because it moves with the camera no matter where it goes. The reason is that my 2D text are like a custom GUIText of Unity. So The linear interpolation problem happens when I position those custom GUIText at half pixel. Our texture are optimized so the characters are really close to each others and it is not an option for now to modify those texture to add a 1-2 pixel border around each characters.
Also, we do have scroll bars and stuff like this. We did also notice that it is not really smooth, but in our case it’s not so bad. We basically round the position to make them move only pixel per pixel to avoid any problem.
Finally, I still have my question in mind: Is there a clean way to reproduce an Override behavior for the transform.localPosition? Because if we want to position our GUI dynamically, we must ensure to not use half pixel position.
I know this post is super old, but I came across it many times while searching for a solution to my answer.
I found one that helped me very much, solved all my half-pixel/texel issues and my GUI elements align perfectly with my pixel-snapped/pixel-perfect objects in game now. See the links in the accepted answer here for a shader to use with DirectX that will fix half-pixel issues.