VTK的ProjectionTransformMatrix和OpenGL的GL_PROJECTION有什么区别?

j18*_*897 5 c++ opengl computer-vision augmented-reality vtk

我在理解 VTK 所涉及的转换方面遇到了深刻的问题。OpenGL 有相当好的文档,我的印象是 VTK 与 OpenGL 非常相似(在很多方面都是如此)。但当谈到转型时,情况似乎完全不同。

这是一个关于所涉及的变换的很好的 OpenGL 文档: http://www.songho.ca/opengl/gl_transform.html

OpenGL中的透视投影矩阵为:

在此输入图像描述

我想看看在 VTK 中应用这个公式是否会给出 VTK 的投影矩阵(通过与 VTK 投影矩阵交叉检查)。

相关相机和渲染器参数:

camera->SetPosition(0,0,20);
camera->SetFocalPoint(0,0,0);
double crSet[2] = {10, 1000};
renderer->GetActiveCamera()->SetClippingRange(crSet);
double windowSize[2];
renderWindow->SetSize(1280,720);
renderWindowInteractor->GetSize(windowSize);
proj = renderer->GetActiveCamera()->GetProjectionTransformMatrix(windowSize[0]/windowSize[1], crSet[0], crSet[1]);
Run Code Online (Sandbox Code Playgroud)

我为此配置得到的投影变换矩阵是:

在此输入图像描述

投影矩阵的 (3,3) 和 (3,4) 值(假设行和列的索引为 1 到 4)应为 - (f+n)/(fn) 和 -2*f*n /(fn) 分别。在我的 VTK 相机设置中,nearz 为 10,farz 为 1000,因此我应该在矩阵的 (3,3) 和 (3,4) 位置分别得到 -1.020 和 -20.20。但它是-1010和-10000。

我已经更改了剪切范围值以查看更改,并且 (3,3) 位置始终接近 z+farz,这对我来说没有任何意义。另外,如果有人能解释为什么 (1,1) 和 (2,2) 位置上的值是 3.7320,那就太好了。当我更改渲染器窗口的窗口大小时,该值不会改变。让我很困惑。

我在 VTKCamera 类参考中看到 GetProjectionTransformMatrix() 返回从相机坐标映射到视口坐标的变换矩阵。

VTK 相机类参考

这是对 OpenGL 渲染中涉及的变换的很好的描述:

在此输入图像描述

OpenGL 投影矩阵是从眼睛坐标映射到剪辑坐标的矩阵。毫无疑问,OpenGL中的眼睛坐标与VTK中的相机坐标相同。但是OpenGL中的剪辑坐标与VTK中的视口坐标相同吗?

我的目标是在 VTK 中模拟真实的网络摄像头(已校准)以渲染 3D 模型。

der*_*ass 3

好吧,您链接到的文档实际上解释了这一点(强调我的):

vtkCamera::GetProjectionTransformMatrix:

返回投影变换矩阵,该矩阵从相机坐标转换为视口坐标。此方法计算方面、nearz 和 farz,然后调用 Get Composite ProjectionTransformMatrix的更具体签名

和:

vtkCamera::GetCompositeProjectionTransformMatrix:

返回 ViewTransform 和 ProjectionTransform 的串联。此变换会将世界坐标转换为视口坐标。“aspect”是视口的宽度/高度,nearz 和 farz 是映射到近剪裁平面和远剪裁平面的 Z 缓冲区值。位于视锥体内的点的视口坐标在 ([-1,+1],[-1,+1], [nearz,farz] )范围内。

请注意,这既不匹配 OpenGL 的窗口空间,也不匹配标准化的设备空间。如果找到术语“视口坐标”来表示这是一个糟糕的选择,但无论如何。更让我烦恼的是,矩阵实际上并没有转换为“视口空间”,而是转换为某些等效的剪辑空间。只有在透视划分之后,坐标才会在上述“视口空间”定义给出的范围内。

但是OpenGL中的剪辑坐标与VTK中的视口坐标相同吗?

所以答案是明确的“不”。但已经很接近了。基本上,该投影矩阵只是沿 z 维度缩放和移动,并且很容易在这两者之间进行转换。基本上,您可以简单地取出znearVTKzfar的矩阵,并将其放入上面链接的 OpenGL 投影矩阵公式中,仅替换这两个矩阵元素。