Tag: Webxr
-
VR panorama browser
Zoals ik afgelopen week al schreef, wilde ik de panorama-viewer verder uitbreiden om meer foto’s toe te voegen. Interacties in de derde dimensie werken echter nét anders dan op het platte scherm. Daarnaast zijn allerlei conventies nog helemaal niet uitgewerkt, dus iedereen doet maar wat en dat is heel verfrissend.
In de 20e eeuw werden de nieuwe grafische interfaces aangeleerd door het gebruik van bedieningselementen die waren ontworpen naar het voorbeeld van een fysieke tegenhanger, een skeuomorfisme zoals dat heet. Mappen, schuifknoppen en zandlopers; allemaal elementen uit de echte wereld om ons te laten begrijpen hoe de interface werkt in de platte digitale wereld.
Meta Quest: Zwevende 2D windows met een 3D sausjeDigitale 3D werelden kunnen werken op een heel andere manier, maar de interface-ontwerpers maken het zich er makkelijk vanaf en plakken gewoon een 2D interface in de lucht, want die kennen we al. Ze willen het ons nu nog niet te lastig maken, maar de échte revolutie moet nog komen, denk ik.
Apple visionOS: Nog niet veel beterSimpel
Hoe dan ook, ik wilde iets simpels maken om mee te beginnen. Met A-Frame doe je dat met Custom Elements in HTML. Hieronder zie je het specifieke deel om de scene te definiëren.
<a-scene> <a-assets> <img id="image-0" src="image-0.jpg"> <img id="city" src="https://cdn.aframe.io/a-painter/images/sky.jpg"> <img id="floor" src="https://cdn.aframe.io/a-painter/images/floor.jpg"> </a-assets> <a-sky src="#city"></a-sky> <a-curvedimage id="panorama" src="#image-0" position="0 2 0" height="2.5" radius="2" theta-start="60" theta-length="240"></a-curvedimage> <a-cylinder id="ground" src="#floor" radius="32" height="0.1"></a-cylinder> </a-scene>
Eerst definieer je een aantal assets, in dit geval afbeeldingen, waar je vanaf andere plekken naar kan verwijzen. Om te voorkomen dat je in het luchtledige lijkt te zweven is het verstandig een
a-sky
toe te voegen met een 360º afbeelding. Daarnaast heb ik eena-cylinder
toegevoegd die als een soort vloer dient.De
a-curvedimage
bevat het echte panorama-plaatje en is eigenlijk een boogsegment van de wand van een cilinder. Het is een beetje zoeken naar de juiste waardes, maar de meeste van mijn panorama’s zijn ongeveer 240º. Als het niet helemaal klopt, is dat nog niet zo’n ramp, want dat zie je amper, behalve als je met veel rechte lijnen werkt en het allemaal precies zou moet passen.Nu voeg ik nog twee
a-image
toe onder de panorama om zometeen vooruit en achteruit te kunnen en voila, de scène is zo’n beetje klaar:
Overzicht van de sceneMet A-Frame hoef je je om de rendering verder geen zorgen meer te maken. Je headset schakelt om naar VR-modus en je wordt omringd door de scène die je hebt gebouwd. De interactie daarentegen zul je wel zelf moeten opbouwen, want anders dan op het platte web kan je hier niet gewoon ergens een
<a href=...>
wegzetten om een link te maken.Interactie
In 2D interfaces zijn we gewend dat we één aanwijzer hebben die we eventueel met meerdere apparaten kunnen bedienen ( muis, touchpad, tekenpen, …). In de 3D wereld zijn al die apparaten opeens onafhankelijke bedieningen geworden, vergelijkbaar met hoe een smartphone elke vinger apart detecteert en “multitouch gestures” herkent. A-Frame ondersteunt hoofd- en controller-tracking, dus je kijkrichting en wat je met je controllers doet kan als invoer dienen. Omdat je hoofd (waarschijnlijk) geen knoppen heeft, werkt een interactie daarmee anders dan met een hand-controller.
Een controller declareer je door een
a-entity
te maken met een aantal attributen, bijvoorbeeld zo:<a-entity oculus-touch-controls="hand: right" laser-controls b-button-listener></a-entity>
Met
oculus-touch-controls="hand: right"
zeg je dat je de Meta Quest controller voor de rechter hand wil configureren. Delaser-controls
zorgt ervoor dat de controller een laserstraal afschiet in de wijsrichting, en dat een aantal events worden afgevuurd als die laserstraal een object raakt, waarover later meer.Uit de VR-modus gaan
Ten slotte koppel ik met
b-button-listener
mijn eigen code aan de controller hardware:AFRAME.registerComponent('b-button-listener', { init: function () { this.el.addEventListener('bbuttondown', function (e) { const sceneEl = document.querySelector('a-scene'); if (sceneEl.is('vr-mode')) { sceneEl.exitVR(); } }); } });
Dit zorgt ervoor dat als je op de B knop op de controller drukt wanneer je in VR-mode bent, dat je uit VR-mode gaat.
Een foto vooruit of achteruit gaan
De twee kleine fotootjes onderaan op het screenshot had ik nog niet aan de scène toegevoegd, dus dat doen we nog even:
<a-image id="prev-image" src="#image-2" position="-1 0.5 -1.5" rotation="-45 30 0" width="1" height="0.33" cursor-listener="direction: prev"></a-image> <a-image id="next-image" src="#image-1" position="1 0.5 -1.5" rotation="-45 -30 0" width="1" height="0.33" cursor-listener="direction: next"></a-image>
Hier zie je de
cursor-listener
component. Deze code is straks verantwoordelijk voor het naar hetclick
signaal luisteren dat delaser-controls
component produceert wanneer je op een van dea-image
s “klikt”. Je ziet dat je extra informatie kan meegeven, net als bij deoculus-touch-controls
, om de component te configureren.AFRAME.registerComponent('cursor-listener', { schema: { direction: {type: 'string', default: 'next'} }, init: function () { this.el.addEventListener('click', (e) => { switch (this.data.direction) { case 'prev': nextImage(-1); break; default: nextImage(1); break; } }); } });
In de code hierboven wordt aan
this.el
, dat is dea-image
waar het op staat, een event listener toegevoegd voor hetclick
signaal. Afhankelijk van de waarde vandirection
zal hij nu de volgende of de vorige afbeelding inladen.De logica voor het wisselen van de afbeelding is niet A-Frame of WebXR specifiek en kan je vinden in de source van de panorama pagina (net als de rest van deze blog trouwens).
En dat is het! Het resultaat is een wereld waarin je kan schakelen tussen zes panorama’s met behulp van je controllers! Voor degenen zonder headset, een filmpje:
Nuttige links
- Een lijst van voorbeelden met A-Frame (in onwijze 90s homepage vibe) van Lee Stemkoski
- A-Frame documentatie
-
Aan de slag in Virtual Reality met WebXR
We hebben onszelf laatst een VR-headset cadeau gedaan. Om Beat Saber te spelen natuurlijk, maar ook om lekker mee te knutselen. Er zijn native ontwikkelomgevingen voor zo’n beetje elke headset die op de markt te krijgen is, maar er is ook een W3C specificatie voor VR- en AR-applicaties, gezamenlijk vaak XR genoemd. Die specificatie heet WebXR en breidt het 2D web uit met de derde dimensie.
Nu is de W3C specificatie vrij low-level dus is het lastig daar een toepassing mee te maken, maar er zijn al frameworks ontwikkeld die het veel makkelijker maken. Een van die frameworks is A-Frame en daarmee heb ik al een simpele viewer geknutseld voor de panoramafoto’s die ik in de loop van de tijd heb gemaakt.
Met een desktop browser kan je die pagina gewoon openen en in XR-emulatie bekijken, met een headset krijg je een “immersieve ervaring” zoals dat zo mooi heet.
Kijk maar eens naar het panorama van de Pont du Gard in VR wat ik afgelopen vakantie heb gemaakt.
Ik wil de viewer nog verder uitbreiden zodat het een echte applicatie is waarin je meerdere panorama’s kan bekijken, want ze komen in VR echt veel beter tot hun recht dan op een plat beeldscherm.