Advertisement

PerspectiveOffCenterLH

Started by August 20, 2018 02:49 PM
2 comments, last by Tape_Worm 6 years, 5 months ago

So, I'm using PerspectiveOffCenterLH (in SharpDX, but that should not matter) to project perspective correct stuff into screen space. Up until last night, it was working well. I could translate on all axes, and I can rotate on the Z axis just fine.

So I added y-axis rotation for giggles and that's when things went all weird.  Every time I rotated about the Y-axis, my geometry (a simple quad) gets distorted.  Now, I have to admit to being a dumbass when it comes to linear algebra, and it's been a very long time since I've had to deal with a projection matrix directly, so it could be that I'm using the wrong tool for the job due to my ignorance. 

Basically it looks like the vertices on each side stretch off into the distance (more and more as I rotate):

 Distorted.png.361edca3d7a7b5e815c83044baa5f0cd.png 

I'd like to note that I have another app, where I'm using PerspectiveFovLH, and that's working just fine. So again, this very well could be a case of "the wrong tool for the job".

Here's the code I'm using to build up my stuff:


// Matrix construction code.  Anchor is 0, 0 for now, so we can ignore it.  
// ViewDimensions is the width and height of the render target.
var anchor =  DX.Vector2.Zero;
DX.Matrix.PerspectiveOffCenterLH(-anchor.X,
                                 ViewDimensions.Width - anchor.X,
                                 ViewDimensions.Height - anchor.Y,
                                 -anchor.Y,
                                 MinimumDepth,
                                 MaximumDepth,
                                 out ProjectionMatrix);

// This is my code for combining my view + projection
DX.Matrix.Multiply(ref ViewMatrix, ref ProjectionMatrix, out ViewProjectionMatrix);

// And this is my code for building the view.
DX.Matrix translation = DX.Matrix.Identity;
DX.Matrix.RotationYawPitchRoll(_yaw.ToRadians(), 0, _roll.ToRadians(), out DX.Matrix rotation);
// NOTE: This doesn't work either.
//DX.Matrix.RotateY(_yaw.ToRadians());
DX.Matrix.Multiply(ref rotation, ref translation, out ViewMatrix);

// My code in the vertex shader is pretty simple:
Vertex output = input;
output.position = mul(ViewProjection, output.position);
return output;

The order of operations is indeed correct.  It works just fine when I don't rotate on the Y (or X - but that's not important for today) axis.  

So, yeah, can someone tell me if I'm dumb and using the wrong projection matrix type?  And if I can, an explanation for it would be much appreciated to so I don't make this mistake again (don't go too math crazy, I'm old and my math skills are worse than ever - talk to me like I'm 5).

The "OffCenter" functions let you create an skewed/asymmetical projection, as opposed to the typical symmetrical perspective projection that's normally used for rendering. Unless you're doing something special (like per-eye VR rendering), you probably don't want an asymmetrical projection.  A normal projection looks like this (top-down view):

image.png.3b8c057ae0dc749acafaaf9e92165405.png

The projection that you're creating is going to look like this:

image.png.7a1cbdc350d0c449c269cea7a38f8392.png

You can create a symmetrical projection with the OffCenter functions, but you can also just use the PerspectiveFov functions instead.

As for your view matrix, you need to invert the camera's transformation matrix to create a view matrix (the view matrix brings things from world coordinates into the camera's frame of reference). 

Advertisement

Awesome, thanks for the explanation.

I managed to make it all work out by just transforming my quads instead and leaving the camera fixed.  By doing that (and countless other small adjustments...) I got the end result I wanted:

MarioK.thumb.png.7ea768431da51f103635f7f19206fe93.png

I did this all with my 2D API that I've been writing off and on over the last... well... very long time.

This topic is closed to new replies.

Advertisement