Donnerstag, 2. Juni 2016

Erstellen einer eigenen VR-Welt welche in Browsern auf allen Plattformen läuft

Lange nicht gesehen! Sorry, ich bin sehr beschäftigt ...

Heute möchte ich euch zeigen, wie man ganz einfach eine eigene VR-Erfahrung mit dem WebVR Boilerplate erstellt:
Ein THREE.js-basierter Ausgangspunkt für VR Erfahrungen, welcher sowohl Google-Cardboards als auch andere VR-Headsets unterstützt. Außerdem wird ein Fallback angeboten, der das Erleben des gleichen Inhalts erlaubt, ohne dass eine VR-Vorrichtung erforderlich ist.
Das Ergebnis am Ende wird wie folgt aussehen:


Dieser Screenshot wurde in Chrome (Version 50.0.2661.102 m) ohne den VR-Modus gemacht.
Ihr könnt es selbst auf http://badtoxic.de/webvr begutachten.
Wenn euer Browser mit dem VR-Modus kompatibel ist, seht ihr einen kleinen Cardboard-Button in der rechten unteren Ecke. Ich habe den VR-Modus mit Android, iOS (Safari auf dem iPhone 6+, iOS 9.3.2) und einem speziellem Chromium-Build auf meinem PC mit einer HTC Vive getestet. Ihr könnt auch eine Firefox Nightly Version mit dem Oculus Rift Enabler verwenden.
Für weitere Infos könnt ihr webvr.info besuchen.

Los geht's

1. Zuerst solltet ihr Boris’ WebVR Boilerplate repo klonen oder herunterladen
git clone https://github.com/borismus/webvr-boilerplate.git

2. Dies könnt ihr dann auf euren Webserver hochladen oder einen lokalen starten, genauso, wie ihr es für jede andere Web-Anwendung tun würdet
cd webvr-boilerplate/
python -m SimpleHTTPServer 8000

Um zu testen, ob der Server läuft, öffnet localhost auf dem Port, mit dem der Server spricht. (Standard: http://localhost:8000)


Alternativ könnt ihr einen Dropbox Public-Ordner verwenden, wenn ihr einen habt, wie ich es hier gemacht habe:
Web VR BadToxic Beispiel auf Dropbox

Ihr solltet nun die Standard-Boilerplate-Szene, mit einem sich drehenden Würfel vor einem schwarzen Hintergrund mit grünen Rasterlinien sehen.


Glückwunsch! Ihr habt eure erste VR-Web-App erstellt.

3. Nun lasst uns beginnen, indem wir die Szene modifizieren - wir ersetzen das Hintergrund-Gitter mit einer Skybox-Kugel.
Als erstes lasst uns alles entfernen, was mit dem Laden der Hintergrundtextur img/box.png und der alten skybox zu tun hat. Stattdessen laden wir eine andere Textur, die wir im img-Ordner abgelegt haben - zum Beispiel ein skybox.png, welches wir vielleicht durch eine Suche nach "skybox" mit Google gefunden haben... Aber denkt stets daran, dass Texturen immer Größen von 2er-Potenzen haben müssen, wie etwa 1024x512. Ich habe dieses Bild gefunden:


Und so kann unser Code wie folgt aussehen:
var textureLoader = new THREE.TextureLoader();
var skybox;
textureLoader.load('img/skybox.png', function (skyboxTexture) {
  var skyboxMaterial = new THREE.MeshBasicMaterial();
  skyboxMaterial.map = skyboxTexture;
  skyboxMaterial.side = THREE.BackSide;

  // Create the mesh based on geometry and material
  var skyboxSphereGeometry = new THREE.SphereGeometry(50, 200, 200);
  var skyboxmesh = new THREE.Mesh(skyboxSphereGeometry, skyboxMaterial);
  skybox = new THREE.Mesh(skyboxSphereGeometry, skyboxMaterial);
  scene.add(skybox);
};

Hier haben wir einen Textur-Loader erstellt und rufen seine Funktion load auf, um unser neues Bild zu laden. Die Funktion benötigt auch eine weitere Funktion, die aufgerufen wird, wenn das Laden der Textur abgeschlossen wurde. Wenn diese asynchrone Funktion aufgerufen wird, wird das Skybox-Material mit der geladenen Textur erstellen und die Skybox instanziiert, welche wir dann zu unserer Szene hinzufügen.

4. Danach können wir unserem Würfel eine ausgefallene Textur hinzufügen. Also laden wir einfach eine andere Textur wie im vorherigen Schritt und binden diese an den Würfel.
So habe ich den folgenden Code direkt nach dem scene.add(skybox); des letzten Code-Ausschnitts hinzugefügt (in unserer asynchronen Funktion der Skybox).
textureLoader.load('img/toxicon_logo.png', function (toxiconLogoTexture) {
  var toxiconCubeGeometry = new THREE.BoxGeometry(0.5, 0.5, 0.5);
  var toxiconCubeMaterial = new THREE.MeshBasicMaterial();
  toxiconCubeMaterial.map = toxiconLogoTexture;
  toxiconCube = new THREE.Mesh(toxiconCubeGeometry, toxiconCubeMaterial);

  // Position cube mesh to be right in front of you.
  toxiconCube.position.set(0, controls.userHeight, -1);
  
  // Add cube mesh to your three.js scene
  scene.add(toxiconCube);
  
  // For high end VR devices like Vive and Oculus, take into account the stage
  // parameters provided.
  setupStage();
});



Fertig!

Also - das sollte für unser kleines Tutorial ausreichen. Unser Code resultiert nun in folgende Szene.


Dieses Mal habe ich den erwähnten Chromium-Build verwendet und den VR-Modus gestartet. Deshalb sehen wir zwei Bilder - eines für jedes Auge.
Wenn ihr Fragen oder Anregungen habt, fühlt euch frei unten die Kommentar-Funktion zu nutzen.
Und wenn ihr das komplette Projekt anschauen wollt, können ihr mich auf GitHub besuchen unter:



Vielen Dank für's Lesen - man sieht sich!
Übrigens, auch mein Mii mag VR!




Quellen:
WebVR
WebVR Boilerplate
Responsive WebVR
4 Steps to Start Experimenting with WebVR in 10 Minutes

Siehe auch:
MOZVR
WebVR Samples

Mittwoch, 1. Juni 2016

Creating your own VR world running in browsers on all platforms

Long time no see! Sorry, I'm very busy...

Today I want to show you, how you can easily create your own VR experience using WebVR Boilerplate:
A THREE.js-based starting point for VR experiences that work well in both Google Cardboard and other VR headsets. Also provides a fallback for experiencing the same content without requiring a VR device.
 The result will look like this in the end:


This screenshot was taken in Chrome (Version 50.0.2661.102 m) without the VR mode enabled.
You can check it out yourself by visiting http://badtoxic.de/webvr.
If your browser is compatible to the VR mode you will see a little cardboard button on the bottom right. I testet the VR mode with Android, iOS (Safari on iPhone 6+, iOS 9.3.2) and a special chromium build on my pc with a HTC Vive. You also can use Firefox Nightly with an Oculus Rift enabler installed.
For more info visit webvr.info.

Getting started

1. At first you should clone or download Boris’ WebVR Boilerplate repo
git clone https://github.com/borismus/webvr-boilerplate.git

2. Then you can upload this to your web server or start a local one, similar to way you’d have to spin up a server for any regular web app like
cd webvr-boilerplate/
python -m SimpleHTTPServer 8000

To test that your server is running, open up localhost on the port that your server is talking to. (Default: http://localhost:8000)

Alternatively you can use a Dropbox Public folder, if you have one, like I did here:
Web VR BadToxic example on Dropbox

You should now see the default boilerplate scene, with a spinning cube against a black background with green gridlines.



Congratulations! You just deployed your first VR web app.

3. Now let us start modifying the scene by replacing the background grid with a skybox sphere.
So first remove everything that has to do with loading the background texture img/box.png and the skybox. Instead we load another texture we placed in the img folder - for example a skybox.png we may have found via google by searching "skybox"... But remember that textures always have to have any power of 2 size like 1024x512. So I just found this image:


And so our code may look like the following:
var textureLoader = new THREE.TextureLoader();
var skybox;
textureLoader.load('img/skybox.png', function (skyboxTexture) {
  var skyboxMaterial = new THREE.MeshBasicMaterial();
  skyboxMaterial.map = skyboxTexture;
  skyboxMaterial.side = THREE.BackSide;

  // Create the mesh based on geometry and material
  var skyboxSphereGeometry = new THREE.SphereGeometry(50, 200, 200);
  var skyboxmesh = new THREE.Mesh(skyboxSphereGeometry, skyboxMaterial);
  skybox = new THREE.Mesh(skyboxSphereGeometry, skyboxMaterial);
  scene.add(skybox);
};

Here we created a texture loader and call its function load for our new image. The function also need a further function that will be called when loading the texture has finished. When this asynchronous function is called, it will create the skybox material with the loaded texture and instanciate the skybox we then add to our scene.

4. After that we may want to add some fancy texture to our cube. So we just do load another texture like in the previous step and bind it to the cube.
So I added the following code just after the scene.add(skybox); of the last one (inside our asynchronous function of the skybox).
textureLoader.load('img/toxicon_logo.png', function (toxiconLogoTexture) {
  var toxiconCubeGeometry = new THREE.BoxGeometry(0.5, 0.5, 0.5);
  var toxiconCubeMaterial = new THREE.MeshBasicMaterial();
  toxiconCubeMaterial.map = toxiconLogoTexture;
  toxiconCube = new THREE.Mesh(toxiconCubeGeometry, toxiconCubeMaterial);

  // Position cube mesh to be right in front of you.
  toxiconCube.position.set(0, controls.userHeight, -1);
  
  // Add cube mesh to your three.js scene
  scene.add(toxiconCube);
  
  // For high end VR devices like Vive and Oculus, take into account the stage
  // parameters provided.
  setupStage();
});



Finished!

So - this may be enough for our little tutorial. Our code now results in the following scene.


This time I used the mentioned chromium build and startet the VR mode. That's why we see two views - one for each eye.
If you have any questions or suggestions, feel free to use the comment function below.
And if you want to check out the complete project you can visit me on GitHub:



Thank you for reading and see you later!
BTW, also my Mii likes VR!




Sources:
WebVR
WebVR Boilerplate
Responsive WebVR
4 Steps to Start Experimenting with WebVR in 10 Minutes

See also:
MOZVR
WebVR Samples