我听说裁剪应该在裁剪坐标系中完成。 这本书提出了一种情况,即从摄像机后面到观看体积中放置一条线。 (我们将此行定义为PQ,P位于摄像机点后面) 我无法理解为什么它会成为一个问题。
(书中说,在完成正常化转换后,P将放在镜头前。)
我认为在制作剪裁坐标系之前,摄像机在原点(0,0,0,1)上,因为我们进行了观察变换。 但是,在NDCS中,我无法想到相机的位置。
我有第二个问题。 在顶点着色器中,我们进行模型视图转换,然后进行投影转换。最后,我们将这些顶点输出到光栅化器。 (某些顶点的w不等于'1')
在这里,我有好奇心。渲染管道会自动进行除法程序(通过w)?完成剪裁后。
答案 0 :(得分:1)
有时并非所有模型都可以在屏幕上看到,主要是因为它的某些物体位于相机后面(或“视角”)。这些对象被剪掉了。如果只能看到对象的一部分,那么只有那部分必须被剪掉,剩下的就像看到的一样。
OpenGL在剪切坐标空间(CCS)中执行此裁剪。这是一个大小为2w x 2w x 2w的立方体,其中'w'是(4x4)x(4x1)矩阵和点乘法得到的第四个坐标。仅仅比较坐标足以判断该点是否被剪裁。如果该点通过测试,则其坐标除以'w'(所谓的“透视划分”)。请注意,对于正交投影'w'始终为1,并且透视通常不是1。
如果模型太大,您可能希望节省GPU资源或提高帧速率。因此,您决定跳过那些将被剪辑的对象。然后你自己做数学(在CPU上)并且只向GPU发送通过测试的顶点。请注意,某些对象可能会剪切某些顶点,而此同一对象的其他顶点可能不会。 也许您确实将它们发送到GPU并让它处理这些特殊情况。
您定义了一个卷,其中只能看到内部对象。该体积由六个平面定义。让我们把自己放在相机中看看这个卷:如果你的投影是透视的,那么六架飞机会形成一个“fustrum”,一种截断的金字塔。如果投影是正交的,则平面形成平行六面体。
为了剪裁或不剪辑顶点,您必须使用从顶点到这六个平面中的每一个的距离。你需要一个有符号的距离,这意味着符号告诉你从顶点看到的平面的哪一侧。如果六个距离符号中的任何一个不是正确的,则顶点被丢弃,被剪裁。
如果一个平面由方程Ax + By + Cz + D = 0定义,那么与p1,p2,p3的符号距离为(Ap1 + Bp2 + Cp3 + D)/ sqrt(A A + B B + C * C)。你只需要这个标志,所以不要费心去计算分母。
现在你拥有了所有工具。如果您在“摄像机视图”上知道您的飞机,您可以计算六个距离并剪切或不剪切顶点。但考虑到您必须将顶点坐标从模型转换为相机(视图)空间,ViewModel矩阵计算,这可能是一项昂贵的操作。使用相同的成本,您可以使用预先计算的ProjectionViewModel矩阵并获得CCS坐标,这些坐标更容易与CCS立方体的大小“2w”进行比较。
有时你想要跳过一些不是由于它们被剪裁而导致的顶点,而是因为它们的深度会破坏你正在使用的标准。在这种情况下,CCS不适合使用,因为Z坐标转换为[-w,w]范围,深度以某种方式“丢失”。相反,您可以在“视图空间”中进行剪辑测试。