【问题标题】:Calculating the X and Z position of a vertex (within a mesh) using gl_VertexID使用 gl_VertexID 计算顶点(在网格内)的 X 和 Z 位置
【发布时间】:2019-11-14 00:57:05
【问题描述】:

我正在尝试生成 3D 地形。我的目标是将顶点的高度传递给顶点着色器,并使用gl_VertexID 从顶点着色器中计算 x 和 z 位置。顶点在 x 和 z 轴上相距 1。这是顶点着色器:

#version 330 core

uniform mat4 projection;
uniform mat4 view;
uniform mat4 world;

layout(location = 0) in float height;

// vertex offset; position of vertex relative to the top left corner of square
const vec2 offset[6] = vec2[](
    vec2(0, 0), // top left
    vec2(0, 1), // bottom left
    vec2(1, 1), // bottom right
    vec2(1, 1), // bottom right
    vec2(0, 0), // top left
    vec2(1, 0)  // top right
);

void main() {
    // index of square
    int squareIndex = gl_VertexID / 6;
    // index of vertex within square
    int vertexIndex = gl_VertexID % 6;

    // xz position of vertex
    vec2 position = offset[vertexIndex] + vec2(squareIndex % LENGTH, squareIndex / LENGTH);

    gl_Position = projection * view * world * vec4(position.x, height, position.y, 1.0f);
}

三角形从左到右,从上到下绘制。这是 EBO 的生成:

for(unsigned int xSquare = 0; xSquare < LENGTH; xSquare++) {
   for(unsigned int zSquare = 0; zSquare < LENGTH; zSquare++) {
      size_t squareIndex = zSquare * LENGTH + xSquare;
      unsigned int topLeft = squareIndex;
      unsigned int topRight = squareIndex + 1;
      unsigned int bottomLeft = squareIndex + LENGTH;
      unsigned int bottomRight = squareIndex + LENGTH + 1;
      elements[squareIndex] = topLeft;
      elements[squareIndex + 1] = bottomLeft;
      elements[squareIndex + 2] = bottomRight;
      elements[squareIndex + 3] = bottomRight;
      elements[squareIndex + 4] = topLeft;
      elements[squareIndex + 5] = topRight;
   }
}

我已经使用 qrenderdoc 检查了顶点数据输入,并且高度正在正确地传递给顶点着色器。然而, the rendered output looks like this.

我已经检查了顶点着色器逻辑,但没有发现任何问题。有谁知道我做错了什么?

【问题讨论】:

    标签: c++ opengl glsl


    【解决方案1】:

    注意不要将索引缓冲区(有时称为元素缓冲区)与顶点缓冲区混淆。请注意,gl_VertexID 是“顶点的索引”,而不是“索引的索引”。您的着色器可以简单地做:

    int row = gl_VertexID / LENGTH;
    int col = gl_VertexID % LENGTH;
    

    顺便说一句,当您构建索引缓冲区时,您应该确保每个三角形对的方向一致。现在看起来一个是顺时针的,另一个是逆时针的。使用 GL_CULL_FACE 看看这会如何影响事物。

    这里只是空中编码,但我会做这样的事情:

    unsigned int elementIndex = 0;
    for(unsigned int zSquare = 0; zSquare < LENGTH - 1; zSquare++) {
       for(unsigned int xSquare = 0; xSquare < LENGTH - 1; xSquare++) {
          size_t vertexIndex = zSquare * LENGTH + xSquare;
          unsigned int topLeft = vertexIndex;
          unsigned int topRight = vertexIndex + 1;
          unsigned int bottomLeft = vertexIndex + LENGTH;
          unsigned int bottomRight = vertexIndex + LENGTH + 1;
          elements[elementIndex++] = topLeft;
          elements[elementIndex++] = bottomLeft;
          elements[elementIndex++] = bottomRight;
          elements[elementIndex++] = bottomRight;
          elements[elementIndex++] = topRight;
          elements[elementIndex++] = topLeft;
       }
    }
    

    虽然使用gl_VertexID 看起来很聪明,但在顶点缓冲区中简单地包含 X 和 Y 是一种更简单的选择,如果您想在地形镶嵌方面更聪明(例如,也许您会希望在平坦区域使用较大的三角形)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-17
      • 1970-01-01
      • 2019-09-12
      相关资源
      最近更新 更多