2

我正在尝试在软件级别实现图形管道。我现在在裁剪和剔除方面遇到了一些问题。

基本上,有两个主要问题:

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

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

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

4

1 回答 1

3

(1)

背面剔除可以在您想要的任何地方进行。

在 3dfx 硬件上,可能还有其他只光栅化的卡,它是在窗口坐标中实现的。正如您所说,这会让您处理一些您从未使用过的顶点,但您需要将其与其他成本进行权衡。

您还可以剔除世界坐标;您知道相机的位置,因此您知道从相机到脸部的矢量——只需转到任何边缘顶点。因此,您可以针对正常情况测试其点积。

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

(2)

Sutherland-Cohen 的变体是我记得最常看到的东西。您将在多边形外部进行前向扫描,依次检查每条边并进行适当调整。

因此,例如,您从点(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)进行查找。如果您为自己设置了额外的间接级别,则将结果存储在边缘对象中。

于 2013-02-16T00:40:38.527 回答