2013-02-16 155 views
2

我正试图在软件级别实现图形管道。我现在有一些剪辑和剔除的问题。我应该在哪个阶段进行剔除和裁剪,我应该如何在裁剪后重建三角形

基本上,主要有两个顾虑:

  1. 时候应该背面剔除发生?眼坐标,裁剪坐标或窗口坐标?我最初在眼睛坐标上做了剔除过程,认为这样可以减轻裁剪过程的负担,因为许多背面顶点已经被丢弃。但后来我意识到,这样顶点需要进行2次矩阵乘法,即左乘法模型 - 视点矩阵 - >剔除 - >左乘法透视矩阵,这在一定程度上增加了开销。

  2. 如何裁剪和重建三角形?据我所知,剪切发生在剪切坐标中(透视变换后),换句话说齐次坐标中每个顶点正在被确定是否不应该通过比较它的x,y,z分量与w分量而被丢弃。到目前为止很好,对吧?但在此之后,我需要重建那些丢弃了一个或两个顶点的三角形。我搜索了一下,Liang-Barsky算法在这种情况下会有所帮助,但是在裁剪坐标系中我应该使用哪个裁剪平面?我应该只记录剪切后的三角形并在NDC中重建它们?

任何想法都会有所帮助。谢谢。

回答

3

(1)

背面剔除可以发生在任何你想要的地方。

在3dfx硬件上,可能还有其他只有光栅化的卡,它是在窗口坐标中实现的。正如你所说,让你处理一些你永远不会使用的顶点,但是你需要权衡其他成本。

你也可以选择世界坐标;你知道相机的位置,所以你知道从相机到脸部的矢量 - 只要去任何边缘顶点。因此,您可以测试与正常情况相对应的点积。

当我为一个基于z80的micro实现一个软件光栅时,我超越了这一步,并将相机转换为模型空间。所以你得到了模型矩阵的逆矩阵(在这种情况下便宜,因为它们保证了正交,所以转置就可以),将它应用到摄像机,然后从那里剔除。它仍然是一个矢量差分和点积,但是如果您仅将曲面法线用于剔除,那么无需为了相机的利益而转换它们中的每一个。对于那个特定的渲染器,我可以继续前进,从中可以看到哪些面,以确定哪些顶点是可见的,并只将它们转换为窗口坐标。

(2)

上萨瑟兰 - 科恩一个变体是我记得看到最常见的事情。你可以在多边形的外侧进行正向扫描,依次检查每个边缘并进行适当的调整。

因此,例如,从点(V1,V2,V3)之间的凸多边形开始。对于每个裁剪平面轮流你会做这样的事情:

for(Vn in input vertices) 
{ 
    if(Vn is on the good side of the plane) 
     add Vn to output vertices 

    if(edge from Vn to Vn+1 intersects plane) // or from Vn to 0 if this is the last edge 
    { 
     find point of intersection, I 
     add I to output vertices 
    } 
} 

并重复每个飞机。如果你担心重复成本,那么你需要采用一种在面和边之间额外增加间接级别的结构,或者只保留一个缓存。一旦将它们标记为“入”或“出”,您可能会做一些操作,如缓存顶点,然后缓存每个边的交点,并通过键(v1,v2)查找。如果你已经设置了额外的间接级别,然后将结果存储在边缘对象中。

+0

谢谢@Tommy的建议。那么你什么时候做Sutherland-Cohen测试并计算边缘和平面的交点?裁剪坐标?假设一个三角形TriA(v0,v1,v2)处于剪切坐标中,并且我将每个顶点的x,y,z与它的w值进行比较,结果应该丢弃v1,v2。问题来了,我应该在这之后做些什么?将edge01和edge02的三角形和计算机交叉点标记到某个平面上? – Nowibananatzki 2013-02-16 04:35:36

+0

再次,我猜想有各种各样的答案,但我个人通常在变换到相机空间后剪辑,以移除'x> z','y <-z','z <1'等等,以便您支付这种变化,但不是为了投影。在一个非常小的系统上,这是很好的,因为它支付了一些乘法,但避免了一些冗余的划分,而这在旧硬件上当然是非常昂贵的。 – Tommy 2013-02-16 05:30:01

+0

感谢您的澄清。我会在稍后尝试。 – Nowibananatzki 2013-02-16 06:21:14