Vertex 屬性陣列的例項化

Version >= 3.3

可以通過修改如何將頂點屬性提供給頂點著色器來完成例項化。這引入了一種訪問屬性陣列的新方法,允許它們提供看起來像常規屬性的每個例項資料。

單個例項表示一個物件或一組頂點(一個草葉等)。與例項化陣列關聯的屬性僅在例項之間前進; 與常規頂點屬性不同,它們不會獲得每頂點的新值。

要指定屬性陣列是例項化的,請使用以下呼叫:

glVertexAttribDivisor(attributeIndex, 1);

這設定了頂點陣列物件狀態。1 表示每個例項的屬性都是高階的。傳遞 0 會關閉屬性的例項化。

在著色器中,instanced 屬性看起來像任何其他頂點屬性:

in vec3 your_instanced_attribute;

要渲染多個例項,你可以呼叫值 glDraw*呼叫的 Instanced 形式之一。例如,這將繪製 1000 個例項,每個例項由 3 個頂點組成:

glDrawArraysInstanced(GL_TRIANGLES, 0, 3, 1000); 

例項陣列程式碼

設定 VAO,VBO 和屬性:

// List of 10 triangle x-offsets (translations)
GLfloat translations[10];
GLint index = 0;
for (GLint x = 0; x < 10; x++)
{
    translations[index++] = (GLfloat)x / 10.0f;
}

// vertices
GLfloat vertices[] = {
     0.0f,   0.05f,
     0.05f, -0.05f, 
    -0.05f, -0.05f,
     0.0f,  -0.1f,
};

// Setting VAOs and VBOs
GLuint meshVAO, vertexVBO, instanceVBO;
glGenVertexArrays(1, &meshVAO);    
glGenBuffers(1, &instanceVBO);
glGenBuffers(1, &vertexVBO);

glBindVertexArray(meshVAO);

    glBindBuffer(GL_ARRAY_BUFFER, vertexVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)0);

    glBindBuffer(GL_ARRAY_BUFFER, instanceVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(translations), translations, GL_STATIC_DRAW);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, sizeof(GLfloat), (GLvoid*)0);
    glVertexAttribDivisor(1, 1); // This sets the vertex attribute to instanced attribute.

    glBindBuffer(GL_ARRAY_BUFFER, 0);

glBindVertexArray(0);

Draw call:

glBindVertexArray(meshVAO);
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 10); // 10 diamonds, 4 vertices per instance
glBindVertexArray(0);

頂點著色器:

#version 330 core
layout(location = 0) in vec2 position;
layout(location = 1) in float offset;

void main()
{
    gl_Position = vec4(position.x + offset, position.y, 0.0, 1.0);
}

片段著色器:

#version 330 core
layout(location = 0) out vec4 color;

void main()
{
    color = vec4(1.0, 1.0, 1.0, 1.0f);
}