在图形管道中的哪个阶段执行裁剪?

At what stage is clipping performed in the graphics pipeline?

出于学习目的,我正在用 C++ 编写一个软渲染器,但我遇到了一些障碍。我不知道我是否遗漏了什么,但我不确定何时进行剪裁。一些消息来源谈到它发生在剪辑 space 中,在应用透视投影矩阵之后但在透视分割之前(所以仍然在 3D space 中)。其他消息来源谈到使用诸如 Cohen-Sutherland 线裁剪算法之类的算法在 2D space(在透视划分之后)中执行它。如果我应该在 3D 中剪辑 space 那么深度缓冲区是否仅用于决定以什么顺序栅格化对象,或者我必须在 2D 中剪辑但还要防止 z 缓冲区中超过 -1 的点的栅格化?

基本上,这方面的资料不是很清楚,我也没有真正看到如何在同质剪辑中剪辑space。据说你应该做,但没有人告诉你怎么做。

剪辑在 Vertex Post-Processing stage in the Rendering Pipeline 中完成。

基元被裁剪到视图体积,具体取决于 homogeneous clip-space position of its vertices (gl_Position), before the perspective divide。裁剪规则为:

-w <=  x, y, z  <= w.

有关详细信息,请参阅 OpenGL 4.6 API Core Profile Specification - 13.7 Primitive Clipping

Some sources talk about it happening in clip space after the perspective projection matrix is applied but before the perspective divide (so still in 3D space). Other sources talk about performing it in 2D space (after the perspective divide) with an algorithm such as the Cohen-Sutherland line clipping

传统的裁剪算法,如 Cohen-Sutherland 线裁剪或 Sutherland-Hodgman 多边形裁剪可能在 2D 中描述,但它们原则上也适用于 3D。

Basically, the information on this is not very clear and I haven't actually seen how one can actually clip in homogeneous clip space. It is said that you should do it but nobody shows how.

从齐次space和裁剪条件-w <= x,y,z <= w的定义自然可以得出。考虑剪裁一条直线段 AB(而多边形剪裁基本上可以实现为在多边形边缘上进行一系列线剪裁)。 Cohen-Sutherland 线裁剪算法简单地扩展到齐次 space,您只需应用 -ww 作为每个维度中查看体积的边界。对于实际的交点计算,我们需要搜索一个新的齐次点C =(C_x, C_y, C_z, C_w)^T,使得C位于AB上的交平面上,所以我们需要为

找到一个t
C = t * A + (1-t) * B

假设我们要裁剪近平面,即 z = -w

要使 C 位于该平面上,则遵循 C_z = -C_w。这给我们留下了一个简单的线性方程组:

C_x = t * A_x + (1-t) * B_x
C_y = t * A_y + (1-t) * B_y
C_z = t * A_z + (1-t) * B_z = -t * A_w - (1-t)*B_w
C_w = t * A_w + (1-t) * B_w 

根据 C_z 的等式,如果满足:

t = (B_z + B_w) / ( (B_z + B_w) - (A_z + A_w))

另请注意,此 t 也可用于为 C 插值所有关联的顶点属性。即使在透视扭曲的情况下,线性插值也完全足够,因为我们在此处进行透视划分之前,整个透视变换是完全仿射的。我们工作的 4D space。