5
$\begingroup$

So ordinarily we have this

enter image description here

But I'm after this!

enter image description here

Is it possible to do this? Ideally by changing the projection matrix?

The reasoning is kinda interesting - I am developing for mobile VR, and I have found that putting my phone (and surely many others) in headsets that are too wide for them makes its so that your horizontal perspective convergence point is in the wrong place.

$\endgroup$

1 Answer 1

7
$\begingroup$

Yes, you can use an off-axis projection matrix. This is what I use in my code (note: I shift the centre upwards, not left as you do in your example.)

void camera_setAspectRatio(float aspect, float zNear, float zFar, bool offaxis)
{
        // create a projection matrix
        const float f = 1.0f / tanf(fovy_radians/2.0f);
        fovx_radians = 2.0f * atanf( aspect * tanf(fovy_radians/2.0f) );
        float* mout = proj.data;

        mout[0] = f / aspect;
        mout[1] = 0.0f;
        mout[2] = 0.0f;
        mout[3] = 0.0f;

        mout[4] = 0.0f;
        mout[5] = f;
        mout[6] = 0.0f;
        mout[7] = 0.0f;

        mout[8] = 0.0f;
        mout[9] = offaxis ? -0.25f : 0.0f; // off axis projection!
        mout[10] = (zFar+zNear) / (zNear-zFar);
        mout[11] = -1.0f;

        mout[12] = 0.0f;
        mout[13] = 0.0f;
        mout[14] = 2 * zFar * zNear /  (zNear-zFar);
        mout[15] = 0.0f;
}

Stereo Projection screens (not head-mounted) tend to use Off-Axis projection matrices as well. Paul Bourke has a great write up on these projections.

$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.