GLSL 曲面细分着色器为每个面片以不同方向绘制三角形

问题描述 投票:0回答:1

我正在使用曲面细分着色器和补丁在 OpenGL 上构建一个简单的地形,但我在 OpenGL 如何绘制这些补丁方面遇到了麻烦。 OpenGL 生成的三角形对于每个面片以不同的方向绘制,如图所示。

Difference between triangles of neighbour patches

Overview of different patches

我想知道是否有一个简单的方法来解决这个问题,例如使用一些OpenGL内置参数,或者需要手动重新调整三角形的方向。

我正在使用 OpenGL 4.0。我总共创建了 8 个补丁,我的 tessLevel 设置为 64。

目前,我的代码如下所示:

曲面细分控制着色器

#version 400

layout (vertices = 4) out;

uniform int tessLevel;
#define ID gl_InvocationID

void Preset();

void main()
{
    gl_out[ID].gl_Position = gl_in[ID].gl_Position;

    if (ID == 0)
    {
        Preset();
    }
}

void Preset()
{
    gl_TessLevelOuter[0] = tessLevel;
    gl_TessLevelOuter[1] = tessLevel;
    gl_TessLevelOuter[2] = tessLevel;
    gl_TessLevelOuter[3] = tessLevel;

    gl_TessLevelInner[0] = tessLevel;
    gl_TessLevelInner[1] = tessLevel;
}

曲面细分评估着色器

#version 400

layout(quads, equal_spacing, cw) in;

uniform vec3 lightPos;
out vec3 tesLightDirection;

vec4 CalculateInterpolatedPosition(float u, float v);

void main()
{
    float u = gl_TessCoord.x;
    float v = gl_TessCoord.y;

    vec4 interpolatedPosition = CalculateInterpolatedPosition(u, v);
    tesLightDirection = normalize(lightPos - interpolatedPosition.xyz);

    gl_Position = interpolatedPosition;
}

vec4 CalculateInterpolatedPosition(float u, float v)
{
    vec4 p0 = gl_in[0].gl_Position;
    vec4 p1 = gl_in[1].gl_Position;
    vec4 p2 = gl_in[2].gl_Position;
    vec4 p3 = gl_in[3].gl_Position;

    return  p0 * (1 - u) * (1 - v) +
            p1 * u * (1 - v) +
            p3 * v * (1 - u) +
            p2 * u * v;
}

我的补丁是通过以下方式在我的 C++ 程序中构建的:

void Terrain::GenerateVertices()
{
    for (int i = 0; i < totalPatches + 1; i++)
    {
        for (int j = 0; j < totalPatches + 1; j++)
        {
            vertices.push_back(vec3(j, 0, i));
        }
    }

    for (int i = 0; i < totalPatches; i++)
    {
        for (int j = 0; j < totalPatches; j++)
        {
            int startingPoint = i * (totalPatches + 1) + j;

            indices.push_back(startingPoint);
            indices.push_back(startingPoint + 1);
            indices.push_back(startingPoint + totalPatches + 2);
            indices.push_back(startingPoint + totalPatches + 1);
        }
    }
}

void Terrain::Render(mat4 projection, mat4 view)
{
    shader.use();
    mat4 VPMatrix = projection * view;

    shader.setUniform("VP", VPMatrix);
    shader.setUniform("M", transform.modelMatrix());

    glBindVertexArray(vaoID);
    glPatchParameteri(GL_PATCH_VERTICES, 4);
    glDrawElements(GL_PATCHES, indices.size(), GL_UNSIGNED_INT, (GLubyte*)NULL);
    glBindVertexArray(0);
}
c++ opengl glsl tesselation gl-triangle-strip
1个回答
0
投票

您无法控制网格的三角测量。关于三角测量的工作原理有一些基本保证,但除此之外,这取决于实现。因此,无论您在镶嵌器中做什么,都需要能够使用any(合理的)三角测量。

© www.soinside.com 2019 - 2024. All rights reserved.