我必须分别渲染2个场景,并将其中一个场景作为一个平面嵌入到另一个场景中。渲染为平面的子场景将使用根据相对摄像机位置和透视矩阵计算的视图矩阵,考虑距离和计算的偏斜以渲染子场景,就好像该场景实际放置在该点上一样。
为了描述更多细节,这是一个描述更简单案例的图。 (在这种情况下,我们在主平截头体的中心线上有子场景)
通过使用这些参数,很容易计算出可视化为红色平截头体的透视矩阵。
但是,我很难解决其他情况。如果在中心线之外存在子场景,我应该将投影矩阵倾斜以对应外部场景。
我认为这是一种倾斜的透视投影。而且这与渲染镜非常相似。如何计算此透视矩阵?
答案 0 :(得分:2)
如何计算此透视矩阵?
非对称透视(列主要顺序)投影矩阵的设置如下:
m[16] = [
2*n/(r-l), 0, 0, 0,
0, 2*n/(t-b), 0, 0,
(r+l)/(r-l), (t+b)/(t-b), -(f+n)/(f-n), -1,
0, 0, -2*f*n/(f-n), 0];
其中r
,l
,b
和t
是近平面上平截头体平面的左,右,底和顶距离。 n
和f
是距离近距离和远距离的距离。
通常,在框架或库中,像这样的投影矩阵由名为 frustum 的函数设置。
e.g。
OpenGL固定功能管道:glFrustum
答案 1 :(得分:2)
正如@ Rabbid76已经指出这只是一个标准的不对称截头体。为此,您只需要在眼睛空间中知道您将要使用的近平面上的矩形坐标。
但是,还有另一种选择:您还可以修改现有的投影矩阵。如果您知道矩形在窗口坐标或标准化设备坐标中的位置,那么这种方法会更容易。您可以简单地预缩放比例和平移矩阵,以选择原始截头体的任何子区域。
假设您的视口宽度为w * h
像素,并从窗口中的(0,0)
开始。并且您想要创建一个视锥体,它只是渲染一个从像素(x,y)
的左下角开始的子矩形,其宽a
像素高,b
像素高。
转换为NDC:
x_ndc = (x / w) * 2 - 1
和y_ndc = (y / h) * 2 - 1
a_ndc = (a / w) * 2
和b_ndc = (b / h) * 2
创建缩放和平移变换,将范围[x_ndc, x_ndc+a_ndc]
映射到[-1,1]
,并且类似于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 )
(请注意,因子2
将被排除。而不是在步骤1中转到[-1,1] NDC空间,我们也可以使用标准化的[0,1],我只是想使用标准空间。)
预乘M
到原始投影矩阵P
:
P' = M * P
请注意,即使我们在NDC空间中定义了转换,并且P
在分割之前在剪辑空间中工作,数学仍然可以解决。通过使用同质坐标,M
的翻译部分将相应地缩放w
。得到的矩阵只是一般的非对称投影矩阵。
现在,这不会调整原始投影的near
和far
剪裁平面。但是,您可以通过向z
坐标添加适当的比例和平移来以相同的方式调整它们。
另请注意,使用此方法,您甚至不能仅限于选择轴平行矩形,也可以任意旋转或倾斜它,因此基本上,您可以在窗口空间中选择任意平行四边形。