在互联网上,我找到了一些TCS代码示例,其中gl_TessLevel*
变量仅针对一个输出补丁顶点设置
// first code snippet
if ( gl_InvocationID == 0 ) // set tessellation level, can do only for one vertex
{
gl_TessLevelOuter [0] = foo
gl_TessLevelOuter [1] = bar;
}
而不仅仅是
// second code snippet
gl_TessLevelOuter [0] = foo;
gl_TessLevelOuter [1] = bar;
在有条件检查和无条件检查的情况下它的工作方式类似,但我在OpenGL wiki上找不到任何关于此类用法的内容。
如果要逻辑思考,只在一个TCS调用中设置这些变量应该可以,并且根据gl_InvocationID
将它们设置为不同的值会很奇怪。所以我的问题是:
gl_TessLevel*
的方式是否正确,是否可能导致某些平台出现错误或崩溃?答案 0 :(得分:3)
你在这里看到的是着色器的作者试图建立一个类似于激发其他原始类型使用的顶点的约定。
OpenGL Shading Language 4.50 - 2.2曲面细分控制处理器 - p。 7
Tessellation控件着色器调用主要独立运行, 未定义相对执行顺序。 但是,内置函数
barrier()
可用于通过同步调用来控制执行顺序,从而有效地将细分控制着色器执行划分为一组阶段。如果一次调用在同一阶段中的任何时刻读取由另一个调用写入的每顶点或每个补丁属性,则曲面细分控制着色器将获得未定义结果,或 if两次调用尝试写不同的 在单个阶段中,每个补丁输出的值相同。
鉴于着色器伪代码,foo
和bar
在所有TCS调用中是否一致,目前还不清楚。如果不是,则第二个着色器片段由于未定义的相对排序而调用未定义的行为。
任意决定第一次调用是唯一允许编写每个补丁属性的解决方案,解决了这个问题,类似于第一个顶点激发约定。最后一个顶点约定可以很容易地实现,因为所有调用都知道补丁顶点的数量。
如果你知道foo
和bar
是不变的,那么这一切都不是必需的。