Wenn wir von Teil 1, wo wir uns mit Papervision3D befasst haben, fortfahren, führt Teil 2 unsere Szene ein wenig weiter. In diesem abschließenden Teil erfahren Sie, wie Sie Ihre drehenden Würfel mit einer 3D-Brille zum Betrachter springen lassen.
Ich weiß, dass dort oben gesagt wird, dass es in diesem Tutorial um Papervision3D in Flash geht, aber eigentlich geht es darum, Ihr Gehirn zu betrügen. Wir werden Ihrem Gehirn den Eindruck vermitteln, dass es sich um ein echtes 3D-Objekt handelt, obwohl es tatsächlich nur ein 2D-Bild ist.
Wenn Sie mit Papervision3D vertraut sind, können Sie dies durch die Verwendung eines Projekts mit Szene, Kamera und Ansichtsfenster verfolgen. Wenn nicht, schauen Sie sich zuerst Teil 1 dieses Tutorials an. Ich werde dort weitermachen, wo wir aufgehört haben. Hier ist das, woran wir arbeiten werden:
Zeigen Sie mit dem Finger in die Luft und halten Sie ihn vor die Nase.
Betrachten Sie es mit nur Ihrem rechten Auge, dann nur mit Ihrem linken. Sehen Sie, wie es scheint, von links nach rechts zu springen, während sich das, was sich im Hintergrund befindet, kaum bewegt?
Ihr Gehirn bemerkt diese Unterschiede zwischen dem, was jedes Ihrer Augen sieht, und verwendet sie, um eine vollständige 3D-Simulation der Welt um Sie herum zu generieren. In deinem Kopf. Sofort. Ziemlich beeindruckend!
Wenn wir Ihr Gehirn betrügen wollen, müssen wir jedem Ihrer Augen ein anderes Bild zeigen. Zu Beginn fügen wir der Szene ein weiteres "Auge" (eine andere Kamera) hinzu. Dies wird verwendet, um das Bild für Ihr rechtes Auge zu erstellen, während das Bild der vorhandenen Kamera auf Ihr linkes Auge übertragen wird.
Erstellen Sie eine neue öffentliche Variable namens camera2…
public var camera2: Camera3D;
… Und initialisieren Sie es in der Konstruktorfunktion Main ():
Kamera = neue Kamera3D ();
Wir benötigen ein anderes Ansichtsfenster, um die Kameraausgabe aufzunehmen. Fügen Sie also Folgendes hinzu:
public var viewport2: Viewport3D;
viewport2 = new Viewport3D (); viewport2.autoScaleToStage = true; // Dadurch wird das Ansichtsfenster so groß wie die Bühne. addChild (viewport2);
(Ich durchsteige das, da wir das letzte Mal alles behandelt haben.)
Merken, viewport2 bleibt leer, bis wir etwas dazu rendern. Dafür müssen wir keinen neuen Renderer erstellen. Verwenden Sie einfach das vorhandene zweimal. Nehmen Sie in Main () diesen Code an:
Renderer = new BasicRenderEngine (); Renderer.RenderScene (Szene, Kamera, Darstellungsbereich);
… Und fügen Sie eine neue Zeile hinzu, um die zweite Kamera wie folgt in den zweiten Ansichtsbereich zu rendern:
Renderer = new BasicRenderEngine (); Renderer.RenderScene (Szene, Kamera, Darstellungsbereich); Renderer.RenderScene (Szene, Kamera2, Darstellungsbereich2);
Machen Sie dasselbe auch in Ihrer onEnterFrame () - Funktion:
Renderer.RenderScene (Szene, Kamera, Darstellungsbereich); Renderer.RenderScene (Szene, Kamera2, Darstellungsbereich2);
Wenn Sie das jetzt testen, wird es genauso aussehen wie zuvor:
Kein Wunder: Zum einen befinden sich die beiden Kameras genau am selben Ort!
Kameras sind standardmäßig unter (x = 0, y = 0, z = -1000) platziert. Sie können dies überprüfen trace (camera.x, camera.y, camera.z).
Von oben gesehen sieht die Szene so aus:
Von der Seite gesehen ist es so:
Um unsere eigenen Augen richtig zu imitieren, sollten wir unsere zweite Kamera etwas rechts von unserer ersten positionieren:
Versuchen wir, es um 50 Pixel nach rechts zu verschieben und zu sehen, was passiert. Fügen Sie dies in Main () ein, nachdem Sie die zweite Kamera erstellt haben:
camera2.x = camera.x + 50;
Testen Sie es jetzt und sehen Sie, was Sie bekommen:
Es sieht komisch aus, aber es funktioniert eindeutig! Der Bereich um die Würfel ist in jedem Ansichtsfenster transparent, sodass der erste hinter dem zweiten sichtbar ist.
Es ist nützlich, in der Lage zu sein, zu sehen, was jede Kamera einzeln sieht. Lassen Sie uns also die Augen-Analogie weiterführen, indem Sie sie "zwinkern", wenn wir klicken. Fügen Sie zunächst jedem Ereignisfenster einen Ereignis-Listener hinzu, um die Mausklicks zu erkennen:
viewport.addEventListener (MouseEvent.CLICK, onClickViewport); viewport2.addEventListener (MouseEvent.CLICK, onClickViewport2);
Setzen Sie das am Ende der Main () - Funktion. Vergessen Sie nicht, MouseEvent zu importieren:
import flash.events.MouseEvent;
Fügen Sie Ihrem Code diese neuen Funktionen außerhalb der Main () - Funktion hinzu, jedoch innerhalb der Main-Klasse:
öffentliche Funktion onClickViewport (mouseEvt: MouseEvent): void öffentliche Funktion onClickViewport2 (mouseEvt: MouseEvent): void
Wenn wir auf das erste Ansichtsfenster klicken, müssen wir es unsichtbar machen, während das zweite sichtbar wird (und umgekehrt, wenn wir auf das zweite klicken). Ändern Sie also Ihre Event-Handler wie folgt:
öffentliche Funktion onClickViewport (mouseEvt: MouseEvent): void viewport.visible = false; viewport2.visible = true; public function onClickViewport2 (mouseEvt: MouseEvent): void viewport.visible = true; viewport2.visible = false;
Versuch es:
Beachten Sie, dass Sie auf einen der Würfel klicken müssen. Die transparenten Bereiche lösen kein CLICK MouseEvent aus.
Sie benötigen eine 3D-Anaglyphenbrille. die Art, bei der jede Linse eine andere Farbe hat. Das Paar, das ich verwende, hat eine gelbe Linse im linken Auge und eine blaue Linse im rechten Auge (ColorCode3D-System genannt), aber auch andere Farbkombinationen sind beliebt, wie Rot und Cyan.
Sie können diese Brille bei eBay für ein paar Dollar finden: suchen Sie einfach nach 3D-Brille
Alternativ können Sie sogar Ihre eigenen machen! Im ersten Teil dieses Tutorials hat André einen Kommentar gepostet, in dem er erklärt, dass er Tic-Tac-Boxen in verschiedenen Farben für seine Herstellung verwendet. Genius!
Obwohl meine Beispiele für gelbe und blaue Brillen gemacht werden, versuche ich, die Prinzipien zu erklären, damit Sie Ihre Farben mit den von Ihnen verwendeten Farben zum Laufen bringen können. Es ist ein bisschen knifflig, bitte poste hier einen Kommentar, wenn dies verwirrend wird!
Jedes Pixel auf Ihrem Computer ist wie eine Gruppe von drei Glühbirnen: eine rote, eine grüne und eine blaue.
Durch Anpassen der Helligkeit jeder "Birne" können wir die Farbe dieses Pixels ändern:
Die Linsen in einer 3D-Brille verhindern, dass das Licht einiger dieser Lampen durchkommt. Zum Beispiel verhindert die blaue Linse in meiner Brille, dass rotes und grünes Licht mein Auge erreicht.
Wenn ich also dieses Bild durch meine blaue Linse sehe, kann ich es nicht lesen:
Aus dem schwarzen Bereich fällt kein Licht in mein Auge, da alle drei Lampen ausgeschaltet sind. Und aus dem grünen Bereich fällt kein Licht in mein Auge, weil nur die grüne Birne eingeschaltet ist und die blaue Linse das herausfiltert. Ich sehe also nur ein schwarzes Rechteck.
Nun, OK, wenn Sie dies selbst versuchen, stellen Sie möglicherweise fest, dass dies nicht ganz richtig ist. Ihr Objektiv ist wahrscheinlich nicht zu 100% aus reinem Blau, sodass etwas grünes und rotes Licht durchgelassen wird. Oder vielleicht werden die Farben Ihres Monitors anders kalibriert als meine, sodass der grüne Text etwas Rot und Blau enthält. Um ehrlich zu sein, dasselbe gilt für mich - aber es spielt keine Rolle, solange der Text vorliegt schwer lesen.
Unser Ziel ist es, Ihrem rechten Auge das Bild von der linken Kamera sowie dem linken und der rechten Kamera zu erschweren.
Die blaue Linse ist über meinem rechten Auge. Wenn ich also das gesamte blaue Bild von der linken Kamera entferne, kann ich es theoretisch nicht mit meinem rechten Auge sehen.
In diesem Schritt soll das Bild des linken Ansichtsfensters nur rotes und grünes Licht emittieren. überhaupt kein blaues Licht. Wir können dies mit einem tun ColorTransform. Diese sind einfach einzurichten. Importiere zuerst die Klasse:
import flash.geom.ColorTransform;
Erstellen Sie dann eine neue öffentliche Variable, die eine Instanz der Klasse enthalten soll:
public var leftViewportColorTransform: ColorTransform;
Erstellen Sie nun diese neue Instanz in Main ():
leftViewportColorTransform = new ColorTransform ();
Weisen Sie Flash schließlich an, diese ColorTransform auf das Ansichtsfenster der linken Kamera anzuwenden:
viewport.transform.colorTransform = leftViewportColorTransform;
(Diese letzte Zeile muss sich erst befinden, nachdem Sie den Darstellungsbereich und die Farbumwandlung erstellt haben. Es ist wahrscheinlich am einfachsten, ihn direkt am Ende von Main () festzulegen.)
Die SWF-Datei sieht noch nicht anders aus, da ColorTransform das Bild standardmäßig nicht ändert.
Wir können wählen, welchen Bruchteil des Lichts jeder Birne wir durch Ändern der Glühlampe durchlassen wollen blueMultiplier, greenMultiplier und redMultiplier Eigenschaften unserer ColorTransform.
Setzen Sie eine dieser Einstellungen auf 1 teilt Flash mit, es in Ruhe zu lassen, während es eingestellt wird 0 weist Flash an, es vollständig auszuschalten. Und natürlich, 0,5 Dadurch wird die Ausgabe um die Hälfte reduziert, 2,0 wird es verdoppeln, und so weiter.
Um das gesamte Blau aus dem linken Ansichtsfenster zu entfernen, können Sie Folgendes tun:
leftViewportColorTransform.blueMultiplier = 0;
Sie müssen das vor die Zeile setzen, die die Transformation für das Ansichtsfenster anwendet, wie folgt:
leftViewportColorTransform.blueMultiplier = 0; viewport.transform.colorTransform = leftViewportColorTransform;
Wenn Ihre Brille eine rote oder grüne Linse über dem rechten Auge hat, sollten Sie die Brille einstellen redMultiplier oder greenMultiplier zu 0, anstatt das Blau. Für alle anderen Farben müssen Sie eine Mischung aus Rot, Grün und Blau verwenden - mehr dazu in Schritt 15.
Testen Sie die SWF:
Es ist schwierig, das "a" des Logos durch die blaue Linse zu erkennen, aber es ist überhaupt nicht schwierig, die Form der Würfel vor diesem weißen Hintergrund zu erkennen!
Wenn Sie den Hintergrund Ihrer SWF-Datei ändern, wird das Problem angezeigt. Da der "weiße" Bereich um die Würfel eigentlich nicht weiß ist, sondern transparent ist und den weißen Hintergrund der SWF-Datei durchscheinen lässt, wird er nicht von der ColorTransform beeinflusst.
Um dies zu beheben, müssen wir dem Ansichtsfenster einen durchgehenden weißen Hintergrund geben, auf dem die Würfel darüber gerendert werden. Das ist leicht genug. Gehen Sie einfach dorthin zurück, wo Sie das Ansichtsfenster erstellt haben:
viewport = new Viewport3D (); viewport.autoScaleToStage = true; // Dadurch wird der Darstellungsbereich so groß wie die Bühne
… Und fügen Sie ein paar Zeilen hinzu, um ein weißes Rechteck zu zeichnen, das so groß ist wie die Bühne:
viewport = new Viewport3D (); viewport.autoScaleToStage = true; // Dadurch wird das Ansichtsfenster so groß wie die Bühne. viewport.graphics.beginFill (0xffffff); // 0xffffff is white viewport.graphics.drawRect (0, 0, stage.stageWidth, stage.stageHeight);
Testen Sie es noch einmal:
Das Bild sollte wirklich schwach, stumpf und durch die rechte Linse schwer zu sehen sein, aber so leicht wie das normale Bild, durch die linke Linse zu sehen.
Wir müssen jetzt dasselbe für das richtige Ansichtsfenster tun. So erstellen Sie Ihre neue ColorTransform:
public var rightViewportColorTransform: ColorTransform;
rightViewportColorTransform = new ColorTransform ();
Wenden Sie diese neue Transformation nun auf das rechte Ansichtsfenster an:
viewport2.transform.colorTransform = rightViewportColorTransform;
Da meine linke Linse gelb ist, muss ich alles gelbe aus diesem Ansichtsfenster entfernen.
(Wenn Ihr linkes Objektiv rot ist, ist dieser Schritt einfach - setzen Sie einfach das redMultiplier Ihrer neuen ColorTransform auf 0.)
Aber wie bekommen wir Gelb aus Rot, Grün und Blau??
Wenn wir Farben verwenden, könnten wir nicht; Gelb ist in diesem Fall eine Primärfarbe. Im Umgang mit Licht sind die Dinge jedoch anders. Schau dir das an:
Bild aus Wikimedia Commons. Danke, Mike Horvath und Jacobolus!
Wie Sie sehen, mischen sich Rot und Grün zu Gelb (was erklärt, warum der Hintergrund des linken Ansichtsfensters gelb wurde, als wir alle blauen Bereiche entfernt hatten). Um also das gesamte Gelb aus unserem Bild zu entfernen, müssen wir das gesamte Rote und das Grüne entfernen!
Wir können das so machen:
rightViewportColorTransform = new ColorTransform (); rightViewportColorTransform.redMultiplier = 0; rightViewportColorTransform.greenMultiplier = 0; viewport2.transform.colorTransform = rightViewportColorTransform;
Oh, richtig, wir müssen auch den Hintergrund dieses Viewports ausfüllen.
Tun Sie dies auf dieselbe Weise wie zuvor:
viewport2 = new Viewport3D (); viewport2.autoScaleToStage = true; // Dadurch wird das Ansichtsfenster so groß wie die Bühne. viewport2.graphics.beginFill (0xffffff); // 0xffffff is white viewport2.graphics.drawRect (0, 0, stage.stageWidth, stage.stageHeight);
Testen Sie es aus:
Die gelbe Linse an meiner Brille lässt zwar ziemlich viel blaues Licht durch, ist aber durch diese Linse viel dunkler als durch die blaue Linse, und darauf kommt es an.
Wir haben also unsere zwei Bilder eingerichtet und farblich verändert. Das Problem ist, im Moment können wir jeweils nur einen von ihnen sehen.
Der naheliegendste Weg, uns beide gleichzeitig sehen zu lassen, besteht darin, das Alpha (die Transparenz) des Ansichtsfensters an der Vorderseite zu reduzieren, wie dies z.
Viewport2α = 0,5;
Testen Sie das aus:
Ah. OK, kein mitreißender Erfolg. Alpha ist eindeutig nicht das richtige Werkzeug für den Job; Was haben wir noch??
Flash gibt uns die Wahl zwischen mehreren Mischmodi, Methoden zum Zusammenfügen von zwei Anzeigeobjekten. Es gibt eine vollständige Liste hier, aber ich werde mich nur auf die genannte konzentrieren hinzufügen.
Das hinzufügen Der Mischmodus durchläuft jedes Pixel der beiden Bilder und addiert die Helligkeit aller drei Lampen.
Wenn also bei einem bestimmten Pixel im ersten Bild die grüne Birne vollständig eingeschaltet ist und die anderen beiden vollständig ausgeschaltet sind und derselbe Pixel im zweiten Bild die blaue Birne vollständig und die anderen beiden vollständig ausgeschaltet ist, dann werden das grüne und das grüne Element miteinander vermischt Die blauen Glühbirnen leuchten vollständig und die rote Glühbirne ist vollständig ausgeschaltet.
Wenn für das erste und zweite Bild die rote Birne zur Hälfte eingeschaltet und die anderen beiden vollständig ausgeschaltet sind, wird die rote Birne für das gemischte Bild vollständig eingeschaltet sein, während die anderen beiden ausgeschaltet bleiben.
Verstehe? Großartig, lass es uns benutzen. Löschen Sie die gerade geschriebene Zeile, die das Alpha angepasst hat, und ersetzen Sie es durch Folgendes:
viewport2.blendMode = "add";
(Der Mischmodus muss nicht auf beide Ansichtsfenster angewendet werden, sondern nur auf den Modus oben in der Anzeigeliste.)
Testen Sie es aus:
Das ist eher so!
Wenn Sie es mit einem Auge auf einmal betrachten, sollten Sie feststellen, dass jedes Auge einen anderen Ansichtsbereich auffälliger sieht. Sie werden wahrscheinlich auch einen schwachen Geist des anderen Ansichtsfensters sehen können, aber das ist kein Problem. Ihr Gehirn kann das ignorieren.
Allerdings sieht das Bild noch nicht ganz 3D aus. Lass uns das klären.
Obwohl Ihre Augen andere Bilder sehen, reicht dies nicht aus, um Ihr Gehirn zu täuschen. Ihr Gehirn ist ziemlich schlau, verstehen Sie? Einige würden sogar sagen, dass es das klügste Organ in Ihrem Körper ist. Es weiß, dass es andere Hinweise verwenden sollte, um herauszufinden, ob ein Objekt 3D ist oder nicht. Perspektive zum Beispiel: Wie klein ein Objekt aussehen sollte, je nachdem, wie weit es entfernt ist.
Das Hauptproblem dabei ist, dass unsere beiden Kameras viel weiter voneinander entfernt sind als unsere eigenen Augen. Das ist nicht überraschend, da ich zufällig die Nummer 50 gewählt habe.
Der tatsächliche Abstand, den wir verwenden sollten, hängt von einer Reihe von Faktoren ab, beispielsweise davon, wie weit Sie vom Monitor entfernt sind und wie groß Ihr Bildschirm ist. Daher kann ich Ihnen nicht einfach eine magische Zahl angeben. Wir müssen es manuell herausfinden.
Wir könnten dies tun, indem wir viele verschiedene Zahlen nacheinander ausprobieren, aber das ist langweilig und wird ewig dauern. Ich habe eine bessere Idee.
Fügen Sie diese Zeile Ihrer onEnterFrame () - Funktion hinzu:
camera2.x = camera.x + (mouseX * 0,1);
Ändern Sie nun Ihre onClickViewport- und onClickViewport2-Funktionen wie folgt:
öffentliche Funktion onClickViewport (mouseEvt: MouseEvent): void trace (camera2.x - camera.x); public function onClickViewport2 (mouseEvt: MouseEvent): void trace (camera2.x - camera.x);
Führen Sie die SWF-Datei aus und bewegen Sie die Maus nach links und rechts. Es wird so aussehen:
Setzen Sie Ihre Brille auf, schalten Sie das Licht aus und bewegen Sie die Maus, bis Sie den "Sweet Spot" finden, an dem das Bild fest zu sein scheint. Klicken Sie an dieser Stelle mit der Maus, und es wird eine Zahl ermittelt. Notieren Sie es sich!
Sobald Sie die optimale Trennung gefunden haben, löschen Sie die gerade hinzugefügte Zeile zur onEnterFrame () - Funktion:
camera2.x = camera.x + (mouseX * 0,1);
Suchen Sie nun die Linie in Main (), in der Sie den Abstand zwischen den Kameras einstellen:
camera2.x = camera.x + 50;
… Und ersetzen Sie die 50 durch die Nummer, die Sie notiert haben. Ich fand, dass 18 eine gute Zahl für mein Setup war.
Zum Schluss testen Sie die SWF:
Ta-da!
Gut gemacht - Sie haben eine 3D-Szene in Flash erstellt und mit einem Verstand in eine 3D-Szene in Ihrem Kopf übertragen.
Wenn Sie alles verstanden haben, was Sie durchgemacht haben, sollten Sie in der Lage sein, 3D-Anaglyphenbilder mit anderen 3D-Engines zu erstellen.
Ich habe im ersten Teil erwähnt, dass Sie vielleicht versuchen möchten, dass der Benutzer die Kamera mit der Maus bewegen kann. Jetzt haben Sie den Anaglypheneffekt hinzugefügt. Das Bewegen der Kameras nach vorne und hinten wird sehr eindrucksvoll aussehen.
Vielen Dank, dass Sie dieses Tutorial gelesen haben. Ich hoffe, Sie fanden es nützlich. Wenn Sie Fragen haben, fragen Sie sie bitte in den Kommentaren unten.