Szukaj…


Wprowadzenie

Instancja to technika renderowania, która pozwala nam narysować wiele kopii tego samego obiektu w jednym wywołaniu losowania. Zwykle służy do renderowania cząstek, liści lub dużych ilości dowolnych innych rodzajów obiektów.

Wystąpienie przez tablice atrybutów wierzchołków

3.3

Instancje można wykonać poprzez modyfikacje sposobu, w jaki atrybuty wierzchołków są dostarczane do modułu cieniującego wierzchołki. Wprowadza to nowy sposób dostępu do tablic atrybutów, umożliwiając im dostarczanie danych dla poszczególnych instancji, które wyglądają jak zwykłe atrybuty.

Pojedyncze wystąpienie reprezentuje jeden obiekt lub grupę wierzchołków (jeden liść trawy itp.). Atrybuty związane z tablicami instancji przesuwają się tylko między instancjami; w przeciwieństwie do zwykłych atrybutów wierzchołków, nie otrzymują nowej wartości na wierzchołek.

Aby określić, że wystąpiła tablica atrybutów, użyj tego wywołania:

glVertexAttribDivisor(attributeIndex, 1);

Ustawia stan obiektu tablicy wierzchołków. „1” oznacza, że atrybut jest zaawansowany dla każdej instancji. Podanie 0 wyłącza instancję atrybutu.

W module cieniującym atrybut instancji wygląda jak każdy inny atrybut wierzchołka:

in vec3 your_instanced_attribute;

Aby renderować wiele instancji, możesz wywołać jedną z Instanced postaci wartości glDraw* . Na przykład spowoduje to narysowanie 1000 wystąpień, przy czym każde wystąpienie będzie składać się z 3 wierzchołków:

glDrawArraysInstanced(GL_TRIANGLES, 0, 3, 1000); 

Instancyjny kod macierzy

Konfigurowanie VAO, VBO i atrybutów:

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

Narysuj połączenie:

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

Moduł cieniujący wierzchołek:

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

Moduł cieniujący fragmenty:

#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
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow