4
layout (vertices = 3) out;

void main(void)
{
    if (gl_InvocationID == 0)
    {
        gl_TessLevelInner[0] = 5.0;
        gl_TessLevelOuter[0] = 5.0;
        gl_TessLevelOuter[1] = 5.0;
        gl_TessLevelOuter[2] = 5.0;
    }
    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
}

摘自:Haemel,尼古拉斯。“OpenGL 超级圣经:

我如何理解 TessLevelInner 和 Outer 以及为什么 id 0 被列出两次?

4

2 回答 2

16

我怎么能理解gl_TessLevelInnergl_TessLevelOuter

请参阅: gl_TessLevelInner, gl_TessLevelOuter, OpenGL Tessellation - Levels

正如它们的名字所暗示的那样,它们控制正在处理的基元的内部和外部细分因子级别。下图显示了各种内部/外部级别设置的结果。

在此处输入图像描述 来源:http ://antongerdelan.net/opengl/tessellation.html


为什么索引0使用了两次?

它被使用了两次,因为它正在访问两个不同的对象。索引的第一个用途0

gl_TessLevelInner[0]

第二个是

gl_TessLevelOuter[0]
于 2014-06-06T19:24:33.500 回答
2

对于三角形,前三个“外部”gl_TessLevelOuter[] 镶嵌值中的每一个都控制三角形三个边之一的细分,第四个值未使用。

仅使用第一个“内部”gl_TessLevelInner[0] 值来确定内部三角形的细分。这个内在层次比外在层次更令人困惑,所以看一张图片总比试图解释它好。

这是与已接受答案类似的图像,但内部值行标签已更正,并且您可以使用一个程序来试验自己的值。

已接受答案上的图像源链接目前已损坏(2019 年 5 月)。再加上标有“Inner Tesselation Factor”的行减一。第一行的内部镶嵌值实际上为零。

三角形镶嵌矩阵

用于创建上述图像的 Python 程序:

import inspect, glfw, numpy
from OpenGL.GL import *
from OpenGL.GL import shaders

glfw.init()
tile_size, tile_count = 80, 8
width = tile_size * tile_count
glfw.window_hint(glfw.SAMPLES, 16)
window = glfw.create_window(width, width, 'tessellation demo', None, None)
glfw.make_context_current(window)
glBindVertexArray(glGenVertexArrays(1))
triangle = numpy.array([
    [-0.9, -0.9, 0.5],  # lower left
    [ 0.9, -0.9, 0.5],  # lower right
    [ 0.0,  0.9, 0.5],  # top
], dtype=numpy.float32)
glBindBuffer(GL_ARRAY_BUFFER, glGenBuffers(1))
glBufferData(GL_ARRAY_BUFFER, triangle, GL_STATIC_DRAW)
glEnableVertexAttribArray(0)
glVertexAttribPointer(index=0, size=3, type=GL_FLOAT, normalized=False, stride=0, pointer=None)
program = shaders.compileProgram(
    shaders.compileShader(source=inspect.cleandoc('''
        #version 460 core
        in vec3 aPos;
        void main() {
            gl_Position = vec4(aPos, 1);
        }
    '''), shaderType=GL_VERTEX_SHADER),
    # Tessellation control shader not defined here because default is OK.
    shaders.compileShader(source=inspect.cleandoc('''
        #version 460 core
        layout(triangles) in;
        void main() {
            gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position) +
                          (gl_TessCoord.y * gl_in[1].gl_Position) +
                          (gl_TessCoord.z * gl_in[2].gl_Position);
        }
    '''), shaderType=GL_TESS_EVALUATION_SHADER),
    shaders.compileShader(source=inspect.cleandoc('''
        #version 460 core
        out vec4 fragColor;
        void main() {
            fragColor = vec4(vec3(0.1), 1);  // dark gray
        }
    '''), shaderType=GL_FRAGMENT_SHADER),)
glUseProgram(program)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
glPatchParameteri(GL_PATCH_VERTICES, 3)
glClearColor(0.95, 0.95, 0.95, 1)  # pale gray
outer_levels = numpy.array([1, 1, 1, 1], dtype=numpy.float32)
inner_levels = numpy.array([1, 1], dtype=numpy.float32)
while not glfw.window_should_close(window):
    glClear(GL_COLOR_BUFFER_BIT)
    for outer in range(tile_count + 1):  # increase outer tessellation factors left to right
        for inner in range(tile_count + 1):  # inner tesselation factors top to bottom
            glViewport(outer * tile_size, width - inner * tile_size, tile_size, tile_size)
            outer_levels[:] = [outer + 1] * 4  # range 1 to 9; zero means no triangles at all
            inner_levels[:] = [inner] * 2  # range 0 to 8
            glPatchParameterfv(GL_PATCH_DEFAULT_OUTER_LEVEL, outer_levels)
            glPatchParameterfv(GL_PATCH_DEFAULT_INNER_LEVEL, inner_levels)
            glDrawArrays(GL_PATCHES, 0, 3)
    glfw.swap_buffers(window)
    glfw.poll_events()
glfw.terminate()
于 2019-05-14T00:20:52.683 回答