【发布时间】:2021-05-11 22:43:41
【问题描述】:
Vertex后处理的输出值在窗口空间,然后我们有原始组装和Face culling阶段。如果是Face culling发生在窗口空间?
【问题讨论】:
-
@Rabbid:谢谢..为什么它发生在窗口空间,而不是在剪辑空间。?任何优势。
标签: opengl graphics opengl-es gpu
Vertex后处理的输出值在窗口空间,然后我们有原始组装和Face culling阶段。如果是Face culling发生在窗口空间?
【问题讨论】:
标签: opengl graphics opengl-es gpu
让我引用OpenGL 4.6 core profile specification,第 1.2.3 节“什么是 OpenGL 图形系统?|我们的观点”(强调我的观点):
我们将 OpenGL 视为具有一些可编程阶段和一些 由一组调用的状态驱动的固定功能阶段 具体的绘图操作。这个模型应该产生一个 满足程序员和需求的规范 实施者。 但是,它不一定提供一个模型 执行。实现必须产生符合以下条件的结果 那些由指定的方法产生的,但可能有一些方法可以 执行比计算更有效的特定计算 一个指定的。
这意味着,如果实现与完全遵循规范的实现所获得的结果相同,则实现是一致的。
因此,面部剔除的行为方式必须与您在窗口空间中执行的方式相同。它显然有顶点着色器阶段,因为在此之前,顶点的最终坐标是未知的。(现在这里有一个有趣的旁注。它是iirc nvidia,它拥有分割顶点的专利着色器分为两部分:仅计算 gl_Position 并且可以优化所有对您没有贡献的计算,以及其余的输出。这将允许他们只使用 部分进行裁剪和剔除 的 VS 已执行。不确定他们是否真的在他们的驱动程序中采用了该策略,但该专利在某处。然而,这是一个很好的例子,说明了现实世界的实现可能会有哪些奇怪的技巧 em> 做。)
那么人脸剔除是否发生在窗口空间中?只有您的 OpenGL 实现者才能确定。但是换个角度说:可以在剪辑空间中实现人脸剔除吗?
首先,让我们看看它是否可以发生在规范化的设备空间:
显然,对于面部剔除,只有三角形二维投影的缠绕顺序很重要,所以 z 无关紧要。当您从剪辑空间转到窗口空间时,这个方向不会改变,或者是吗?这里有一些观察:
x_win = A * x_ndc + B *y_ndc + c * z_ndc + D 形式的交叉影响,但B 和C 在这里保证为0 .glViewport*() 函数系列中再次引用 GL 4.6 规范:“INVALID_VALUE 错误如果 w 或 h 为负数,则生成"这意味着面部剔除可以在 NDC 中完成,而无需考虑实际的视口参数。
人脸剔除可以发生在剪辑空间中吗?
w<0 永远无法满足剪裁条件-w <= x,y,z <= w,因此从剪裁空间到NDC 的w 步除只会发生在w>0 上,因此永远不要翻转三角形。但这要求至少已经发生了原始裁剪(考虑一个顶点位于相机后面,两个位于相机前面的情况)。w 坐标即使在剪裁之后仍然很棘手。考虑这样一种情况,你站在一个天花板倾斜的房间里,直视一侧的墙壁,但只能看到天花板的一部分。天花板上的三角形可能会导致以下剪辑空间坐标(-1,1,z_1,1)、(1,1,z_2,1)、(0,1.2,z_3,10)(其中一些z_is 满足剪辑条件,实际值在这里无关紧要)。如果您只获取剪辑空间x 和y 值(就像您在窗口空间或NDC 中所做的那样),您会看到一个2D 投影,其中第三个顶点位于前两个顶点形成的线上方。但除以w 之后,它会在下方,并且三角形顺序会翻转(因为w 可以每个顶点有所不同)。那么这是否意味着在透视除以w之前无法进行人脸剔除?不,不一定。 也许有一些聪明的方法可以在分割之前在剪辑空间中进行剔除,但无论哪种方式,剪辑空间w坐标需要以某种方式考虑到 。
所以我不能真正回答你的问题,但一般原则是实施者尽可能早地尝试在管道中执行任何类型的剔除/丢弃步骤(当然,在他们将拥有的所有大量工程限制范围内)。
【讨论】: