I have to render 2 scenes separately and embed one of them into another scene as a plane. The sub scene that is rendered as a plane will use a view matrix calculated from relative camera position and perspective matrix considering distance and calculated skew to render sub scene as if that scene is placed actually on the point.
For describing more detail, this is a figure to describe the simpler case.
(In this case, we have the sub scene on the center line of the main frustum)
It is easy to calculate perspective matrix visualized as red frustum by using these parameters.
However, it is very difficult for me to solve the other case. If there were the sub scene outside of the center line, I should skew the projection matrix to correspond with scene outside.
I think this is kind of oblique perspective projection. And also this is very similar to render mirror. How do I calculate this perspective matrix?
As @Rabbid76 already pointed out this is just a standard asymmetric frustum. For that, you just need to know the coordinates of the rectangle on the near plane you are going to use, in eye-space.
However, there is also another option: You can also modify the existing projection matrix. That approach will be easier if you know the position of your rectangle in window coordinates or normalized devices coordinates. You can simply pre-multiply scale and translation matrices to select any sub-region of your original frustum.
Let's assume that your viewport is w * h
pixels wide, and starts at (0,0)
in the window. And you want to create a frustum which just renders a sub-rectangle which starts at the lower left corner of pixel (x,y)
, and which is a
pixels wide and b
pixels tall.
Convert to NDC:
x_ndc = (x / w) * 2 - 1
and y_ndc = (y / h) * 2 - 1
a_ndc = (a / w) * 2
and b_ndc = (b / h) * 2
Create a scale and translation transform which maps the range [x_ndc, x_ndc+a_ndc]
to [-1,1]
, and similiar for y:
( 2/a_ndc 0 0 -2*x_ndc/a_ndc-1 )
M = ( 0 2/b_ndc 0 -2*y_ndc/b_ndc-1 )
( 0 0 1 0 )
( 0 0 0 1 )
(note that the factor 2
is going to be cancled out. Instead of going to [-1,1] NDC space in step 1, we could also just have used the normalized [0,1], I just wanted to use the standard spaces.)
Pre-Multiply M
to the original projection matrix P
:
P' = M * P
Note that even though we defined the transformation in NDC space, and P
works in clip space before the division, the math still will work out. By using the homogenous coordinates, the translation part of M
will be scaled by w
accordingly. The resulting matrix will just be a general asymmetric projection matrix.
Now this does not adjust the near
and far
clipping planes of the original projection. But you can adjust them in the very same way by adding appropriate scale and translation to the z
coordinate.
Also note that using this approach, you are not even restricted to selecting an axis-parallel rectangle, you can also rotate or skew it arbitrarily, so basically, you can select an arbitrary parallelogram in window space.