2016-08-02 49 views
0

Ich lerne gerade WebGL und bin dabei, eine Szene mit vielen identischen Cubes zu rendern, aber mit unterschiedlichen Übersetzungen.WebGL; Puffer oder uniform4fv?

Ich glaube, ich habe 2 Optionen in Bezug auf diese zeichnen;

  • einen einzelnen Würfel Puffer verwenden, um einen für uniform4fv übersetzen und senden es für jeden Würfel (auf den Vertex-Shader).

  • Puffer alle meine Würfel (Vertices mit Übersetzung codiert).

Meine Frage ist in Bezug auf welche Option in welchen Fällen vorzuziehen? - Ich würde denken, dass die erste Option vorzuziehen war, aber das hängt vom Overhead oder von der Aktualisierung der Uniform-Variablen ab.

+0

Ich render meine meine Würfel mit gl.drawArrays, vielleicht mit ELEMENT-Puffer wäre auch eine Option? – Skeen

Antwort

1

Wie WaclawJasper sagte, gibt es viele Kompromisse.

Die allgemeine Vorgehensweise in WebGL ist ein Zeichenaufruf pro Objekt (Ihre erste Methode).

Eine andere wäre instanced Zeichnung using ANGLE_instanced_arrays zu verwenden. In dieser Methode würden Ihre Übersetzungen in einem Puffer gespeichert werden. Sie würden den Puffer nur eine Übersetzung pro Instanz aktualisieren (gegenüber einer pro Vertex in der zweiten Methode). Bei dieser Methode wird davon ausgegangen, dass alle Instanzen identisch sind.

Wenn Ihre Geometrie zufällig gemischt ist (Würfel + Kugel + Pyramide), wäre eine andere Methode, Ihre Orientierungsdaten in eine Textur zu bringen. Indem Sie jedem Stützpunkt eine instanceId geben, können Sie damit den Speicherort der Daten dieser Instanz in der Textur berechnen. In diesem Fall würden Sie eine Ausrichtung pro Instanz wie die vorherige Methode aktualisieren. Sie würden nur eine Textur anstelle eines Puffers aktualisieren. Wenn die Hardware das Lesen von Gleitkomma-Texturen (OES_texture_float) unterstützt, die die meisten Hardware an diesem Punkt verwendet, ist diese Methode ziemlich einfach.

Als Beispiel für das Speichern der Ausrichtung in einer Textur speichert three.js optional Knochenmatrizen in Texturen für das Rendering mit Skinned Mesh, um eine begrenzte Anzahl von Uniformen zu umgehen.

Beachten Sie, dass Sie mithilfe von Texturen auch die Scheitelpunktdaten in eine Textur einfügen können. Die Puffer würden dann nur Vertex-Indizes enthalten.

+0

Update: Ich habe mich entschieden, mit den 'ANGLE_instanced_arrays' zu gehen, aber ich habe ein neues Problem, nämlich Gesichter einzigartig zu färben. Weitere Informationen finden Sie unter https://stackoverflow.com/questions/38804356/. – Skeen

1

Zunächst hängt es davon ab, ob die Objekte, die Sie rendern, dynamisch oder statisch sind.

Für statische Geometrie wird Methode 2 effizienter sein.

Für dynamische Geometrie hängt es ab. Der Kompromiss besteht zwischen dem Overhead der Zustandsänderung mit Methode 1 gegenüber den Kosten der Berechnung der neuen Scheitelpunkte auf CPU + dem Laden dieser Scheitelpunkte in GPU jeden Frame mit Methode 2. Es ist schwierig, die genauen Kosten der Zustandsänderung zu quantifizieren, aber, es ist sicher, dass größere Objekte länger brauchen, um die GPU zu berechnen und zu aktualisieren.

Aus Erfahrung funktioniert Methode 2 besser mit "kleinen" Objekten wie Sprites, Boxen usw. und Methode 1 funktioniert besser mit "komplexen" Objekten, die Tausende von Vertices haben. Was genau als "klein" oder "komplex" quantifiziert wird, ist wahrscheinlich GPU- und Treiber-abhängig und muss individuell getestet werden.

drawElements wird fast immer über drawArrays wann immer möglich bevorzugt.