Was genau bewirkt, dass eine Oberfläche eine andere überlappt?

10

Ich kann nicht wirklich herausfinden, warum eine Oberfläche eine andere überlappt. In einer 3D-Engine, die ich erstelle, schlägt meine Technik in Randfällen fehl.

Meine Methode besteht darin, die zu lackierenden Flächen vom weitesten zum nächsten zu sortieren. Um die Nähe zu bestimmen, vergleiche ich die durchschnittlichen z-Werte. Manchmal hat eine überlappende Oberfläche jedoch einen höheren durchschnittlichen z-Wert als die überlappende. So wird die weiter entfernte Oberfläche über die nähere gestrichen - was zu einer bizarren Darstellung wie folgt führt:

Großes lila Quadrat mit einem roten Abschnitt an der Seite

Was man sehen soll, ist nur die lila Vorderseite des Würfels, während die rote Seitenfläche über die lila gemalt ist. Der durchschnittliche z-Wert der violetten Oberfläche ist höher und daher "weiter entfernt". Ich habe also Zweifel, ob diese Technik korrekt ist.

Was ich auch versucht habe, ist die Entfernung von der Kamera (dh dem Ursprung) zur Oberfläche, aber dann brauchte ich einen Punkt. Ich habe die Mitte jeder Oberfläche gewählt, aber auch dies scheint nicht immer zu funktionieren, da nicht alle Oberflächen so groß wie die anderen sind.

Was ist daher ein zuverlässiger Weg, um die Reihenfolge der Nähe von Oberflächen zum Ursprung zu bestimmen?

pimvdb
quelle

Antworten:

11

Sie scheinen zu versuchen, den Painters-Algorithmus zu implementieren . Ich vermute, Sie versuchen, als Lernübung einen Rasterisierer von Grund auf neu zu schreiben, da die meisten modernen 3D-Hardware das verwenden, was Bart erwähnt hat (den Z / Depth-Puffer). Damit der Maleralgorithmus in allen Fällen funktioniert, müssen Sie darauf vorbereitet sein, die gerenderten Oberflächen zu unterteilen, um mögliche Szenarien zu lösen (z. B. das auf der Wikipedia-Seite gezeigte überlappende Polygonproblem).

Wenn Sie vom weitesten zum nächsten rendern, verbringen Sie auch Zeit mit dem Rendern von Pixeln, die möglicherweise später von anderen Polygonen verdeckt werden. Wenn Sie Texturen und komplexe Shader auf die Polygone setzen, werden wertvolle Zyklen verschwendet. Dies ist der Grund, warum moderne Hardware es vorziehen würde, von vorne nach hinten zu rendern, indem der Tiefenpuffer verwendet wird, um zu bestimmen, ob das zu rendernde Pixel weiter entfernt ist als das auf dem Bildschirm (und daher verworfen werden kann).

Selbst mit den meisten modernen Beschleunigungshardware müssen Sie halbtransparente Polygone von hinten nach vorne sortieren und rendern. Dies wird erst wiedergegeben, wenn alle undurchsichtigen Polygone gerendert wurden.

Roger Perkins
quelle
Sie sagen zu Recht, dass ich einen einfachen Renderer erstelle. Der Punkt ist, dass ich keine 3D-Bibliotheken verwende. Ich mache alle Projektionsberechnungen selbst und zeichne dann die Linien mit einer 2D-Zeichnungsbibliothek. Dies ist nicht die schnellste da draußen und ich mache nichts pro Pixel. Ich habe nur 4 Punkte von jeder Oberfläche und fülle die rechteckige Form mit einer Farbe. Da ich auf einmal eine vollständige Oberfläche zeichne, kann ich zu Recht sagen, dass ich von hinten nach vorne zeichnen muss?
Pimvdb
Klingt nach viel Spaß und einer großartigen Art zu lernen. Von hinten nach vorne ist Ihr einziger Weg, wenn Sie dies ohne jeglichen Tiefenpuffer tun. Ich denke, Sie müssen alle Bildschirmkoordinaten Ihrer Polygone berechnen und dann auf Überlappungen prüfen. Wenn sie sich in der Tiefe überlappen, müssen Sie möglicherweise die zu rendernden Polygone zerlegen, damit Sie die Sortierung tatsächlich korrekt auflösen können. Vielleicht möchten Sie auch in Back Face Culling schauen, um Polygone zu entfernen, die nicht unbedingt sichtbar sein sollten
Roger Perkins
Roger Perkins hat recht. Auf diese Weise können Sie keine korrekte Z-Sortierung erzielen (was bedeutet, dass Sie immer einige Randfälle haben), es sei denn, Sie zerlegen die Polygone. Das kann allerdings ziemlich langsam werden.
Bummzack
Ich habe es geschafft! Was ich getan habe, war eine Kombination aus Backface-Culling und Sortieren: In einem festen Würfel sind einige Gesichter nicht sichtbar, während andere sichtbar sind (maximal 3). Also habe ich zuerst die nicht sichtbaren Teile und die sichtbaren Teile darüber gemalt. Dies funktioniert wie ein Zauber. Wenn ich eine oder mehrere Seiten entferne, überlappen sie sich, werden aber immer noch in der richtigen Reihenfolge gezeichnet. Vielen Dank!
Pimvdb
1
Das funktioniert nur für einfache konvexe Formen wie Würfel. Ich bin froh, dass es derzeit für Sie funktioniert, aber es ist keine allgemeine Lösung.
Richard Fabian
3

Was Sie haben, ist ein Sichtbarkeitsproblem . Eine Lösung ist die Verwendung eines Z-Puffers .

Bart van Heukelom
quelle
Danke, aber die Z-Pufferung erfordert ein Rendering pro Pixel, wenn ich mich nicht irre. Ich mache das nicht - ich zeichne gerade Linien zwischen den projizierten Punkten des Würfels. Ist Z-Pufferung noch möglich?
Pimvdb
Selbst wenn Sie gerade Linien zeichnen, wird das Bild irgendwann, bevor es auf den Bildschirm (oder die Bitmap-Datei) gelangt, im Pixelformat angezeigt.
Bart van Heukelom
Das ist richtig, aber meine Zeichnungsbibliothek ist zu langsam, um Pixel mit 20 fps zu rendern. Trotzdem danke.
Pimvdb
2

Das Sortieren der Flächen nach ihrem durchschnittlichen Z-Wert funktioniert nicht, da der durchschnittliche Z-Wert keine Informationen über den tatsächlichen Z-Wert der Scheitelpunkte oder sogar Oberflächenpixel liefert.

Beispiel (Warnung, ASCII-Grafik voraus):

          /
         /
cam     /
-->    / 
      /
     /--       <--B
    /
    ^--A

Es gibt zwei Gesichter A und B. Aus Sicht der Kamera liegt A vor B. Der durchschnittliche z-Wert von B ist jedoch kleiner. Schauen wir uns die anderen Z-Werte an:

  • der minimale z-Wert von A ist 4
  • Der maximale Z-Wert von A beträgt 11
  • daher beträgt der durchschnittliche z-Wert von A 7,5
  • der minimale z-Wert von B ist 6
  • der maximale z-Wert von B ist 8
  • daher ist der durchschnittliche z-Wert von B 7

Sie könnten versuchen, sie nach ihren minimalen Z-Werten zu sortieren, aber es gibt Fälle, in denen dies auch nicht funktioniert. Es gibt einfach keine Möglichkeit, beliebige Flächen mit nur einem Z-Wert korrekt zu sortieren.

In Newells Algorithmus http://en.wikipedia.org/wiki/Newell 's_algorithm sortieren Sie die Min / Max-Bereiche der Z-Werte. Wenn sich die Bereiche zweier Flächen nicht überlappen, können Sie sicher wissen, welche vorne liegt. Wenn ja, müssen Sie manchmal unbedingt die Gesichter teilen. Manchmal reicht es aus, jeden Scheitelpunkt für die Okklusion oder eine andere Technik zu strahlen.

Jonas Bötel
quelle
Dieses Diagramm ist eine Draufsicht auf das, was ich in seinem Screenshot erraten wollte.
Schockieren
1

Es ist gut, dass Sie etwas über das Rendern lernen. Ein großes Lob. In diesem Fall gibt es keine "Maleralgorithmus" -Lösung, anstatt zu versuchen, sie durch Sortieren zu beheben. Auf der PS1 haben wir nur versucht, Polygone ungefähr gleich groß zu halten, wenn sie nebeneinander waren (wie Sie es tun) soweit ich das beurteilen kann) und backface cull (was du nicht tust)

Beim Backface-Culling wird die Oberflächennormale im Bildschirmbereich auf ihre Richtung überprüft (erhalten Sie einfach das Vorzeichen des Tiefenelements aus dem normal transformierten Bildschirmbereich (in unserem Fall das z der Normalen) oder das Kreuzprodukt zweier Vektoren der Dreieck dh Kreuz (v1-v0, v2-v0))

Wenn Sie Backface-Culling implementieren, reduzieren Sie auch das Rastering, das Sie durchführen. Double Win.

Richard Fabian
quelle
Vielen Dank für Ihre Antwort. Ich habe über das Keulen von Rückseiten gelesen, aber der Punkt ist, dass ich in der Lage sein möchte, eine Seite zu entfernen. Mit einem festen Würfel mag das einfach großartig funktionieren, aber wenn ich eine Seite entferne, passiert eine Okkulision - also muss ich sie wohl noch sortieren. Wie auch immer, ich kam auf die Idee, einen Strahl vom Ursprung durch den Mittelpunkt einer Oberfläche abzufeuern. Wenn dieser Strahl danach eine andere Oberfläche kreuzt, überlappt die erste Oberfläche die zweite. Könnten Sie mir vielleicht sagen, ob diese Idee so richtig ist? Vielen Dank!
Pimvdb
Obwohl Ihre Idee für Ihren Beispielfall funktionieren würde, gibt es viele andere Fälle, in denen sie nicht funktionieren wird. Zum Beispiel dieselbe Szene, die Sie dort haben, aber die Kamera ist so geneigt, dass sich die Mitte des falschen Rendering-Quad nicht überlappt. Ich denke, Sie müssen Ihre Grundelemente in kleinere Teile zerlegen.
Richard Fabian