我使用实例渲染来绘制大量的立方体。现在,显然立方体中可见面的最大数量是3,这意味着就着色而言,我所做的工作量是所需的两倍。
因为这是实例化,所以我不能简单地只传递要绘制到着色器的几何体。但如果在着色器中(我想这将是几何或细分)我可以使用普通信息来丢弃一个原语,我可以减少不必要的操作次数。
例如,如果观察方向与表面法线之间的角度小于90度,我可以假设当前方向前面有一个三角形,因此丢弃了这个给定的原语。
管道中是否有一种方法可以确定是否需要片段并相应地丢弃它?
答案 0 :(得分:5)
在回答问题之前,让我先解决您的实际问题:使用back-face culling。为每个立方体的三角形赋予一致的顺序,这样当从正面看时,屏幕空间中面部的排序将是单向的,但是当从后面看时,顺序将是另一个。你选择的是一个由你决定的约定,但选择一个并保持一致。
然后使用glFrontFace
告诉OpenGL哪个约定是"前面"为你,并使用glEnable(GL_CULL_FACE)
和glCullFace(GL_BACK)
告诉OpenGL剔除后向三角形。
这种剔除是作为原始装配的一部分发生的,因此它已经过了vertex processing和post-processing。
这就是你真正需要做的。哦,当然,你仍然会在三角形上花费多达一半的顶点处理,但是如果你想要剔除它们,你仍然需要花时间弄清楚你是否想要剔除它们。请记住:GPU在锁定步骤中执行着色器调用。由于条件操作而剔除三角形/面/任何事情并不总能使任何事情更快,因为这些调用仍将继续执行。他们的结果将被抛弃。
面部剔除远比你能编码的任何东西都高效。
现在,让我们回答实际问题:基于着色器的剔除有哪些选择?
您无法从顶点着色器中丢弃顶点。基元是基于特定的顶点数(GL_TRIANGLES
意味着每组3个顶点都是一个三角形),因此如果顶点被杀死,那么它将如何起作用。
您可以使用用户定义的剔除输出变量来仅从顶点着色器中剔除三角形。这类似于user-defined clipping planes,其中顶点着色器提供特殊的数字输出。对于削波,如果内插输出为正,则三角形的该部分是可见的;当插值变为负值时,三角形的那部分通过削波变得不可见。
使用用户定义的剔除平面,如果特定基元的任何顶点具有剔除的负值,则整个基元被剔除。这允许一个着色器调用通过给出负的剔除值来选择剔除它所处的原语。
细分控制着色器可以放弃修补程序。如果补丁的TCS导致zero value for any of the outer tessellation levels,则他们正在处理的补丁将被曲面细分原语生成器剔除。
几何着色器当然可以完全不输出基元。