我正在向管道输送一个三角形,并希望将其镶嵌成sierpinski垫圈。通过几何着色器的实例化,感觉这会更容易,因此请告诉我使用曲面细分着色器进行操作的想法是否完全错误。
在曲面细分控制期间,我会针对0-11
检查ID,并将顶点位置和颜色存储在当前ID的位置。
我为我的tesselation控件着色器定义了glPatchParameteri(GL_PATCH_VERTICES, 3);
和layout(vertices = 12) out;
,因为我想将每个三角形镶嵌成4个三角形。
在我的细分评估着色器中,in vec3 tcPosition[];
和in vec3 tcColor[];
数组在正确的顺序中包含正确的12
值。但是:如何在评估期间正确关联它们?曲面细分评估期间是否有类似gl_primitiveID
的内容?对于所有生成的顶点,我需要替换gl_primitiveID
0
,因为它们是从同一个补丁中生成的。目前我只使用前三个顶点(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);
}
如何巧妙地细分三角形,以便我以后能够使用变换反馈进行乒乓球渲染的任何见解或想法都受到高度赞赏。
答案 0 :(得分:1)
我正在管道中发送一个三角形,并希望将其镶嵌成sierpinski垫圈。
停止。你不能这样做。
三角曲面细分没有以允许您生成它的方式完成。 particular tessellation algorithm required for tessellation旨在让边缘更容易连接。它还可以实现自适应和平滑的镶嵌。
Sierpinski triangles没有这些属性。
如果您需要严格控制曲面细分的确切方法,我建议您在CPU上进行曲面细分。一个GS将无法精确地镶嵌三角形;大多数OpenGL实现都不允许GS输出那么多三角形,即使使用geometry shader instancing。
关于你问题的细节:
我定义
glPatchParameteri(GL_PATCH_VERTICES, 3);
和布局(顶点= 12);对于我的tesselation控件着色器,因为我想将每个三角形镶嵌成4个三角形。
这不是曲面细分的工作原理。
每个到达tessellation primitive generator的补丁(TCS之后的步骤),无论它有多少个顶点,都被认为是要进行细分的单个基元。你的TCS在补丁中输出12个顶点,但补丁本身仍然是一个三角形。
允许您控制顶点数量,可以定义“顶点”对于曲面细分算法的含义。例如,Bezier曲面有16个控制点顶点,但它仍然是四边形。这允许基于Bezier的TES在生成顶点位置时将所有16个控制点作为输入。
此外,根据询问您获得了多少三角形,曲面细分不起作用。它的工作原理基于你想要多少细分。这就是外部和内部曲面细分级别定义的内容:三角形边缘将被细分为的段数。
但是:如何在评估期间正确关联它们?
TES的输入是TCS编写的相同的值。按照相同的顺序。
曲面细分的工作方式是,镶嵌的内容不是由TCS编写的您的顶点。被镶嵌的是abstract patch。曲面细分原语生成器生成关于抽象补丁的“顶点”。
gl_TessCoord
允许您检测抽象补丁中在内的特定TES调用的位置。然后将其与TCS的输出数据(它们是TES的输入)组合,以生成该坐标所需的每顶点值。
我需要替换gl_primitiveID,它对于所有生成的顶点都是0,因为它们是从同一个补丁生成的。
它已经这样做了。 gl_PrimitiveID
对于单个补丁中的每个TES调用都是相同的。