Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Half a pixel visual offset between DirectX and OpenGL?

Discussion in 'Editor & General Support' started by j-robichaud, Jan 11, 2011.

  1. j-robichaud

    j-robichaud

    Joined:
    Aug 26, 2010
    Posts:
    40
    Hi everyone,

    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.

    Note: Make sure the following image is not stretched to see the problem properly. Up is DirectX and Down is OpenGL running on the same machine.
    http://dl.dropbox.com/u/18185132/DifferenceBetweenOpenGLAndDirectX.png

    Anyone knows why it does that?

    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.
     
  2. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    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.
     
  3. Matt_001

    Matt_001

    Joined:
    Sep 17, 2010
    Posts:
    101
    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?
     
  4. j-robichaud

    j-robichaud

    Joined:
    Aug 26, 2010
    Posts:
    40
    I have recommendations with pixel alignment.

    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.
     
  5. Matt_001

    Matt_001

    Joined:
    Sep 17, 2010
    Posts:
    101
    Greetings jrobichaud,

    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.
     
    Last edited: Jan 12, 2011
  6. j-robichaud

    j-robichaud

    Joined:
    Aug 26, 2010
    Posts:
    40
    I have no idea. You might want to make your own topic about this or try in unity answers.
     
  7. Matt_001

    Matt_001

    Joined:
    Sep 17, 2010
    Posts:
    101
    I did create my own post here but unfortunately I haven't receive any reply.
     
  8. brent ragsdale

    brent ragsdale

    Joined:
    Oct 26, 2013
    Posts:
    1
    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.