使用gl_VertexID计算顶点(在网格内)的X和Z位置

我正在尝试生成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,// bottom right
    vec2(1,// bottom right
    vec2(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.

使用gl_VertexID计算顶点(在网格内)的X和Z位置

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

liwentao19931129 回答:使用gl_VertexID计算顶点(在网格内)的X和Z位置

请注意不要将索引缓冲区(有时称为元素缓冲区)与顶点缓冲区混淆。请注意,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是一种更简单的选择,并且如果您希望对地形细分更加精明,那么将来可以更轻松地扩展代码(例如,也许您想在平坦区域中使用较大的三角形。

本文链接:https://www.f2er.com/3105902.html

大家都在问