Babylon.js로 크로스 플랫폼 WebGL 게임 만들기

게시 됨: 2022-03-10
빠른 요약 ↬ 여기 당신을 위한 도전이 있습니다: 주말에 3D 게임을 만드는 것은 어떻습니까? Babylon.js는 HTML5, WebGL 및 Web Audio를 사용하여 3D 게임을 빌드 하기 위한 JavaScript 프레임워크입니다. 라이브러리의 새 버전 2.3을 기념하기 위해 "Sponza"라는 새 데모를 빌드하여 오늘날 훌륭한 게임을 구축할 때 WebGL 엔진과 HTML5로 수행할 수 있는 작업을 강조하기로 결정했습니다. 아이디어는 모든 WebGL 지원 플랫폼에서 동일하지는 않더라도 일관되고 유사한 경험을 만들고 기본 앱의 기능에 도달하려고 시도하는 것이었습니다. 이 기사에서 나는 우리가 직면한 다양한 도전과 그것을 구축하면서 배운 교훈과 함께 이 모든 것이 어떻게 함께 작동하는지 설명할 것입니다.

여기 당신을 위한 도전이 있습니다: 주말에 3D 게임을 만드는 것은 어떻습니까? Babylon.js는 HTML5, WebGL 및 Web Audio를 사용하여 3D 게임을 빌드 하기 위한 JavaScript 프레임워크입니다. 라이브러리의 새 버전 2.3을 기념하기 위해 "Sponza"라는 새 데모를 빌드하여 오늘날 훌륭한 게임을 구축할 때 WebGL 엔진과 HTML5로 수행할 수 있는 작업을 강조하기로 결정했습니다.

아이디어는 모든 WebGL 지원 플랫폼에서 동일하지는 않더라도 일관되고 유사한 경험을 만들고 기본 앱의 기능에 도달하려고 시도하는 것이었습니다. 이 기사에서 나는 우리가 직면한 다양한 도전과 그것을 구축하면서 배운 교훈과 함께 이 모든 것이 어떻게 함께 작동하는지 설명할 것입니다.

SmashingMag에 대한 추가 정보:

  • Babylon.js로 셰이더 만들기
  • 웹 게임에서 게임패드 API 사용하기
  • 다각형 모델링 및 Three.js 소개
  • 반응형 8비트 드럼 머신을 만드는 방법

이 목표를 달성하기 위해 Sponza는 WebGL, Web Audio, 포인터 이벤트(jQuery PEP 폴리필 덕분에 현재 널리 지원됨), Gamepad API, IndexedDB, HTML5 AppCache, CSS3 전환/애니메이션, 플렉스박스 및 전체 화면과 같은 다양한 HTML5 기능을 사용합니다. API. 데스크톱, 모바일 또는 Xbox One에서 Sponza 데모를 테스트할 수 있습니다.

점프 후 더! 아래에서 계속 읽기 ↓
스폰자 게임의 홀
대화형 Sponza 데모의 메인 홀.

데모 발견

먼저 장면을 만든 사람에게 크레딧을 제공하는 자동 애니메이션 시퀀스를 시작합니다. 팀 구성원의 대부분은 데모 장면에서 왔습니다. 이것이 3D 개발자 문화의 중요한 부분임을 알게 될 것입니다. 저는 Atari에 있었고 David Catuhe는 Amiga에 있었고 여전히 믿거나 말거나 우리 사이에서 정기적인 갈등의 원인이 됩니다. 약간의 코딩을 했지만 주로 데모 그룹에서 음악을 작곡했습니다. 저는 Future Crew, 특히 제가 가장 좋아하는 데모 장면 작곡가인 Purple Motion의 열렬한 팬이었습니다. 그러나 주제에서 벗어나지 맙시다.

Sponza의 경우 기여자는 다음과 같습니다.

  • Michel Rousseau (일명 "Mitch")는 3D 아티스트로 활동하면서 놀라운 비주얼 애니메이션 및 렌더링 최적화를 수행했습니다. Crytek이 웹사이트에서 무료로 제공하는 Sponza 모델을 사용하고 3DS Max 내보내기를 사용하여 보는 것을 생성했습니다.
  • David Catuhe (일명 "deltakosh")는 Babylon.js 엔진의 핵심 부분과 데모의 모든 코드(커스텀 로더, 페이드 투 블랙 포스트 프로세스를 사용하는 데모 모드의 특수 효과 등)를 수행했습니다. 모든 유형의 입력을 일반적인 방식으로 처리하는 " UniversalCamera "라는 새로운 유형의 카메라.
  • Renoise와 EastWest Symphonic Orchestra 사운드 뱅크를 사용하여 음악을 작곡했습니다. 관심이 있으시면 Renoise 추적기 및 East West VST 플러그인을 사용하여 World Monger Windows 8 게임용 음악 작곡에 대한 기사에서 내 작업 흐름과 프로세스를 이미 공유했습니다.
  • Julien Moreau-Mathis 는 3D 아티스트가 모델링 도구(3DS Max, Blender)와 최종 결과 간의 작업을 마무리하는 데 도움이 되는 새로운 도구를 구축하여 우리를 도왔습니다. 예를 들어 Michel은 이를 사용하여 다양한 애니메이션 카메라를 테스트 및 조정하고 장면에 입자를 주입했습니다.

자동 시퀀스가 ​​끝날 때까지 "Epic Finish"까지 기다리면 자동으로 대화형 모드로 전환됩니다. 데모 모드를 우회하려면 카메라 아이콘을 클릭하거나 게임패드에서 A 를 누르십시오.

대화형 모드에서는 Mac이나 PC를 사용하는 경우 FPS 게임처럼 키보드/마우스를 사용하여 장면 내부를 이동할 수 있습니다. 스마트폰을 사용 중이라면 터치 한 번으로 이동할 수 있습니다(카메라를 회전하려면 2 ). 마지막으로 Xbox One에서는 게임패드(또는 게임패드를 연결하는 경우 데스크탑)를 사용할 수 있습니다. 재미있는 사실: Windows 터치 PC에서는 잠재적으로 3가지 유형의 입력을 동시에 사용할 수 있습니다.

인터랙티브 모드에서는 분위기가 다릅니다. 3D 환경에 무작위로 배치된 3개의 폭풍 오디오 소스가 있으며, 각 모서리에는 바람이 불고 균열이 있습니다. 지원되는 브라우저(Chrome, Firefox, Opera 및 Safari)에서는 전용 아이콘을 클릭하여 일반 스피커 모드와 헤드폰 모드 간에 전환할 수도 있습니다. 그런 다음 헤드폰을 통해 듣는 경우 보다 사실적인 오디오 시뮬레이션을 위해 Web Audio의 바이노럴 오디오 렌더링 을 사용합니다.

완전한 앱과 같은 경험을 제공하기 위해 모든 플랫폼에 대한 아이콘과 타일을 생성했습니다. 예를 들어 Windows 810 에서는 웹 앱을 "시작" 메뉴에 고정할 수 있습니다. 다양한 크기를 사용할 수도 있습니다.

웹 앱을 시작 메뉴에 고정할 수 있습니다.
아이콘 및 타일을 생성한 후 웹 앱을 "시작" 메뉴에 고정할 수 있습니다.
iOS, Android 또는 Windows Mobile의 시작 메뉴에 웹 앱을 고정할 수 있습니다.
iPhone, Android 기기 또는 Windows Mobile에서도 작동합니다.

먼저 오프라인!

데모가 완전히 로드되면 휴대전화를 비행기 모드로 전환하여 연결을 끊고 Sponza 아이콘을 클릭할 수 있습니다. 웹 앱은 여전히 ​​WebGL 렌더링, 3D 웹 오디오 및 터치 지원을 통해 완벽한 경험을 제공합니다. 전체 화면으로 전환하면 말 그대로 데모와 기본 앱 경험의 차이를 느낄 수 없을 것입니다.

이를 위해 기본적으로 Babylon.js 내부에서 사용할 수 있는 IndexedDB 레이어를 사용하고 있습니다. 장면(JSON 형식) 및 리소스(JPG/PNG 텍스처와 음악 및 사운드용 MP3)는 IDB에 저장됩니다. 그러면 HTML5 애플리케이션 캐시와 결합된 IDB 계층이 오프라인 경험을 제공합니다. 이 부분과 유사한 결과를 얻기 위해 게임을 구성하는 방법에 대해 자세히 알아보려면 IndexedDB를 사용하여 3D WebGL 자산 처리에 대한 기사를 읽을 수 있습니다. Babylon.js의 Babylon.JS 및 Caching Resources에 대한 피드백 및 팁 공유

Xbox One은 쇼를 즐깁니다.

마지막으로 중요한 것은 Xbox One의 MS Edge에서도 동일한 데모가 완벽하게 작동한다는 것입니다.

Xbox One의 MS Edge

A 를 눌러 대화형 모드 로 전환합니다. Xbox One은 이제 3D 장면 내에서 게임패드를 사용하여 이동할 수 있음을 알려줍니다.

Xbox One 알림: 이제 3D 장면 내에서 게임패드를 사용하여 이동할 수 있습니다.

자, 간단히 요약해 보겠습니다.

매우 동일한 코드 기반이 Mac, Linux, MS Edge의 Windows, Chrome, Firefox, Opera 및 Safari, iPhone/iPad, Chrome 또는 Firefox가 설치된 Android 장치, Firefox OS 및 Xbox One에서 작동합니다! 멋지지 않아? 웹 서버에서 직접 네이티브와 유사한 완전한 기능을 갖춘 많은 장치를 대상으로 할 수 있습니까?

나는 웹의 이전 기사에서 기술의 잠재력에 대한 나의 흥분을 이미 공유했습니다: 다음 게임 프론티어?

디버그 레이어로 장면 해킹

Michel이 3D 모델링의 마법을 마스터하는 방법을 이해하려면 Babylon.js 디버그 레이어 도구를 사용하여 장면을 해킹할 수 있습니다. 키보드가 있는 컴퓨터에서 활성화하려면 CMD/CTRL + SHIFT + D 를 누르고 PC 또는 Xbox에서 게임패드를 사용하는 경우 Y 를 누릅니다. 디버그 레이어를 표시하는 것은 렌더링 엔진이 수행해야 하는 합성 작업으로 인해 약간의 성능 비용이 든다는 점에 유의하십시오. 따라서 표시된 FPS는 디버그 레이어가 표시되지 않은 실제 FPS보다 덜 중요합니다.

예를 들어 PC에서 테스트해 보겠습니다.

사자 머리 근처로 이동하여 셰이더 파이프라인에서 범프 채널을 잘라냅니다.

사자의 머리

이제 머리가 덜 사실적임을 알 수 있습니다. 다른 채널과 함께 플레이하여 무슨 일이 일어나고 있는지 확인하세요.

동적 번개 엔진을 차단하거나 충돌 엔진을 비활성화하여 벽을 뚫고 날아가거나 이동할 수도 있습니다. 예를 들어, " collision " 체크박스를 비활성화하고 1층으로 날아갑니다. 카메라를 빨간 깃발 앞에 놓으십시오. 조금씩 움직이는 것을 볼 수 있습니다. Michel은 Babylon.js의 뼈대/뼈대 지원을 사용하여 이동했습니다. 이제 " skeletons " 옵션을 비활성화하면 이동이 중지됩니다.

스켈레톤 옵션

마지막으로 오른쪽 상단에 메쉬 트리를 표시할 수 있습니다. Michel이 수행한 작업을 완전히 중단하기 위해 활성화하거나 비활성화할 수 있습니다.

지오메트리, 셰이더의 채널 또는 엔진의 일부 옵션을 제거하면 현재 비용이 너무 많이 드는 항목을 확인하기 위해 특정 장치의 성능 문제를 해결할 수 있습니다. CPU 제한인지 GPU 제한인지 확인할 수도 있지만 대부분의 경우 JavaScript의 모노 스레딩 특성으로 인해 WebGL에서 CPU 제한이 있습니다. 마지막으로 이 도구는 3D 아티스트가 장면을 구축한 방법을 배우는 데 매우 유용합니다.

그건 그렇고, Xbox One에서도 꽤 잘 작동합니다.

엑스박스 원 스폰자

도전

그 과정에서 우리는 데모를 구축하는 데 많은 문제와 도전에 직면했습니다. 그 중 일부를 자세히 살펴보겠습니다.

WebGL 성능 및 플랫폼 간 호환성

프로그래밍 쪽은 아마도 Babylon.js 엔진 자체에서 완전히 처리되기 때문에 다루기 가장 쉬운 쪽이었을 것입니다. 우리는 다양한 폴백을 사용하여 현재 브라우저/GPU에 사용할 수 있는 최상의 셰이더를 찾으려고 노력 함으로써 플랫폼에 자체적으로 적응하는 맞춤형 셰이더 아키텍처를 사용하고 있습니다. 아이디어는 화면에 의미 있는 것을 표시할 수 있을 때까지 렌더링 엔진의 품질과 복잡성을 낮추는 것입니다.

Babylon.js는 주로 WebGL 1.0을 기반으로 하여 그 위에 구축된 3D 경험이 거의 모든 곳에서 실행되도록 보장합니다. 웹 철학을 염두에 두고 구축되었으므로 셰이더 컴파일 프로세스를 점진적으로 개선하고 있습니다. 이것은 대부분의 시간에 이러한 복잡성을 처리하고 싶지 않은 3D 아티스트에게 완전히 투명합니다.

그래도 3D 아티스트는 성능 최적화에서 매우 중요한 역할을 합니다. 그녀는 대상으로 하는 플랫폼, 지원되는 기능 및 제한 사항을 알아야 합니다. 고급 GPU 및 DirectX 12용으로 제작된 AAA 게임에서 가져온 자산을 WebGL 엔진에서 실행되는 게임에 통합할 수 없습니다. 오늘날 WebGL을 대상으로 하는 것은 모바일 장치에서 경험을 최적화하기 위해 수행해야 하는 작업과 매우 유사하며 고도로 모노 스레드되어야 하는 추가 JavaScript가 있다고 주장합니다.

Mitch는 텍스처 최적화, 번개를 미리 계산하여 텍스처로 굽기, 드로우 콜 횟수를 최대한 줄이는 등 매우 잘합니다. 그는 수년간의 경험을 가지고 있으며 다양한 세대의 3D 하드웨어 및 엔진(PowerVR/3DFX에서 오늘날의 GPU에 이르기까지)은 데모를 구현하는 데 실제로 도움이 되었습니다.

그는 이미 Real Time 3D에 대한 기사에서 이러한 기본 사항 중 일부를 공유했습니다: WebGL 목적-기본을 위한 데모 만들기 및 이미 여러 번 작은 통합 GPU에서 고성능으로 웹에서 매우 매혹적인 시각적 경험을 만들 수 있음을 입증했습니다. 맨션, 힐 밸리 또는 에스필릿 데모 장면. 관심이 있다면 시간을 내어 NGF2014 – 모바일 세계 및 웹을 위한 3D 자산 만들기, 3D 디자이너의 관점에서 자신의 경험과 Hill Valley 장면을 최적화하는 방법을 공유한 그의 연설을 시청하십시오. 1fps 미만 ~ 60fps.

Sponza의 초기 목표는 두 개의 장면을 만드는 것이었습니다. 하나는 데스크탑용이고 다른 하나는 덜 복잡하고 더 작은 텍스처와 더 단순한 메시 및 지오메트리로 모바일용입니다. 그러나 테스트 중에 마침내 데스크톱 버전이 iPhone 6s 또는 Android OnePlus 2에서 최대 60fps로 실행될 수 있으므로 모바일에서도 꽤 잘 실행되고 있음을 발견했습니다. 그런 다음 더 간단한 모바일 버전에서 작업을 계속하지 않기로 결정했습니다.

그러나 다시 말하지만, Sponza에 대한 깨끗한 모바일 우선 접근 방식을 사용하여 많은 모바일 장치에서 30fps 이상에 도달한 다음 고급 모바일 및 데스크톱의 장면을 향상시키는 것이 더 나았을 것입니다. 그러나 지금까지 Twitter에서 받은 피드백의 대부분은 최종 결과가 대부분의 장치에서 매우 잘 작동한다는 것을 나타내는 것 같습니다. 확실히 Sponza는 실제 고급형 모바일 GPU와 거의 동일한 HD4000 GPU(Intel Core i5 통합)에 최적화되어 있습니다.

우리는 우리가 달성한 성과에 매우 만족했습니다. Sponza는 앰비언트 , 디퓨즈 , 범프 , 스페큘러리플렉션 이 활성화된 셰이더를 사용하고 있습니다. 각 모서리에 있는 작은 불을 시뮬레이션하기 위한 입자 가 있고, 빨간 깃발을 위한 애니메이션 뼈대 , 대화식 모드를 사용하여 이동할 때 3D 위치 사운드충돌 을 시뮬레이션할 수 있습니다.

기술적으로 말하면, 우리는 씬에서 98개의 메시를 사용하고 있으며 , 최대 377781개의 버텍스, 16개의 활성 뼈, 최대 36개의 드로우 콜을 생성할 수 있는 60개 이상의 파티클을 생성합니다. 우리는 무엇을 배웠습니까? 한 가지 확실한 점은 드로우 콜을 줄이는 것이 최적의 성능을 위한 핵심입니다. 웹에서는 더욱 그렇습니다.

로더

Sponza의 경우, BabylonJS 웹사이트에서 사용하는 기본 로더와 다른 새 로더를 만들어 깨끗하고 세련된 웹 앱을 만들고 싶었습니다. 그런 다음 Michel에게 새로운 것을 제안해 달라고 요청했습니다.

그는 먼저 다음 화면을 나에게 보냈습니다.

로딩 설명

실제로 화면은 처음 볼 때 매우 멋지게 보입니다. 그러나 모든 장치에서 진정으로 반응하는 방식으로 작동하게 하려면 어떻게 해야 하는지 궁금할 것입니다. 알아봅시다.

먼저 배경에 대해 이야기합시다. Michel이 만든 흐릿한 효과는 좋았지만 모든 창 크기와 해상도에서 잘 작동하지 않아 모아레가 발생했습니다. 그런 다음 장면의 "고전적인" 스크린샷으로 대체했습니다. 그러나 배경이 검은색 막대 없이 화면을 완전히 채우고 비율을 깨뜨리기 위해 이미지를 늘리지 않고 싶었습니다.

솔루션은 주로 CSS background-size: cover + X 및 Y 축에 이미지를 중앙에 배치하는 것에서 나옵니다. 결과적으로, 어떤 화면 비율이 사용되든 내가 찾던 경험을 할 수 있습니다.

스폰자 100퍼센트

다른 부분은 좋은 비율 기반 CSS 위치 지정을 사용하고 있습니다. 자, 정렬된 상태에서 타이포그래피를 어떻게 처리합니까? font-size는 뷰포트의 크기를 기반으로 해야 합니다. 분명히 뷰포트 단위를 사용할 수 있습니다. vwvh (여기서 1vw는 뷰포트 너비의 1%이고 1vh는 뷰포트 높이의 1%)는 모든 브라우저, 특히 모든 WebGL 호환 브라우저에서 상당히 잘 지원됩니다. (또한 Smashing Magazine에 Viewport Sized Typography에 대한 기사가 있으니 꼭 읽어보길 권합니다.)

마지막으로 0에서 100%로 이동하는 현재 다운로드 프로세스를 기반으로 배경 이미지의 opacity 속성을 사용하여 0 에서 1 로 이동합니다.

아, 그건 그렇고, 텍스트 애니메이션은 CSS 전환을 사용하거나 플렉스박스 레이아웃과 결합된 애니메이션을 사용하여 간단하지만 중앙이나 각 모서리에 표시할 수 있는 간단하지만 효율적인 방법을 제공합니다.

모든 입력을 투명한 방식으로 처리

WebGL 엔진은 모든 플랫폼에서 시각적 개체를 올바르게 표시하기 위해 렌더링 측면에서 모든 작업을 수행하고 있습니다. 그러나 사용된 입력 유형에 관계없이 사용자가 장면 내에서 이동할 수 있다는 것을 어떻게 보장할 수 있습니까?

이전 버전 Babylon.js에서는 키보드/마우스, 터치, 가상 터치 조이스틱, 게임패드, 장치 방향 VR(카드 보드용) 및 WebVR과 같은 모든 유형의 입력 및 사용자 상호 작용을 각각 전용 카메라를 통해 지원했습니다. 설명서를 읽고 이에 대해 자세히 알아볼 수 있습니다.

터치는 jQuery PEP 폴리필(필요한 경우 앱에 대한 터치 이벤트 생성)을 통해 모든 플랫폼에 전파된 포인터 이벤트 사양으로 보편적으로 관리됩니다. 포인터 이벤트에 대해 자세히 알아보려면 Unifying touch and mouse: Pointer Events를 사용하여 브라우저 간 터치 지원을 쉽게 만드는 방법을 참조하세요.

그런 다음 데모로 돌아갑니다. Sponza의 아이디어는 데스크톱, 모바일 및 콘솔과 같은 모든 사용자의 시나리오를 한 번에 처리하는 고유한 카메라를 갖는 것이었습니다.

결국 UniversalCamera 를 만들었습니다. 솔직히 말해서 만들기가 너무 명확하고 간단해서 왜 우리가 전에는 하지 않았는지 아직도 모르겠습니다. UniversalCamera는 FreeCamera 를 확장하는 TouchCamera 를 확장하는 게임패드 카메라입니다.

FreeCamera는 키보드/마우스 로직을 제공합니다. TouchCamera는 터치 로직을 제공하고 최종 확장은 게임패드 로직을 제공합니다.

UniversalCamera는 이제 기본적으로 Babylon.js에서 사용됩니다. 데모를 탐색하는 경우 모든 장면에서 마우스, 터치 및 게임패드를 사용하여 장면 내부로 이동할 수 있습니다. 다시 한 번, 코드를 연구하여 코드가 정확히 어떻게 수행되었는지 확인할 수 있습니다.

음악과 전환 동기화

자, 이 부분에서 우리가 스스로에게 가장 많은 질문을 던졌습니다. 소개 시퀀스가 ​​음악 재생 트랙의 특정 영역과 동기화되어 있음을 눈치채셨을 것 입니다. 드럼 소리가 들리면 첫 번째 줄이 표시되고 마지막 엔딩 시퀀스는 우리가 사용하는 호른 악기의 각 음표에서 한 카메라에서 다른 카메라로 빠르게 전환됩니다.

WebGL 렌더링 루프와 오디오를 동기화하는 것은 쉽지 않습니다. 다시 말하지만, 이것은 이러한 복잡성을 생성하는 JavaScript의 모노 스레드 특성입니다. HTML5 웹 작업자 소개: JavaScript 다중 스레딩 접근 방식에 대한 기사에서는 이에 대한 몇 가지 통찰력을 공유합니다. 우리가 직면한 글로벌 문제를 이해하려면 문제를 이해하는 것이 정말 중요하지만 여기에서 자세히 설명하는 것은 이 기사의 범위를 벗어납니다.

일반적으로 데모 장면(및 비디오 게임)에서 비주얼을 사운드/음악과 동기화하려면 오디오 스택에 의해 구동됩니다. 두 가지 접근 방식이 자주 사용됩니다.

  1. 오디오 파일에 삽입할 메타데이터를 생성한 다음 특정 부분에 도달했을 때 일부 이벤트를 "호출"할 수 있습니다.
  2. FFT 또는 유사한 기술을 통한 오디오 스트림의 실시간 분석을 통해 시각적 엔진에 대한 이벤트를 다시 생성할 흥미로운 피크 또는 BPM 변경을 감지합니다.

이러한 접근 방식은 C++와 같은 다중 스레드 환경에서 특히 잘 작동합니다. 그러나 JavaScript에서 Web Audio에는 두 가지 문제가 있습니다.

  1. 모노 스레드인 JavaScript는 불행히도 대부분의 경우 웹 작업자가 실제로 도움이 되지 않습니다.
  2. 웹 오디오는 웹 오디오가 브라우저에 의해 별도의 스레드에서 처리되는 경우에도 UI 스레드로 다시 보낼 수 있는 이벤트가 없습니다 .

Web Audio는 JavaScript보다 훨씬 정확한 타이머를 가지고 있습니다. 이벤트를 UI 스레드로 되돌리기 위해 별도의 스레드에서 이 별도의 타이머를 사용할 수 있었다면 환상적이었을 것입니다. 그러나 오늘날에는 그렇게 할 수 없습니다(아직?).

다른 쪽에서는 WebGL과 requestAnimationFrame 메서드를 사용하여 장면을 렌더링합니다. 이것은 "가장 좋은 경우"에서 16ms의 창 시간 프레임이 있음을 의미합니다. 하나를 놓치면 사운드 동기화를 반영하기 위해 다음 프레임에서 작동할 수 있으려면 최대 16ms를 기다려야 합니다(예: "페이드-투-블랙" 효과 시작).

그런 다음 requestAnimationFrame 루프에 동기화 논리를 삽입하는 방법에 대해 생각했습니다. 시퀀스 시작부터 소요된 시간을 연구하고 오디오 이벤트에 반응하도록 시각 효과를 조정하는 옵션을 조사했습니다. 좋은 소식은 웹 오디오가 메인 UI 스레드에서 진행되는 모든 사운드를 렌더링한다는 것입니다. 예를 들어, GPU가 장면을 렌더링하는 데 어려움을 겪고 있더라도 음악의 12초 타임스탬프가 음악 재생이 시작된 후 정확히 12초에 도착할 것임을 확신할 수 있습니다.

결국 우리는 setTimeout() 호출을 사용하여 가장 간단한 솔루션을 마침내 선택했습니다! 네, 알겠습니다. 위에 링크된 기사를 포함하여 대부분의 기사를 살펴보면 그것이 매우 신뢰할 수 없다는 것을 알게 될 것입니다. 그러나 우리의 경우 장면을 렌더링할 준비가 되면 모든 리소스(텍스처 및 사운드)를 다운로드하고 셰이더를 컴파일했음을 알 수 있습니다. UI 스레드를 포화시키는 예기치 않은 이벤트에 너무 짜증을 내지 않아야 합니다. GC가 문제가 될 수 있지만 엔진에서 이에 맞서 싸우는 데 많은 시간을 할애했습니다. Internet Explorer 11의 F12 개발자 표시줄을 사용하여 가비지 수집기에 대한 압력을 줄이는 것입니다.

그러나 우리는 이 솔루션이 이상적이지 않다는 것을 알고 있습니다. 다른 탭으로 전환하거나 전화기를 잠그고 몇 초 후에 잠금을 해제하면 데모의 동기화 부분에서 몇 가지 문제가 발생할 수 있습니다. Page Visibility API를 사용하여 이러한 문제를 해결할 수 있습니다. 예를 들어 렌더링 루프, 다양한 사운드를 일시 중지하고 setTimeout() 호출에 대한 다음 시간 프레임을 다시 계산하면 됩니다.

하지만 우리가 놓친 것이 있을지도 모릅니다. 이 문제를 처리하는 더 나은 접근 방식이 있을 수 있습니다. 동일한 문제를 해결하는 더 좋은 방법이 있다고 생각되면 의견 섹션에서 귀하의 생각과 제안을 듣고 싶습니다.

iOS에서 웹 오디오 처리

마지막으로 공유하고 싶은 문제는 iPhone 및 iPad의 iOS에서 웹 오디오를 처리하는 방식입니다. "웹 오디오 + iOS"에 대한 기사를 찾으면 iOS에서 사운드를 재생하는 데 어려움을 겪는 많은 사람들을 찾을 수 있습니다. 자, 무슨 일이죠?

iOS는 웹 오디오, 심지어 바이노럴 오디오 모드까지 지원합니다. 그러나 Apple은 특정 사용자의 상호 작용 없이 기본적으로 웹 페이지에서 소리를 재생할 수 없다고 결정했습니다. 이 결정은 아마도 원치 않는 소리를 재생하여 사용자를 방해하는 광고 또는 기타 내용을 피하기 위해 내린 것입니다.

웹 개발자에게 이것은 무엇을 의미합니까? 음, 사운드를 재생하기 전에 먼저 사용자 터치 후 iOS의 웹 오디오 컨텍스트를 잠금 해제 해야 합니다. 그렇지 않으면 웹 응용 프로그램이 필사적으로 음소거 상태로 유지됩니다.

불행히도 기능 감지 방법을 찾지 못했기 때문에 사용자 플랫폼 스니핑 접근 방식을 사용하여 이 검사를 수행할 수 있는 유일한 방법을 찾았습니다. 그것은 끔찍하고 방탄 기술이 아니지만 문제를 해결할 다른 해결책을 찾을 수 없었습니다. 코드? 자!

iPad/iPhone/iPod를 사용하지 않는 경우 오디오 컨텍스트를 즉시 사용할 수 있습니다. 그렇지 않으면 touchend 이벤트에서 코드 생성 빈 사운드를 재생하여 iOS의 오디오 컨텍스트를 잠금 해제합니다. 게임을 시작하기 전에 기다리려면 onAudioUnlocked 이벤트에 등록할 수 있습니다. 따라서 iPhone/iPad에서 Sponza를 실행하는 경우 로딩 시퀀스가 ​​끝나면 다음과 같은 최종 화면이 표시됩니다.

시작하려면 터치하세요.

화면의 아무 곳이나 터치하면 iOS의 오디오 스택이 잠금 해제되고 "쇼"가 시작됩니다.

자! 데모 개발에 대한 몇 가지 통찰력을 즐겼기를 바랍니다. 자세히 알아보려면 GitHub에서 이 데모의 전체 소스 코드를 읽어보세요. 분명히 모든 것이 오픈 소스이며 GitHub에서 index.js 및 babylon.demo.ts의 기본 파일을 찾을 수 있습니다.

마지막으로, 이제 웹이 확실히 게임을 위한 훌륭한 플랫폼이라는 사실을 더욱 확신하게 되기를 바랍니다! 지금 이 순간에 새로운 데모를 작업 중이므로 계속 지켜봐 주십시오. 데모도 매우 인상적일 것입니다.

이 기사는 실용적인 JavaScript 학습, 오픈 소스 프로젝트 및 Microsoft Edge 브라우저를 포함한 상호 운용성 모범 사례에 대한 Microsoft 기술 전도사 및 엔지니어의 웹 개발 시리즈의 일부입니다.

Windows 10용 기본 브라우저인 Microsoft Edge를 비롯한 여러 브라우저 및 장치에서 dev.microsoftedge.com의 무료 도구(F12 개발자 도구 포함)를 사용하여 테스트하는 것이 좋습니다. 웹 페이지 속도를 높입니다. 또한 Edge 블로그를 방문하여 Microsoft 개발자 및 전문가로부터 최신 정보를 얻고 최신 정보를 얻으십시오.