曲面细分着色器 - OpenGL

问题描述 投票:0回答:2
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,Nicholas。 《OpenGL超级圣经》:

我如何理解

TessLevelInner
TessLevelOuter
以及为什么id 0被列出两次?

opengl tessellation
2个回答
17
投票

如何理解

gl_TessLevelInner
gl_TessLevelOuter

请参阅:

gl_TessLevelInner
gl_TessLevelOuter
OpenGL 曲面细分 - 级别

顾名思义,它们控制正在处理的图元的内部和外部曲面细分因子级别。下面的图像说明了各种内部/外部级别设置的结果。

enter image description here 资料来源:http://antongerdelan.net/opengl/tessellation.html


为什么索引

0
使用了两次?

它被使用两次,因为它访问两个不同的对象。索引

0
的第一次使用是 with

gl_TessLevelInner[0]

第二个是

gl_TessLevelOuter[0]

2
投票

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

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

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

已接受答案上的图像源链接目前已损坏(2019 年 5 月)。另外,标记为“内部曲面细分因子”的行减少了一位。第一行的内部镶嵌值实际上为零。

用于创建上述图像的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()
© www.soinside.com 2019 - 2024. All rights reserved.