2012-08-14 12 views
10

Ich habe OpenGL gelernt, und das eine Thema, das mich weiterhin verwirrt, ist die weit entfernte Clipping-Ebene. Während ich die Überlegungen hinter der nahen Clipping-Ebene und den seitlichen Clipping-Ebenen verstehen kann (die niemals einen wirklichen Effekt haben, weil Objekte außerhalb von ihnen niemals gerendert werden), scheint die ferne Clipping-Ebene nur ein Ärgernis zu sein.Warum hat OpenGL eine ferne Clipping-Ebene, und welche Idiome werden verwendet, um damit umzugehen?

Da die hinter OpenGL offensichtlich das durchdacht haben, weiß ich, dass da etwas fehlen muss. Warum hat OpenGL eine ferne Clipping-Ebene? Was ist noch wichtiger, weil es nicht möglich ist, das zu deaktivieren, was sind die empfohlenen Idiome und Praktiken, wenn man Objekte in großen Entfernungen zeichnet (für Objekte wie Sterne, die Tausende von Einheiten in einem Weltraumspiel, einer Skybox usw. entfernt sind)? Wird erwartet, dass die Clipping-Ebene nur sehr weit entfernt ist, oder gibt es eine elegantere Lösung? Wie wird das in der Produktionssoftware gemacht?

Antwort

19

Der einzige Grund ist Tiefengenauigkeit. Da Sie im Tiefenpuffer nur eine begrenzte Anzahl von Bits haben, können Sie damit auch nur eine begrenzte Anzahl von Tiefen darstellen.

Sie können jedoch die ferne Ebene unendlich weit einstellen: Siehe this. Es wird einfach nicht gut mit dem Tiefenpuffer funktionieren - Sie werden viele Artefakte sehen, wenn Sie weit entfernt Okklusion haben.

Da dies sich um den Tiefenpuffer dreht, werden Sie kein Problem mit weiter entfernten Dingen haben, solange Sie es nicht benutzen. Zum Beispiel besteht eine übliche Technik darin, die Szene in "Platten" zu rendern, die jeweils nur den Tiefenpuffer intern (für das gesamte Material in einer Platte) verwenden, aber eine Form des Maleralgorithmus extern (für die Platten also den weitesten zeichnen) zuerst)

+0

Es kann erwähnenswert sein, dass die Einstellung der nahen Clipping-Ebene nahe Null zu dem gleichen Effekt führt wie die Einstellung der fernen Clipping-Ebene zu weit entfernt. Laut http://www.opengl.org/archives/resources/faq/technical/depthbuffer.htm ist ungefähr die Anzahl der verlorenen Bits log2 (weit/nahe). –

9

Warum hat OpenGL eine ferne Clipping-Ebene?

Da Computer sind endlich.

Es gibt im Allgemeinen zwei Möglichkeiten, um damit umzugehen. Ein Weg besteht darin, die Projektion zu konstruieren, indem die Grenze als z-fern angenähert in die Unendlichkeit genommen wird. Dies wird auf endliche Werte konvergieren, aber es kann Verwüstung mit Ihrer Tiefengenauigkeit für entfernte Objekte verursachen.

Eine Alternative (wenn Sie Objekte über eine bestimmte Distanz hinaus haben möchten, die überhaupt nicht korrekt getestet werden können) ist, die Tiefenklemmung mit glEnable(GL_DEPTH_CLAMP) einzuschalten. Dies verhindert Clipping gegen die nahen und fernen Ebenen; es ist nur so, dass alle Fragmente, die normalisierte Z-Koordinaten außerhalb des [-1, 1] -Bereichs hätten, an diesen Bereich geklammert werden. Wie zuvor erwähnt, werden Tiefenprüfungen zwischen Fragmenten, die geklemmt werden, verschraubt, aber normalerweise sind diese Objekte weit entfernt.

0

Es ist nur "die Tatsache", dass OpenGL Tiefentest wurde in Window Space Coordinates durchgeführt (Normalized Gerätekoordinaten in [-1,1]^3. Mit zusätzlichen Skalierung glViewport und glDepthRange).

Also aus meiner Sicht ist es einer der Design-Sicht der OpenGL-Bibliothek.


Ein Ansatz, um diese OpenGL-Erweiterung/OpenGL Kernfunktionalität zu beseitigen https://www.opengl.org/registry/specs/ARB/depth_clamp.txt wenn es in Ihrer OpenGL-Version verfügbar ist.


Ich möchte beschreiben, dass in der perspektivischen Projektion nichts über "far Clipping-Ebene" ist.

3.1 Für die perspektivische Projektion müssen Sie den Punkt \ vec {c} als Projektionszentrum und Ebene festlegen, auf der die Projektion durchgeführt wird. Nennen wir es Bildebene T: (\ vec {r} - \ vec {r_0}, \ vec {n})

3.2 Nehmen wir an, dass projizierte Ebene T split arbitrary Punkt \ vec {r} und \ vec { c} zentral für die Projektion. In anderen Fällen sind \ vec {r} und \ vec {c} in einem einzigen Raum und Punkt \ vec {r} sollte verworfen werden.

3.4 Die Idee der Projektion ist Kreuzung zu finden \ vec {i} mit der Ebene T \ vec {i} = (1-t) \ vec {c} + t \ vec {r}

3.5 wie es ist (\ vec {i} - \ vec {r 0}, \ vec {n}) = 0

=>

((1-t) \ vec {c} + t \ vec {r} - \ vec {r 0}, \ vec {n}) = 0

=>

(\ vec {c } + t (\ vec {r} - \ vec {c}) - \ vec {r_0}, \ vec {n}) = 0

3.6. Von "3.5" abgeleitetes t kann in "3.4" ersetzt werden und Sie erhalten Projektion in Ebene T.

3.7. Nach der Projektion liegt der Punkt in der Ebene. Aber wenn angenommen wird, dass die Bildebene parallel zur OXY-Ebene ist, kann ich vorschlagen, die ursprüngliche "Tiefe" für den Punkt nach der Projektion zu verwenden.

Also aus der Perspektive der Geometrie ist es möglich, die ferne Ebene überhaupt nicht zu verwenden. Wie auch das Modell [-1,1]^3 explizit nicht zu verwenden.

p.s. Ich weiß nicht, wie man Latexformeln richtig eintippt, z. Sie werden wiedergegeben.

Verwandte Themen