←Terug naar Blog

Hoe mijn browsergame in VR draait op een Meta Quest

26 sep 20264 min read

Mijn game Bannermarch draait in de browser, en aangezien het nu 3D is, wilde ik kijken of ik het in VR kon spelen. Dat kan. Ik zette mijn Meta Quest op, opende de game in de browser van de headset en drukte op een knop met de tekst Enter VR. Daarna stond ik binnen de muren van mijn kasteel, met de donjon (de hoofdtoren) op de heuvel voor me. Ik heb niets geïnstalleerd. Het is dezelfde webpagina die je op een laptop zou openen.

Dit werkt dankzij twee dingen. Browsers hebben een ingebouwde API voor VR-headsets genaamd WebXR, en de game gebruikt al Babylon.js, een 3D-engine die weet hoe deze te gebruiken.

Hoe de browser VR doet

WebXR laat een webpagina communiceren met een VR-headset. De Quest-browser heeft het, en Chrome en Edge ook op een computer met een aangesloten PC VR-headset. Safari op de iPhone niet.

Eerst vraagt de pagina de browser of VR beschikbaar is. Zo ja, dan toont de pagina een Enter VR-knop. Je moet ergens op klikken om VR te starten, omdat browsers een pagina dit niet zelfstandig laten doen (het is dezelfde regel die voorkomt dat video's met geluid automatisch afspelen).

Nadat je hebt geklikt, neemt de browser het scherm van de headset over. Vele malen per seconde vertelt het de pagina waar je hoofd en handen zich bevinden. De pagina tekent vervolgens de game twee keer, één voor elk oog, elk vanuit een iets andere positie. Dat kleine verschil is wat dingen 3D laat lijken in de headset.

// Pure WebXR, geen engine
if (await navigator.xr?.isSessionSupported("immersive-vr")) {
  button.onclick = async () => {
    const session = await navigator.xr.requestSession("immersive-vr");
    const space = await session.requestReferenceSpace("local-floor");
    session.requestAnimationFrame(function frame(time, xrFrame) {
      const pose = xrFrame.getViewerPose(space);
      for (const view of pose.views) {
        // teken de scène met view.transform en view.projectionMatrix
      }
      session.requestAnimationFrame(frame);
    });
  };
}

Het local-floor deel vertelt de browser om de vloer van de game op de plek van je echte vloer te plaatsen, zodat je de wereld vanuit je eigen hoogte ziet.

De browser doet de moeilijke dingen, zoals het volgen van je hoofd en het aanpassen van het beeld aan de lenzen. De game tekent alleen wat de camera ziet.

Hoe Babylon.js helpt

Ik heb die code niet zelf geschreven. Babylon.js heeft een hulpfunctie genaamd WebXRDefaultExperience die dit voor je doet. Het start de VR-sessie en beweegt de camera als je je hoofd beweegt. Het geeft je ook laserpointers op de controllers en laat je teleporteren. Dit is ongeveer alle setup die ik nodig had.

const xr = await WebXRDefaultExperience.CreateAsync(scene, {
  disableDefaultUI: true,
  floorMeshes: [ground],
  disableHandTracking: true,
  inputOptions: {
    doNotLoadControllerMeshes: true,
    disableOnlineControllerRepository: true,
  },
  teleportationOptions: { forceHandedness: "right" },
});

// later, vanaf de Enter VR-knop
await xr.baseExperience.enterXRAsync("immersive-vr", "local-floor");

Ik hoefde de game zelf niet te veranderen. Het is dezelfde 3D-wereld die je op een laptop ziet, met dezelfde gebouwen, mensen en boten. Als je naar een gebouw wijst en de trekker overhaalt, verschijnt de naam erboven. Haal de trekker nogmaals over en de game haalt je uit VR met het menu van dat gebouw geopend. Je kasteel beheren is nog steeds makkelijker op een normaal scherm.

Mensen op telefoons en laptops downloaden geen van de VR-code. Het wordt alleen geladen op apparaten die het kunnen gebruiken.

Wat er misging

Het werkte niet meteen. De thumbsticks op de controllers deden eerst niets. Babylon downloadt een bestand voor elke controller dat aangeeft welke knoppen deze heeft, maar de beveiligingsinstellingen van mijn site blokkeren die download. Zonder het bestand behandelde Babylon de controllers alsof ze alleen een trekker hadden. Ik heb het opgelost door die bestanden in de game te plaatsen, zodat deze ze niet hoeft te downloaden.

Toen ik lopen op de linkerstick toevoegde, verdween de Enter VR-knop. Babylon's ingebouwde lopen kan niet tegelijkertijd met teleporteren worden ingeschakeld, dus de VR-setup crashte. Ik heb in plaats daarvan mijn eigen lopen geschreven, ongeveer 30 regels code. De linkerstick laat je lopen in de richting waarin je kijkt, en de rechterstick teleporteert je of draait je in stappen. Ik heb vloeiend draaien weggelaten omdat veel mensen daar misselijk van worden.

De kleuren zagen er raar uit in de headset. De game past zijn kleuren aan als laatste stap op de normale camera, en die stap wordt niet uitgevoerd op de VR-camera, dus ik moest het op een andere manier in VR toepassen.

De game bevroor ook zodra ik VR binnenging. Om batterij te besparen, stopt het met tekenen als je naar een andere tabblad schakelt. De Quest-browser vertelde de game dat zijn tabblad verborgen was terwijl ik in VR was, dus de game stopte. Nu blijft het tekenen terwijl VR aan staat.

De grafische chip van de Quest is ongeveer net zo sterk als die van een telefoon, en hij moet alles twee keer tekenen, dus hij krijgt de lage grafische instelling van de game te zien. Sommige telefoons zeggen ook dat ze VR ondersteunen (voor kartonnen kijkers), dus ik toon de knop alleen op headsets en computers.

Inloggen was een apart probleem, aangezien het typen van een wachtwoord op een zwevend toetsenbord pijnlijk is. Ik heb geschreven hoe ik het heb opgelost in het inloggen op een VR-headset zoals je tv.

Blijf Op de Hoogte

Ontvang de nieuwste berichten en inzichten rechtstreeks in uw inbox.

Geen spam. Altijd uitschrijfbaar.