WebVR Bölüm 5: Tasarım ve Uygulama
Yayınlanan: 2022-03-11Projeleri "bitirmeyi" seviyorum. Yolculuğumuzun sonuna ve WebVR'deki göksel yerçekimi simülasyonumuzun doğuşuna geldik.
Bu son gönderide, yüksek performanslı simülasyon kodumuzu (Madde 1,2,3) tuval görselleştiricisine dayalı bir WebVR görselleştiricisine bağlayacağız (Madde 4).
- “n-body problemi” Giriş ve Mimari
- Web Çalışanları bize ek tarayıcı ileti dizileri sağlar
- O(n²) performans darboğaz kodumuz için WebAssembly ve AssemblyScript
- Kanvas Veri Görselleştirme
- WebVR Veri Görselleştirme
Bu daha uzun bir makale olduğundan, daha önce ele alınan bazı teknik ayrıntıları atlayacağız. Bir oryantasyon istiyorsanız veya tehlikeli bir şekilde okumak istiyorsanız önceki gönderilere göz atın.
Tarayıcının tek iş parçacıklı JavaScript çalışma zamanından çok iş parçacıklı (web çalışanları) yüksek performanslı çalışma zamanına (WebAssembly) paradigma değişimini araştırıyoruz. Bu performanslı masaüstü bilgi işlem özellikleri, Progressive Web Apps ve SaaS dağıtım modelinde mevcuttur.
VR, iletişim kurmak, ikna etmek ve katılımı ölçmek (göz izleme ve etkileşim) için dikkat dağıtıcı olmayan, ilgi çekici satış ve pazarlama ortamları yaratacaktır. Veriler yine sıfırlar ve birler olacak, ancak beklenen yönetici özeti ve tüketici deneyimi WebVR olacak - tıpkı bugün düz web için mobil pano deneyimleri oluşturduğumuz gibi.
Bu teknolojiler ayrıca dağıtılmış tarayıcı uç bilgi işlem sağlar. Örneğin, bir simülasyonda milyonlarca yıldız için WebAssembly hesaplamalarımızı çalıştırmak için web tabanlı bir uygulama oluşturabiliriz. Başka bir örnek, kendinizinkini düzenlerken diğer kullanıcıların yarattıklarını işleyen bir animasyon uygulamasıdır.
Eğlence içeriği, tıpkı mobil cihazlarda yönetilen eğlence gibi, Sanal Gerçekliğin benimsenmesine öncülük ediyor. Bununla birlikte, VR normal hale geldiğinde (bugün mobil öncelikli tasarımın olduğu gibi), beklenen deneyim olacaktır (VR öncelikli tasarım). Tasarımcı ve geliştirici olmak için çok heyecan verici bir zaman ve VR tamamen farklı bir tasarım paradigması.
Eğer kavrayamıyorsanız, bir VR tasarımcısı değilsiniz. Bu cesur bir ifade ve bugün VR tasarımına yapılan derin dalış. Siz bunu okurken bu alan icat ediliyor. Amacım, “VR-ilk tasarım” sohbetini başlatmak için yazılım ve filmdeki deneyimlerimi paylaşmak. Hepimiz birbirimizden öğreniyoruz.
Bu görkemli tahminleri göz önünde bulundurarak, bu projeyi profesyonel bir teknoloji demosu olarak tamamlamak istedim - WebVR bunun için harika bir seçim!
WebVR ve Google A-Frame
WebVR git deposu, birkaç nedenden dolayı tuval sürümünün bir çatalıdır. Projeyi Github sayfalarında barındırmayı kolaylaştırır ve WebVR, tuval sürümünü ve bu makaleleri karmaşıklaştıracak birkaç değişiklik gerektirdi.
Mimari hakkındaki ilk yazımızı hatırlarsanız, simülasyonun tamamını nBodySimulator
.
Web çalışanı gönderisi, nBodySimulator'ın simülasyonun her 33 nBodySimulator
bir step()
işlevine sahip olduğunu gösterdi. step()
, O(n²) WebAssembly simülasyon kodumuzu (madde 3) çalıştırmak için hesapForces calculateForces()
)'i çağırır, ardından konumları günceller ve yeniden boyar. Bir tuval görselleştirmesi oluşturan önceki gönderimizde, bunu bu temel sınıftan başlayarak bir tuval öğesiyle uyguladık:
/** * 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)) } }
Entegrasyon Zorluğunu Tanımlayın
Simülasyon elimizde. Şimdi, projemizi yeniden tasarlamadan WebVR ile entegre olmak istiyoruz. Simülasyonda yaptığımız ayarlamalar ne olursa olsun, paint(bodies)
işlevindeki ana UI iş parçacığında her 33ms'de bir gerçekleşir.
“Tamamlandı” yı bu şekilde ölçeceğiz. Heyecanlıyım - hadi işe başlayalım!
Sanal Gerçeklik Nasıl Yapılır?
İlk olarak, bir tasarıma ihtiyacımız var:
- VR neyden yapılmıştır ?
- WebVR tasarımı nasıl ifade edilir ?
- Onunla nasıl etkileşim kurabiliriz?
Sanal Gerçeklik zamanın başlangıcına kadar gider. Her kamp ateşi hikayesi, önemsiz ayrıntılarla kaplanmış, tuhaf abartılardan oluşan küçük bir sanal dünyadır.
3D stereoskopik görseller ve ses ekleyerek kamp ateşi hikayemizi 10 katına çıkarabiliriz. Film prodüksiyon bütçeleme eğitmenim şöyle derdi: “Biz sadece afişin parasını ödüyoruz. Gerçekliği inşa etmiyoruz.”
DOM tarayıcısına aşina iseniz, onun ağaç benzeri bir hiyerarşik yapı oluşturduğunu bilirsiniz.
Web tasarımında gizli olan şey, “önden” bakan izleyicidir. Yandan bakıldığında DOM öğeleri çizgiler olarak ortaya çıkar ve arkadan, alt öğelerini gizlediği için sadece <body>
etiketini görürüz.
Sürükleyici VR deneyiminin bir parçası, kullanıcının kendi bakış açısını, stilini, hızını ve etkileşim sırasını kontrol etmesine izin vermektir. Özellikle hiçbir şeye dikkat etmek zorunda değiller. Kamerayı programlı olarak hareket ettirir veya döndürürseniz, kelimenin tam anlamıyla VR hastalığından kusarlar.
Lütfen VR hastalığının şaka olmadığını unutmayın. Hem gözlerimiz hem de iç kulaklarımız hareketi algılar. Dik yürüyen bir hayvan için çok önemlidir. Bu hareket sensörleri aynı fikirde olmadığında, beynimiz doğal olarak ağzımızın tekrar saçmalık yediğini varsayar ve kusar. Hepimiz bir zamanlar çocuktuk. VR'deki bu hayatta kalma içgüdüsü hakkında zaten çok şey yazıldı. “Epik Eğlence” başlığı Steam'de ücretsizdir ve hız treni, bulduğum en iyi VR hastalık demosu.
Sanal Gerçeklik bir "sahne grafiği" olarak ifade edilir. Bir sahne grafiği, ikna edici bir 3B ortamın ayrıntılarını ve karmaşıklığını gizlemek için DOM ile aynı ağaç benzeri desene sahiptir. Ancak kaydırma ve yönlendirme yerine, izleyiciyi deneyimi kendilerine çekmek istedikleri yere konumlandırıyoruz.
Google'ın A-Frame WebVR Çerçevesinden Merhaba Dünya sahne grafiği:
<!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>
Bu HTML belgesi, tarayıcıda bir DOM oluşturur. <a-*>
etiketleri, A-Frame çerçevesinin bir parçasıdır ve <a-scene>
, sahne grafiğinin köküdür. Burada, sahnede görüntülenen dört 3B ilkel görüyoruz.
İlk olarak, sahneyi bir düz web tarayıcısından izlediğimize dikkat edin. Sağ alttaki küçük maske, kullanıcıyı 3D stereoskopik moda geçmeye davet ediyor.
Teorik olarak şunları yapabilmelisiniz:
- Bunu telefonunda aç
- Telefonunuzu yüzünüze doğru tutun
- Yeni bir gerçekliğin görkeminden keyif alın!
Bir VR kulaklığının süslü lensleri olmadan bunu asla başaramadım. Bir Android telefon için VR kulaklığı ucuza alabilirsiniz (Google Cardboard tabanlı temel bir cihaz), ancak içerik geliştirmek için Oculus Quest gibi bağımsız bir HMD (Başa Monte Edilen Ekran) öneririm.
Tüplü dalış veya paraşütle atlama gibi, Sanal Gerçeklik bir dişli sporudur.
VR Tasarımcılarının Öğrenimi “Cliff”
A-Frame Hello World sahnesinin varsayılan bir aydınlatma ve kameraya sahip olduğuna dikkat edin:
- Küpün yüzleri farklı renklerdedir - küp kendi kendini gölgeler.
- Küp uçağa bir gölge atıyor - yönlü bir ışık var.
- Küp ile düzlem arasında boşluk yoktur - bu yerçekimi olan bir dünyadır.
Bunlar izleyiciye "Rahatlayın, yüzünüzdeki bu şey tamamen normal" diyen kritik ipuçları.
Ayrıca, bu varsayılan kurulumun yukarıdaki Merhaba Dünya sahnesinin kodunda örtük olduğuna dikkat edin. A-Frame akıllıca mantıklı bir varsayılan sağlar, ancak dikkat edin - kamera ve aydınlatma, düz web tasarımcılarının VR oluşturmak için geçmeleri gereken uçurumdur.
Varsayılan aydınlatma kurulumunu kabul ediyoruz. Örneğin, düğmeler:
Bu örtük aydınlatmanın tasarım ve fotoğrafçılıkta ne kadar yaygın olduğuna dikkat edin. "Düz tasarım" düğmesi bile web'in varsayılan aydınlatmasından kurtulamadı - aşağı ve sağa bir gölge atıyor.
Aydınlatma ve kamera kurulumlarını tasarlamak, iletmek ve uygulamak, WebVR tasarımcısının öğrenme uçurumudur. “Filmin Dili” , hikayeyi duygusal olarak izleyiciye ileten - farklı kamera ve ışık kurulumları olarak ifade edilen - kültürel normların bir koleksiyonudur. Bir sahne etrafında ışık ve kamera tasarlayan/hareket ettiren film profesyonelleri kavrama departmanıdır.
Sanal Gerçekliğimize Geri Dön
O halde şimdi işimize dönelim. Göksel WebVR sahnemiz de benzer bir yapıya sahiptir:
<!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>
Bu HTML belgesi, A-Frame çerçevesini ve bir etkileşim eklentisini yükler. Sahnemiz <a-scene>
ile başlıyor.
İçeride, sahnede tanımlamadığımız her şeyi arka plan rengine dönüştürmek için bir <a-sky color="#222"></a-sky>
öğesiyle başlıyoruz.
Ardından, garip ve bilinmeyen dünyamızda uçarken izleyicinin "tutunması" için bir "yörünge düzlemi" yaratırız. Bunu bir disk ve (0,0,0) noktasında küçük bir siyah küre olarak oluşturuyoruz. Bu olmadan, dönüş bana “temelsiz” geldi:
<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>
Ardından, A-Frame varlıklarını ekleyebileceğimiz/kaldırabileceğimiz/yeniden konumlandırabileceğimiz bir koleksiyon tanımlarız.
<a-entity></a-entity>
Bu, nBodyVisualizer
paint(bodies)
işini yapması için yapılan temizlemedir.
Ardından izleyici ile bu dünya arasındaki ilişkiyi oluşturuyoruz. Bir teknoloji demosu olarak, bu dünyanın amacı, izleyicinin WebVR'ı ve onu etkinleştiren tarayıcı teknolojisini keşfetmesine izin vermektir. Basit bir "astronot" anlatısı bir oyun duygusu yaratır ve bu harika yön tabelası, navigasyon için başka bir referans noktasıdır.
<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>
Bu, sahne grafiğimizi tamamlıyor. Son olarak, bir telefon demosunda kullanıcı ile bu dönen dünya arasında bir tür etkileşim olmasını istedim. VR'de "Enkaz Atın" düğmesini nasıl yeniden oluşturabiliriz?
Düğme, tüm modern tasarımın ilk öğesidir - VR düğmeleri nerede?
WebVR'deki Etkileşimler
Sanal Gerçekliğin kendi "üst" ve "ekranın altı" vardır. Bir izleyicinin ilk etkileşimi avatarı veya kamerası aracılığıyla olur. Yakınlaştırmak için tüm kontroller bu.
Bunu bir masaüstünde okuyorsanız, hareket etmek için WASD ve kamerayı döndürmek için fareyi kullanabilirsiniz. Bu keşif bilgiyi açığa çıkarır, ancak isteğinizi ifade etmez.
Real Reality'nin web'de pek bulunmayan birkaç önemli özelliği vardır:
- Perspektif - nesneler bizden uzaklaştıkça gözle görülür şekilde küçülür.
- Tıkanma - nesneler pozisyona göre gizlenir ve açığa çıkar.
VR, 3D efekti oluşturmak için bu özellikleri simüle eder. Bilgi ve arayüzü ortaya çıkarmak ve etkileşimleri sunmadan önce havayı ayarlamak için VR'de de kullanılabilirler. Çoğu insanın ilerlemeden önce deneyimin tadını çıkarmak için bir dakikaya ihtiyacı olduğunu gördüm.

WebVR'da 3B uzayda etkileşim kurarız. Bunun için iki temel aracımız var:
- Çarpışma - iki nesne aynı alanı paylaştığında tetiklenen pasif bir 3B olay.
- Projeksiyon - bir çizgiyle kesişen tüm nesneleri listeleyen aktif bir 2B işlev çağrısı.
Çarpışma En "VR-benzeri" Etkileşimdir
VR'de bir "çarpışma" tam olarak kulağa nasıl geliyorsa öyledir: İki nesne aynı alanı paylaştığında, A-Frame bir olay yaratır.
Kullanıcının bir düğmeye "basması" için, onlara bir piyon ve düğmeye basacak bir şey vermeliyiz.
Ne yazık ki, WebVR henüz denetleyicileri üstlenemiyor - birçok kişi masaüstü veya telefonlarında düz web sürümüne bakacak ve birçoğu stereoskopik bir sürüm göstermek için Google Cardboard veya Samsung Gear VR gibi bir kulaklık kullanacak.
Kullanıcının denetleyicileri yoksa, uzanamaz ve nesnelere "dokunamaz", bu nedenle herhangi bir çarpışmanın "kişisel alanı" ile olması gerekir.
Oyuncuya hareket etmesi için astronot şeklinde bir piyon verebiliriz, ancak kullanıcıyı dönen bir gezegen miazmasına zorlamak biraz rahatsız edici ve tasarımımızın genişliğine aykırı görünüyor.
Projeksiyon 2B "Web benzeri" bir 3B Uzayda Tıklayın
"Çarpışma"nın yanı sıra "yansıtma" da kullanabiliriz. Sahnemize bir çizgi yansıtabilir ve neye dokunduğunu görebiliriz. En yaygın örnek "ışınlanma ışını" dır.
Bir teleport ışını, bir oyuncunun nereye hareket edebileceğini göstermek için dünyadaki bir çizgiyi izler. Bu “projeksiyon” inecek yerleri arar. Projeksiyon yolundaki bir veya daha fazla nesneyi döndürür. İşte bir teleport ışını örneği:
Işının aslında aşağıyı gösteren bir parabol olarak uygulandığına dikkat edin. Bu, fırlatılan bir nesne gibi doğal olarak “yer” ile kesiştiği anlamına gelir. Bu aynı zamanda doğal olarak maksimum ışınlanma mesafesini de belirler. Sınırlar, VR'deki en önemli tasarım seçenekleridir. Neyse ki, gerçekliğin birçok doğal sınırlaması vardır.
Projeksiyon, 3B dünyayı 2B'ye "düzleştirir", böylece fare gibi tıklamak için nesneleri işaret edebilirsiniz. Birinci şahıs nişancı oyunları, son derece sinir bozucu düğmeler üzerinde ayrıntılı "2D tıklama" oyunlarıdır - genellikle bu lanet düğmelerin neden sizi "tıkladığını" açıklamak için ayrıntılı bir hikaye ile.
VR'de çok fazla silah var çünkü silahlar doğru ve güvenilir 3D fareler olarak mükemmelleştirildi - ve tıklama, tüketicilerin öğrenmeden nasıl yapacaklarını bildikleri şeydir.
Projeksiyon, sahne ile ilişkide mesafenin güvenliğini de sunar. Unutmayın, VR'de bir şeye yaklaşmak, önemi henüz ortaya çıkmamış olabilecek diğer tüm şeyleri doğal olarak kapatacaktır.
“Bakış” Kullanan Kontrolörler Olmadan Projeksiyon
WebVR'de denetleyiciler olmadan bu ilkel etkileşimi yaratmak için, izleyicilerin "bakışlarını" bir görüş hattı "imleç" olarak yansıtabiliriz. Bu imleç, nesnelerle bir "sigorta" ile etkileşim kurmak için programlı olarak kullanılabilir. Bu, izleyiciye küçük mavi bir daire olarak iletilir. Şimdi tıklıyoruz!
Kamp ateşi hikayelerini hatırlarsanız, yalan ne kadar büyükse, onu satmak için o kadar az ayrıntı gerekir. Açık ve saçma bir "bakış" etkileşimi, güneşe bakmaktır. Simülasyonumuza yeni "enkaz" gezegenler eklemeyi tetiklemek için bu "bakış"ı kullanıyoruz. Hiçbir izleyici bu seçimi sorgulamadı - VR saçma olduğunda oldukça çekici.
A-Frame'de kamerayı (oyuncuların görünmez piyonu) ve bu görüş hattını “imleç” olarak kamera donanımımız olarak ifade ediyoruz. <a-cursor>
<a-camera>
içine yerleştirmek, kameranın dönüşümlerinin imlece de uygulanmasına neden olur. Oyuncu piyonunu hareket ettirdiğinde/döndürdüğünde ( a-camera
), bakışlarını da hareket ettirir/döndürür ( 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>
İmlecin "sigortası", bir olay yayınlamadan önce tam bir saniye "bakma" geçene kadar bekler.
Güneşin aydınlatılmamış bir "arkası" olduğunu fark edebilmeniz için varsayılan aydınlatmayı kullandım. Yörünge düzleminin dışına çıkmamış olsam da, güneşin böyle çalıştığını düşünmüyorum. Ancak, gerçekliğin teknik demo posteri için çalışıyor.
Alternatif bir seçenek, aydınlatmayı kamera elemanının içine yerleştirmek olabilir, böylece kullanıcı ile birlikte hareket eder. Bu, daha samimi ve muhtemelen ürkütücü bir asteroid madenciliği deneyimi yaratacaktır. Bunlar eğlenceli tasarım seçenekleri.
Bir Entegrasyon Planımız Var
Bununla, artık A-Frame <a-scene>
ve JavaScript simülasyonumuz arasında entegrasyon noktalarımız var:
A-Çerçeve <a-scene>
:
Gövdeler için adlandırılmış bir koleksiyon:
<a-entity></a-entity>
Projeksiyon olaylarını yayan bir imleç:
<a-cursor color="#4CC3D9" fuse="true" timeout="1"></a-cursor>
JavaScript simülasyonumuz:
nBodyVisWebVR.paint(bodies)
- simülasyon gövdelerinden VR varlıklarını ekleyin/kaldırın/yeniden konumlandırınsimülasyona yeni kalıntı gövdeleri eklemek için
addBodyArgs(name, color, x, y, z, mass, vX, vY, vZ)
index.html
, simülasyonumuzu tuval sürümüne çok benzer şekilde main.js
yükler:
// 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)) }
Burada, gövdeleri tutmak için görselleştiricinin htmlElement
a-bodies
koleksiyonuna ayarladığımızı fark edeceksiniz.
JavaScript'ten A-Frame Nesnelerini Programlı Olarak Yönetme
index.html
sahnemizi ilan ettikten sonra, şimdi görselleştiriciyi kodlamaya hazırız.
İlk olarak, nBodyVisualizer
gövdeleri listesinden okumak ve <a-entity></a-entity>
koleksiyonunda A-Frame nesneleri oluşturmak/güncellemek/silmek için nBodySimulation
.
// 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() {}
Yapıcıda, A-Frame koleksiyonumuzu kaydederiz, simülasyonu bulmak için bakış olayımız için global bir değişken belirleriz ve simülasyonumuz ile A-Frame'in sahnesi arasındaki gövdeleri eşleştirmek için kullanacağımız bir id sayacı başlatırız.
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) }) }
İlk olarak, A-Frame varlıklarını simülasyon gövdeleriyle eşleştirmek için bir arama tablosu oluşturmak ve/veya etiketlemek için sim gövdeleri arasında döngü yaparız.
Ardından, mevcut A-Frame gövdeleri arasında dolaşıyoruz ve simülasyon tarafından sınırların dışına çıkmak için kırpılanları kaldırıyoruz. Bu, deneyimin algılanan performansını artırır.
Son olarak, eksik gövdeler için yeni bir <a-sphere>
oluşturmak ve diğerlerini aBody.object3D.position.set(body.x, body.y, body.z)
ile yeniden konumlandırmak için sim gövdeleri arasında döngü yaparız.
Standart DOM işlevlerini kullanarak A-Frame sahnesindeki öğeleri programlı olarak değiştirebiliriz. Sahneye bir öğe eklemek için kapsayıcının innerHTML'sine bir dize ekleriz. Bu kod bana garip geliyor ama işe yarıyor ve daha iyi bir şey bulamadım.
Eklenecek dizeyi oluşturduğumuzda fark edeceksiniz, bir öznitelik ayarlamak için "yıldız" yakınında üçlü bir operatörümüz var.
<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>`
Vücut bir "yıldız" ise, olaylarını tanımlayan bazı ekstra nitelikler ekleriz. DOM'a monte edildiğinde yıldızımız şöyle görünür:
<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>
Üç nitelik, debris-listener
, event-set__enter
ve event-set__leave
, etkileşimlerimizi kurar ve entegrasyonumuzun son turudur.
A-Frame Olaylarını ve Etkileşimlerini Tanımlama
İzleyici ona “baktığında” güneşin rengini değiştirmek için varlığın niteliklerinde NPM paketi “aframe-event-set-component” kullanırız.
Bu “bakış”, izleyicinin konumundan ve rotasyonundan bir izdüşümdür ve etkileşim, bakışlarının bir şey yaptığına dair gerekli geri bildirimi sağlar.
Yıldız küremizde artık eklenti tarafından etkinleştirilen iki stenografi olayı var, event-set__enter
ve event-set__leave
:
<a-sphere ... event-set__enter="_event: mouseenter; color: green" event-set__leave="_event: mouseleave; color: yellow" … ></a-sphere>
Ardından, yıldız küremizi özel bir A-Frame bileşeni olarak uygulayacağımız bir debris-listener
ile süslüyoruz.
<a-sphere ... debris-listener="" … ></a-sphere>
A-Frame bileşenleri global düzeyde tanımlanır:
// 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)) } }) } })
Bu A-Frame bileşeni, sahnemize 10 yeni rastgele cisim eklemek için bakış imleci tarafından tetiklenebilen bir 'tıklama' dinleyicisi gibi davranır.
Özetlemek:
- WebVR sahnesini standart HTML'de A-Frame ile ilan ediyoruz.
- JavaScript'ten sahnedeki A-Frame varlıklarını programlı olarak ekleyebilir/kaldırabilir/güncelleyebiliriz.
- A-Frame eklentileri ve bileşenleri aracılığıyla olay işleyicilerle JavaScript'te etkileşimler oluşturabiliriz.
WebVR: Veni, Vidi, Vici
Umarım siz de bu teknoloji demosundan benim kadar faydalanmışsınızdır. Bu özellikleri (web çalışanları ve WebAssembly) WebVR'a uyguladığımız yerde, bunlar aynı zamanda tarayıcı uç bilişimine de uygulanabilir.
Devasa bir teknoloji dalgası geldi - Sanal Gerçeklik (VR). Bir akıllı telefonu ilk tuttuğunuzda ne hissettiyseniz, VR'yi ilk kez deneyimlemek, bilgisayarın her alanında 10 kat duygusal bir deneyim sunar. İlk iPhone'un üzerinden sadece 12 yıl geçti.
VR çok daha uzun süredir var, ancak VR'yi ortalama kullanıcılara getirmek için gereken teknoloji, PC devrimi değil, mobil devrim ve Facebook'un Oculus Quest'i aracılığıyla geldi.
İnternet ve açık kaynak, insanlığın dünyanın en büyük harikaları arasındadır. Düz interneti yaratan tüm insanlara - Cesaretinize ve macera duygunuza kadeh kaldırıyorum.
Manifesto! Dünyalar inşa edeceğiz, çünkü yaratma gücümüz var.