几年前,我尝试在OpenGL中实现此GPU Gem,以使用Marching Cubes生成3D程序地形。本文建议在几何着色器中实现Marching Cubes,以实现最大效率。这意味着我需要为域中的每个体素运行一次着色器,它将在该单元格中生成整个几何。

我偶然遇到的一个问题是如何使几何着色器在不运行的情况下运行实际上有任何要在该着色器之外渲染的东西。我的解决方案(似乎很棘手)是在每个单元格中渲染一个点,用几何着色器将其丢弃,然后发射我的三角形。我从未找到合适的解决方案,并且此解决方法仍保留在最终代码中。

因此,是否有任何办法告诉OpenGL从没有任何输入几何的几何着色器开始渲染过程?还是我总是必须向GPU发送一些虚拟点才能使事情运行。

#1 楼

不,实际上没有办法。

几何着色器调用需要一个输入图元并生成0个或多个输出图元。没有输入原语,实际上就没有办法真正调用几何着色器。当然,您可以为每个输入图元拉伸几何着色器的最大输出图元数限制(目前尚不知道实际的限制,可能应该在数千个左右)。因此,您可能可以为每个点生成1024个三角形,但始终必须有一些输入图元。

但是,您不需要的是几何的实际概念。您实际上不必在任何合理的位置渲染3D点,它们也可以只具有一些抽象索引或纹理坐标或诸如属性之类的东西,而不一定具有有意义的3D位置。没有人指出您的顶点具有哪些属性。您甚至可以渲染没有任何属性的顶点。但是,即使这些图元没有任何实际属性,您也必须渲染一些图元以在其上调用几何着色器(不过,如何在几何着色器中计算输出几何是一个不同的问题)。

但是您实际上所做的就是为每个网格单元绘制一个点并根据该网格为该单元生成行进立方体三角形,这是简单明了的方法。当然,此单元格包含的属性取决于您,它可以是3D位置,也可以是将texcoord转换为3D纹理,无论如何,但是这些是您渲染的网格单元。纯粹从语义上讲,您实际上并没有“丢弃”这些点,而是用三角形“替换”它们,而是将每个点“转换”为一组三角形。这正是几何着色器的用途,并且没有任何“ hacky”或“不合适”的地方。没有人说几何着色器必须生成与输入相同的输出基本类型,才能“正确”。


您可以通过绘制一组无属性的点来实现大致上无需输入的渲染体素网格的方法(而这可能正是您真正要的)。这意味着您根本不需要任何属性数组,只需禁用所有属性数组,然后调用具有所需单元格数量的简单glDrawArrays。然后,在顶点着色器或几何着色器中,您可以根据输入的顶点ID(即gl_VertexID,这是您仅有的信息),通过一点索引魔术生成必要的3D网格单元索引,然后从查找中计算行进立方体的几何进入3D体积纹理(或任何数据结构)中。

因此,回想起来,我应该从一开始就重申我的陈述:您不能在没有任何输入基元的情况下生成基元,但可以在没有任何输入基元的情况下生成它们输入几何。