So mischen Sie zwei Kameras, wenn Sie in Unity3D durch ein Portal reisen

18

Bevor ich zu meiner Frage komme, weiß ich, dass die naheliegendste Lösung darin besteht, das normalisierte Ansichtsfenster "Rect" zu verwenden. Ich benötige jedoch komplexere Formen als ein Rechteck, und ich habe versucht, das Ansichtsfenster "Rect" zu verwenden, was anscheinend nicht der Fall ist sei meine Lösung.

EDIT: Einige Leute waren durch meine Frage verwirrt, lassen Sie mich etwas näher darauf eingehen. Bildbeschreibung hier eingeben Was passiert ist, dass der Player in ein Portal einzieht, ich einen Klon-FPS-Controller erstelle und ihn aus dem anderen herausziehe. Dies gibt mir zwei Kameras und die Ansicht, die Sie oben rechts sehen. Es zeigt nur eine Kamera und schneidet durch das Portal. Was ich will , ist so etwas wie dieswo sich die Kameras mischen, um die Illusion eines sanften Übergangs zu erzeugen. Was ich tun möchte, ist alles aus dem grünen Bild links im Bild unten zu löschen und das durch die andere Kamera zu ersetzen. Auf diese Weise erhalten Sie den Teil der Ansicht von Kamera A, der aus dem Portal herausragt, und den Teil der Ansicht von Kamera B, der aus dem anderen Portal herausragt, um ein vollständiges Bild zu erhalten. Und wenn Sie sich durch das Portal bewegen, ändert sich der Schnitt entsprechend.

Ich habe ein Portalsystem entworfen, ich habe alles inaktiviert, einschließlich der Möglichkeit, den Player reibungslos durch das Portal zu bewegen. Mein Hauptproblem besteht nun darin, den Effekt zu erzielen, den Valve mit dem Kamera-Mischeffekt erzielt. Ich brauche zwei Kameras, die nahtlos zusammenpassen, als würdest du deinen Kopf durch das Portal stecken. Und es kann nicht nur ein Rechteck sein, es muss übereinstimmen, wie auch immer der Spieler durch das Portal schaut.

Meine derzeit beste Lösung besteht darin, möglicherweise einen Tiefenmasken-Shader hinter jedes Portal zu projizieren und dann die Kamera von dem Portal, auf dem Sie unterwegs sind, auf Tiefe zu stellen. Dann mischen sich irgendwie die beiden Kameras. Mein Hauptproblem besteht darin, genau herauszufinden, wie ich das machen würde, wie die zweite Kamera nur das rendert, was außerhalb des Portals ist, und den Rest standardmäßig auf Kamera 1 zu setzen, um eine Vollbildprojektion zu erhalten.

Wenn Sie mir Ideen geben oder erklären könnten, wie ich dies mit dem Tiefenmasken-Shader tun kann, wäre dies eine enorme Hilfe. Ich werde weiter daran arbeiten und aktualisieren, wenn ich Durchbrüche mache.

Timothy Williams
quelle
5
Können Sie erläutern, was das "Kamera-Mischeffekt-Ventil" bewirkt? Ich habe verstanden, dass im Portal-Rendering eine einzige Kamera ausreicht. In Ego-Spielen wird es an den Spieler angehängt und automatisch an den neuen Ort verschoben, wenn Sie zusammen mit dem Spieler das Portal durchlaufen. Zum Rendern des Portaleffekts wird eine transformierte Kopie der Szene gerendert. Dies kann auch mit einer zweiten Kamera erreicht werden, es sollte jedoch keine Notwendigkeit für eine Überblendung zwischen diesen Kameras bestehen.
Msell
1
Ich habe schon die visuellen Effekte perfekt runter. Was ich versuche, ist herauszufinden, wie ich den Effekt bekomme, durch das Portal zu laufen. Ich habe bereits alle Charaktergrafiken und solche, die sich reibungslos bewegen, ich brauche sie nur, um aus der Perspektive der ersten Person reibungslos auszusehen.
Timothy Williams
1
Ich bin sicher, dass viele Leute Ihnen bei dem Problem helfen möchten, wenn sie verstanden haben, was es war. Sie müssen das Problem wirklich besser erklären, vielleicht Bilder hinzufügen oder sogar ein Video, das den Fehler visualisiert.
Msell
2
Könnten Sie einen Link zu einem Beispielvideo des Effekts hinzufügen?
Mike Baxter
2
Was wäre, wenn Sie nur eine Kamera / einen FPS-Controller verwenden würden? Wenn sich die Kamera durch das Portal bewegt, können Sie sie in die neue Position und Ausrichtung umwandeln. Wenn das Portal-Rendering korrekt ist, sollte der Übergang nahtlos sein und keine Überblendung erforderlich sein.
msell

Antworten:

6

Das Problem verstehen

Was ich sehe, ist das Problem, das Sie beschreiben, das Ergebnis der nahen Ebene der Kamera, die die vom Portal definierte Ebene schneidet. Während diese Kreuzung auftritt, können Sie hinter der Wand sehen, auf der sich das Portal befindet.

Dies ähnelt einem Problem, das bei anderen Spielen auftritt, wenn der Spieler gerade von über Wasser zu unter Wasser wechselt. Befindet sich die Kamera direkt über dem Wasser, wird kein Nachbearbeitungseffekt angewendet, um die Sicht des Spielers zu verschleiern (machen Sie sie dunkel und verschwommen und blau). Wenn sich der Boden des nahen Flugzeugs gerade unter Wasser befindet, kann der Spieler unter Wasser klar sehen.

Wenn ich richtig bin, können Sie dies bestätigen, indem Sie beim Definieren der Projektionsmatrix die Position dieser Ebene ändern. Je größer der Abstand vom Kameraursprung zur nahen Ebene ist, desto größer sollte das Problem sein.

Die einfache Lösung

Wenn Sie das nahe Flugzeug sehr nah an der Kamera positionieren, kann dieses Problem fast behoben werden. Diese Lösung ist nicht vollständig, liefert aber in den allermeisten Fällen ein ausreichend gutes Ergebnis und ist effizient.

Die vollständige Lösung

Wenn es nicht ausreicht, die nahe Ebene näher an die Kamera heranzuführen, können Sie eine "Maske" erstellen, um die durch Rendern der Szene aus der Player- und Portalperspektive erzeugten Bilder zu mischen.

Angenommen, Sie lassen nur zu, dass Portale auf ebene Flächen angewendet werden, können Sie die Schnittlinie zwischen der nahen Ebene der Kamera und der durch das Portal (oder die Wand, auf der es liegt) definierten Ebene berechnen. Diese Zeile teilt den Bildschirm in zwei Teile. Wenn Sie bestimmen, auf welcher Seite der Linie sich ein Bildschirmpixel befindet, erfahren Sie, welches Renderbild verwendet werden soll, das Portalbild oder das Player-Kamerabild.

Denken Sie daran, dass sich der Kameraansichtsstumpf in diesem Fall vollständig innerhalb des Portals befinden muss, damit die Schnittlinie immer vollständig von einer Bildschirmkante zur anderen verläuft.

Dieser Link soll Ihnen bei der Suche nach der Linie helfen. Der folgende Code sollte ungefähr korrekt sein.

Die Schnittlinie wird über einen Punkt auf der Linie und die Linienrichtung definiert. Unterhalb der Schnittrichtung wird aus dem Kreuzprodukt der Portal-Normalen und der Kamera-Blickrichtung (nahe Normalenebene) gerechnet. Ein Punkt auf der Linie wird angegeben, indem ein Strahl von einem Punkt in der nahen Ebene direkt in Richtung der Portalebene (entlang der Portalnormalen) geworfen und der Schnittpunkt ermittelt wird.

Vector3 intersectionDir = Vector3.cross(portalNorm, viewDir);
Ray ray = new Ray(camPos + viewDir * camNearPlaneDist, portalNorm);
Vector3 intersectionPos = ray.intersects(new Plane(portalVert1, portalVert2, portalVert3);

Stellen Sie sicher, dass viewDir ein Einheitsvektor ist. portalVert1, 2 und 3 sind nur 3 der 4 Scheitelpunkte, die für das Portal-Abziehbild oder die Oberfläche verwendet werden, auf der es sich befindet. Es gibt andere Möglichkeiten, die Ebene zu definieren, auf der das Portal liegt, aber ich gehe davon aus, dass dies die am leichtesten verfügbaren Informationen sind.

Wenn Sie diese beiden Vektoren haben, um die Schnittlinie zu definieren, multiplizieren Sie sie mit der Ansicht und dann mit den Projektionsmatrizen, um sie in den Bildschirmbereich zu bringen.

Sie können dann einen Post-Process-Shader verwenden, um diese Bilder zu mischen. Sie wählen aus, welches Bild an jedem Pixel verwendet werden soll, indem Sie festlegen, auf welcher Seite der Trennlinie das aktuelle Pixel liegt. Dies geschieht, indem Sie die Pixelposition (die auch die Position ist, an der Sie das Render-Ziel-Texel nachschlagen) nehmen und dies tun.

float d = (pixelX - intersectionPos.X) * intersectionDir.Y - (pixelY - intersectionPos.Y) * intersectionDir.X;

Die Seite ist gegeben durch, ob d mehr oder weniger als 0 ist. Wenn es genau 0 ist, dann sind Sie auf der Linie.

Siehe oben Bezug auf die Mathematik dies .

Diese Methode kann auch zum Erstellen einer Tiefenmaske / eines Schablonenpuffers vor dem Rendern aus der Portalperspektive verwendet werden. Sie können ein Vollbild-Quad erstellen und die Linie zum Schneiden verwenden.

OriginalDaemon
quelle
Das nahe Clip-Flugzeug war eine gute Idee, aber nicht genau das, wonach ich suche. Dieser zweite Teil ist jedoch ein interessanter Ansatz. Momentan verwende ich einen Tiefenmasken-Shader für alle Objekte hinter der ausgehenden Portalebene und setze dann die klaren Markierungen der ausgehenden Kamera nur auf Tiefe. Dies bewirkt, dass jeder Teil der aus dem Portal herausragenden Kamera auf dem Bildschirm und die eintretende Kamera auf der Tiefenmaske gezeichnet wird. Dadurch wird ein Bild erstellt, indem die Teile jeder Kamera gemischt werden, die aus dem Portal herausragend sind jeweiligen Portal. Das einzige Problem ist, ich bekomme ein paar kleinere Beschneidungsprobleme und als
Timothy Williams
leichter Ruck, während der Spieler durch reist. Diese Idee, die Sie angesprochen haben, klingt vielversprechend. Ich muss also im Wesentlichen die Linie auf dem Bildschirm berechnen, auf der sich die Kamera in der Nähe der Ebene und die Portalebene schneiden. Die Richtung gibt an, in welche Richtung die Linie verläuft, und der Punkt gibt die verschiedenen Punkte der Linie an. Wie würde ich dann in einem Shader / Skript bestimmen, auf welcher Seite der Trennlinie ein Pixel liegt?
Timothy Williams
Ich habe die Antwort ein wenig aktualisiert, um einen Basiscode zu geben. Vergewissern Sie sich, dass Sie die Ansicht in der Nähe des Schnittebenenabstands ändern, um das Problem zu bestätigen. Möglicherweise reicht es auch aus, dies so klein wie möglich zu halten. Denken Sie daran, bringen Sie es zum Laufen, bringen Sie es zum Laufen und bringen Sie es dann zum Laufen.
OriginalDaemon
1
In Verbindung stehender Artikel: de.wikibooks.org/wiki/OpenGL_Programming/Mini-Portal_Smooth
msell
Ich habe getestet, wie ich den Abstand der nahen Schnittebene geändert habe, was das Problem etwas verbessert hat, aber wie in dem Artikel, den Mell veröffentlicht hat, angegeben ist, wird das Problem beim Durchstreichen nicht behoben. Ich habe immer noch das Gefühl, dass die Schnittlinie funktionieren könnte, also werde ich es ausprobieren. Ich werde auch ein bisschen mehr in diesen Artikel schauen, den Mell gepostet hat. Am Ende kommt es darauf an, ob eine Tiefenmaske schneller ist oder ob diese Schnittlinie schneller ist
Timothy Williams,
3

Die vorgeschlagenen Antworten waren sehr gut, aber ich entschied mich für eine andere Technik mit einer Tiefenmaske.

Sie nehmen DIESES Skript und diesen Shader, setzen das Skript auf jedes Objekt mit einem Renderer in Ihrer Szene und stellen die Renderwarteschlange auf 3020 (ich werde später ein Skript veröffentlichen, um dies zu vereinfachen).

Dann erstellen Sie eine Kiste mit Ebenen (alle nach innen gerichtet, auf dem Bild sehen Sie nicht die Seite der Kiste, die Ihnen am nächsten liegt, aber wenn Sie sich in der Kiste befinden, sollten Sie nur Grau sehen) hinter BEIDEN Ihrer Portale wie so: Bildbeschreibung hier eingeben Und lege sie auf eine eigene spezielle Ebene (ich habe "DepthMask" für meine ausgewählt), dann fügst du ein Material mit dem Shader darüber hinzu. Bildbeschreibung hier eingeben

Dann nimmst du die Hauptkamera und hebst die Markierung deiner Spezialebene von der Auslese-Maske auf (ich habe die Tiefenmasken-Ebene deaktiviert) und stellst die Tiefe auf 0. Bildbeschreibung hier eingeben

Wenn Sie dann durch die Kamera teleportieren und sie klonen, setzen Sie die Markierung der anderen Kamera auf "Nur Tiefe" und die Tiefe auf 1. Bildbeschreibung hier eingeben

Sie erhalten dann einen nahtlosen Bildschirm zwischen den beiden Kameraansichten.

Timothy Williams
quelle