Was ist der beste Weg, um viele Bäume zu zeichnen

8

Ich schreibe eine App, die eine zufällige Insel mit Bäumen bepflanzt. Die Bäume sind derzeit zwei Quads, gekreuzt und mit Texturen gezeichnet. Ich plane komplexere Maschen, die verschiedene Pflanzentypen bilden, z. B. eine Palme, Eiche, Gräser usw.

Beispielinsel

Das Problem ist, dass ich die Texturen von hinten nach vorne zeichnen muss, weil sie transparent sind. Plan-b ist die Verwendung von Discard im Frag-Shader, aber die Z-Reihenfolge liefert bessere Ergebnisse:

uniform float uTreeAlpha;
uniform sampler2D uTexture;

varying vec2 vTexCoordOut;

void main (void)
{
  vec4 colour = texture2D(uTexture, vTexCoordOut);
  if (colour.a < 0.1) {
    discard;
  }
  gl_FragColor = vec4(colour.rgb, colour.a * uTreeAlpha);   
}

Das zweite Problem ist, dass sich die Reihenfolge je nach Kamera und Aussehen ändert. Ich kenne keine effiziente Methode, um sie in OpenGL in einem einzigen Aufruf zu zeichnen.

Derzeit sieht mein Rendering-Code wie folgt aus:

if cameraChangedFromLastTime() then
  sortTreesBackToFront();
end
for i = 0 to trees.size() -1
  drawTree()
end

Wobei jeder drawTree () einige Uniformen festlegt, die Textur festlegt und dann glDrawArrays () aufruft. Ich habe einige Optimierungen, um das Festlegen einer Textur oder das Aktualisieren von Texturkoordinaten zu überspringen, wenn der letzte Baum und die aktuelle identisch sind, und einige allgemeine Uniformen außerhalb der Schleife festzulegen und Bäume zu überspringen, die zu weit entfernt sind, aber im Grunde genommen, wenn ich 3000 Bäume habe Gehen Sie 3000 Mal um die Schleife.

Jeder Baum einzeln zu zeichnen ist der Leistungskiller. Wenn ich sie in einem einzigen Aufruf oder in Stapeln (unter Beibehaltung der Z-Reihenfolge) zeichnen könnte, würde ich dies wahrscheinlich in 1/10 der Zeit tun.

Wie würde ich das machen? Denken Sie daran, dass meine Bäume Platzhalter sind und ich schließlich:

  • Unterschiedliche Maschen für unterschiedliche Bäume
  • Verschiedene Maßstäbe und Winkel für Bäume, um mehr Abwechslung zu bieten
  • Unterschiedliche Texturen für unterschiedliche Bäume, möglicherweise mehrere Texturen, die auf ein Netz angewendet werden (z. B. Blätter eine Textur, Stamm eine andere)
  • Bäume sind alle miteinander vermischt, so dass es keine einfache Möglichkeit gibt, eine Art und dann eine andere zu zeichnen
  • Eine Form einfacher zyklischer Animation (Äste, die im Wind wackeln)
  • Alle Texturen würden sich in einem einzigen Atlas befinden

Was ist hier der beste Ansatz? Ist es möglich, in einem Durchgang zu rendern? Wenn ich glDrawElements verwenden würde, um die Indizes, aber nicht die Eckpunkte neu zu erstellen, könnte ich dies erreichen?

locka
quelle
vterrain.org , siehe rechte Spalte unter Abschnitt Pflanzen für das Pflanzen-Rendering, jeweilige linke Spalte, Abschnitt-Rendering für Detailgenauigkeit / allgemeine Rendering-Beschleunigungen. Achtung: Die Quelle ist mehr Auflistung von Forschungsarbeiten als Tutorial.
Exilyth
Ich weiß nicht viel über dieses Zeug. Schauen Sie sich aber die VUE-Software an. Es wird verwendet, um Landschaften mit Bäumen, Bergen, Atmosphäre und vielem mehr in 3D zu erstellen. Aber ich bin nicht sicher, ob es in Ihrer Situation helfen wird
user1981248

Antworten:

3

Was Sie wollen, ist Hardware-Instanz . Hinweis: Ich habe dies in XNA (dh DirectX) getan, aber ich weiß nicht viel über OpenGL. Ich bin mir jedoch sicher, dass es eine vergleichbare Funktion gibt. Grundsätzlich geht es darum, die Scheitelpunkte Ihres Baummodells mit einem anderen Scheitelpunktstrom zu verbinden, der Weltkoordinaten für jede Instanz enthält.

DrHeinous
quelle
1
Das OpenGL-Äquivalent wäre die Erweiterung opengl.org/registry/specs/EXT/draw_instanced.txt . Zunächst sollten jedoch Listen in älteren OpenGL- und Vertex-Array-Objekten / Vertex-Pufferobjekten in modernem OpenGL angezeigt werden. In beiden Fällen wird ein Objekt / Netz in der Liste / VAO / VBO gespeichert, und dann wird jede Instanz mit einer anderen Transformation gezeichnet. Mithilfe statischer Netze können die Daten einmal hochgeladen und dann wiederverwendet werden. sol.gfxile.net/instancing.html gibt einen kurzen Überblick über die verschiedenen Methoden.
Exilyth
Danke, Instanzen ist eine interessante Idee. Ich konnte jedoch keine draw_instanced-Erweiterung verwenden, da ich OpenGL ES 2.0 verwende und an etwas arbeite, das für alles funktioniert. Ich denke vielleicht, dass ich die verschiedenen Baumnetze in ein VBO laden kann (möglicherweise mit einfacheren Modellen weiter entfernt), z-sortieren und sie dann in Stapeln aus einem Indexpuffer zeichnen kann, den ich für jeden Stapel erstellen würde. Auf diese Weise kann ich möglicherweise 30 oder 40 gleichzeitig zeichnen.
Locka
2

Die Transparenz muss nur bestellt werden, wenn keine additive Mischung verwendet wird. Für eine Tonne entfernter Werbetafeln ist das Mischen nicht erforderlich (Sie können es nicht wirklich sehen). Rendern Sie mindestens die weiteren mit ausgeschnittener Transparenz (Alpha von nur 1 oder 0), und Sie müssen sie nicht sortieren.

Sie können eine Art Sprite-Blatt verwenden, um verschiedene Baumarten mit gebackenen Animationen zu rendern. Zeichnen Sie Maschen für nähere Bäume, die Sie je nach Wind oder was auch immer Sie möchten, mit größerer Genauigkeit animieren können.

Sean Middleditch
quelle
Ich habe mit Verwerfen und ohne Sortieren experimentiert, aber die Ergebnisse sehen ein bisschen duff aus - Bäume überlappen sich häufig stark. Wenn es also keine einheitliche Reihenfolge gibt, bekomme ich viel Pop, wenn ein Baum vor den anderen geht und " gewinnt "das Pixel. Ich habe den Abwurf beibehalten, da es immer noch gelegentlich zu Kollisionen kommt (z. B. 2 Bäume mit genau demselben Abstand von der Kamera), aber es ist ein Fallback. Ich habe auch mit Werbetafeln experimentiert und der Effekt ist besonders für Überführungen zu falsch.
Locka
Verwenden Sie bessere Werbetafeln. Idealerweise haben Sie ein Baummodell. Generieren Sie das Plakat-Sprite für einen Betrachtungswinkel und verwenden Sie dieses Sprite dort, wo der Winkel ungefähr übereinstimmt. Bei Ausschnitten funktionieren sie am besten in der Ferne, wo Sie den Unterschied nicht erkennen können. Wenn Sie näher kommen, müssen Sie mehr kokmplizierte Modelle verwenden (möglicherweise einige Quads pro Baum), oder Sie können zur Transparenz der Bildschirmtür wechseln.
Sean Middleditch
Irgendwann müssen Sie das akzeptable Gleichgewicht zwischen Qualität und Geschwindigkeit herausfinden. Sie werden für die komplexesten Szenen auf Standardhardware nicht "blitzschnell" und "perfekt".
Sean Middleditch