5

我正在尝试创建一个简单的 3D 图形引擎,并找到并使用了我在这里找到的方程式:http ://en.wikipedia.org/wiki/3D_projection#cite_note-0 。(我有 Dx、Dy、Dz 和 Bx、By 的计算)

我可以工作,但是当我旋转相机时,足够多的线条开始在整个地方飞来飞去,最终你会看到离开屏幕的多边形开始回到屏幕的另一侧(你可以去这里:http://mobile. sheridanc.on.ca/~claassen/3d.html并使用 W、A、S 和 D 键旋转相机以查看我在说什么)

我阅读了这个讨论:如何将 3D 点转换为 2D 透视投影?他谈到使用剪辑矩阵的地方,但我仍然对如何使用剪辑矩阵有点困惑。此外,我不确定我是否使用讨论中描述的“齐次坐标”。

4

2 回答 2

26

乘以透视投影矩阵(又名剪辑矩阵)后,您将得到一个齐次的 4 向量 [x,y,z,w]。这称为 npc(归一化投影坐标),也称为剪辑坐标。要在屏幕上获取 2D 坐标,您通常使用类似的东西

xscreen = (x/w) * screen_width
yscreen = (y/w) * screen_width

对于相机前面的点,这可以满足您的需求。但是相机后面的点将具有 w<0 并且即使该点位于相机后面,您也会得到映射到有效屏幕坐标的值。为避免这种情况,您需要进行剪辑。任何具有 w<0 的顶点都需要被剪裁。

一个快速的尝试是,如果任一顶点的 w<0,则不画任何线。这应该可以修复场景中出现的奇怪多边形。但它也会删除一些应该可见的线条。

要完全解决这个问题,您需要剪裁所有在相机前面有一个顶点和在相机后面有一个顶点的线。剪辑意味着将线切成两半并扔掉相机后面的一半。这条线被穿过相机并与显示屏平行的平面“剪裁”。问题是在直线上找到与该平面相对应的点(即直线与平面相交的位置)。这将发生在线上 w==0 的点。你可以找到这个点,但是当你试图找到屏幕坐标时

xscreen = (x/w) * screen_width
yscreen = (y/w) * screen_width

你最终除以 0 (w==0)。这就是“近剪裁平面”的原因。近剪裁平面也平行于显示屏,但位于相机前面(相机和场景之间)。相机和近剪裁平面之间的距离是投影矩阵的“近”参数:

[    near/width   ][        0        ][         0              ][        0       ]
[        0        ][    near/height  ][         0              ][        0       ]
[        0        ][        0        ][(far+near)/(far-near)   ][        1       ]
[        0        ][        0        ][-(2*near*far)/(far-near)][        0       ]

要裁剪到近平面,您必须找到与近裁剪平面相交的线上的点。这是 w == 附近的点。因此,如果您有一条带有顶点 v1,v2 的线,其中

v1 = [x1, y1, z1, w1]
v2 = [x2, y2, z2, w2]

您需要检查每个顶点是在近剪裁平面的前面还是后面。如果 w1 >= near,则 V1 在前面,如果 w1 < near,则 V1 在后面。如果 v1 和 v2 都在前面,则画线。如果 v1 和 v2 都在后面,则不要画线。如果 v1 在前面而 v2 在后面,那么您需要找到 vc 直线与近裁剪平面相交的位置:

n = (w1 - near) / (w1 - w2)
xc = (n * x1) + ((1-n) * x2)
yc = (n * y1) + ((1-n) * y2)
zc = (n * z1) + ((1-n) * z2)
wc = near
vc = [xc, yc, zc, wc]

现在画出 v1 和 vc 之间的界限。

于 2013-11-24T20:29:53.233 回答
4

这可能是对术语的误解。剪辑矩阵更恰当地称为投影矩阵。至少在 OpenGL 中,投影矩阵将视图坐标空间 (VCS)中的 4D 齐次坐标转换为裁剪坐标空间 (CCS)。从CCS 到标准化设备坐标空间(NDCS)的投影需要透视除法,即将每个分量除以W 分量。在此步骤之前已正确完成剪辑。因此,“剪裁矩阵”不会消除在投影之前剪裁几何图形的需要。我希望我已经理解你了,这听起来并不居高临下。

也就是说,我认为你显然得到了正确的投影矩阵 - 它有效。我怀疑经过眼睛后面的顶点有负 W,这意味着它们应该被剪裁;但我也怀疑它们的 Z 值为负,因此除法产生的 Z 值为正。如果您真的想剪裁几何图形,而不是丢弃整个三角形,请搜索“均匀剪裁”。如果您不是真正在 4D 同质空间中工作,您可以从查看“Sutherland-Hodgman”3D 剪裁开始。

于 2011-10-01T14:49:49.037 回答