1

我正在向管道发送一个三角形,并希望将其镶嵌到一个 sierpinski 垫圈中。感觉使用几何着色器的实例化会容易得多,因此请告诉我使用曲面细分着色器的想法是否完全错误。

在镶嵌控制期间,我检查 ID0-11并将顶点位置和颜色存储在当前 ID 的位置上。

我为我的镶嵌控制着色器定义glPatchParameteri(GL_PATCH_VERTICES, 3);layout(vertices = 12) out;,因为我希望将每个三角形镶嵌成 4 个三角形。

看起来在我的镶嵌评估着色器中,in vec3 tcPosition[];in vec3 tcColor[];数组包含12正确顺序的正确值。但是:如何在评估过程中正确关联它们?gl_primitiveID在镶嵌评估期间有什么类似的吗?我需要替换所有生成的顶点,因为它们是从同一个补丁中产生的gl_primitiveID0目前我只使用前三个顶点(0, 1, 2)的信息,但我需要在每个生成的三角形之后将这些索引移动 3。

void main(){
    vec3 p0 = gl_TessCoord.x * tcPosition[0];
    vec3 p1 = gl_TessCoord.y * tcPosition[1];
    vec3 p2 = gl_TessCoord.z * tcPosition[2];
    tePosition = p0 + p1 + p2;
    teColor = gl_TessCoord.x * tcColor[0] + gl_TessCoord.y * tcColor[1] + gl_TessCoord.z * tcColor[2]; 
    gl_Position = mvp * vec4(tePosition, 1);
} 

非常感谢任何如何巧妙地镶嵌三角形以便我以后能够使用变换反馈进行乒乓渲染的见解或想法。

4

1 回答 1

1

我正在向管道发送一个三角形,并希望将其镶嵌到一个 sierpinski 垫圈中。

停止。你不能这样做。

三角形镶嵌不是以允许您生成它的方式完成的。细分所需的特定细分算法旨在使边缘易于连接。它还旨在使自适应和平滑的镶嵌成为可能。

谢尔宾斯基三角形没有这些性质。

如果您需要对细分的确切方法进行如此严格的控制,我建议您在 CPU 上进行细分。GS 无法将三角形细分得足够精细;大多数 OpenGL 实现不允许 GS 输出那么多三角形,即使使用几何着色器实例化也是如此。

至于你的问题的细节:

我定义glPatchParameteri(GL_PATCH_VERTICES, 3);和布局(顶点= 12);对于我的镶嵌控制着色器,因为我希望每个三角形镶嵌成 4 个三角形。

这不是镶嵌的工作方式。

到达曲面细分图元生成器(TCS 之后的步骤)的每个补丁,无论它有多少顶点,都被认为是一个要细分的图元。您的 TCS 在这里输出一个补丁中的 12 个顶点,但补丁本身仍然是一个三角形。

允许您控制顶点的数量允许您定义“顶点”对您的细分算法意味着什么。例如,一个贝塞尔曲面有 16 个控制点顶点,但它仍然是一个四边形。这允许基于 Bezier 的 TES 在生成顶点位置时将所有 16 个控制点作为输入。

此外,基于询问您获得多少个三角形,曲面细分不起作用。它的工作原理取决于您想要多少细分。这就是外部和内部细分级别定义的内容:三角形边缘将被细分为的段数。

但是:如何在评估过程中正确关联它们?

TES 的输入与 TCS 写入的值相同。以相同的顺序。

镶嵌的工作方式是镶嵌的不是TCS 写入的顶点。被镶嵌的是一个抽象的补丁。镶嵌图元生成器相对于抽象补丁生成“顶点”。

gl_TessCoord使您可以检测特定 TES 调用抽象补丁中的位置。然后将其与 TCS 的输出数据(TES 的输入)结合起来,生成该坐标所需的每个顶点值。

我需要替换 gl_primitiveID ,因为它们是从同一个补丁中生成的,所以所有生成的顶点都为 0。

它已经这样做了。gl_PrimitiveID对于单个补丁中的每个 TES 调用将是相同的。

于 2016-06-18T20:45:00.500 回答