Skip to main content
GameDev.net gamedev.net
🔒 Locked

Problem with View/Projection Matrices

Started by Laccolith Jan 24, 2011 at 2:11 AM 1 replies 1.2k views
Original Post
Laccolith
Laccolith
I'm creating a game using DirectX 11 but I don't want to use the supplied DirectX matrices and functions. I have created my own Math classes with the help of some sources online. However my View Projection matrix is giving incorrect behavior. It looks okay until I try to move the camera, then everything changes in all sorts of strange ways, which makes be believe the problem lies with the View matrix.

I'm constructing the View Matrix like so:


m_vLook.Normalise();

m_vUp = m_vLook.crossProduct(m_vRight);
m_vUp.Normalise();

m_vRight = m_vUp.crossProduct(m_vLook);
m_vRight.Normalise();

float x = -m_vRight.dotProduct(m_vPosition);
float y = -m_vUp.dotProduct(m_vPosition);
float z = -m_vLook.dotProduct(m_vPosition);

Matrix4 ret;

ret[0][0] = m_vRight.x;
ret[0][1] = m_vUp.x;
ret[0][2] = m_vLook.x;
ret[0][3] = 0.0f;

ret[1][0] = m_vRight.y;
ret[1][1] = m_vUp.y;
ret[1][2] = m_vLook.y;
ret[1][3] = 0.0f;

ret[2][0] = m_vRight.z;
ret[2][1] = m_vUp.z;
ret[2][2] = m_vLook.z;
ret[2][3] = 0.0f;

ret[3][0] = x;
ret[3][1] = y;
ret[3][2] = z;
ret[3][3] = 1.0f;

return ret;



And for the Projection Matrix:


Matrix4 ret = Matrix4::Zero;

float yScale = Cot(fFOV/2);
float xScale = yScale / fAspect;

ret[0][0] = xScale;
ret[1][1] = yScale;
ret[2][2] = fFar / (fFar - fNear);
ret[2][3] = 1.0f;
ret[3][2] = -fNear * fFar / (fFar - fNear);

return ret;



I then multiply them together and directly use them in my Constant Buffer, The rest of the graphics pipeline is how it was when it worked using D3DXMATRIX. My matrixs data is defined as :float m[4][4];

Thanks
Zakwayda
Zakwayda
The view matrix looks ok, but the projection matrix looks to me like it might be missing a couple of terms.

Here's the corresponding bit of code from the CML (please excuse all the template stuff):

value_type inv_width = value_type(1) / (right - left);
value_type inv_height = value_type(1) / (top - bottom);
value_type near2 = value_type(2) * n;

// ...

m.set_basis_element(0,0,near2 * inv_width );
m.set_basis_element(1,1,near2 * inv_height );
m.set_basis_element(2,0,-s * (right + left) * inv_width );
m.set_basis_element(2,1,-s * (top + bottom) * inv_height);

And here's the code that converts vertical field of view and aspect ratio to width and height at the near plane:

value_type height = value_type(2) * std::tan(yfov * value_type(.5)) * n;
matrix_perspective(
m, height * aspect,
height,
n,
f,
handedness,
z_clip
);

'left', 'right', 'top', and 'bottom' are just computed as -width / 2, width / 2, etc.

Anyway, the last three terms of your projection matrix look correct. Not sure about the first two terms (although I'm guessing they're correct), but it does seem like you may have missed a couple of elements elsewhere.
Laccolith
Laccolith
Ah, Fixed It, I was multiplying the view with the projection matrix in the wrong order and then I needed to transpose the combined matrix.

Thanks anyway

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.