我正在尝试在软件级别实现图形管道。我现在有一些剪裁和剔除的问题。
基本上,有两个主要问题:
什么时候应该进行背面剔除?眼睛坐标,剪裁坐标或窗口坐标?我最初在眼睛坐标中进行了剔除过程,这样思考可以减轻剪裁过程的负担,因为许多背面顶点已被丢弃。但后来我意识到,这样顶点需要进行2次矩阵乘法,即左乘法模型 - 视图矩阵 - >剔除 - >左乘多透视矩阵,这会在一定程度上增加开销。
如何裁剪和重建三角形?据我所知,裁剪发生在裁剪坐标(透视变换之后),另一个字是齐次坐标,其中每个顶点都是通过比较其x,y,z分量与w分量来确定是否应该丢弃它。到目前为止一切都那么好吧?但之后我需要重建那些丢弃了一个或两个顶点的三角形。我用Google搜索了Liang-Barsky算法在这种情况下会有所帮助,但是在剪切坐标中我应该使用哪个剪裁平面?我应该只记录剪切的三角形并在NDC中重建它们吗?
任何想法都会有所帮助。感谢。
答案 0 :(得分:3)
(1)
可以在任何地方进行背面剔除。
在3dfx硬件上,可能只有光栅化的其他卡片,它是在窗口坐标中实现的。正如你所说的那样让你处理一些你从未使用过的顶点,但你需要权衡它与其他成本的比较。
你也可以剔除世界坐标;你知道相机的位置,所以你知道从相机到脸部的矢量 - 只需转到任何边缘顶点。所以你可以针对正常情况测试它的点积。
当我为基于z80的micro实现软件rasteriser时,我更进了一步,将相机转换为模型空间。所以你得到模型矩阵的逆(在这种情况下它很便宜,因为它们保证是正交的,所以转置会这样做),将它应用到相机然后从那里剔除。它仍然是矢量差异和点积,但如果你只使用表面法线进行剔除,那么为了照相机的利益,它可以节省必须转换它们中的每一个。对于那个特定的渲染器,我可以向前工作,从哪些面可见,以确定哪些顶点是可见的,并仅转换为窗口坐标。
(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
}
}
并重复每架飞机。如果您担心重复的成本,那么您需要采用在面和边之间具有额外间接水平的结构,或者只保留缓存。你可能会做一些事情,比如在将它们标记为in或out时绕过顶点,然后缓存每条边的交点,通过键(v1,v2)查找。如果你已经设置了额外的间接级别,那么将结果存储在边缘对象中。