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

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!

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

1 Like

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

3D graphics isn’t the same as a paint package. :wink:

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

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)

2 Likes

Agree with that one, very annoying!

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.

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…

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 :wink:

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.

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.

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.

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

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

You never need to do that; just use Event.current.mousePosition like I mentioned.

–Eric