opengl 中的面部剔除是否发生在 window space 中?
Do Face culling in opengl happens in window space?
顶点 post 处理的输出值在 Window space,然后我们有原始组装和面剔除 stages.If 所以面剔除发生在 window space?
让我引用 OpenGL 4.6 core profile specification 第 1.2.3 节“什么是 OpenGL 图形系统?| 我们的观点”(重点是我的):
We view OpenGL as a pipeline having some programmable stages and some
statedriven fixed-function stages that are invoked by a set of
specific drawing operations. This model should engender a
specification that satisfies the needs of both programmers and
implementors. It does not, however, necessarily provide a model for
implementation. An implementation must produce results conforming to
those produced by the specified methods, but there may be ways to
carry out a particular computation that are more efficient than the
one specified.
这意味着如果实现与完全遵循逐字规范的实现获得的结果相同,则实现是符合标准的。
因此面部剔除的行为方式必须与您在 window space 中执行的方式相同。它显然有顶点着色器阶段,因为在那之前,顶点的最终坐标是未知的。(现在这里有一个有趣的旁注。这是iirc nvidia,它拥有关于将顶点着色器分成两部分:只计算 gl_Position
并且可以优化所有对它没有贡献的计算,一个用于其余输出。这将允许他们只进行裁剪和剔除执行了 VS 的 部分 。不确定他们是否真的在他们的驱动程序中采用了该策略,但专利在某处。然而,这是一个很好的例子,说明了真正的怪异技巧 -世界实现 可能 会。)
window space 中是否会进行人脸剔除?只有您的 OpenGL 实现者才能确定。但换个角度问:Can face culling to happen in clip space?
首先,让我们看看它是否可以在 标准化设备中发生 space:
显然,对于面剔除,只有三角形二维投影的缠绕顺序很重要,所以 z 无关紧要。当您从剪辑 space 转到 window space 时,这个方向不会改变,是吗?这里有一些观察:
- NDC 到 window space 的转换只是一个缩放和平移,它单独作用于每个组件,我们没有得到
x_win = A * x_ndc + B *y_ndc + c * z_ndc + D
形式的交叉影响,但是 B
和C
这里保证为0。
- 因此,从剪辑 space 到 window space 时翻转三角形方向的唯一方法是比例因子为负,并再次引用 GL 4.6 规范在
glViewport*()
函数系列上:“如果 w 或 h 为负,则会生成 INVALID_VALUE
错误”
这意味着面部剔除可以在 NDC 中完成,而无需考虑实际的视口参数。
可以在剪辑 space 中进行面部剔除吗?
- 任何点
w<0
永远无法满足裁剪条件 -w <= x,y,z <= w
,因此从裁剪 space 到 NDC 的 w 步除法只会发生在 w>0
所以永远不要翻转三角形。但这要求至少已经发生原始裁剪(考虑一个顶点位于相机后面,两个顶点位于相机前面的情况)。
- 然而,
w
坐标即使在裁剪后仍然很棘手。考虑这样一种情况,您站在天花板倾斜的房间里,直视前方的侧墙,但只能看到天花板的一部分。天花板上的三角形可能会导致以下裁剪 space 坐标 (-1,1,z_1,1)
、(1,1,z_2,1)
、(0,1.2,z_3,10)
(有一些 z_i
满足裁剪条件,实际值这里没关系)。如果你只取剪辑 space x
和 y
值(就像你在 window space 或 NDC 中所做的那样),你会看到一个二维投影由前两个顶点形成的线上方的第三个顶点。但在除以 w
之后,它会在 下方 ,并且三角形顺序被翻转(因为 w
每个顶点可能不同)。
那么这是否意味着在透视除以w
之前不能进行面部剔除?不,不一定。 也许有一些聪明的方法可以在分割之前在剪辑 space 中进行剔除,但无论哪种方式,剪辑 space w
坐标需要考虑不知何故.
所以我无法真正回答你的问题,但一般原则是实施者会尽可能早地尝试在管道中进行任何类型的剔除/丢弃步骤(在他们将拥有的所有工程限制范围内,当然)。
顶点 post 处理的输出值在 Window space,然后我们有原始组装和面剔除 stages.If 所以面剔除发生在 window space?
让我引用 OpenGL 4.6 core profile specification 第 1.2.3 节“什么是 OpenGL 图形系统?| 我们的观点”(重点是我的):
We view OpenGL as a pipeline having some programmable stages and some statedriven fixed-function stages that are invoked by a set of specific drawing operations. This model should engender a specification that satisfies the needs of both programmers and implementors. It does not, however, necessarily provide a model for implementation. An implementation must produce results conforming to those produced by the specified methods, but there may be ways to carry out a particular computation that are more efficient than the one specified.
这意味着如果实现与完全遵循逐字规范的实现获得的结果相同,则实现是符合标准的。
因此面部剔除的行为方式必须与您在 window space 中执行的方式相同。它显然有顶点着色器阶段,因为在那之前,顶点的最终坐标是未知的。(现在这里有一个有趣的旁注。这是iirc nvidia,它拥有关于将顶点着色器分成两部分:只计算 gl_Position
并且可以优化所有对它没有贡献的计算,一个用于其余输出。这将允许他们只进行裁剪和剔除执行了 VS 的 部分 。不确定他们是否真的在他们的驱动程序中采用了该策略,但专利在某处。然而,这是一个很好的例子,说明了真正的怪异技巧 -世界实现 可能 会。)
window space 中是否会进行人脸剔除?只有您的 OpenGL 实现者才能确定。但换个角度问:Can face culling to happen in clip space?
首先,让我们看看它是否可以在 标准化设备中发生 space:
显然,对于面剔除,只有三角形二维投影的缠绕顺序很重要,所以 z 无关紧要。当您从剪辑 space 转到 window space 时,这个方向不会改变,是吗?这里有一些观察:
- NDC 到 window space 的转换只是一个缩放和平移,它单独作用于每个组件,我们没有得到
x_win = A * x_ndc + B *y_ndc + c * z_ndc + D
形式的交叉影响,但是B
和C
这里保证为0。 - 因此,从剪辑 space 到 window space 时翻转三角形方向的唯一方法是比例因子为负,并再次引用 GL 4.6 规范在
glViewport*()
函数系列上:“如果 w 或 h 为负,则会生成INVALID_VALUE
错误”
这意味着面部剔除可以在 NDC 中完成,而无需考虑实际的视口参数。
可以在剪辑 space 中进行面部剔除吗?
- 任何点
w<0
永远无法满足裁剪条件-w <= x,y,z <= w
,因此从裁剪 space 到 NDC 的 w 步除法只会发生在w>0
所以永远不要翻转三角形。但这要求至少已经发生原始裁剪(考虑一个顶点位于相机后面,两个顶点位于相机前面的情况)。 - 然而,
w
坐标即使在裁剪后仍然很棘手。考虑这样一种情况,您站在天花板倾斜的房间里,直视前方的侧墙,但只能看到天花板的一部分。天花板上的三角形可能会导致以下裁剪 space 坐标(-1,1,z_1,1)
、(1,1,z_2,1)
、(0,1.2,z_3,10)
(有一些z_i
满足裁剪条件,实际值这里没关系)。如果你只取剪辑 spacex
和y
值(就像你在 window space 或 NDC 中所做的那样),你会看到一个二维投影由前两个顶点形成的线上方的第三个顶点。但在除以w
之后,它会在 下方 ,并且三角形顺序被翻转(因为w
每个顶点可能不同)。
那么这是否意味着在透视除以w
之前不能进行面部剔除?不,不一定。 也许有一些聪明的方法可以在分割之前在剪辑 space 中进行剔除,但无论哪种方式,剪辑 space w
坐标需要考虑不知何故.
所以我无法真正回答你的问题,但一般原则是实施者会尽可能早地尝试在管道中进行任何类型的剔除/丢弃步骤(在他们将拥有的所有工程限制范围内,当然)。