Stereoskopie mit Windows Phone und MonoGame

StereoscopicTest03

Inzwischen findet sich immer mehr Zubehör für das Smartphone, um etwas Ähnliches zu schaffen wie die Oculus Rift. Zum Thema habe ich vor ein einigen Tagen im AppStore fürs Windows Phone nach solchen Apps mit Stereoskopie Ausgabe erfolglos gesucht. Die Verbreitung ist offenbar Android und iOS vorbehalten. Kommen wir aber zu der Frage: wie schwer ist die Umsetzung einer Stereoskopie Wiedergabe?

Das Prinzip ist simpel. Der gezeigte Inhalt wird für das linke und das rechte Auge gerendert. Um den 3d Effekt zu erzielen, müssen, wie in der realen Welt, zwei Kameras eingesetzt werden, die zueinander leicht versetzt sind. Doch wie sieht das im Programmcode aus?

Tatsächlich wird das für dieses Beispiel mit wenigen Ergänzungen im Programmcode erreicht. Und am Ende werden Sie sich fragen, wieso das noch keiner für Windows Phone gemacht hat.

Bevor Sie starten, sollten Sie neben Visual Studio 2013 noch MonoGame installiert haben und dann können Sie mit einem neuen Projekt für Windows Phone 8.1 starten.

image

Mit dem neuen Projekt wird in der Vorlage bereits eine fertige Szene mit einem 3d Würfel vorgegeben. Daher gehe ich im Beispiel nur auf das Wesentliche ein, nämlich, welche Ergänzungen notwendig sind.

Öffnen Sie die Game1.cs und legen sie oben zusätzliche Member Variable an.

// Ausgabebereich
Viewport viewportDefault;
Viewport viewportLeft;
Viewport viewportRight;

// Renderbereich
Matrix matrixProjection;
Matrix matrixProjectionHalf;

// Kamera Position und Ausrichtung
Matrix matrixViewLeft;
Matrix matrixViewRight;

In der Methode ‘Initialize()’ wird die Kameraposition und Ausrichtung festgelegt. Zusätzlich wird der ViewPort zusammengestaucht und der Platz für zwei Bilder hergerichtet. Mit den zwei Variablen für die Projektion wird noch der Renderbereich festgelegt.

this.matrixViewLeft = Matrix.CreateLookAt(new Vector3(.3f, 1f, -4f), new Vector3(0, 0, 0), Vector3.Up);
this.matrixViewRight = Matrix.CreateLookAt(new Vector3(-0.3f, 1f, -4f), new Vector3(0, 0, 0), Vector3.Up);

this.viewportDefault = this.GraphicsDevice.Viewport;
this.viewportLeft = viewportDefault;
this.viewportRight = viewportDefault;
this.viewportLeft.Width = viewportLeft.Width / 2;
this.viewportRight.Width = viewportRight.Width / 2;
this.viewportRight.X = viewportLeft.Width;

this.matrixProjection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 4.0f / 3.0f, 1, 10000);
this.matrixProjectionHalf = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 2.0f / 3.0f, 1, 10000);

Zuletzt wird eine Änderung an der ‘Draw()’ Methode vorgenommen. Der zu rendernde Inhalt wird nun als eigene Methode mit dem Namen ‘DrawScene’ ausgelagert.

image

Damit dürfte Anschließend Ihre Methode so aussehen.

private void DrawScene(ref Matrix View, ref Matrix Projection, ref Matrix World)
{
    vertexBuffer.SetData(cube, 0, 8, SetDataOptions.Discard);
    indexBuffer.SetData(cubeIndices, 0, 36, SetDataOptions.Discard);

    GraphicsDevice device = basicEffect.GraphicsDevice;
    device.SetVertexBuffer(vertexBuffer);
    device.Indices = indexBuffer;

    basicEffect.View = View;
    basicEffect.Projection = Projection;
    basicEffect.World = World;
    foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
    {
        pass.Apply();
        device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 8, 0, 36);
    }
}

Die Matrix Variable für ‘View’ und ‘Projection’ werden ersetzt. Im folgenden Code werden Sie erkennen, wie nun das Splitting erreicht wird.

// Linke Seite
this.GraphicsDevice.Viewport = this.viewportLeft;
this.DrawScene(ref this.matrixViewLeft, ref this.matrixProjectionHalf, ref World);

// Rechte Seite
this.GraphicsDevice.Viewport = this.viewportRight;
this.DrawScene(ref this.matrixViewRight, ref this.matrixProjectionHalf, ref World);

Und schon ist das Beispiel fertig. Nach Drücken auf die F5 Taste und hochladen auf das Smartphone dürfte nun, wie im Bild zu sehen, dieses Ergebnis erscheinen:

Stereoscopic_01

Fehlt noch der Aufsatz, um die Stereoskopie zu erleben. Für wenig Geld bekommen Sie bei Online Händlern z.B. ein aus Pappe hergestelltes Gestell mit den entsprechenden Linsen. Achten Sie in diesem Fall darauf, welche Größe Ihr Smartphone hat.

DIY Google Karton_01 DIY Google Karton_02
DIY Google Karton_03

Was eigentlich noch fehlt, um die Sache im wahrsten Sinne des Wortes abzurunden, ist die fehlende Krümmung. Der 3D-Effekt wirkt ein wenig nach innen gezogen. Wer bereits die Oculus Rift oder Bilder davon gesehen hat, wird feststellen, dass die Renderbilder einen leichten Fischaugeneffekt haben. Was den Komfort angeht, naja, zum Experimentieren reicht die Lösung aus.

Quellen:

Suchbegriffe:

  • Virtual Reality
  • VR Handy 3d
  • Google Cardboard

Beispiel Solution: ExampleMonoGameStereoscopic (VS2013, MonoGame)

Kommentare

Beliebte Posts aus diesem Blog

Arduino Control (Teil 5) - PWM Signal einlesen

RC Fahrtenregler für Lego Kettenfahrzeug

Angular auf dem Raspberry Pi