Search Unity

Get/SetPixel(0,0) at bottom-left! Why?

Discussion in 'Scripting' started by andyz, Oct 28, 2010.

  1. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,266
    So not only is the Input.mousePosition.y upside-down but writing/reading from textures is too! What is with this weirdness Unity?
    Also a bug with SetPixel - if you SetPixels on a texture in your Project, afterwards the pixels remain changed in the image until you do a re-import!
     
  2. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    It's not weird or upside-down; it's a mathematical convention. The origin in a graph of positive numbers is in the lower-left, the origin in OpenGL is lower-left, the origin in UV coordinates is lower-left, etc.

    That's not a bug. If you don't want to overwrite your original texture, don't do SetPixels on it, but rather use a copy.

    --Eric
     
    Rutenis likes this.
  3. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,266
    It is upside down if you have ever used a paint package and it is the reverse of the GUI coordinate system!
    The origin in UV coordinates is upper-left in DirectX - (i.e 0,0 in a paint package) - is OpenGL different?
    3D and 2D are different coordinate systems - editing a texture is 2D.

    But why would the texture get saved after the changes? Am I not setting pixels on an in-memory copy of the image?
    It is the same with materials...
    I've not seen this effect in any other 3D engines
     
    Last edited: Oct 29, 2010
  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    3D graphics isn't the same as a paint package. ;)

    It's lower-left everywhere I've ever seen: Blender, Unity, .obj files, etc., though I haven't worked with Direct3D.

    Unless you instantiate a copy, no. If you link to a texture in your project then that's exactly what you're working with.

    That's too bad, because it makes it easy to do editor scripts in Unity to create/modify assets. If you could only work off copies in memory then you could never save anything.

    --Eric
     
  5. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    Unity indeed has a very ugly missbehavior by not following the same convention for all things

    Rect vs Mouse Position vs Texture coordinates can and will get you regularly until UT finally decides if 0,0 is top left or bottom left and not "either the one or the other depending on the context".

    Its especially annoying when you do rect tests for the mouse to prevent GUI interactions from having an impact (due to rect overlay side effects etc) as rect is top left and mouse is bottom left (and so is Input.mousePosition)
     
    samochreno and Novack like this.
  6. jcarpay

    jcarpay

    Joined:
    Aug 15, 2008
    Posts:
    561
    Agree with that one, very annoying!
     
  7. tonyd

    tonyd

    Joined:
    Jun 2, 2009
    Posts:
    1,224
    Traditionally, when doing 2D computer graphics the coordinate system started in the upper left corner (0,0).

    OpenGL and 3D graphics have changed this, basically reversing the Y axis.

    This actually makes more sense for some genres of gaming (anything requiring gravity), but old school programmers (like myself) have a hard time wrapping our heads around it.

    You can always create your own functions that automatically reverse the Y axis before calling Unity's built-in functions. I did this myself when working with Python and OpenGL.
     
  8. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,266
    Actually I see it as quite simple - there is the 3D coordinate system for the 3D scene (i.e polygons) with +Y as up.
    Then there is the 2D coordinate system for GUIs, textures/images etc. Here 0,0 is top-left and +Y is down.

    My point is Unity seems to have blurred these together, so Input.mousePosition and Set/GetPixels routines are the opposite of the GUI coordinate system leading to confusion - though yes, ultimately a few additional helper functions can fix...
     
  9. Jesse Anders

    Jesse Anders

    Joined:
    Apr 5, 2008
    Posts:
    2,857
    I agree that the 'mixing' of conventions in Unity can be a bit confusing.

    But, I suggest not getting too attached to the idea that one particular convention is 'more correct' or 'makes more sense' than some other equally arbitrary convention. I've gotten into these discussions here on the forums before, and I always seem to lose (in the sense of not being able to convince people that conventions are just conventions), but I persist anyway ;)

    In any case, there's absolutely nothing odd about placing the origin in the lower-left; it's not 'upside-down'. It's just a convention; it may be different than what you're used to, but there's nothing unusual about it.
     
  10. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    Considering your eyes actually see the world upside down and that your brain translates the information to right side up, 0,0 is the lower left, it only gets confusing when using a Plane as a render surface, at least for me, never can get it rotated right to be right side up and frontwards, always tworks my brain cells into contorting. I simply adjust and move on. If a flip of a pixel was the most I had to worry about with my project and where 0,0 was, I would be GOLDEN.
     
  11. BlackRabbit

    BlackRabbit

    Joined:
    Oct 22, 2010
    Posts:
    11
    Anyone who's been to school knows Y is positive going up.

    The reason for the 2D screen being 0,0 at the top left corner is because we read the page top to bottom, left to right (in English).

    That being the case, screen sizes had to grow down and to the right. If the coor system started with Y at the bottom, then the developer would never know where the top coor was as the screen (or window) size changed (ie: the starting point of text). Remember we are talking 30 years ago when they didn't have the automatic hardware polling and massive graphic libraries that we have now.
     
  12. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You use Event.current.mousePosition in that case, which is top-left. The OnGUI system is top-left, everything else is bottom-left, so it's all consistent. You shouldn't mix Input code in with OnGUI code...actually it would probably be better if Unity would just disallow the Input class in OnGUI; it leads to bugs and confusion.

    --Eric
     
  13. zBlaze

    zBlaze

    Joined:
    Sep 9, 2013
    Posts:
    2
    Like others have sayd it's easy to make a function wich calculates the y position like (0,0) was on the top left corner. This is simply:

    Screen.height - Input.mousePosition.y;

    Regards,

    Tom
     
  14. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You never need to do that; just use Event.current.mousePosition like I mentioned.

    --Eric