Rotation problem on multiple monitors

Started by
3 comments, last by BattleMetalChris 12 years, 8 months ago
I am trying to use multiple monitors to extend the field of view. To do so, I apply an offset to my view matrix like this:
[source]

Matrix4 matXYZ; matXYZ.translation(m_position);
Matrix4 matRotation; matRotation.setYawPitchRoll(m_yaw, m_pitch, m_roll);
Matrix4 matOffset; matOffset.rotationY(offset);
Matrix4 matTransformation = matOffset * matRotation * matXYZ;
[/source]

Now the problem is when I rotate around Y axis, the horizon will not appear on a line (there are discontinuities on the borders). How can I fix this problem?

(Attached image shows what I want to achieve!)
Advertisement

I am trying to use multiple monitors to extend the field of view. To do so, I apply an offset to my view matrix like this:
[source]

Matrix4 matXYZ; matXYZ.translation(m_position);
Matrix4 matRotation; matRotation.setYawPitchRoll(m_yaw, m_pitch, m_roll);
Matrix4 matOffset; matOffset.rotationY(offset);
Matrix4 matTransformation = matOffset * matRotation * matXYZ;
[/source]

Now the problem is when I rotate around Y axis, the horizon will not appear on a line (there are discontinuities on the borders). How can I fix this problem?

(Attached image shows what I want to achieve!)


Its easier to calculate your view & projection matricies as per normal, but then edit the projection matrix with a scale & translate matrix to shift the results onto the appropriate screen.

Remember that the results of the final projection matrix yield a clip space coordinate from -1 : 1. You want -1 : 0 to end up on the left screen and 0 : 1 to end up on the right screen.

Its easier to calculate your view & projection matricies as per normal, but then edit the projection matrix with a scale & translate matrix to shift the results onto the appropriate screen.

Remember that the results of the final projection matrix yield a clip space coordinate from -1 : 1. You want -1 : 0 to end up on the left screen and 0 : 1 to end up on the right screen.




Trouble with that is it's all projected into the same viewing plane, just with a huge horizontal FOV which creates pretty atrocious warping at the edges of the display with multiple monitors (I run three monitors in compatible games, and my usual horizontal FOV is 160 degrees).

Ideally you want all the monitors to face the player and each display produced by a different view matrix, essentially using three cameras at different angles, instead of one stretched across all displays This creates a pleasing psudo-cylindrical projection, lets you run FOVs over 180 degrees and limits the warping to just the kind of extents you usually see on a single monitor with 90 degree FOV.

See the difference between these screenshots, both with 160 degree FOV (the discontinuities in the second shot are due to it compensating for the monitor bezels)

http://dl.dropbox.co...00003704384.png
http://dl.dropbox.co...00003988555.png

In response to the OP, is it not just a case of tweaking your offset value until they line up?

Its easier to calculate your view & projection matricies as per normal, but then edit the projection matrix with a scale & translate matrix to shift the results onto the appropriate screen.

Remember that the results of the final projection matrix yield a clip space coordinate from -1 : 1. You want -1 : 0 to end up on the left screen and 0 : 1 to end up on the right screen.


I came up with this projection matrix:

[source]

void Matrix4::perspectiveFovOffCenter(float fov, float aspect, float zn, float zf, float cX, float cY)
{
float yScale = cotf(fov/2);
float xScale = yScale / aspect;
float xOffset = -2*cX;
float yOffset = -2*cY;

_11 = xScale; _12 = 0; _13 = 0; _14 = 0;
_21 = 0; _22 = yScale; _23 = 0; _24 = 0;
_31 = xOffset; _32 = yOffset; _33 = zf/(zf-zn); _34 = 1;
_41 = 0; _42 = 0; _43 = zn*zf/(zn-zf);_44 = 0;
}[/source]


This seems to work fine except it messes up half of my shaders, and I get all distorted shadows and lighting artifacts on the translated image!
If you're translating the camera as well as rotating it, remember that you'll need to change the eye position as each monitor's image is rendered.

This topic is closed to new replies.

Advertisement