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);
}