2
\$\begingroup\$

I'm trying to achieve a dolly zoom effect.
My first try was the obvious one, the original "zoom in & dolly out" technique, which works nicely.
Except that there are cases which this is not possible due spatial conditions (E.g.: camera close to a wall)

If you pull back the camera too much you may occlude the view with some other objects (the red area).

To solve this I figured that I can't move the camera. Instead, I have to change the frustum, making a larger near plane and a smaller far plane.
This way, it's possible to control de effect without moving the camera.

I know how to build the perspective and orthogonal projection matrices, and I was able to interpolate between them (interpolating each element separately).
This got me really near to solve the puzzle.

The only problem now is to set a distance from the camera to keep my frustum height, effectively locking the focus in an object/position.
But I can't figure this one out.

So, any ideas?


Aditional info

This is the matrices that I'm using:

4x4 matrix for orthogonal projection

   0         1         2          3
  -----------------------------------------------
0 | 2/(r-l) |         |          | -(r+l)/(r-l) |
  -----------------------------------------------
1 |         | 2/(t-b) |          | -(t+b)/(t-b) |
  -----------------------------------------------
2 |         |         | -2/(f-n) | -(f+n)/(f-n) |
  -----------------------------------------------
3 |         |         |          | 1            |
  -----------------------------------------------

4x4 matrix for perspective projection

   0           1         2              3
  -----------------------------------------------------
0 | 2n/(r-l) |          | (r+l)/(r-l)  |              |
  -----------------------------------------------------
1 |          | 2n/(t-b) | (t+b)/(t-b)  |              |
  -----------------------------------------------------
2 |          |          | -(f+n)/(f-n) | -2*f*n/(f-n) |
  -----------------------------------------------------
3 |          |          | -1           |              |
  -----------------------------------------------------

To interpolate them, I use something like this (pseudo-code):

interpolate (from, to, percentage)
{
    matrix = []
    i = 0
    while (i < 16)
    {
        matrix[i] = from[i] + (to[i] - from[i]) * percentage
        i++
    }
    return matrix;
}

projection = interpolate(perspective, orthogonal, 0.75)
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.