Ich rolle meine eigene 3D-Engine in JavaScript und verwende nur Zeichenfläche, kein WebGL. Dies ist ein weiterer Minecraft-Klon. Ich liebe Kisten, verurteile mich nicht.
Bisher funktioniert alles wunderbar, bis auf eines: Wenn in 3D einige Scheitelpunkte hinter der nahen Schnittebene liegen, kommt ihre Projektion auf dem Bildschirm merkwürdig heraus (vorausgesetzt, andere Scheitelpunkte, die zum Verfolgen einer Ebene verwendet werden, sind vorne).
Ich habe versucht, diese Punkte auszuschneiden, aber dann kann ich durch die Oberflächen sehen, die diese Scheitelpunkte verwenden. In WebGL / OpenGL kümmert sich die Grafikkarte um diese Punkte und die Ebene wird korrekt gerendert, aber ich habe keinen Zugriff auf Hardware, daher muss ich diese selbst codieren.
Ich bin mir nicht ganz sicher, was ich davon halten soll. Derzeit ist das letzte, was mir in den Sinn gekommen ist, die Projektion von Punkten hinter der Clipping-Ebene des Spielers umzukehren, was logisch erscheint, da ich einen Punkt auf einen Bildschirm projizieren muss, der vor mir liegt des Scheitelpunkts.
Hier sind meine Gedanken:
Hier sind einige Bilder, die veranschaulichen, was passiert:
Aus der Ferne macht sich die blaue Box perfekt.
Wenn einige der Scheitelpunkte hinter der nahen Clipping-Ebene des Players liegen, mache ich eine Umkehrprojektion, aber es sieht nicht richtig aus:
focalLength *= -1;
2d.x = x*focalLength/z;
2d.y = y*focalLength/z;
Beachten Sie, dass das graue Feld dahinter vollständig entfernt ist, da sich alle zum Zeichnen der Gesichter verwendeten Scheitelpunkte hinter dem Player befinden.
Dies ist, was passiert, wenn Sie nach oben oder unten schauen.
Ich weiß nicht, was ich mit der Mathematik dahinter anfangen soll. Ich hoffe, jemand hat bereits das gleiche Problem und kann mir helfen.
quelle
lineTo(x,y)
Funktion weiterhin aufgerufen werden konnte. Ich weiß nur nicht, wie sie sich verhält. Es ist eine bizarre Dimension, da stimme ich zu.Antworten:
Der Zweck der Near-Clipping-Ebene ist, dass es sich um eine Clipping-Ebene handelt . Dreiecke, die sich außerhalb einer Schnittebene befinden, werden geschnitten : Schneiden Sie sie so in Stücke, dass sich jedes verbleibende Stück innerhalb des Schnittbereichs befindet.
Sie können versuchen, den Near-Clip zu ignorieren, wenn Sie dies wünschen. In der Tat haben OpenGL und D3D Möglichkeiten, das Abschneiden in der Nähe von Ebenen zu deaktivieren (obwohl der Tiefenpuffer immer noch einen minimalen Nahwert hat). Das Problem ist nicht der nahe Clip.
Das Problem sind Scheitelpunkte, die sich hinter der Kamera befinden.
Sie können keine Dreiecke rendern, die sich hinter der Kamera befinden. Nicht mit einer perspektivischen Projektion. Solche Dreiecke sind unter den mathematischen Gesichtspunkten hinter perspektivischen Projektionen nicht sinnvoll. Darüber hinaus befinden sie sich auch außerhalb des Kegelstumpfes.
Beim Ausschalten in der Nähe von Ausschnitten wird ein Kegelstumpf zu einer Pyramide. Der Grund, warum die Pyramide an dem Punkt anhält, liegt darin, dass sich Punkte über der Pyramide hinter allen vier Seiten der Pyramide befinden. Jeder Punkt hinter der Kamera (die Spitze der Pyramide) befindet sich oberhalb, unterhalb, links und rechts des sichtbaren Bereichs des Bildschirms. Alles zur selben Zeit.
Wie gesagt: Scheitelpunkte unter einer perspektivischen Projektion, die sich hinter der Kamera befinden, ergeben keinen Sinn.
Sie müssen Clipping implementieren. Sie müssen feststellen, wann sich ein Scheitelpunkt eines Dreiecks im Clip-Raum ( vor der perspektivischen Unterteilung) hinter der Kamera befindet. Wenn dies der Fall ist, müssen Sie dieses Dreieck abschneiden und nur Dreiecke erzeugen, die sich vor der Kamera befinden.
Dies ist kein einfacher Prozess. Es handelt sich um Mathematik, die nur Sinn macht, wenn Sie die homogenen Koordinatensysteme vollständig verstehen. Alternativ können Sie jedes Dreieck auch direkt nach oben ziehen, wenn sich ein Scheitelpunkt hinter der Kamera befindet.
quelle
Wenn ein Teil des Dreiecks hinter der nahen Ebene liegt, können Sie dann pro Pixel prüfen, ob die Pixelposition hinter der Beschneidungsebene liegt?
Sie können die nahe Ebene wie jede andere Schnittebene behandeln. Zum Beispiel werden Schnittebenen für Dinge wie Wasserflugzeuge (für Reflexionen und Refraktionen) verwendet. Ich würde denken, dass diese Beschneidungsebene genau wie die nahe Beschneidungsebene funktioniert und auf Pixelbasis beschneidet.
Ich weiß, wie man Clipping-Ebenen in HLSL mit DirectX handhabt, aber ihre Implementierung könnte proprietär sein. Wenn Sie sich die Informationen dafür besorgen könnten, wäre dies möglicherweise hilfreich.
Außerdem finden Sie hier einen Link, der Ihnen helfen könnte: http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter42.html
quelle