Jeff Weber

When setting up a 2D world using 3D XNA constructs (Custom quads as opposed to sprites), what is the best way to setup the ProjectionMatrix

Should I create an Orthographic projection matrix, or should I define a normal fov style projection matrix What are the trade-offs


Re: XNA Game Studio Express 2D World Using 3D Constructs ?


If you use the ortho view matrix, then objects won't be skewed from a distance. it keeps everything the same size no matter how far back the depth of the object is, so it'll be a pretty close representation of 2D while using 3D.

If you use a normal Perspective FOV matrix, then when these 2D objects are farther back, they will be skewed. So you could really have a 2D looking game that has depth.

It'll probably depend on the type of game you're trying to make. But you can develop the game either way, and change between perspectives with relative easy to see which one looks better in your own eyes.

Re: XNA Game Studio Express 2D World Using 3D Constructs ?

Richard Kain

You know what would be really mind-bending Use more than one projection matrix. Use a full-on perspective projection matrix for the background elements. Then use an orthographic projection matrix for the foreground interactive elements. (player, enemies, etc...) It would probably look kind of like the original 2D Grand Theft Auto titles. (3D environments with 2D characters)

Of course, this is just a suggestion. It could be that the title will look better with just one projection matrix. But its something to think about, and a possible experiment if you have the time. Personally, I think it would look very cool.

Re: XNA Game Studio Express 2D World Using 3D Constructs ?

Jeff Weber

Not a bad I idea. I will keep that possiblity in mind. By the way, this will be type of 2D scroller.

Re: XNA Game Studio Express 2D World Using 3D Constructs ?


This is the code I use in 2D apps for a projection matrix:

public void Create2DProjectionMatrix()
// Projection matrix ignores Z and just squishes X or Y to balance the upcoming viewport stretch
float projScaleX;
float projScaleY;
float width = graphics.GraphicsDevice.Viewport.Width;
float height = graphics.GraphicsDevice.Viewport.Height;
if (width > height)
// Wide window
projScaleX = height / width;
projScaleY = 1.0f;
// Tall window
projScaleX = 1.0f;
projScaleY = width / height;
projMatrix = Matrix.CreateScale(projScaleX, projScaleY, 0.0f);
projMatrix.M43 = 0.5f;

Remember that after world/view/projection transformation, everything outside of (-1, 1) in x/y/z gets clipped, then the result gets stretched into the viewport. So all I do (as the comment says) is compress either the X or Y values so that, after the viewport rescale, squares show up as square.

I just throw away the pre-transformation Z value and let all vertices wind up with a Z coordinate of 0.5 (so they don't get clipped). If you want to use the depth buffer to help determine visibility, you might let the input Z values determine the transformed depth.