Inverting Y Axis

Hi! This is my first post here, and I’m brand new to MonoGame.

I come from using Unity for about four years. Unity’s y axis puts 0 at the bottom and positive y goes upwards. MonoGame (and several other libraries) doesn’t do it this way, instead putting y = 0 at the top.

I’m currently trying to move a Unity project over to MonoGame due to being fed up with Unity’s limitations. On top of it being completely unintuitive and confusing for me to do it how MonoGame does it, the code is not built to work that way.

I’m wondering: is there any way to flip the Y axis to do it the way I’m used to?

I’ve searched through all the posts I could find online and came across things such as:

-> Get used to it, that’s how most libraries do it!

Hopefully there’s a better option…

->Multiply with a scale matrix that has -1 as the y component.

This prevents everything from rendering. One person had said that this was due to culling (had to reverse the cull direction), but even setting it to CullNone didn’t fix it for me - still nothing rendering.

Is there anything I can do about this or must I follow the ‘get used to it’ advice?

Thanks in advance.

I THINK Its something monogame inherits from vanilla c# I think… The same “Y starts at the top and down is up” is true even without monogame… Even in paint programs and such.
Thats what makes it so cool. The logic of Y=zero at the top, makes for code that corresponds with pixels in images, and index numbers of arrays etc…

So I dont think its just a setting you can toggle… At least, I’ve never seen it happen.

I’m afraid you will have to change your code (your initializers and updates,
and all the associated variables…)

Shouldn’t be that hard, just a chore to do.

Pretty sure this has to do with the coordinate system xna used i think all the matrices are right handed in xna. Yep i would definately ditch the unity system even if i had to write a new set of full projects that are monogame versions of my old ones the reason is Math.

If you really are intent on staying with the unity coordinates.
Things i would try before i refactored the entire project would be.

in 3d try

setting your eye matrix / your view camera’s up to down. i.e. your vector3 up to *= -1;
xna ms matrix page
or

multiplying your world matrixs before passing your effect draws by a matrix identity
that has its .M22 row colum set to = -1 instead of the default 1
e.g . m11 = 1 m22 = -1 m33 = 1
if you try to do by the world though that might mess things up.
You could try setting m24 to -1 instead.that is essentially the skewing portion w of the matrix.

you will probably need to demo test that first.

or

If its 2d, you could invert all your values around y screenHeight sort of a pain in the ass to do that and confusing it would mean a performance hit as well but i guess it would work.
wrap a spriteBatch call and use that.
rectangle n.Y = -(r.Y - screenHeight) + screenHeight;
ex rectangle 0,0,1,1 screen width height 1080, 720 the Y value becomes 0, (0-1) + 720 , 1080,720 then calling spritebatch (, SpriteEffects.FlipVertically); placing the rectangle at 719 drawn to 720 from down to up.
Note

This and any of these solutions will make it tough to use the math class and a lot of math functions. That is the main problem with flipping the y to be like unitys. Later it will cause you headache after headache
^^^
Personally if i was you if your switching from unity to monogame i would do it all the way and commit if your gonna do it, do it. Think of it as a break to go thru all your code and review it.

Get your head into top down not down up. To be honest down up is a relic from the old days, when the coordinate system used in early gdi’s, aligned to a drawing graph with a absolute coordinate system in the +,+ region. Its far less intuitive in practice. Internally mono game is relying on gl and dx though gl is left handed and dx is right handed. monogame sets up the conversion somewere for you but that deals with the x axis primarily and the order of matrix arthmitic.

It does seem logical to get used to the top down approach, and so I will. Thanks for the responses :).

@JasonBricco

Use a orthographic projection matrix like this to get y=0 at the bottom. Note that this example also does adds an offset of half a pixel to properly account for sampling texels. You may wish to change the far and near plane to whatever.

var viewport = GraphicsDevice.Viewport;
var projectionMatrix = Matrix.CreateTranslation(-0.5f, -0.5f, 0) * Matrix.CreateOrthographicOffCenter(0, viewport.Width, 0, viewport.Height, 0, 1);

See https://msdn.microsoft.com/en-us/library/bb195659.aspx for details on Matrix.CreateOrthographicOffCenter.