WebVR ตอนที่ 5: การออกแบบและการใช้งาน

เผยแพร่แล้ว: 2022-03-11

ฉันชอบที่จะทำโครงการให้ "เสร็จสิ้น" เรามาถึงจุดสิ้นสุดของการเดินทางแล้ว - และการกำเนิดของการจำลองแรงโน้มถ่วงบนท้องฟ้าใน WebVR

ในโพสต์สุดท้ายนี้ เราจะเสียบโค้ดการจำลองประสิทธิภาพสูงของเรา (บทความ 1,2,3) ลงในโปรแกรมสร้างภาพ WebVR โดยอิงจากโปรแกรมสร้างภาพแคนวาส (มาตรา 4)

  1. "ปัญหาร่างกาย" บทนำและสถาปัตยกรรม
  2. Web Workers รับเธรดเบราว์เซอร์เพิ่มเติมให้เรา
  3. WebAssembly และ AssemblyScript สำหรับรหัสคอขวดด้านประสิทธิภาพ O(n²) ของเรา
  4. การแสดงข้อมูลผ้าใบ
  5. การแสดงข้อมูล WebVR

นี่เป็นบทความที่ยาวขึ้น ดังนั้นเราจะข้ามรายละเอียดทางเทคนิคที่กล่าวถึงก่อนหน้านี้ ตรวจสอบโพสต์ก่อนหน้านี้หากคุณต้องการปฐมนิเทศหรืออ่านในเชิงอันตราย

เราได้สำรวจการเปลี่ยนกระบวนทัศน์ของเบราว์เซอร์จากรันไทม์ JavaScript แบบเธรดเดียวไปเป็นแบบมัลติเธรด (ผู้ทำงานเว็บ) รันไทม์ประสิทธิภาพสูง (WebAssembly) คุณลักษณะการประมวลผลเดสก์ท็อปที่มีประสิทธิภาพเหล่านี้มีอยู่ใน Progressive Web Apps และรูปแบบการแจกจ่าย SaaS

การสาธิต WebVR
การสาธิต WebVR, โค้ดตัวอย่าง

VR จะสร้างสภาพแวดล้อมการขายและการตลาดที่ปราศจากสิ่งรบกวนที่น่าสนใจเพื่อสื่อสาร โน้มน้าวใจ และวัดผลการมีส่วนร่วม (การติดตามการมองและการโต้ตอบ) ข้อมูลจะยังคงเป็นศูนย์และหนึ่ง แต่บทสรุปสำหรับผู้บริหารที่คาดหวังและประสบการณ์ของผู้บริโภคจะเป็น WebVR เช่นเดียวกับที่เราสร้างประสบการณ์แดชบอร์ดบนมือถือสำหรับเว็บทั่วไปในปัจจุบัน

เทคโนโลยีเหล่านี้ยังเปิดใช้งานการประมวลผลขอบเบราว์เซอร์แบบกระจาย ตัวอย่างเช่น เราสามารถสร้างแอปพลิเคชันบนเว็บเพื่อเรียกใช้การคำนวณ WebAssembly สำหรับดาวนับล้านในการจำลอง อีกตัวอย่างหนึ่งคือแอปพลิเคชันแอนิเมชั่นที่แสดงการสร้างสรรค์ของผู้ใช้รายอื่นในขณะที่คุณกำลังแก้ไขของคุณเอง

เนื้อหาความบันเทิงเป็นผู้นำในการเข้าถึง Virtual Reality เช่นเดียวกับความบันเทิงบนมือถือ อย่างไรก็ตาม เมื่อ VR เป็นเรื่องปกติ (เช่น การออกแบบเพื่ออุปกรณ์พกพาเป็นหลักในปัจจุบัน) ก็จะเป็นประสบการณ์ที่คาดหวัง (การออกแบบที่เน้น VR เป็นหลัก) นี่เป็นช่วงเวลาที่น่าตื่นเต้นมากในการเป็นนักออกแบบและนักพัฒนา และ VR เป็นกระบวนทัศน์การออกแบบที่แตกต่างไปจากเดิมอย่างสิ้นเชิง

คุณไม่ใช่นักออกแบบ VR หากคุณจับไม่ได้ นั่นเป็นคำกล่าวที่ชัดเจน และวันนี้เป็นการเจาะลึกในการออกแบบ VR ฟิลด์นี้กำลังถูกประดิษฐ์ขึ้นเมื่อคุณอ่านข้อความนี้ จุดประสงค์ของฉันคือการแบ่งปันประสบการณ์ของฉันในซอฟต์แวร์และภาพยนตร์เพื่อเน้นการสนทนา “การออกแบบที่เน้น VR เป็นหลัก” เราทุกคนเรียนรู้จากกันและกัน.

เมื่อคำนึงถึงการคาดการณ์อันยิ่งใหญ่เหล่านั้น ฉันต้องการทำโปรเจ็กต์นี้ให้เสร็จด้วยการสาธิตเทคโนโลยีระดับมืออาชีพ - WebVR เป็นตัวเลือกที่ยอดเยี่ยมสำหรับสิ่งนั้น!

WebVR และ Google A-Frame

WebVR git repo เป็นทางแยกของเวอร์ชันแคนวาสด้วยเหตุผลสองประการ ทำให้การโฮสต์โปรเจ็กต์บนหน้า Github ง่ายขึ้น และ WebVR ต้องการการเปลี่ยนแปลงสองสามอย่างซึ่งจะทำให้เวอร์ชันแคนวาสและบทความเหล่านี้รก

หากคุณจำโพสต์แรกของเราเกี่ยวกับสถาปัตยกรรมได้ เราได้มอบหมายการจำลองทั้งหมดไปที่ nBodySimulator

`nBodySimulator`

โพสต์ของ Web Worker แสดงให้เห็นว่า nBodySimulator มีฟังก์ชัน step() ที่เรียกว่าทุกๆ 33ms ของการจำลอง step() เรียก calcForces calculateForces() เพื่อเรียกใช้โค้ดจำลอง O(n²) WebAssembly ของเรา (ข้อ 3) จากนั้นอัปเดตตำแหน่งและทาสีใหม่ ในโพสต์ก่อนหน้าของเราที่สร้างการแสดงภาพแคนวาส เราได้ใช้งานสิ่งนี้กับองค์ประกอบแคนวาส โดยเริ่มจากคลาสพื้นฐานนี้:

 /** * 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)) } }

กำหนดความท้าทายในการบูรณาการ

เรามีแบบจำลอง ตอนนี้ เราต้องการผสานรวมกับ WebVR โดยไม่ต้องออกแบบโครงการใหม่ ไม่ว่าเราจะทำการปรับเปลี่ยนอะไรกับการจำลองทุกๆ 33ms ในเธรด UI หลักในฟังก์ชัน paint(bodies)

นี่คือวิธีที่เราจะวัดว่า "เสร็จสิ้น" ฉันตื่นเต้น - ไปทำงานกันเถอะ!

วิธีสร้างความจริงเสมือน

อันดับแรก เราต้องออกแบบ:

  • VR ทำมาจาก อะไร?
  • การออกแบบ WebVR แสดงออก อย่างไร ?
  • เราจะ โต้ตอบ กับมันได้อย่างไร

Virtual Reality ย้อนเวลากลับไปสู่รุ่งอรุณของเวลา เรื่องราวแคมป์ไฟทุกเรื่องเป็นโลกเสมือนจริงเล็ก ๆ ของการพูดเกินจริงที่บรรยายโดยรายละเอียดเล็กน้อย

เราเพิ่มเรื่องราวแคมป์ไฟได้ 10 เท่าด้วยการเพิ่มภาพและเสียงสามมิติแบบสามมิติ ผู้สอนด้านงบประมาณการผลิตภาพยนตร์ของฉันเคยพูดว่า “เราจ่ายแค่ค่าโปสเตอร์เท่านั้น เราไม่ได้สร้างความเป็นจริง”

หากคุณคุ้นเคยกับ DOM ของเบราว์เซอร์ คุณจะรู้ว่ามันสร้างโครงสร้างแบบลำดับชั้นเหมือนต้นไม้

กราฟฉากเว็บแบน
เว็บแบน "กราฟฉาก"

โดยนัยในการออกแบบเว็บคือการที่ผู้ชมดูจาก "ด้านหน้า" เมื่อมองจากด้านข้างจะเห็นองค์ประกอบ DOM เป็นเส้น และจากด้านหลัง เราจะเห็นแท็ก <body> เพราะมันบดบังลูกๆ

ส่วนหนึ่งของประสบการณ์เสมือนจริงของ VR คือการให้ผู้ใช้ควบคุมมุมมอง สไตล์ ฝีเท้า และลำดับของการโต้ตอบ พวกเขาไม่ต้องสนใจอะไรเป็นพิเศษ หากคุณย้ายหรือหมุนกล้องโดยทางโปรแกรม กล้องจะ อ้วก จากการเจ็บป่วย VR

โปรดทราบว่าการเจ็บป่วย VR ไม่ใช่เรื่องตลก ทั้งตาและหูชั้นในของเราตรวจจับการเคลื่อนไหว มันสำคัญมากสำหรับสัตว์ที่เดินตัวตรง เมื่อเซ็นเซอร์ตรวจจับความเคลื่อนไหวเหล่านั้นไม่เห็นด้วย สมองของเราจะถือว่าโดยธรรมชาติแล้วปากของเราได้กินเรื่องไร้สาระอีกแล้วและอาเจียนออกมา เราทุกคนเคยเป็นเด็กมาก่อน มีการเขียนเกี่ยวกับสัญชาตญาณการเอาชีวิตรอดใน VR ไว้มากมายแล้ว ชื่อ “Epic Fun” นั้นเล่นได้ฟรีบน Steam และรถไฟเหาะเป็นการสาธิตการเจ็บป่วย VR ที่ดีที่สุดที่ฉันเคยพบ

ความเป็นจริงเสมือนจะแสดงเป็น "กราฟฉาก" กราฟฉากมีรูปแบบคล้ายต้นไม้เหมือนกับ DOM เพื่อซ่อนรายละเอียดและความซับซ้อนของสภาพแวดล้อม 3 มิติที่น่าเชื่อ อย่างไรก็ตาม แทนที่จะเลื่อนและกำหนดเส้นทาง เราวางตำแหน่งผู้ดูในตำแหน่งที่พวกเขาต้องการดึงประสบการณ์ไปทางพวกเขา

นี่คือกราฟฉาก Hello World จาก A-Frame WebVR Framework ของ Google:

 <!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>

เอกสาร HTML นี้สร้าง DOM ในเบราว์เซอร์ แท็ก <a-*> เป็นส่วนหนึ่งของเฟรมเวิร์ก A-Frame และ <a-scene> เป็นรากของกราฟฉาก ในที่นี้ เราจะเห็นภาพ 3D primitives สี่ภาพที่แสดงอยู่ในฉาก

ฉาก A-Frame ในเว็บเบราว์เซอร์แบบเรียบ
ฉาก A-Frame ในเว็บเบราว์เซอร์แบบเรียบ

อันดับแรก สังเกตว่าเรากำลังดูฉากนี้จากเว็บเบราว์เซอร์แบบเรียบ หน้ากากเล็ก ๆ ที่ด้านล่างขวาเชิญชวนให้ผู้ใช้เปลี่ยนไปใช้โหมดสามมิติสามมิติ

ฉาก A-Frame เสมือนจริง
ฉาก A-Frame ใน Virtual Reality - หนึ่งภาพสำหรับตาแต่ละข้าง

ตามทฤษฎีแล้ว คุณควรจะสามารถ:

  1. เปิดสิ่งนี้บนโทรศัพท์ของคุณ
  2. ถือโทรศัพท์แนบหน้า
  3. ดื่มด่ำกับความงดงามของความเป็นจริงครั้งใหม่!

ฉันไม่เคยใช้งานมันเลยหากไม่มีเลนส์แฟนซีของชุดหูฟัง VR คุณสามารถรับชุดหูฟัง VR สำหรับโทรศัพท์ Android ในราคาถูก (อุปกรณ์พื้นฐานที่ใช้ Google Cardboard) อย่างไรก็ตาม สำหรับการพัฒนาเนื้อหา ฉันขอแนะนำ HMD แบบสแตนด์อโลน (Head Mounted Display) เช่น Oculus Quest

เหมือนกับการดำน้ำลึกหรือดิ่งพสุธา Virtual Reality เป็นกีฬาที่มีอุปกรณ์ครบครัน

การเรียนรู้ของนักออกแบบ VR "หน้าผา"

ความเป็นจริงด้วยแรงโน้มถ่วงและแสง
ยินดีต้อนรับสู่ความเป็นจริงที่สะดวกสบายด้วยแรงโน้มถ่วงและแสง

สังเกตว่าฉาก A-Frame Hello World มีแสงและกล้องเริ่มต้น:

  • ใบหน้าของลูกบาศก์มีสีต่างกัน - ลูกบาศก์มีเงาในตัว
  • ลูกบาศก์กำลังขว้างเงาบนเครื่องบิน - มีแสงบอกทิศทาง
  • ไม่มีช่องว่างระหว่างลูกบาศก์กับระนาบ - นี่คือโลกที่มีแรงโน้มถ่วง

นี่เป็นสัญญาณสำคัญที่บอกผู้ชมว่า “ผ่อนคลาย สิ่งนี้บนใบหน้าของคุณเป็นเรื่องปกติโดยสิ้นเชิง”

นอกจากนี้ โปรดสังเกตว่าการตั้งค่าเริ่มต้นนี้มีนัยในโค้ดของฉาก Hello World ด้านบน A-Frame เป็นค่าเริ่มต้นที่สมเหตุสมผล แต่โปรดทราบว่ากล้องและแสงเป็นช่องว่างที่นักออกแบบต้องข้ามเพื่อสร้าง VR

เราใช้การตั้งค่าแสงเริ่มต้นตามที่เห็นสมควร ตัวอย่างเช่น ปุ่ม:

ปุ่ม

สังเกตว่าแสงโดยนัยนี้แพร่หลายมากเพียงใดในการออกแบบและการถ่ายภาพ แม้แต่ปุ่ม "การออกแบบเรียบๆ" ก็ไม่สามารถหลีกหนีจากแสงเริ่มต้นของเว็บได้ เนื่องจากมันทำให้เงาตกกระทบไปทางขวา

การออกแบบ สื่อสาร และใช้งานการจัดแสงและการตั้งค่ากล้องคือจุดเริ่มต้นการเรียนรู้ของนักออกแบบ WebVR “ภาษาของภาพยนตร์” คือชุดของบรรทัดฐานทางวัฒนธรรม ซึ่งแสดงเป็นกล้องและการจัดแสงที่แตกต่างกัน ซึ่งจะสื่ออารมณ์เรื่องราวให้ผู้ชมได้ทราบ มืออาชีพในภาพยนตร์ที่ออกแบบ/ย้ายไฟและกล้องไปรอบๆ ฉากคือแผนกกริป

กลับสู่ความเป็นจริงเสมือนของเรา

งั้นเรากลับไปทำงานกันเถอะ ฉาก WebVR บนท้องฟ้าของเรามีรูปแบบที่คล้ายกัน:

 <!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>

เอกสาร HTML นี้โหลดเฟรมเวิร์ก A-Frame และปลั๊กอินการโต้ตอบ ฉากของเราเริ่มต้นที่ <a-scene>

ข้างใน เราเริ่มด้วยองค์ประกอบ <a-sky color="#222"></a-sky> เพื่อสร้างสีพื้นหลังทุกอย่างที่เราไม่ได้กำหนดไว้ในฉาก

ต่อไป เราสร้าง "ระนาบโคจร" เพื่อให้ผู้ชม "จับ" ขณะที่พวกเขาบินผ่านโลกที่แปลกประหลาดและไม่รู้จักของเรา เราสร้างสิ่งนี้เป็นแผ่นดิสก์และทรงกลมสีดำขนาดเล็กที่ (0,0,0) หากปราศจากสิ่งนี้ การหันกลับรู้สึกว่า "ไม่มีเหตุผล" สำหรับฉัน:

 <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-Frame

 <a-entity></a-entity>

นี่คือการล้างเพื่อให้ paint(bodies) ของ nBodyVisualizer ทำงาน

จากนั้นเราก็สร้างความสัมพันธ์ระหว่างผู้ดูกับโลกนี้ ในการสาธิตเทคโนโลยี จุดประสงค์ของโลกนี้คือเพื่อให้ผู้ดูสำรวจ WebVR และเทคโนโลยีของเบราว์เซอร์ที่เปิดใช้งาน การเล่าเรื่องแบบ "นักบินอวกาศ" ที่เรียบง่ายช่วยสร้างความรู้สึกสนุกสนาน และป้ายบอกทางที่เป็นตัวเอกนี้ก็เป็นอีกจุดอ้างอิงสำหรับการนำทาง

 <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>

นั่นทำให้กราฟฉากของเราสมบูรณ์ สุดท้ายนี้ ฉันต้องการปฏิสัมพันธ์ บางอย่าง ในการสาธิตทางโทรศัพท์ระหว่างผู้ใช้กับโลกที่ปั่นป่วนนี้ เราจะสร้างปุ่ม "โยนเศษซาก" ใน VR ได้อย่างไร?

ปุ่มนี้เป็นองค์ประกอบหลักของการออกแบบที่ทันสมัย ​​ปุ่ม VR อยู่ที่ไหน

การโต้ตอบใน WebVR

Virtual Reality มี "ด้านบน" และ "ครึ่งหน้าล่าง" ของตัวเอง การโต้ตอบครั้งแรกของผู้ดูคือผ่านอวาตาร์หรือกล้อง นี่คือการควบคุมทั้งหมดสำหรับการซูมไปรอบๆ

หากคุณกำลังอ่านข้อความนี้บนเดสก์ท็อป คุณสามารถ WASD เพื่อย้ายและเลื่อนเมาส์เพื่อหมุนกล้อง การสำรวจนี้เปิดเผยข้อมูลแต่ไม่ได้แสดงเจตจำนงของคุณ

Real Reality มีคุณสมบัติที่สำคัญสองสามอย่างที่ไม่ค่อยพบในเว็บ:

  • มุมมอง - วัตถุจะเล็กลงอย่างเห็นได้ชัดเมื่อพวกมันเคลื่อนตัวออกห่างจากเรา
  • การ บดเคี้ยว - วัตถุถูกซ่อนและเปิดเผยตามตำแหน่ง

VR จำลองคุณสมบัติเหล่านี้เพื่อสร้างเอฟเฟกต์ 3D นอกจากนี้ยังสามารถใช้ใน VR เพื่อเปิดเผยข้อมูลและอินเทอร์เฟซ และเพื่อสร้างอารมณ์ก่อนที่จะนำเสนอการโต้ตอบ ฉันพบว่าคนส่วนใหญ่ต้องใช้เวลาสักครู่เพื่อเพลิดเพลินกับประสบการณ์นี้ก่อนที่จะก้าวไปข้างหน้า

ใน WebVR เราโต้ตอบในพื้นที่ 3 มิติ เรามีเครื่องมือพื้นฐานสองอย่างสำหรับสิ่งนี้:

  • Collision - เหตุการณ์ 3D แบบพาสซีฟเกิดขึ้นเมื่อวัตถุสองชิ้นใช้พื้นที่เดียวกัน
  • การฉายภาพ - การเรียกใช้ฟังก์ชัน 2D ที่ใช้งานอยู่ซึ่งแสดงรายการวัตถุทั้งหมดที่ตัดกันเป็นเส้น

การชนกันเป็นการโต้ตอบที่ "เหมือน VR" ที่สุด

ใน VR "การชนกัน" คือสิ่งที่ดูเหมือน: เมื่อวัตถุสองชิ้นใช้พื้นที่เดียวกัน A-Frame จะสร้างเหตุการณ์ขึ้น

เพื่อให้ผู้ใช้ "กดปุ่ม" เราต้องให้สัญลักษณ์แทนตัวและบางสิ่งที่จะกดปุ่มด้วย

น่าเสียดายที่ WebVR ยังไม่สามารถคาดเดาตัวควบคุมได้ หลายคนจะดูเวอร์ชันเว็บแบบเรียบบนเดสก์ท็อปหรือโทรศัพท์ และหลายคนจะใช้ชุดหูฟัง เช่น Google Cardboard หรือ Gear VR ของ Samsung เพื่อแสดงเวอร์ชันสามมิติ

หากผู้ใช้ไม่มีตัวควบคุม พวกเขาจะเอื้อมมือออกไปและ "สัมผัส" สิ่งต่างๆ ไม่ได้ ดังนั้นการชนกันจะต้องอยู่ที่ "พื้นที่ส่วนตัว"

เราสามารถให้ผู้เล่นจำนำรูปนักบินอวกาศเพื่อเคลื่อนที่ไปรอบ ๆ ได้ แต่การบังคับผู้ใช้ให้กลายเป็นดาวเคราะห์ที่หมุนวนดูเหมือนจะไม่ค่อยดีนักและขัดกับความกว้างขวางของการออกแบบของเรา

การฉายภาพเป็นแบบ 2 มิติ “เหมือนเว็บ” คลิกใน 3D Space

นอกจาก "การชน" เรายังสามารถใช้ "การฉายภาพ" ได้อีกด้วย เราสามารถฉายเส้นผ่านฉากของเราและดูสิ่งที่สัมผัสได้ ตัวอย่างที่พบบ่อยที่สุดคือ "รังสีเทเลพอร์ต"

รังสีเทเลพอร์ตลากเส้นในโลกเพื่อแสดงตำแหน่งที่ผู้เล่นสามารถเคลื่อนที่ได้ “การฉายภาพ” นี้มองหาสถานที่ที่จะลงจอด ส่งคืนวัตถุอย่างน้อยหนึ่งรายการในเส้นทางของการฉายภาพ นี่คือตัวอย่างรังสีเทเลพอร์ต:

รังสีเทเลพอร์ตในเนื้อหาเริ่มต้นของ Unreal Engine
รังสีเทเลพอร์ตในเนื้อหาเริ่มต้นของ Unreal Engine

สังเกตว่าจริง ๆ แล้วรังสีถูกนำมาใช้เป็นพาราโบลาที่ชี้ลง ซึ่งหมายความว่าธรรมชาติตัดกับ "พื้นดิน" เหมือนวัตถุที่ถูกขว้าง สิ่งนี้ยังกำหนดระยะการเคลื่อนย้ายสูงสุดโดยธรรมชาติ ข้อจำกัดคือตัวเลือกการออกแบบที่สำคัญที่สุดใน VR โชคดีที่ความเป็นจริงมีข้อ จำกัด ตามธรรมชาติมากมาย

การฉายภาพ “แผ่” โลก 3D ให้เป็น 2D เพื่อให้คุณสามารถชี้ไปที่สิ่งต่างๆ เพื่อคลิกได้เหมือนเมาส์ เกมยิงมุมมองบุคคลที่หนึ่งเป็นเกมที่ซับซ้อนของการ "คลิก 2 มิติ" บนปุ่มที่น่าผิดหวัง - มักจะมีเรื่องราวที่ซับซ้อนเพื่ออธิบายว่าทำไมมันจึงไม่โอเคที่ปุ่มเหล่านั้นจะ "คลิก" คุณกลับ

มีปืนจำนวนมากใน VR เนื่องจากปืนได้รับการปรับปรุงให้สมบูรณ์แบบเหมือนเมาส์ 3 มิติที่แม่นยำและเชื่อถือได้ และการคลิกคือสิ่งที่ผู้บริโภครู้วิธีการทำโดยไม่ต้องเรียนรู้

การฉายภาพยังให้ความปลอดภัยในระยะห่างในความสัมพันธ์กับฉาก จำไว้ว่าการเข้าใกล้บางสิ่งใน VR จะทำให้สิ่งอื่น ๆ ที่อาจยังไม่เปิดเผยความสำคัญหายไปโดยธรรมชาติ

การฉายภาพโดยไม่ใช้ตัวควบคุมโดยใช้ “จ้อง”

ในการสร้างปฏิสัมพันธ์แบบดั้งเดิมใน WebVR โดยไม่ต้องใช้ตัวควบคุม เราสามารถฉายภาพ "จ้องมอง" ของผู้ดูเป็น "เคอร์เซอร์" ในสายตา เคอร์เซอร์นี้สามารถใช้โดยทางโปรแกรมเพื่อโต้ตอบกับวัตถุด้วย "ฟิวส์" นี่คือการสื่อสารไปยังผู้ชมเป็นวงกลมสีน้ำเงินขนาดเล็ก ตอนนี้เรากำลังคลิก!

หากคุณจำเรื่องราวเกี่ยวกับแคมป์ไฟได้ ยิ่งเรื่องโกหกมากเท่าไหร่ รายละเอียดก็น้อยลงในการขาย ปฏิสัมพันธ์ "จ้องมอง" ที่เห็นได้ชัดและไร้สาระคือการจ้องไปที่ดวงอาทิตย์ เราใช้ "การจ้อง" นี้เพื่อกระตุ้นการเพิ่มดาวเคราะห์ "เศษซาก" ใหม่ลงในการจำลองของเรา ผู้ชมไม่เคยตั้งคำถามกับตัวเลือกนี้ - VR ค่อนข้างมีเสน่ห์เมื่อไร้สาระ

ใน A-Frame เราแสดงกล้อง (สัญลักษณ์แทนตัวที่มองไม่เห็นของผู้เล่น) และ "เคอร์เซอร์" ของสายตานี้เป็นอุปกรณ์สำหรับกล้องของเรา การวาง <a-cursor> ไว้ใน <a-camera> จะทำให้การแปลงของกล้องมีผลกับเคอร์เซอร์ด้วย เมื่อผู้เล่นเคลื่อนที่/หมุนสัญลักษณ์แทนตัว ( a-camera ) ผู้เล่นก็จะเคลื่อนที่/หมุนการจ้องมองด้วย ( 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>

"ฟิวส์" ของเคอร์เซอร์จะรอจนกระทั่ง "จ้อง" ครบหนึ่งวินาทีก่อนที่จะปล่อยเหตุการณ์

ฉันใช้แสงเริ่มต้น ดังนั้นคุณอาจสังเกตเห็นว่ามี "ด้านหลัง" ของดวงอาทิตย์ที่ไม่มีแสงสว่าง แม้ว่าฉันจะไม่ได้อยู่นอกระนาบโคจร ฉันก็ไม่คิดว่าดวงอาทิตย์จะทำงานแบบนั้น อย่างไรก็ตาม มันใช้ได้กับโปสเตอร์สาธิตเทคโนโลยีของความเป็นจริงของเรา

อีกทางเลือกหนึ่งคือการจัดแสงภายในองค์ประกอบของกล้องเพื่อให้เคลื่อนที่ไปพร้อมกับผู้ใช้ สิ่งนี้จะสร้างประสบการณ์การขุดดาวเคราะห์น้อยที่ใกล้ชิดและน่ากลัวยิ่งขึ้น นี่เป็นตัวเลือกการออกแบบที่สนุกสนาน

เรามีแผนบูรณาการ

ด้วยเหตุนี้ เราจึงมีจุดรวมระหว่าง A-Frame <a-scene> และการจำลอง JavaScript ของเรา:

A-Frame <a-scene> :

  • คอลเลกชันที่มีชื่อสำหรับเนื้อหา: <a-entity></a-entity>

  • เคอร์เซอร์ที่จะปล่อยเหตุการณ์การฉาย: <a-cursor color="#4CC3D9" fuse="true" timeout="1"></a-cursor>

การจำลอง JavaScript ของเรา:

  • nBodyVisWebVR.paint(bodies) - เพิ่ม/ลบ/เปลี่ยนตำแหน่งเอนทิตี VR จากตัวจำลอง

  • addBodyArgs(name, color, x, y, z, mass, vX, vY, vZ) เพื่อเพิ่มวัตถุใหม่ลงในการจำลอง

index.html โหลด main.js ซึ่งเริ่มต้นการจำลองของเราเหมือนกับเวอร์ชันผ้าใบ:

 // 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)) }

คุณจะสังเกตเห็นว่าที่นี่เราตั้งค่า htmlElement ของ visualizer เป็นคอลเล็กชัน a-bodies เพื่อเก็บศพ

การจัดการอ็อบเจ็กต์ A-Frame โดยทางโปรแกรมจาก JavaScript

หลังจากประกาศฉากของเราใน index.html แล้ว เราก็พร้อมที่จะโค้ดโปรแกรมสร้างภาพ

อันดับแรก เราตั้งค่า nBodyVisualizer ให้อ่านจากรายการเนื้อหา nBodySimulation และสร้าง/อัปเดต/ลบออบเจ็กต์ A-Frame ในคอลเล็กชัน <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() {}

ในตัวสร้าง เราบันทึกคอลเลกชัน A-Frame ของเรา ตั้งค่าตัวแปรส่วนกลางสำหรับเหตุการณ์การจ้องมองของเราเพื่อค้นหาการจำลอง และเริ่มต้นตัวนับรหัสที่เราจะใช้เพื่อจับคู่เนื้อหาระหว่างการจำลองของเรากับฉากของ 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) }) }

ขั้นแรก เราวนลูปผ่านเนื้อความของซิมเพื่อติดป้ายกำกับและ/หรือสร้างตารางค้นหาสำหรับการจับคู่เอนทิตี A-Frame กับเนื้อหาการจำลอง

ต่อไป เราจะวนรอบร่างกาย A-Frame ที่มีอยู่และลบส่วนใดก็ตามที่ถูกตัดแต่งโดยการจำลองสำหรับการเดินทางออกนอกขอบเขต สิ่งนี้ช่วยเพิ่มประสิทธิภาพการรับรู้ของประสบการณ์

สุดท้าย เราวนลูปผ่านเนื้อความของซิมเพื่อสร้าง <a-sphere> ใหม่สำหรับร่างกายที่หายไป และเพื่อปรับตำแหน่งอื่นๆ ด้วย aBody.object3D.position.set(body.x, body.y, body.z)

เราสามารถปรับเปลี่ยนองค์ประกอบในฉาก A-Frame โดยทางโปรแกรมได้โดยใช้ฟังก์ชัน DOM มาตรฐาน ในการเพิ่มองค์ประกอบให้กับฉาก เราผนวกสตริงเข้ากับ innerHTML ของคอนเทนเนอร์ รหัสนี้มีรสชาติแปลกสำหรับฉัน แต่ใช้งานได้ และฉันไม่พบอะไรที่ดีกว่านี้

คุณจะสังเกตเห็นว่าเมื่อเราสร้างสตริงที่จะผนวก เรามีตัวดำเนินการ ternary ใกล้ "star" เพื่อตั้งค่าแอตทริบิวต์

 <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>`

หากร่างกายเป็น "ดาว" เราจะเพิ่มคุณลักษณะพิเศษบางอย่างที่อธิบายเหตุการณ์ของมัน นี่คือลักษณะของดาวของเราเมื่อติดตั้งใน 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>

แอตทริบิวต์สามอย่าง, debris-listener , event-set__enter และ event-set__leave ตั้งค่าการโต้ตอบของเราและเป็นรอบสุดท้ายของการรวมระบบของเรา

การกำหนดเหตุการณ์ A-Frame และการโต้ตอบ

เราใช้แพ็คเกจ NPM "aframe-event-set-component" ในแอตทริบิวต์ของเอนทิตีเพื่อเปลี่ยนสีของดวงอาทิตย์เมื่อผู้ดู "มอง" ไปที่มัน

“การจ้องมอง” นี้เป็นการฉายภาพจากตำแหน่งและการหมุนของผู้ดู และการโต้ตอบให้ข้อเสนอแนะที่จำเป็นว่าการจ้องมองของพวกเขากำลังทำอะไรบางอย่าง

ทรงกลมดาวของเราตอนนี้มีเหตุการณ์ชวเลขสองเหตุการณ์ที่เปิดใช้งานโดยปลั๊กอิน event-set__enter และ event-set__leave :

 <a-sphere ... event-set__enter="_event: mouseenter; color: green" event-set__leave="_event: mouseleave; color: yellow" … ></a-sphere>

ต่อไป เราตกแต่งทรงกลมดาวของเราด้วยเครื่อง debris-listener เราจะนำไปใช้เป็นส่วนประกอบ A-Frame ที่กำหนดเอง

 <a-sphere ... debris-listener="" … ></a-sphere>

ส่วนประกอบ A-Frame ถูกกำหนดในระดับโลก:

 // 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)) } }) } })

คอมโพเนนต์ A-Frame นี้ทำหน้าที่เหมือนผู้ฟัง 'คลิก' ที่เคอร์เซอร์การจ้องมองสามารถกระตุ้นเพื่อเพิ่ม 10 เนื้อหาแบบสุ่มใหม่ให้กับฉากของเรา

เพื่อสรุป:

  1. เราประกาศฉาก WebVR ด้วย A-Frame ใน HTML มาตรฐาน
  2. เราสามารถเพิ่ม/ลบ/อัปเดตเอนทิตี A-Frame ในฉากจาก JavaScript โดยทางโปรแกรม
  3. เราสามารถสร้างการโต้ตอบใน JavaScript กับตัวจัดการเหตุการณ์ผ่านปลั๊กอินและส่วนประกอบ A-Frame

WebVR: Veni, Vidi, Vici

ฉันหวังว่าคุณจะได้รับประโยชน์จากการสาธิตเทคโนโลยีนี้มากเท่ากับที่ฉันทำ เมื่อเราใช้คุณลักษณะเหล่านี้ (ผู้ปฏิบัติงานเว็บและ WebAssembly) กับ WebVR ก็สามารถใช้คุณลักษณะเหล่านี้กับการประมวลผลขอบของเบราว์เซอร์ได้

คลื่นเทคโนโลยีขนาดใหญ่มาถึงแล้ว - Virtual Reality (VR) ไม่ว่าคุณจะรู้สึกอะไรในครั้งแรกที่คุณถือสมาร์ทโฟน การได้สัมผัสกับ VR เป็นครั้งแรกจะมอบประสบการณ์ทางอารมณ์ 10 เท่าในทุกแง่มุมของการใช้คอมพิวเตอร์ เป็นเวลาเพียง 12 ปีแล้วตั้งแต่ iPhone เครื่องแรก

VR มีมานานแล้ว แต่เทคโนโลยีที่จำเป็นในการนำ VR มาสู่ผู้ใช้ทั่วไปได้มาถึงแล้วผ่านการปฏิวัติมือถือและ Oculus Quest ของ Facebook ไม่ใช่การปฏิวัติพีซี

อินเทอร์เน็ตและโอเพ่นซอร์สเป็นหนึ่งในสิ่งมหัศจรรย์ที่ยิ่งใหญ่ที่สุดในโลกของมนุษยชาติ ถึงทุกคนที่สร้างอินเทอร์เน็ตแบบแบน - ฉันขอแสดงความยินดีกับความกล้าหาญและความรู้สึกของการผจญภัย

ประกาศ! เราจะสร้างโลก เพราะเรามีพลังที่จะสร้าง

การสาธิต WebVR
การสาธิต Canvas, การสาธิต WebVR, โค้ดตัวอย่าง