GLSL曲面细分控制着色器使用gl_InvocationID索引gl_TessLevelOuter

时间:2014-10-13 18:15:16

标签: opengl glsl tessellation

为什么以下曲面细分控制着色器会使大多数三角形消失?

#version 410

layout(vertices = 3) out;

void main(void) {
    gl_TessLevelInner[0]=1;
    gl_TessLevelOuter[gl_InvocationID]=gl_InvocationID+1;
    gl_TessLevelOuter[gl_InvocationID]=gl_InvocationID+1;
    gl_TessLevelOuter[gl_InvocationID]=gl_InvocationID+1;
}

我输入三角形。当我用0,1和2索引gl_TessLevelOuter时,一切正常。 在我看来,这个构造为我节省了if语句,我认为这有助于并行执行着色器。 当然,我在代码段中省略了顶点计算。

3 个答案:

答案 0 :(得分:3)

三角形消失,因为你在"未定义"行为,这就是它。内部细分级别应至少为2。

gl_TessLevelInner[0] = 2;

您获得的奇怪结果是因为当内部等级为1时计算出中心坐标。如果您提供至少2作为值,则可以使用任何您想要的Outerlevels值。

以下是三角形的边缘关联

out0 => edge 1-2
out1 => edge 2-3
out2 => edge 3-1

Tessellated triangle "fan"

Out[0] = 4
Out[1] = 1
Out[2] = 2

如你所见,2的Inner沿三角形的平分线切割三角形两次,而3个不同的Outer级别沿边缘切割三角形(1没有切割2 1}},4两次,值if(gl_InvocationID==0){ gl_TessLevelInner[0] = 2; //take a triangle gl_TessLevelOuter[0] = 1; //and subdivde it in 3 triangles gl_TessLevelOuter[1] = 1; gl_TessLevelOuter[2] = 1; } gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position; 时4件

<强>提示:

还有一些小建议,曲面细分控制中的数据是共享的,这意味着它被多次调用,您只需要设置曲面细分控制一次:

if(gl_InvocationID==0){
    gl_TessLevelInner[0] = 2; //take a triangle
    gl_TessLevelOuter[0] = lenghtOnScreen<5? 3: 4;
}

if(gl_InvocationID==1)
    gl_TessLevelOuter[1] = lenghtOnScreen<5? 3: 4;

if(gl_InvocationID==2)
    gl_TessLevelOuter[2] = lenghtOnScreen<5? 3: 4;

gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;

那么为什么仍然可以为每次调用设置不同的值?根据屏幕错误添加细分(至少是合理使用)。

Inner=3

最后:

Outer=2和{{1}}的另一个例子。

Tessellated triangle

请注意沿着平分线的3个切口和沿着边缘的2个切口,所有其他切口仅用于&#34;无缝过渡&#34;

答案 1 :(得分:2)

接受的答案不正确。您可以指定内部级别1.如果所有外部级别也为1,则不会进行细分(三角形将保持不变)。如果内部是1并且至少一个外部> 1,则内部将有效地为2或3(取决于间距),确保内部区域中至少1个点。

OP代码的实际问题是它将 1 外层设置为3次,而不是设置所有3个外层。另外2个默认为0,导致补丁被丢弃。 就是三角形消失的原因。

参考:https://www.opengl.org/wiki/Tessellation

答案 2 :(得分:-2)

因为你正在使用三角形,你可以给外部的mininmum是3,所以,在你的情况下你将索引0设置为1和1到2和2到3,但是当你将它们加到0时, 1,2,它将作为最终值得到gl_InvocationID = 2 + 1 = 3,因此你可以节省一天的时间,如果你这样做它应该有效:

void main(void) {
    gl_TessLevelOuter[gl_InvocationID] = 3;
    gl_TessLevelInner[0] = max(gl_TessLevelInner[0], gl_TessLevelOuter[gl_InvocationID]); // that is a bonus =D
}