Instancing

Aus DGL Wiki
Wechseln zu: Navigation, Suche
Terrain mit per Instancing gerenderten Pflanzen.

Instancing ist eine Technik die es erlaubt große Mengen gleicher oder ähnlicher Geometrie effizient zu rendern. Die Anzahl der API-Aufrufe und die Menge redundanter Daten wird reduziert. Voraussetzung ist, dass alle Objekte die selbe Primitiv-Anzahl und den selben Primitiv-Typ verwenden.

Instancing wurde mit OpenGL 3.1 in den OpenGL-Kern aufgenommen. Bei älteren OpenGL-Versionen muss man auf eine Extension wie beispielsweise GL_ARB_draw_instanced zurückgreifen.

Mit glDrawArraysInstanced und glDrawElementsInstanced werden zwei neue API-Funktionen eingeführt. Diese sind jeweils äquivalent zu einer Serie von Aufrufen der Funktionen glDrawArrays bzw. glDrawElements. Jeder Aufruf glDraw*-Aufruf innerhalb einer solchen Serie wird Instanz genannt.


Ein Aufruf von glDrawArraysInstanced entspricht dem folgenden Pseudocode:

void glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount) {
    if (mode or count is invalid) {
        generate appropriate error
    }
    else {
        for (i = 0; i < primcount; i++) {
            gl_InstanceID = i;
            glDrawArrays(mode, first, count);
        }
        gl_InstanceID = 0;
    }
}

Im GLSL-Vertexshader steht mit gl_InstanceID ein neues Attribut zur Verfügung. Diese Variable wird zunächst mit 0 initialisiert und dann mit jeder Instanz der Serie inkrementiert. Diese Instanz ID (oder Vielfache davon) können als Index für ein Uniform-Array, eine Textur oder ein TexturBufferObjekt mit Transformations-Daten genutzt werden. Ein Vertexshader ist so in der Lage mehrere Instanzen eines Objektes mit einem einzigen glDraw*-Aufruf zu rendern.

Die Funktion glDrawElementsInstanced funktioniert analog. Ein umfangreiches Beispiel findet sich in der Shadersammlung.

Abgrenzung zu glMultiDrawArrays / glMultiDrawElements

Die beiden schon länger dem OpenGL-Kern angehörenden Funktionen glMultiDrawArrays und glMultiDrawElements haben eine recht ähnliche Funktion. Allerdings ist das Attribut gl_InstanceID nicht im Vertexshader verfügbar. Daher eignen sich diese Funktionen nicht um gleiche Objekte mehrfach an verschiedene Orte der Szene zu rendern, da der Vertexshader immer die gleichen Daten erhalten würde.

Siehe auch