สร้างเกม WebGL ข้ามแพลตฟอร์มด้วย Babylon.js
เผยแพร่แล้ว: 2022-03-10นี่คือความท้าทายสำหรับคุณ: แล้วการสร้างเกม 3 มิติในช่วงสุดสัปดาห์ล่ะ Babylon.js เป็นเฟรมเวิร์ก JavaScript สำหรับการ สร้างเกม 3 มิติด้วย HTML5, WebGL และ Web Audio ซึ่งสร้างโดยคุณและทีมงาน Babylon.js อย่างแท้จริง เพื่อเป็นการเฉลิมฉลองเวอร์ชันใหม่ 2.3 ของไลบรารี เราตัดสินใจสร้างตัวอย่างใหม่ชื่อ “Sponza” เพื่อเน้นสิ่งที่สามารถทำได้ด้วยเอ็นจิน WebGL และ HTML5 เมื่อพูดถึงการสร้างเกมที่ยอดเยี่ยมในปัจจุบัน
แนวคิดคือการสร้างประสบการณ์ที่สอดคล้องกัน คล้ายกัน หากไม่เหมือนกัน บนแพลตฟอร์มที่รองรับ WebGL ทั้งหมด และพยายามเข้าถึงคุณสมบัติของแอปที่มาพร้อมเครื่อง ในบทความนี้ ฉันจะอธิบายวิธีการทำงานร่วมกัน พร้อมกับความท้าทายต่างๆ ที่เราเผชิญและบทเรียนที่เราได้เรียนรู้ขณะสร้าง
อ่านเพิ่มเติม เกี่ยวกับ SmashingMag:
- สร้างเฉดสีด้วย Babylon.js
- การใช้ Gamepad API ในเว็บเกม
- บทนำสู่การสร้างแบบจำลองเหลี่ยมและ Three.js
- วิธีสร้างเครื่องดรัม 8 บิตที่ตอบสนองได้ดี
เพื่อให้บรรลุเป้าหมายนี้ Sponza ใช้คุณลักษณะ HTML5 จำนวนหนึ่ง เช่น WebGL, Web Audio และ Pointer Events (ได้รับการสนับสนุนอย่างกว้างขวางในขณะนี้ด้วย jQuery PEP polyfill), Gamepad API, IndexedDB, HTML5 AppCache, การเปลี่ยนภาพ/ภาพเคลื่อนไหว CSS3, flexbox และ Fullscreen เอพีไอ คุณสามารถทดสอบการสาธิต Sponza ได้บนเดสก์ท็อป มือถือ หรือ Xbox One
การค้นพบการสาธิต
ขั้นแรก คุณจะเริ่มในซีเควนซ์แอนิเมชั่นอัตโนมัติที่ให้เครดิตกับผู้ที่สร้างฉากนั้น สมาชิกในทีมส่วนใหญ่มาจากฉากสาธิต คุณจะพบว่านี่เป็นส่วนสำคัญของวัฒนธรรมของนักพัฒนา 3D เคียงข้างฉัน ฉันอยู่ที่ Atari ขณะที่ David Catuhe อยู่ที่ Amiga ซึ่งยังคงเป็นที่มาของความขัดแย้งระหว่างเรา เชื่อหรือไม่ ฉันกำลังเขียนโค้ดอยู่นิดหน่อยแต่ส่วนใหญ่แต่งเพลงในกลุ่มสาธิตของฉัน ฉันเป็นแฟนตัวยงของ Future Crew และโดยเฉพาะอย่างยิ่งของ Purple Motion ผู้แต่งฉากสาธิตที่ฉันชื่นชอบตลอดกาล แต่ขอไม่เบี่ยงเบนจากหัวข้อ
สำหรับ Sponza นี่คือผู้ร่วมให้ข้อมูล:
- Michel Rousseau หรือที่รู้จักในชื่อ “Mitch” ได้สร้างแอนิเมชั่นด้านภาพที่น่าทึ่งและการเพิ่มประสิทธิภาพการเรนเดอร์ที่ทำหน้าที่เป็นศิลปิน 3 มิติ ใช้โมเดล Sponza ที่ Crytek จัดหาให้โดยอิสระบนเว็บไซต์ของพวกเขา และใช้ตัวส่งออก 3DS Max เพื่อสร้างสิ่งที่คุณเห็น
- David Catuhe หรือที่รู้จักว่า “deltakosh” และฉันได้ทำส่วนหลักของเอ็นจิ้น Babylon.js และโค้ดทั้งหมดสำหรับการสาธิตแล้ว (ตัวโหลดแบบกำหนดเอง เอฟเฟกต์พิเศษสำหรับโหมดสาธิตโดยใช้การจางเป็นสีดำหลังกระบวนการ ฯลฯ) เช่นกัน กล้องรูปแบบใหม่ที่ชื่อว่า “ UniversalCamera ” ที่จัดการอินพุตทุกประเภทในลักษณะทั่วไป
- ฉันแต่งเพลงโดยใช้ Renoise และ EastWest Symphonic Orchestra sound bank หากคุณสนใจ ฉันได้แชร์เวิร์กโฟลว์และกระบวนการแล้วในบทความเกี่ยวกับการแต่งเพลงสำหรับเกม World Monger Windows 8 โดยใช้ตัวติดตาม Renoise & ปลั๊กอิน East West VST
- Julien Moreau-Mathis ช่วยเราด้วยการสร้างเครื่องมือใหม่เพื่อช่วยศิลปิน 3D ในขั้นสุดท้ายระหว่างเครื่องมือสร้างแบบจำลอง (3DS Max, Blender) และผลลัพธ์สุดท้าย ตัวอย่างเช่น Michel ใช้เพื่อทดสอบและปรับแต่งกล้องแอนิเมชั่นต่างๆ และฉีดอนุภาคเข้าไปในฉาก
หากคุณรอจนกว่าซีเควนซ์อัตโนมัติจะสิ้นสุดจนถึง “จบแบบมหากาพย์” คุณจะเปลี่ยนเป็นโหมดโต้ตอบโดยอัตโนมัติ หากคุณต้องการข้ามโหมดสาธิต เพียงคลิกที่ไอคอนกล้องหรือกด A
บนแป้นเกมของคุณ
ในโหมดโต้ตอบ หากคุณใช้ Mac หรือ PC คุณจะสามารถเคลื่อนเข้าไปในฉากได้โดยใช้แป้นพิมพ์/เมาส์เหมือนเกม FPS หากคุณใช้สมาร์ทโฟน คุณจะสามารถเคลื่อนที่ได้โดยใช้สัมผัสเดียว (และ 2
เพื่อหมุนกล้อง) สุดท้าย บน Xbox One คุณสามารถใช้แป้นเกม (หรือเดสก์ท็อปหากคุณเสียบแป้นเกมไว้) เกร็ดน่ารู้: บนพีซีระบบสัมผัส Windows คุณสามารถใช้อินพุตได้ 3 ประเภทพร้อมกัน
บรรยากาศจะแตกต่างกันในโหมดโต้ตอบ คุณมีแหล่งกำเนิดเสียงของพายุสามแห่งที่วางตำแหน่งแบบสุ่มในสภาพแวดล้อม 3 มิติ ลมพัด และรอยร้าวของไฟในแต่ละมุม บนเบราว์เซอร์ที่รองรับ (Chrome, Firefox, Opera และ Safari) คุณยังสามารถสลับไปมาระหว่างโหมดลำโพงปกติและโหมดหูฟังโดยคลิกที่ไอคอนเฉพาะ จากนั้นจะใช้การเรนเดอร์ เสียง binaural ของ Web Audio เพื่อการจำลองเสียงที่สมจริงยิ่งขึ้น — หากคุณกำลังฟังผ่านหูฟัง
เพื่อให้ได้รับประสบการณ์ที่เหมือนแอปอย่างสมบูรณ์ เราได้สร้างไอคอนและไทล์สำหรับทุกแพลตฟอร์ม ซึ่งหมายความว่า ตัวอย่างเช่น ใน Windows 8 ⁄ 10 คุณสามารถปักหมุดเว็บแอปลงในเมนู "เริ่ม" เรายังมีหลายขนาดให้เลือก:
ออฟไลน์ก่อน!
เมื่อโหลดการสาธิตเสร็จแล้ว คุณสามารถเปลี่ยนโทรศัพท์เป็นโหมดเครื่องบินเพื่อตัดการเชื่อมต่อและคลิกที่ไอคอน Sponza เว็บแอปจะยังคงมอบประสบการณ์ที่สมบูรณ์ด้วยการแสดงผล WebGL, เสียงเว็บ 3 มิติ และการสนับสนุนระบบสัมผัส เปลี่ยนเป็นโหมดเต็มหน้าจอและคุณจะไม่รู้สึกถึงความแตกต่างระหว่างการสาธิตและประสบการณ์แอพที่มาพร้อมเครื่อง
เรากำลังใช้เลเยอร์ IndexedDB ที่มีอยู่ใน Babylon.js สำหรับสิ่งนั้น ฉาก (รูปแบบ JSON) และทรัพยากร (พื้นผิว JPG/PNG ตลอดจน MP3 สำหรับเพลงและเสียง) ถูกจัดเก็บไว้ใน IDB เลเยอร์ IDB ควบคู่กับแคชแอปพลิเคชัน HTML5 เป็นการมอบประสบการณ์ออฟไลน์ หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับส่วนนี้และวิธีกำหนดค่าเกมของคุณเพื่อให้ได้ผลลัพธ์ที่คล้ายคลึงกัน คุณสามารถอ่านบทความเกี่ยวกับการใช้ IndexedDB เพื่อจัดการเนื้อหา 3D WebGL ของคุณ: การแบ่งปันความคิดเห็นและเคล็ดลับของ Babylon.JS และทรัพยากรแคชใน IndexedDB ใน Babylon.js
Xbox One สนุกกับการแสดง
สุดท้ายแต่ไม่ท้ายสุด การสาธิตเดียวกันนี้ทำงานได้อย่างไม่มีที่ติใน MS Edge บน Xbox One ของคุณ:
กด A
เพื่อเปลี่ยนเป็น โหมด โต้ตอบ Xbox One จะแจ้งให้คุณทราบว่าขณะนี้คุณสามารถย้ายโดยใช้แป้นเกมในฉาก 3 มิติได้แล้ว:
มาสรุปกันสั้นๆ
ฐานรหัสเดียวกันนี้ใช้ได้กับ Mac, Linux, Windows บน MS Edge, Chrome, Firefox, Opera และ Safari บน iPhone/iPad บนอุปกรณ์ Android ที่มี Chrome หรือ Firefox, Firefox OS และ Xbox One! ไม่เจ๋งเหรอ? ความสามารถในการกำหนดเป้าหมายอุปกรณ์จำนวนมากด้วยประสบการณ์การใช้งานแบบเนทีฟที่เหมือนกันโดยตรงจากเว็บเซิร์ฟเวอร์ของคุณใช่หรือไม่
ฉันได้แบ่งปันความตื่นเต้นของฉันเกี่ยวกับศักยภาพของเทคโนโลยีในบทความก่อนหน้านี้บนเว็บ: เกมแนวหน้า?
แฮ็คฉากด้วย Debug Layer
หากคุณต้องการทำความเข้าใจวิธีที่ Michel ควบคุมความมหัศจรรย์ของการสร้างแบบจำลอง 3 มิติ คุณสามารถแฮ็กฉากโดยใช้เครื่องมือ Babylon.js Debug Layer หากต้องการเปิดใช้งานบนเครื่องที่มีแป้นพิมพ์ ให้กด CMD/CTRL + SHIFT + D
และหากคุณใช้แป้นเกมบน PC หรือ Xbox ให้กด Y
โปรดทราบว่าการแสดงเลเยอร์ดีบักนั้นต้องเสียประสิทธิภาพเล็กน้อยเนื่องจากงานองค์ประกอบที่เอ็นจินการเรนเดอร์ต้องทำ ดังนั้น FPS ที่แสดงจึงมีความสำคัญน้อยกว่า FPS จริงที่คุณมีเล็กน้อยโดยไม่ต้องแสดงเลเยอร์ดีบั๊ก
ลองทดสอบบนพีซีเป็นต้น
ย้ายไปใกล้หัวสิงโตแล้วตัดช่องกระแทกจากไปป์ไลน์ของเรา:
คุณควรเห็นว่าตอนนี้ศีรษะมีความสมจริงน้อยลง เล่นกับช่องอื่นเพื่อดูว่าเกิดอะไรขึ้น
คุณยังสามารถตัดเอ็นจิ้นฟ้าผ่าแบบไดนามิกหรือปิดการใช้งานเอ็นจิ้นการชนเพื่อบินหรือเคลื่อนผ่านกำแพง ตัวอย่างเช่น ปิดใช้งานช่องทำเครื่องหมาย " การชนกัน " และบินไปที่ชั้นหนึ่ง วางกล้องไว้หน้าธงแดง คุณสามารถเห็นพวกมันเคลื่อนไหวเล็กน้อย Michel ได้ใช้การรองรับกระดูก/โครงกระดูกของ Babylon.js เพื่อเคลื่อนย้ายพวกมัน ตอนนี้ ปิดการใช้งานตัวเลือก “ โครงกระดูก ” และพวกมันควรหยุดเคลื่อนไหว:
ในที่สุด คุณสามารถแสดงแผนผังที่มุมบนขวาได้ คุณสามารถเปิดหรือปิดใช้งานเพื่อทำลายงานที่ทำโดย Michel ได้อย่างสมบูรณ์:
การถอดรูปทรง ช่องสัญญาณของ shader หรือตัวเลือกบางอย่างของเครื่องยนต์สามารถช่วยคุณแก้ปัญหาประสิทธิภาพการทำงานบนอุปกรณ์เฉพาะเพื่อดูว่าปัจจุบันมีค่าใช้จ่ายมากเกินไปหรือไม่ คุณยังสามารถตรวจสอบได้ว่าคุณจำกัด CPU หรือจำกัด GPU หรือไม่ แม้ว่าโดยส่วนใหญ่ คุณจะจำกัด CPU ใน WebGL เนื่องจากลักษณะการเธรดแบบโมโนของ JavaScript สุดท้ายนี้ เครื่องมือนี้ยังมีประโยชน์มากในการช่วยให้คุณเรียนรู้ว่าฉากนั้นถูกสร้างขึ้นโดยศิลปิน 3D อย่างไร
อย่างไรก็ตาม มันใช้งานได้ดีบน Xbox One เช่นกัน:
ความท้าทาย
ระหว่างทาง เราประสบปัญหาและความท้าทายมากมายในการสร้างการสาธิต ลองมาดูบางส่วนของพวกเขาในรายละเอียด
ประสิทธิภาพ WebGL และความเข้ากันได้ข้ามแพลตฟอร์ม
ด้านการเขียนโปรแกรมน่าจะง่ายที่สุดในการจัดการเพราะถูกจัดการโดยเอ็นจิ้น Babylon.js เอง เรากำลังใช้ สถาปัตยกรรมของ shader แบบกำหนดเองที่ปรับตัวเองให้เข้ากับแพลตฟอร์ม โดยพยายามค้นหา shader ที่ดีที่สุดสำหรับเบราว์เซอร์/GPU ปัจจุบันโดยใช้ทางเลือกอื่น แนวคิดคือลดคุณภาพและความซับซ้อนของเอ็นจิ้นการเรนเดอร์ลง จนกว่าเราจะจัดการแสดงสิ่งที่มีความหมายบนหน้าจอได้
Babylon.js นั้นใช้ WebGL 1.0 เป็นหลักเพื่อรับประกันว่าประสบการณ์ 3D ที่สร้างขึ้นบนนั้นจะทำงานได้แทบทุกที่ มันถูกสร้างขึ้นโดยคำนึงถึงปรัชญาของเว็บ ดังนั้นเราจึงปรับปรุงกระบวนการคอมไพล์ shader ไปเรื่อย ๆ สิ่งนี้โปร่งใสอย่างสมบูรณ์สำหรับศิลปิน 3 มิติที่ไม่ต้องการจัดการกับความซับซ้อนเหล่านี้เกือบตลอดเวลา
ถึงกระนั้น ศิลปิน 3 มิติก็ยังมีบทบาทสำคัญในการเพิ่มประสิทธิภาพการทำงาน เธอต้องรู้จักแพลตฟอร์มที่เธอกำหนดเป้าหมาย คุณลักษณะที่รองรับและข้อจำกัดต่างๆ คุณไม่สามารถนำเนื้อหาที่มาจากเกม AAA ที่สร้างขึ้นสำหรับ GPU ระดับไฮเอนด์และ DirectX 12 มารวมเข้ากับเกมที่ทำงานบนเอ็นจิ้น WebGL ฉันขอยืนยันว่าการกำหนดเป้าหมาย WebGL ในวันนี้ค่อนข้างคล้ายกับงานที่คุณต้องทำเพื่อปรับประสบการณ์ใช้งานบนอุปกรณ์พกพาให้เหมาะสม โดยมี JavaScript พิเศษจำนวนมากที่ต้องมีเธรดเดี่ยวอย่างสูง
มิทช์เก่งมากในเรื่องนั้น: ปรับพื้นผิวให้เหมาะสม คำนวณสายฟ้าล่วงหน้าเพื่ออบเป็นพื้นผิว ลดจำนวนการโทรออกให้มากที่สุด ฯลฯ เขามีประสบการณ์หลายปีอยู่เบื้องหลังและเห็นคนรุ่นต่างๆ ฮาร์ดแวร์และเอ็นจิ้น 3 มิติ (ตั้งแต่ PowerVR/3DFX จนถึง GPU ในปัจจุบัน) ซึ่งช่วยทำให้การสาธิตเกิดขึ้นได้จริงๆ
เขาได้แบ่งปันพื้นฐานเหล่านั้นเล็กน้อยในบทความของเขาเกี่ยวกับ Real Time 3D: การสาธิตสำหรับ WebGL Purposes–Basics และได้รับการพิสูจน์แล้วหลายครั้งว่าคุณสามารถสร้างประสบการณ์ภาพที่น่าสนใจบนเว็บด้วยประสิทธิภาพสูงบน GPU ในตัวขนาดเล็ก เช่น Mansion, Hill Valley หรือฉากสาธิต Espilit หากคุณสนใจ ใช้เวลาในการดูการพูดคุยของเขาใน NGF2014 – สร้างเนื้อหา 3 มิติสำหรับโลกมือถือและเว็บ มุมมองของนักออกแบบ 3 มิติที่เขาแบ่งปันประสบการณ์ของเขาและวิธีที่เขาจัดการเพื่อเพิ่มประสิทธิภาพฉาก Hill Valley น้อยกว่า 1 fps ถึง 60 fps
เป้าหมายเริ่มต้นสำหรับ Sponza คือการสร้างสองฉาก หนึ่งรายการสำหรับเดสก์ท็อปและอีกรายการหนึ่งสำหรับอุปกรณ์เคลื่อนที่ที่มีความซับซ้อนน้อยกว่า พื้นผิวที่เล็กกว่า รวมถึงเมชและเรขาคณิตที่ง่ายกว่า แต่ในระหว่างการทดสอบของเรา ในที่สุดเราก็พบว่าเวอร์ชันเดสก์ท็อปทำงานได้ดีบนอุปกรณ์เคลื่อนที่ เนื่องจากสามารถทำงานได้ถึง 60 เฟรมต่อวินาทีบน iPhone 6s หรือ Android OnePlus 2 เราจึงตัดสินใจที่จะไม่ทำงานในเวอร์ชันสำหรับมือถือที่ง่ายกว่านี้ต่อไป
แต่อีกครั้ง อาจเป็นการดีกว่าที่จะมีแนวทางที่เน้นมือถือเป็นอันดับแรกบน Sponza เพื่อให้ไปถึง 30fps+ บนอุปกรณ์มือถือหลายๆ รุ่น จากนั้นจึงปรับปรุงฉากสำหรับมือถือระดับไฮเอนด์และเดสก์ท็อป ผลตอบรับส่วนใหญ่ที่เราได้รับบน Twitter ดูเหมือนจะบ่งชี้ว่าผลลัพธ์สุดท้ายทำงานได้ดีบนอุปกรณ์ส่วนใหญ่ เป็นที่ยอมรับว่า Sponza ได้รับการปรับให้เหมาะสมบน HD4000 GPU (รวม Intel Core i5) ซึ่งเทียบเท่ากับ GPU ของมือถือระดับไฮเอนด์จริง ๆ
เราค่อนข้างพอใจกับผลงานที่เราทำได้สำเร็จ Sponza กำลังใช้ shader ของเราโดยเปิดใช้งาน Ambient , diffuse , bump , specular และการ สะท้อนแสง เรามี อนุภาค บางส่วนเพื่อจำลองไฟเล็กๆ ในแต่ละมุม กระดูก เคลื่อนไหวสำหรับธงสีแดง เสียง ในตำแหน่ง 3 มิติ และ การชน เมื่อคุณเคลื่อนที่โดยใช้โหมดโต้ตอบ
ในทางเทคนิคแล้ว เรามี 98 เมชที่ใช้ในฉาก โดยสร้างจุดยอดได้มากถึง 377781 จุด, กระดูกแอคทีฟ 16 ชิ้น, อนุภาค 60+ ตัวที่สามารถสร้างการเรียกได้มากถึง 36 ครั้ง เราได้เรียนรู้อะไรบ้าง? สิ่งหนึ่งที่แน่นอน: การดึงสายที่น้อยลงเป็นกุญแจสู่ประสิทธิภาพการทำงานที่เหมาะสม มากยิ่งขึ้นบนเว็บ
ตัวโหลด
สำหรับ Sponza เราต้องการสร้างตัวโหลดใหม่ ต่างจากตัวโหลดเริ่มต้นที่เราใช้บนเว็บไซต์ BabylonJS เพื่อให้มีเว็บแอปที่สะอาดและสวยงาม ฉันได้ขอให้มิเชลแนะนำสิ่งใหม่ๆ
เขาส่งหน้าจอต่อไปนี้มาให้ฉันก่อน:
อันที่จริงหน้าจอดูดีมากเมื่อคุณดูครั้งแรก แต่แล้วคุณอาจเริ่มสงสัยว่าคุณจะทำให้มันทำงานบนอุปกรณ์ทั้งหมดได้อย่างไรในการตอบสนองอย่างแท้จริง? ลองคิดออก
มาพูดถึงเบื้องหลังกันก่อน เอฟเฟกต์ภาพเบลอที่สร้างโดย Michel นั้นดี แต่ใช้งานไม่ได้กับหน้าต่างทุกขนาดและความละเอียดที่สร้างมัวร์ จากนั้นฉันก็แทนที่ด้วยภาพหน้าจอ "คลาสสิก" ของฉากนั้น อย่างไรก็ตาม ฉันต้องการให้พื้นหลังเต็มหน้าจอโดยไม่มีแถบสีดำและไม่ยืดภาพเพื่อทำลายอัตราส่วน
วิธีแก้ปัญหาส่วนใหญ่มาจาก background-size: cover
+ การจัดกึ่งกลางรูปภาพบนแกน X และ Y ด้วยเหตุนี้ เราจึงมีประสบการณ์ที่ฉันต้องการ ไม่ว่าจะใช้อัตราส่วนหน้าจอเท่าใด:
ส่วนอื่น ๆ กำลังใช้การวางตำแหน่ง CSS ตามเปอร์เซ็นต์ที่ดี โอเค เมื่อจัดเรียงแล้ว เราจะจัดการกับตัวพิมพ์อย่างไร — ขนาดฟอนต์ควรขึ้นอยู่กับขนาดของวิวพอร์ต เห็นได้ชัดว่าเราสามารถใช้หน่วยวิวพอร์ตได้ vw
และ vh
(โดยที่ 1vw คือ 1% ของความกว้างของวิวพอร์ต และ 1vh คือ 1% ของความสูงของวิวพอร์ต) ได้รับการสนับสนุนอย่างดีในเบราว์เซอร์ต่างๆ โดยเฉพาะในเบราว์เซอร์ที่เข้ากันได้กับ WebGL ทั้งหมด (ยังมีบทความเกี่ยวกับ Viewport Sized Typography ใน Smashing Magazine ที่ฉันแนะนำให้คุณอ่าน)
สุดท้าย เรากำลังเล่นกับคุณสมบัติ opacity
ของภาพพื้นหลังเพื่อย้ายจาก 0
เป็น 1
ตามกระบวนการดาวน์โหลดปัจจุบันที่ย้ายจาก 0 เป็น 100%
อ้อ อีกอย่าง แอนิเมชั่นข้อความนั้นทำได้ง่ายๆ โดยใช้การเปลี่ยน CSS หรือแอนิเมชั่นรวมกับเลย์เอาต์ flexbox เพื่อให้แสดงวิธีง่ายๆ แต่มีประสิทธิภาพที่ตรงกลางหรือในแต่ละมุม
การจัดการอินพุตทั้งหมดอย่างโปร่งใส
เอ็นจิ้น WebGL ของเราทำงานทั้งหมดในด้านการแสดงผลเพื่อแสดงภาพอย่างถูกต้องบนทุกแพลตฟอร์ม แต่เราจะรับประกันได้อย่างไรว่าผู้ใช้จะสามารถเคลื่อนที่ภายในฉากไม่ว่าจะใช้อินพุตประเภทใดก็ตาม
ในเวอร์ชันก่อนหน้าของ Babylon.js เรารองรับอินพุตทุกประเภทและการโต้ตอบของผู้ใช้: แป้นพิมพ์/เมาส์ การสัมผัส จอยสติ๊กแบบสัมผัสเสมือนจริง เกมแพด เกมแพด การวางแนวอุปกรณ์ VR (สำหรับ Card Board) และ WebVR แต่ละรายการผ่านกล้องเฉพาะ คุณสามารถอ่านเอกสารของเราเพื่อเรียนรู้เพิ่มเติมอีกเล็กน้อยเกี่ยวกับพวกเขา
Touch ได้รับการจัดการในระดับสากลด้วยข้อกำหนด Pointer Events ที่เผยแพร่ไปยังทุกแพลตฟอร์มผ่าน jQuery PEP polyfill (สร้าง Touch Events สำหรับแอปเมื่อจำเป็น) หากต้องการทราบข้อมูลเพิ่มเติมเกี่ยวกับ Pointer Events คุณสามารถอ่านเกี่ยวกับ Unifying touch and mouse: Pointer Events จะทำให้การสนับสนุนแบบสัมผัสข้ามเบราว์เซอร์เป็นเรื่องง่ายได้อย่างไร
กลับไปที่การสาธิตแล้ว แนวคิดสำหรับ Sponza คือการมีกล้องที่ไม่เหมือนใคร ซึ่งจัดการสถานการณ์ของผู้ใช้ทั้งหมดในคราวเดียว: เดสก์ท็อป มือถือ และคอนโซล
เราลงเอยด้วยการสร้าง UniversalCamera พูดตามตรง มันชัดเจนและเรียบง่ายมากในการสร้างจนฉันยังไม่รู้ว่าทำไมเราไม่ทำมาก่อน UniversalCamera เป็นกล้อง gamepad มากหรือน้อยที่ขยาย TouchCamera ซึ่งขยาย FreeCamera
FreeCamera ให้ตรรกะของแป้นพิมพ์/เมาส์ TouchCamera ให้ตรรกะแบบสัมผัส และส่วนขยายสุดท้ายให้ตรรกะของแป้นเกม
ขณะนี้ UniversalCamera ใช้ใน Babylon.js เป็นค่าเริ่มต้น หากคุณกำลังเรียกดูการสาธิต คุณสามารถเคลื่อนเข้าไปในฉากต่างๆ ได้โดยใช้เมาส์ การสัมผัส และแป้นเกมในทุกฉาก อีกครั้ง คุณสามารถศึกษาโค้ดเพื่อดูว่ามันทำงานอย่างไร
การซิงโครไนซ์ทรานซิชันกับเพลง
ส่วนนี้เป็นส่วนที่เราถามคำถามส่วนใหญ่กับตัวเอง คุณอาจสังเกตเห็นว่า ลำดับการแนะนำจะถูกซิงโครไนซ์กับพื้นที่เฉพาะของแทร็กเล่นเพลง บรรทัดแรกจะแสดงขึ้นเมื่อกลองบางท่อนเริ่ม และลำดับการสิ้นสุดสุดท้ายจะเปลี่ยนอย่างรวดเร็วจากกล้องหนึ่งไปยังอีกกล้องหนึ่งในแต่ละโน้ตของเครื่องดนตรีฮอร์นที่เราใช้
การซิงโครไนซ์เสียงกับลูปการเรนเดอร์ WebGL ไม่ใช่เรื่องง่าย อีกครั้ง นี่เป็นลักษณะเธรดเดี่ยวของ JavaScript ที่สร้างความซับซ้อนนี้ บทความเกี่ยวกับบทนำสู่ HTML5 Web Workers: วิธีการมัลติเธรดของ JavaScript แบ่งปันข้อมูลเชิงลึกเบื้องหลังนั้น การเข้าใจปัญหาเพื่อทำความเข้าใจปัญหาระดับโลกที่เรากำลังเผชิญอยู่เป็นสิ่งสำคัญอย่างยิ่ง แต่การดูรายละเอียดที่นี่อยู่นอกเหนือขอบเขตของบทความนี้
โดยปกติ ในฉากสาธิต (และวิดีโอเกม) หากคุณต้องการซิงโครไนซ์ภาพกับเสียง/เพลง คุณจะต้องถูกขับเคลื่อนโดยสแต็กเสียง มักใช้สองวิธี:
- สร้างข้อมูลเมตาที่จะแทรกเข้าไปในไฟล์เสียง และจากนั้นสามารถ "เรียก" เหตุการณ์บางอย่างเมื่อคุณเข้าถึงส่วนใดส่วนหนึ่งของมัน
- การวิเคราะห์สตรีมเสียงแบบเรียลไทม์ผ่าน FFT หรือเทคโนโลยีที่คล้ายคลึงกันเพื่อตรวจจับจุดสูงสุดที่น่าสนใจหรือการเปลี่ยนแปลง BPM ซึ่งจะสร้างเหตุการณ์สำหรับเอ็นจิ้นภาพอีกครั้ง
วิธีการเหล่านั้นทำงานได้ดีในสภาพแวดล้อมแบบมัลติเธรด เช่น C++ แต่ใน JavaScript กับ Web Audio เรามีปัญหาสองประการ:
- JavaScript ซึ่งเป็นแบบ mono-thread และขออภัย ส่วนใหญ่ที่คนงานเว็บจะไม่ช่วยเราจริงๆ
- Web Audio ไม่มีเหตุการณ์ใดๆ ที่สามารถส่งกลับไปยังเธรด UI แม้ว่า Web Audio จะได้รับการจัดการบนเธรดที่แยกจากกันโดยเบราว์เซอร์
Web Audio มีตัวจับเวลาที่แม่นยำกว่า JavaScript มาก คงจะดีไม่น้อยหากสามารถใช้ตัวจับเวลาแยกนี้บนเธรดที่แยกจากกันเพื่อขับเคลื่อนเหตุการณ์กลับไปที่เธรด UI แต่วันนี้คุณยังทำไม่ได้ (ยัง?)
ในอีกด้านหนึ่ง เรากำลังสร้างฉากโดยใช้ WebGL และวิธีการ requestAnimationFrame
ซึ่งหมายความว่าใน "กรณีที่ดีที่สุด" เรามีกรอบเวลาของ windows 16ms หากคุณทำหาย คุณจะต้องรอถึง 16 มิลลิวินาทีจึงจะสามารถดำเนินการในเฟรมถัดไปเพื่อสะท้อนการซิงโครไนซ์เสียงได้ (เช่น เพื่อเปิดเอฟเฟกต์
ตอนนั้นฉันกำลังคิดที่จะฉีดตรรกะการซิงโครไนซ์ลงในลูป requestAnimationFrame
ฉันศึกษาเวลาที่ใช้ตั้งแต่เริ่มซีเควนซ์และมองหาตัวเลือกในการปรับภาพให้ตอบสนองต่อเหตุการณ์ทางเสียง ข่าวดีก็คือ Web audio จะแสดงเสียงที่เกิดขึ้นในเธรด UI หลัก ตัวอย่างเช่น คุณสามารถมั่นใจได้ว่าการประทับเวลา 12 วินาทีของเพลงจะมาถึง 12 วินาทีหลังจากที่เพลงเริ่มเล่น แม้ว่า GPU จะมีปัญหาในการแสดงฉากก็ตาม
ในที่สุด เราก็เลือกวิธีแก้ปัญหาที่ง่ายที่สุดโดยใช้การเรียก setTimeout()
! ใช่ฉันรู้. หากคุณดูบทความส่วนใหญ่ในนั้น รวมถึงบทความที่ฉันลิงก์ไปด้านบน คุณจะพบว่าบทความนั้นค่อนข้างไม่น่าเชื่อถือ แต่ในกรณีของเรา เมื่อฉากพร้อมที่จะแสดงผล เรารู้ว่าเราได้ดาวน์โหลดทรัพยากรทั้งหมดของเรา (พื้นผิวและเสียง) และรวบรวมเฉดสีของเราแล้ว เราไม่ควรหงุดหงิดกับเหตุการณ์ที่ไม่คาดคิดที่ทำให้เธรด UI อิ่มตัว GC อาจเป็นปัญหา ได้ แต่เราใช้เวลามากในการต่อสู้กับมันในเอ็นจิ้น: การลดแรงกดดันต่อตัวรวบรวมขยะโดยใช้แถบนักพัฒนา F12 ของ Internet Explorer 11
ถึงกระนั้น เรารู้ว่าวิธีนี้ยังห่างไกลจากอุดมคติ การสลับไปยังแท็บอื่นหรือล็อกโทรศัพท์ของคุณและปลดล็อกในไม่กี่วินาทีต่อมา อาจทำให้เกิดปัญหาบางอย่างในส่วนการซิงโครไนซ์ของการสาธิต เราสามารถแก้ไขปัญหาเหล่านี้ได้โดยใช้ Page Visibility API เช่น หยุดการวนซ้ำของการแสดงผล เสียงต่างๆ และคำนวณกรอบเวลาถัดไปสำหรับการเรียก setTimeout()
อีกครั้ง
แต่บางทีเราพลาดอะไรบางอย่างไป บางทีและบางทีอาจมีแนวทางที่ดีกว่าในการจัดการปัญหานี้ เรายินดีรับฟังความคิดเห็นและข้อเสนอแนะของคุณในส่วนความคิดเห็น หากคุณคิดว่ามีวิธีแก้ไขปัญหาเดียวกันที่ดีกว่า
การจัดการ Web Audio บน iOS
ความท้าทายสุดท้ายที่ฉันต้องการแชร์กับคุณคือวิธีที่ iOS จัดการ Web Audio บน iPhone และ iPad หากคุณกำลังมองหาบทความเกี่ยวกับ “web audio + iOS” คุณจะพบว่าหลายคนมีปัญหาในการเล่นเสียงบน iOS ตอนนี้เกิดอะไรขึ้นที่นั่น?
iOS มีการรองรับ Web Audio ที่โดดเด่น แม้กระทั่งโหมดเสียง binaural แต่ Apple ได้ตัดสินใจว่าหน้าเว็บไม่สามารถเล่นเสียงใด ๆ ตามค่าเริ่มต้นได้หากไม่มีการโต้ตอบของผู้ใช้รายใดรายหนึ่ง การตัดสินใจนี้อาจเกิดขึ้นเพื่อหลีกเลี่ยงการโฆษณาหรือสิ่งอื่นใดที่รบกวนผู้ใช้โดยการเล่นเสียงที่ไม่พึงประสงค์
นักพัฒนาเว็บมีความหมายอย่างไร? ก่อนอื่นคุณต้อง ปลดล็อกบริบทเสียงบนเว็บของ iOS หลังจากที่ผู้ใช้สัมผัส — ก่อนพยายามเล่นเสียงใดๆ มิฉะนั้น เว็บแอปพลิเคชันของคุณจะยังคงปิดเสียงอยู่
น่าเสียดายที่วิธีเดียวที่ฉันพบว่าทำการตรวจสอบนี้โดยใช้วิธีการดมกลิ่นแพลตฟอร์มผู้ใช้เนื่องจากฉันไม่พบวิธีการตรวจหาคุณลักษณะที่จะทำหรือไม่ นั่นไม่ใช่เทคนิคที่น่ากลัวและไม่ใช่เทคนิคกันกระสุน แต่ฉันไม่พบวิธีอื่นที่จะแก้ปัญหานี้ได้ รหัส? เอาล่ะ!
หากคุณไม่ได้ใช้ iPad/iPhone/iPod บริบทของเสียงจะพร้อมใช้งานทันที มิฉะนั้น เรากำลังปลดล็อกบริบทเสียงของ iOS โดยการเล่นโค้ดที่สร้างเสียงเปล่าในเหตุการณ์ touchend คุณสามารถลงทะเบียนเข้าร่วมกิจกรรม onAudioUnlocked ได้ หากต้องการรอก่อนที่จะเริ่มเกม ดังนั้น หากคุณกำลังเปิดตัว Sponza บน iPhone/iPad คุณจะมีหน้าจอสุดท้ายนี้ที่ส่วนท้ายของลำดับการโหลด:
การแตะที่ใดก็ได้บนหน้าจอจะเป็นการปลดล็อกกองเสียงของ iOS และจะเปิด "แสดง"
เอาล่ะ! ฉันหวังว่าคุณจะสนุกกับข้อมูลเชิงลึกเบื้องหลังการพัฒนาการสาธิตนี้ หากต้องการเรียนรู้เพิ่มเติม โปรดอ่านซอร์สโค้ดที่สมบูรณ์ของการสาธิตนี้บน GitHub ของเรา แน่นอน ทุกอย่างเป็นโอเพนซอร์ส และคุณสามารถหาไฟล์หลักได้ใน GitHub: index.js และ babylon.demo.ts
สุดท้ายนี้ ฉันหวังว่าคุณจะมั่นใจมากขึ้นว่าเว็บนี้เป็นแพลตฟอร์มที่ยอดเยี่ยมสำหรับการเล่นเกมอย่างแน่นอน! โปรดอดใจรอ ในขณะที่เรากำลังดำเนินการเดโมใหม่อยู่ในขณะนี้ และหวังว่ามันจะน่าประทับใจเช่นกัน
บทความนี้เป็นส่วนหนึ่งของชุดการพัฒนาเว็บไซต์จากผู้เผยแพร่เทคโนโลยีและวิศวกรของ Microsoft เกี่ยวกับการเรียนรู้ JavaScript เชิงปฏิบัติ โครงการโอเพนซอร์ส และแนวทางปฏิบัติที่ดีที่สุดในการทำงานร่วมกัน รวมถึงเบราว์เซอร์ Microsoft Edgeเราขอแนะนำให้คุณทดสอบในเบราว์เซอร์และอุปกรณ์ต่างๆ รวมถึง Microsoft Edge ซึ่งเป็นเบราว์เซอร์เริ่มต้นสำหรับ Windows 10 พร้อมเครื่องมือฟรีบน dev.microsoftedge.com รวมถึงเครื่องมือสำหรับนักพัฒนา F12 เครื่องมือเจ็ดรายการที่แตกต่างกันและมีเอกสารครบถ้วนเพื่อช่วยคุณในการดีบัก ทดสอบ และ เพิ่มความเร็วหน้าเว็บของคุณ นอกจากนี้ เยี่ยมชมบล็อก Edge เพื่อรับทราบข้อมูลอัปเดตและรับทราบข้อมูลจากนักพัฒนาและผู้เชี่ยวชาญของ Microsoft