Recherche…


Introduction

L'instanciation est une technique de rendu qui permet de dessiner plusieurs copies du même objet lors d'un appel. Il est généralement utilisé pour rendre des particules, du feuillage ou de grandes quantités de tout autre type d'objets.

Instillation par tableaux d'attributs de vertex

3.3

L'installation peut être effectuée via des modifications de la manière dont les attributs de vertex sont fournis au vertex shader. Cela introduit une nouvelle façon d'accéder aux tableaux d'attributs, leur permettant de fournir des données par instance qui ressemblent à un attribut normal.

Une seule instance représente un objet ou un groupe de sommets (une feuille d'herbe, etc.). Les attributs associés aux tableaux instanciés ne progressent qu'entre les instances. contrairement aux attributs de vertex réguliers, ils n'obtiennent pas de nouvelle valeur par sommet.

Pour spécifier qu'un tableau d'attributs est instancié, utilisez cet appel:

glVertexAttribDivisor(attributeIndex, 1);

Ceci définit l'état d'objet du tableau de vertex. Le "1" signifie que l'attribut est avancé pour chaque instance. Passer un 0 désactive l'instanciation de l'attribut.

Dans le shader, l'attribut instancié ressemble à tout autre attribut vertex:

in vec3 your_instanced_attribute;

Pour rendre plusieurs instances, vous pouvez appeler l'une des formes Instanced de la valeur appels glDraw* . Par exemple, cela va dessiner 1000 instances, chaque instance étant constituée de 3 sommets:

glDrawArraysInstanced(GL_TRIANGLES, 0, 3, 1000); 

Code de tableau instancié

Mise en place de VAO, de VBO et des attributs:

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

Tirage au sort:

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

Vertex Shader:

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

Fragment shader:

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

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


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow