WebVR Część 5: Projekt i wdrożenie
Opublikowany: 2022-03-11Uwielbiam „załatwiać” projekty. Dotarliśmy do końca naszej podróży - i narodzin naszej symulacji grawitacji niebieskiej w WebVR.
W tym ostatnim poście podłączymy nasz wysokowydajny kod symulacyjny (artykuły 1,2,3) do wizualizera WebVR opartego na wizualizatorze kanwy (artykuł 4).
- „Problem n-ciał” Wprowadzenie i architektura
- Web Workers dostarczają nam dodatkowe wątki przeglądarki
- WebAssembly i AssemblyScript dla naszego kodu wąskiego gardła wydajności O(n²)
- Wizualizacja danych na płótnie
- Wizualizacja danych WebVR
Jest to dłuższy artykuł, więc pominiemy niektóre szczegóły techniczne omówione wcześniej. Sprawdź poprzednie posty, jeśli chcesz się orientować, lub czytaj dalej niebezpiecznie.
Badaliśmy zmianę paradygmatu przeglądarki z jednowątkowego środowiska uruchomieniowego JavaScript do wielowątkowego (pracowników sieci Web) wysokowydajnego środowiska uruchomieniowego (WebAssembly). Te wydajne funkcje komputerów stacjonarnych są dostępne w progresywnych aplikacjach internetowych i modelu dystrybucji SaaS.
VR stworzy atrakcyjne, wolne od rozpraszania środowiska sprzedażowe i marketingowe do komunikowania się, przekonywania i mierzenia zaangażowania (śledzenie wzroku i interakcja). Dane nadal będą zerami i jedynkami, ale oczekiwanym podsumowaniem i doświadczeniem konsumenckim będzie WebVR – tak jak dzisiaj budujemy mobilne pulpity nawigacyjne dla płaskiej sieci.
Technologie te umożliwiają również rozproszone przetwarzanie brzegowe przeglądarki. Na przykład moglibyśmy stworzyć aplikację internetową do przeprowadzania obliczeń WebAssembly dla milionów gwiazd w symulacji. Innym przykładem jest aplikacja do animacji, która renderuje kreacje innych użytkowników podczas edytowania własnych.
Treści rozrywkowe przodują w upowszechnianiu wirtualnej rzeczywistości, podobnie jak rozrywka prowadzona na urządzeniach mobilnych. Jednak gdy VR stanie się normalne (tak jak obecnie jest projektowanie mobile-first), będzie to oczekiwane doświadczenie (projekt zorientowany na VR). To bardzo ekscytujący czas na bycie projektantem i programistą – a VR to zupełnie inny paradygmat projektowania.
Nie jesteś projektantem VR, jeśli nie możesz się przyczepić. To odważne stwierdzenie, a dzisiaj jest to głębokie zanurzenie w projektowaniu VR. To pole jest wymyślane, gdy to czytasz. Moim celem jest podzielenie się moimi doświadczeniami związanymi z oprogramowaniem i filmem, aby przygotować rozmowę „projektowanie VR-first”. Wszyscy uczymy się od siebie.
Mając na uwadze te wspaniałe prognozy, chciałem ukończyć ten projekt jako profesjonalne demo techniczne - WebVR to świetny wybór!
WebVR i Google A-Frame
Repo git WebVR jest rozwidleniem wersji płótna z kilku powodów. Ułatwia to hostowanie projektu na stronach Github, a WebVR wymagał kilku zmian, które zaśmieciłyby wersję płótna i te artykuły.
Jeśli pamiętacie nasz pierwszy post dotyczący architektury, całą symulację oddelegowaliśmy do nBodySimulator .
Post pracownika sieci Web pokazał, że nBodySimulator ma funkcję step() wywoływaną co 33 ms symulacji. step() wywołuje calculateForces() , aby uruchomić nasz kod symulacji O(n²) WebAssembly (artykuł 3), a następnie aktualizuje pozycje i odświeża. W naszym poprzednim poście tworzącym wizualizację canvas zaimplementowaliśmy to za pomocą elementu canvas, zaczynając od tej klasy bazowej:
/** * Base class that console.log()s the simulation state. */ export class nBodyVisualizer { constructor(htmlElement) { this.htmlElement = htmlElement this.resize() this.scaleSize = 25 // divided into bodies drawSize. drawSize is log10(mass) // This could be refactored to the child class. // Art is never finished. It must be abandoned. } resize() {} paint(bodies) { console.log(JSON.stringify(bodies, null, 2)) } }Zdefiniuj wyzwanie integracyjne
Mamy symulację. Teraz chcemy zintegrować się z WebVR - bez przebudowy naszego projektu. Bez względu na to, jakie zmiany wprowadzimy w symulacji, następują co 33 ms w głównym wątku interfejsu użytkownika w funkcji paint(bodies) .
W ten sposób będziemy mierzyć „zrobione”. Jestem podekscytowany - do roboty!
Jak stworzyć wirtualną rzeczywistość
Najpierw potrzebujemy projektu:
- Z czego składa się VR?
- Jak wyraża się design WebVR ?
- Jak możemy z nim współdziałać ?
Rzeczywistość wirtualna sięga zarania dziejów. Każda opowieść przy ognisku to mały wirtualny świat dziwacznych przesady, przykryty trywialnymi szczegółami.
Możemy dziesięciokrotnie zwiększyć naszą historię przy ognisku, dodając stereoskopowe wizualizacje i dźwięk 3D. Mój instruktor budżetowania produkcji filmowej mawiał: „Płacimy tylko za plakat. Nie budujemy rzeczywistości”.
Jeśli znasz DOM przeglądarki, wiesz, że tworzy on strukturę hierarchiczną podobną do drzewa.
Nieodłącznym elementem projektowania sieci jest oglądanie przez widza „z przodu”. Patrzenie z boku odsłoniłoby elementy DOM jako linie, a z tyłu po prostu zobaczylibyśmy tag <body> , ponieważ zasłania on swoje dzieci.
Częścią wciągającego doświadczenia VR jest umożliwienie użytkownikowi kontrolowania swojego punktu widzenia, stylu, tempa i kolejności interakcji. Nie muszą zwracać uwagi na nic konkretnego. Jeśli programowo przesuniesz lub obrócisz kamerę, dosłownie zwymiotują z powodu choroby VR.
Pamiętaj, że choroba VR to nie żart. Zarówno nasze oczy, jak i uszy wewnętrzne wykrywają ruch. To bardzo ważne dla zwierzęcia, które chodzi wyprostowane. Kiedy te czujniki ruchu nie zgadzają się, nasz mózg naturalnie zakłada, że nasze usta znowu jedzą bzdury i wymiotują. Wszyscy byliśmy kiedyś dziećmi. Wiele już napisano o tym instynkcie przetrwania w VR. Tytuł „Epic Fun” jest darmowy na Steamie, a kolejka górska to najlepsze demo choroby VR, jakie znalazłem.
Rzeczywistość wirtualna jest wyrażona jako „graficzna scena”. Wykres sceny ma taki sam wzór drzewa jak DOM, aby ukryć szczegóły i złożoność przekonującego środowiska 3D. Jednak zamiast przewijać i przekierowywać, umieszczamy widza w miejscu, w którym chce on przyciągnąć do siebie doświadczenie.
Oto wykres sceny Hello World z Google A-Frame WebVR Framework:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello, WebVR! • A-Frame</title> <meta name="description" content="Hello, WebVR! • A-Frame"> <script src="https://aframe.io/releases/0.9.2/aframe.min.js"></script> </head> <body> <a-scene background="color: #FAFAFA"> <a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9" shadow></a-box> <a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E" shadow></a-sphere> <a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D" shadow></a-cylinder> <a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4" shadow></a-plane> </a-scene> </body> </html> Ten dokument HTML tworzy DOM w przeglądarce. Tagi <a-*> są częścią struktury A-Frame, a <a-scene> jest korzeniem wykresu sceny. Tutaj widzimy cztery prymitywy 3D wyświetlane w scenie.
Po pierwsze, zauważ, że oglądamy scenę z płaskiej przeglądarki internetowej. Mała maska w prawym dolnym rogu zachęca użytkownika do przejścia do trybu stereoskopowego 3D.
Teoretycznie powinieneś być w stanie:
- Otwórz to na swoim telefonie
- Trzymaj telefon blisko twarzy
- Rozkoszuj się blaskiem nowej rzeczywistości!
Nigdy nie udało mi się to działać bez fantazyjnych soczewek zestawu słuchawkowego VR. Gogle VR do telefonu z systemem Android można kupić tanio (podstawowe urządzenie oparte na Google Cardboard), jednak do tworzenia treści proponuję samodzielny wyświetlacz HMD (Head Mounted Display) taki jak Oculus Quest.
Podobnie jak nurkowanie czy skoki spadochronowe, wirtualna rzeczywistość to sport sprzętowy.
Nauka projektantów VR „Cliff”
Zwróć uwagę, że scena A-Frame Hello World ma domyślne oświetlenie i kamerę:
- Twarze sześcianu są w różnych kolorach - sześcian jest samozacieniający.
- Kostka rzuca cień na samolot - jest kierunkowe światło.
- Nie ma przerwy między sześcianem a płaszczyzną - to świat z grawitacją.
Są to krytyczne sygnały, które mówią widzowi: „Zrelaksuj się, ta rzecz na twojej twarzy jest całkowicie normalna”.
Zauważ również, że ta domyślna konfiguracja jest niejawna w powyższym kodzie sceny Hello World. A-Frame mądrze zapewnia rozsądne ustawienie domyślne, ale pamiętaj – kamera i oświetlenie to przepaść, którą projektanci płaskich stron muszą przekroczyć, aby stworzyć VR.
Domyślną konfigurację oświetlenia przyjmujemy za pewnik. Na przykład przyciski:
Zwróć uwagę, jak wszechobecne jest to ukryte oświetlenie w projektowaniu i fotografii. Nawet przycisk „płaska konstrukcja” nie mógł uciec od domyślnego oświetlenia sieci — rzuca cień w dół i w prawo.
Projektowanie, komunikowanie się i wdrażanie ustawień oświetlenia i kamer to klif nauki projektanta WebVR. „Język filmu” to zbiór norm kulturowych – wyrażonych jako różne ustawienia kamery i oświetlenia – które emocjonalnie przekazują historię publiczności. Działem chwytu są profesjonaliści w branży filmowej, którzy projektują/przemieszczają światła i kamerę wokół sceny.
Powrót do naszej wirtualnej rzeczywistości
A teraz wracajmy do pracy. Nasza niebiańska scena WebVR ma podobny wzór:
<!DOCTYPE> <html> <head> <script src="https://aframe.io/releases/0.9.2/aframe.min.js"></script> <script src="https://unpkg.com/[email protected]/dist/aframe-event-set-component.min.js"></script> <script src="main.js"></script> </head> <body> <a-scene> <a-sky color="#222"></a-sky> <a-entity geometry="primitive: circle; radius: 12" position="0 0 -.5" material="color: #333; transparent: true; opacity: 0.5"> <a-sphere color="black" radius=."02"></a-sphere> </a-entity> <a-entity></a-entity> <a-entity geometry="primitive: plane; width: 2; height: auto" position="0 -10 .3" rotation="55 0 0" material="color: blue" text="value: Welcome Astronaut!..."> </a-entity> <a-entity position="0 -12 .7" rotation="55 0 0"> <a-camera> <a-cursor color="#4CC3D9" fuse="true" timeout="1"></a-cursor> </a-camera> </a-entity> </a-scene> </body> </html> Ten dokument HTML ładuje strukturę A-Frame i wtyczkę interakcji. Nasza scena zaczyna się od <a-scene> .
Wewnątrz zaczynamy od elementu <a-sky color="#222"></a-sky> do kolorowania tła wszystkiego, czego nie definiujemy w scenie.
Następnie tworzymy „płaszczyznę orbitalną”, której widz może „trzymać się”, gdy przelatuje przez nasz dziwny i nieznany świat. Tworzymy to jako dysk i małą czarną kulę (0,0,0). Bez tego zwracanie się do mnie wydawało się „nieugruntowane”:
<a-entity geometry="primitive: circle; radius: 12" position="0 0 -.5" material="color: #333; transparent: true; opacity: 0.5"> <a-sphere color="black" radius=."02"></a-sphere> </a-entity>Następnie definiujemy kolekcję, w której możemy dodawać/usuwać/przestawiać encje A-Frame.
<a-entity></a-entity> To jest rozliczenie dla paint(bodies) nBodyVisualizer , aby wykonać swoją pracę.
Następnie tworzymy relację między widzem a tym światem. Jako demonstracja techniczna, celem tego świata jest umożliwienie widzowi poznania WebVR i technologii przeglądarki, która to umożliwia. Prosta narracja o „astronautach” tworzy poczucie zabawy, a ten gwiezdny drogowskaz jest kolejnym punktem odniesienia dla nawigacji.
<a-entity geometry="primitive: plane; width: 2; height: auto" position="0 -10 .3" rotation="55 0 0" material="color: blue" text="value: Welcome Astronaut!\n ..."> </a-entity>To kończy nasz wykres sceny. Na koniec chciałem mieć jakąś interakcję na demo telefonu między użytkownikiem a tym zakręconym światem. Jak możemy odtworzyć przycisk „Rzuć gruz” w VR?
Przycisk to podstawowy element każdego nowoczesnego designu - gdzie są przyciski VR?
Interakcje w WebVR
Rzeczywistość wirtualna ma swoje własne „nad” i „pod zakładką”. Pierwsza interakcja widza odbywa się za pośrednictwem jego awatara lub kamery. To są wszystkie elementy sterujące do powiększania.
Jeśli czytasz to na pulpicie, możesz WASD, aby poruszać i myszką, aby obracać kamerą. Ta eksploracja ujawnia informacje, ale nie wyraża Twojej woli.
Real Reality ma kilka bardzo ważnych funkcji, które rzadko można znaleźć w sieci:
- Perspektywa - obiekty stają się wyraźnie mniejsze, gdy oddalają się od nas.
- Okluzja - obiekty są ukrywane i odsłaniane na podstawie pozycji.
VR symuluje te funkcje, aby stworzyć efekt 3D. Mogą być również używane w VR do ujawniania informacji i interfejsu – oraz do ustawiania nastroju przed prezentacją interakcji. Zauważyłem, że większość ludzi potrzebuje tylko minuty, aby cieszyć się doświadczeniem, zanim ruszy do przodu.

W WebVR wchodzimy w interakcję w przestrzeni 3D. Mamy do tego dwa podstawowe narzędzia:
- Kolizja — pasywne zdarzenie 3D uruchamiane, gdy dwa obiekty dzielą tę samą przestrzeń.
- Projekcja — aktywne wywołanie funkcji 2D wyświetlające wszystkie obiekty przecinające linię.
Zderzenie jest najbardziej „podobną do VR” interakcją
W VR „kolizja” jest dokładnie tym, na co wygląda: gdy dwa obiekty dzielą tę samą przestrzeń, A-Frame tworzy wydarzenie.
Aby użytkownik „nacisnął” przycisk, musimy dać mu pionka i coś do wciśnięcia przycisku.
Niestety, WebVR nie może jeszcze zakładać kontrolerów – wiele osób spojrzy na płaską wersję internetową na swoim komputerze stacjonarnym lub telefonie, a wielu użyje zestawu słuchawkowego, takiego jak Google Cardboard lub Samsung Gear VR, aby pokazać wersję stereoskopową.
Jeśli użytkownik nie ma kontrolerów, nie może sięgnąć i „dotykać” rzeczy, więc każda kolizja będzie musiała nastąpić z jego „przestrzenią osobistą”.
Moglibyśmy dać graczowi pionka w kształcie astronauty do poruszania się, ale zmuszanie użytkownika do wirowania miazmatu planet wydaje się nieco odpychające i sprzeczne z przestronnością naszego projektu.
Projekcja to dwuwymiarowe, przypominające sieć, kliknięcie w przestrzeni 3D
Oprócz „kolizji” możemy również użyć „rzutu”. Możemy rzutować linię przez naszą scenę i zobaczyć, czego ona dotyka. Najczęstszym przykładem jest „promień teleportacji”.
Promień teleportacji wyznacza linię na świecie, aby pokazać, gdzie gracz może się poruszać. Ta „projekcja” szuka miejsc do lądowania. Zwraca jeden lub więcej obiektów na ścieżce projekcji. Oto przykład promienia teleportacji:
Zauważ, że promień jest faktycznie zaimplementowany jako parabola skierowana w dół. Oznacza to, że w naturalny sposób przecina się z „podłożem” jak rzucany przedmiot. To również naturalnie określa maksymalną odległość teleportacji. Ograniczenia to najważniejsze wybory projektowe w VR. Na szczęście rzeczywistość ma wiele naturalnych ograniczeń.
Projekcja „spłaszcza” świat 3D do 2D, dzięki czemu możesz wskazywać elementy, aby klikać je jak myszą. Strzelanki FPS to rozbudowane gry „kliknięcia 2D” na niezwykle frustrujących przyciskach – często z rozbudowaną historią wyjaśniającą, dlaczego nie jest w porządku, te cholerne przyciski „klikają” cię z powrotem.
W rzeczywistości wirtualnej jest tak wiele pistoletów, ponieważ zostały one udoskonalone jako dokładne i niezawodne myszy 3D – a klikanie jest tym, co konsumenci wiedzą, jak zrobić bez uczenia się.
Projekcja zapewnia również bezpieczeństwo na odległość w relacji ze sceną. Pamiętaj, że zbliżanie się do czegoś w VR naturalnie przesłania wszystkie inne rzeczy, których znaczenie może jeszcze nie zostało ujawnione.
Projekcja bez kontrolerów za pomocą „spojrzenia”
Aby stworzyć tę prymitywną interakcję w WebVR bez kontrolerów, możemy wyświetlić „spojrzenie” widzów jako „kursor” linii wzroku. Ten kursor może być używany programowo do interakcji z obiektami z „bezpiecznikiem”. Jest to komunikowane widzowi jako małe niebieskie kółko. Teraz klikamy!
Jeśli pamiętasz historie przy ognisku, im większe kłamstwo, tym mniej szczegółów potrzeba, by je sprzedać. Oczywistą i absurdalną interakcją „spojrzenia” jest wpatrywanie się w słońce. Używamy tego „spojrzenia”, aby wywołać dodawanie nowych „odpadów” planet do naszej symulacji. Żaden widz nigdy nie kwestionował tego wyboru – VR jest dość czarujący, gdy jest absurdalny.
W A-Frame wyrażamy kamerę (niewidzialny pionek graczy) i ten „kursor” linii widzenia jako olinowanie kamery. Umieszczenie <a-cursor> wewnątrz <a-camera> powoduje, że przekształcenia kamery są również stosowane do kursora. Kiedy gracz porusza/obraca pionkiem ( a-camera ), porusza/obraca również jego wzrok ( a-cursor ).
// src/index.html <a-entity position="0 -12 .7" rotation="55 0 0"> <a-camera> <a-cursor color="#4CC3D9" fuse="true" timeout="1"></a-cursor> </a-camera> </a-entity>„Bezpiecznik” kursora czeka, aż minie pełna sekunda „wpatrywania się”, zanim wyemituje zdarzenie.
Użyłem domyślnego oświetlenia, więc możesz zauważyć nieoświetlony „tył” słońca. Chociaż nie byłem poza płaszczyzną orbity, nie sądzę, że tak działa słońce. Działa to jednak w przypadku naszego technicznego plakatu demo rzeczywistości.
Alternatywną opcją byłoby umieszczenie oświetlenia wewnątrz elementu kamery, aby poruszało się wraz z użytkownikiem. Stworzyłoby to bardziej intymne - i prawdopodobnie upiorne - doświadczenie górnika z asteroidami. To są zabawne wybory projektowe.
Mamy plan integracji
Dzięki temu mamy teraz nasze punkty integracji między A-Frame <a-scene> i naszą symulacją JavaScript:
Ramka A <a-scene> :
Nazwany zbiór dla ciał:
<a-entity></a-entity>Kursor, który będzie emitował zdarzenia projekcji:
<a-cursor color="#4CC3D9" fuse="true" timeout="1"></a-cursor>
Nasza symulacja JavaScript:
nBodyVisWebVR.paint(bodies)- dodaj/usuń/zmień położenie bytów VR z brył symulacjiaddBodyArgs(name, color, x, y, z, mass, vX, vY, vZ)aby dodać nowe bryły gruzu do symulacji
index.html ładuje main.js , który inicjuje naszą symulację podobnie jak wersja na płótnie:
// src/main.js import { nBodyVisualizer, nBodyVisWebVR } from ."/nBodyVisualizer" import { Body, nBodySimulator } from ."/nBodySimulator" window.onload = function() { // Create a Simulation const sim = new nBodySimulator() // this Visualizer manages the UI sim.addVisualization(new nBodyVisWebVR(document.getElementById("a-bodies"), sim)) // making up stable universes is hard // name color xyzm vz vy vz sim.addBody(new Body("star", "yellow", 0, 0, 1, 1e9)) sim.addBody(new Body("hot-jupiter", "red", -1, -1, 1, 1e4, .24, -0.05, 0)) sim.addBody(new Body("cold-jupiter", "purple", 4, 4, .5, 1e4, -.07, 0.04, 0)) // Start simulation sim.start() // Add another sim.addBody(new Body("saturn", "blue", -8, -8, .1, 1e3, .07, -.035, 0)) } Zauważysz, że w tym miejscu ustawiliśmy element htmlElement wizualizatora na kolekcję a-bodies , aby przechowywać ciała.
Programowe zarządzanie obiektami A-Frame z JavaScript
Po zadeklarowaniu naszej sceny w index.html , jesteśmy teraz gotowi do zakodowania wizualizatora.
Najpierw konfigurujemy nBodyVisualizer , aby odczytywał z listy ciał nBodySimulation i tworzył/aktualizował/usuwał obiekty A-Frame w kolekcji <a-entity></a-entity> .
// src/nBodyVisualizer.js /** * This is the WebVR visualizer. * It's responsible for painting and setting up the entire scene. */ export class nBodyVisWebVR extends nBodyVisualizer { constructor(htmlElement, sim) { // HTML Element is a-collection#a-bodies. super(htmlElement) // We add these to the global namespace because // this isn't the core problem we are trying to solve. window.sim = sim this.nextId = 0 } resize() {}W konstruktorze zapisujemy naszą kolekcję A-Frame, ustawiamy zmienną globalną dla naszego zdarzenia spojrzenia, aby znaleźć symulację i inicjujemy licznik identyfikatorów, którego użyjemy do dopasowania ciał między naszą symulacją a sceną A-Frame.
paint(bodies) { let i // Create lookup table: lookup[body.aframeId] = body const lookup = bodies.reduce( (total, body) => { // If new body, give it an aframeId if (!body.aframeId) body.aframeId = `a-sim-body-${body.name}-${this.nextId++}` total[body.aframeId] = body return total }, {}) // Loop through existing a-sim-bodies and remove any that are not in // the lookup - this is our dropped debris const aSimBodies = document.querySelectorAll(."a-sim-body") for (i = 0; i < aSimBodies.length; i++) { if (!lookup[aSimBodies[i].id]) { // if we don't find the scene's a-body in the lookup table of Body()s, // remove the a-body from the scene aSimBodies[i].parentNode.removeChild(aSimBodies[i]); } } // loop through sim bodies and upsert let aBody bodies.forEach( body => { // Find the html element for this aframeId aBody = document.getElementById(body.aframeId) // If html element not found, make one. if (!aBody) { this.htmlElement.innerHTML += ` <a-sphere class="a-sim-body" dynamic-body ${ (body.name === "star") ? "debris-listener event-set__enter='_event: mouseenter; color: green' event-set__leave='_event: mouseleave; color: yellow'" : ""} position="0 0 0" radius="${body.drawSize/this.scaleSize}" color="${body.color}"> </a-sphere>` aBody = document.getElementById(body.aframeId) } // reposition aBody.object3D.position.set(body.x, body.y, body.z) }) }Najpierw przechodzimy pętlą przez korpusy sim, aby oznaczyć i/lub utworzyć tabelę przeglądową w celu dopasowania elementów A-Frame do korpusów symulacji.
Następnie wykonujemy pętlę przez istniejące korpusy A-Frame i usuwamy te, które zostały przycięte przez symulację do wyjazdu poza granice. Zwiększa to postrzeganą wydajność doświadczenia.
Na koniec wykonujemy pętlę przez ciała sim, aby utworzyć nową <a-sphere> dla brakujących ciał i zmienić położenie pozostałych za pomocą aBody.object3D.position.set(body.x, body.y, body.z)
Możemy programowo zmieniać elementy w scenie A-Frame za pomocą standardowych funkcji DOM. Aby dodać element do sceny, dołączamy łańcuch do innerHTML kontenera. Ten kod smakuje mi dziwnie, ale działa i nie znalazłem nic lepszego.
Zauważysz, że kiedy tworzymy łańcuch do dołączenia, mamy trójskładnikowy operator w pobliżu „gwiazdy”, aby ustawić atrybut.
<a-sphere class="a-sim-body" dynamic-body ${ (body.name === "star") ? "debris-listener event-set__enter='_event: mouseenter; color: green' event-set__leave='_event: mouseleave; color: yellow'" : ""} position="0 0 0" radius="${body.drawSize/this.scaleSize}" color="${body.color}"> </a-sphere>`Jeśli ciało jest „gwiazdą”, dodajemy dodatkowe atrybuty opisujące jego wydarzenia. Oto jak wygląda nasza gwiazda po zamontowaniu w DOM:
<a-sphere class="a-sim-body" dynamic-body="" debris-listener="" event-set__enter="_event: mouseenter; color: green" event-set__leave="_event: mouseleave; color: yellow" position="0 0 0" radius="0.36" color="yellow" material="" geometry=""></a-sphere> Trzy atrybuty, debris-listener , event-set__enter i event-set__leave , konfigurują nasze interakcje i są ostatnim okrążeniem naszej integracji.
Definiowanie zdarzeń i interakcji A-Frame
Używamy pakietu NPM „aframe-event-set-component” w atrybutach encji, aby zmienić kolor słońca, gdy widz „patrzy” na nie.
To „spojrzenie” jest projekcją z pozycji i rotacji widza, a interakcja dostarcza niezbędnej informacji zwrotnej, że jego spojrzenie coś robi.
Nasza gwiezdna sfera ma teraz dwa skrócone zdarzenia włączone przez wtyczkę, event-set__enter i event-set__leave :
<a-sphere ... event-set__enter="_event: mouseenter; color: green" event-set__leave="_event: mouseleave; color: yellow" … ></a-sphere> Następnie udekorujemy naszą gwiezdną kulę debris-listener , który zaimplementujemy jako niestandardowy komponent A-Frame.
<a-sphere ... debris-listener="" … ></a-sphere>Komponenty A-Frame są definiowane na poziomie globalnym:
// src/nBodyVisualizer.js // Component to add new bodies when the user stares at the sun. See HTML AFRAME.registerComponent('debris-listener', { init: function () { // Helper function function rando(scale) { return (Math.random()-.5) * scale } // Add 10 new bodies this.el.addEventListener('click', function (evt) { for (let x=0; x<10; x++) { // name, color, x, y, z, mass, vx, vy, vz window.sim.addBodyArgs("debris", "white", rando(10), rando(10), rando(10), 1, rando(.1), rando(.1), rando(.1)) } }) } })Ten komponent A-Frame działa jak słuchacz „kliknięcia”, który może zostać wywołany przez kursor spojrzenia, aby dodać 10 nowych losowych ciał do naszej sceny.
Podsumowując:
- Deklarujemy scenę WebVR z A-Frame w standardowym HTML.
- Możemy programowo dodawać/usuwać/aktualizować encje A-Frame w scenie z JavaScript.
- Możemy tworzyć interakcje w JavaScript z obsługą zdarzeń za pomocą wtyczek i komponentów A-Frame.
WebVR: Veni, Vidi, Vici
Mam nadzieję, że wyniosłeś z tego demo technicznego tyle samo, co ja. Tam, gdzie zastosowaliśmy te funkcje (webworkers i WebAssembly) do WebVR, można je również zastosować do przetwarzania brzegowego przeglądarki.
Nadeszła ogromna fala technologii - Wirtualna Rzeczywistość (VR). Niezależnie od tego, co czułeś, gdy pierwszy raz trzymałeś smartfon w dłoni, doświadczanie VR po raz pierwszy zapewnia 10 razy więcej emocji w każdym aspekcie korzystania z komputera. Od pierwszego iPhone'a minęło dopiero 12 lat.
VR istnieje znacznie dłużej, ale technologia potrzebna do udostępnienia VR przeciętnym użytkownikom pojawiła się dzięki rewolucji mobilnej i Oculus Quest na Facebooku – a nie rewolucji na PC.
Internet i open-source to jedne z największych cudów ludzkości na świecie. Wszystkim ludziom, którzy stworzyli płaski internet - wznoszę toast za Waszą odwagę i poczucie przygody.
Manifest! Zbudujemy światy, bo mamy moc tworzenia.
