가상 현실, 증강 현실, 그 사이의 모든 것을 포함한 다양한 몰입형 환경을 준비하기 위한 몇 가지 기본사항입니다.
몰입형 환경은 Chrome 79에서 웹에 도입되었습니다. WebXR Device API는 가상 현실을 도입했으며 증강 현실 지원은 Chrome 81에서 제공됩니다. GamePad API 업데이트는 컨트롤의 고급 사용을 VR로 확장합니다. Firefox Reality, Oculus Browser, Edge, Magic Leap의 Helio 브라우저를 비롯한 다른 브라우저에서도 곧 이러한 사양을 지원할 예정입니다.
이 도움말은 몰입형 웹에 관한 시리즈를 시작합니다. 이 도움말에서는 기본 WebXR 애플리케이션을 설정하고 XR 세션을 시작하고 종료하는 방법을 설명합니다. 이후 도움말에서는 프레임 루프 (WebXR 환경의 핵심), 증강 현실의 세부정보, AR 세션에서 표면을 감지하는 수단인 WebXR Hit Test API를 다룹니다. 달리 명시되지 않는 한, 이 도움말과 후속 도움말에서 다루는 모든 내용은 AR과 VR에 동일하게 적용됩니다.
몰입형 웹이란 무엇인가요?
몰입형 환경을 설명하는 데 증강 현실과 가상 현실이라는 두 가지 용어를 사용하지만 많은 사용자는 완전한 현실에서 완전한 가상에 이르는 스펙트럼으로 생각하며 그 사이에 몰입도를 갖습니다. XR의 'X'는 몰입형 환경의 스펙트럼에 있는 모든 것을 나타내는 일종의 대수 변수로서 이러한 생각을 반영하기 위한 것입니다.
몰입형 환경의 예는 다음과 같습니다.
- 게임
- 360° 동영상
- 몰입형 환경에서 제공되는 기존 2D (또는 3D) 동영상
- 주택 구매
- 구매하기 전에 집에서 제품 보기
- 몰입형 아트
- 아직 아무도 생각하지 못한 멋진 것
개념 및 사용
WebXR Device API 사용의 몇 가지 기본사항을 설명하겠습니다. 제공한 것보다 더 자세한 내용이 필요하면 Immersive Web Working Group의 WebXR 샘플 또는 MDN의 증가하는 참고 자료를 확인하세요. WebXR Device API의 초기 버전에 익숙하다면 이 모든 자료를 살펴보세요. 변경사항이 있습니다.
이 도움말의 코드는 Immersive Web Working Group의 기본 샘플 (데모, 소스)을 기반으로 하지만 명확성과 단순성을 위해 수정되었습니다.
WebXR 사양을 만드는 과정에서 사용자를 보호하기 위한 보안 및 개인 정보 보호 조치가 구체화되었습니다. 따라서 구현은 특정 요구사항을 준수해야 합니다. 웹페이지 또는 앱은 시청자에게 민감한 내용을 요청하기 전에 활성 상태이고 포커스가 있어야 합니다. 웹페이지 또는 앱은 HTTPS를 통해 제공되어야 합니다. API 자체는 작동하는 데 필요한 센서와 카메라에서 얻은 정보를 보호하도록 설계되었습니다.
세션 요청
XR 세션을 시작하려면 사용자 동작이 필요합니다. 이를 가져오려면 기능
감지를 사용하여 XRSystem (navigator.xr을 통해)을 테스트하고
XRSystem.isSessionSupported()을 호출합니다. Chrome 버전 79 및 80에서
XRSystem 객체는 XR이라고 불렸습니다.
아래 예에서는 가상 현실 세션을 'immersive-vr' 세션 유형으로 원한다고 표시했습니다. 다른 세션 유형은 'immersive-ar' 및 'inline'입니다. 인라인 세션은 HTML 내에서 콘텐츠를 표시하기 위한 것이며 주로 티저 콘텐츠에 사용됩니다. 몰입형 AR
세션
샘플은 이를 보여줍니다. 이후 도움말에서 설명하겠습니다.
가상 현실 세션이 지원된다는 것을 알게 되면 사용자 동작을 가져올 수 있는 버튼을 사용 설정합니다.
if (navigator.xr) {
const supported = await navigator.xr.isSessionSupported('immersive-vr');
if (supported) {
xrButton.addEventListener('click', onButtonClicked);
xrButton.textContent = 'Enter VR';
xrButton.enabled = supported; // supported is Boolean
}
}
버튼을 사용 설정한 후 클릭 이벤트를 기다린 다음 세션을 요청합니다.
let xrSession = null;
function onButtonClicked() {
if (!xrSession) {
navigator.xr.requestSession('immersive-vr')
.then((session) => {
xrSession = session;
xrButton.textContent = 'Exit XR';
onSessionStarted(xrSession);
});
} else {
xrSession.end();
}
}
이 코드의 객체 계층 구조를 확인하세요. navigator에서 xr로, XRSession 인스턴스로 이동합니다. API의 초기 버전에서는 스크립트가 세션을 요청하기 전에 기기를 요청해야 했습니다. 이제 기기가 암시적으로 획득됩니다.
세션 시작
세션을 가져온 후 세션을 시작하고 입력해야 합니다. 하지만 먼저 몇 가지를 설정해야 합니다. 사용자가 종료할 때 앱 또는 웹페이지를 재설정할 수 있도록 세션에는 onend 이벤트 핸들러가 필요합니다.
장면을 그릴 <canvas> 요소도 필요합니다. XR 호환
WebGLRenderingContext
또는
WebGL2RenderingContext여야 합니다.
모든 그리기는 이러한 요소 또는
Three.js와 같은 WebGL 기반 프레임워크를 사용하여 실행됩니다.
이제 그릴 위치가 있으므로 그릴 콘텐츠 소스가 필요합니다. 이를 위해 XRWebGLLayer의 인스턴스를 만듭니다. XRSession.updateRenderState()를 호출하여 캔버스와 연결합니다.
세션에 참여한 후에는 가상 현실에서 항목의 위치를 결정하는 방법이 필요합니다. 참조 공간이 필요합니다. 'local-floor' 참조 공간은 원점이 뷰어 근처에 있고 y축이 바닥 수준에서 0이며 이동하지 않을 것으로 예상되는 공간입니다. 다른 유형의 참조 공간도 있지만 여기에서 다루기에는 더 복잡한 주제입니다. 화면에 그릴 때 필요하므로 참조 공간을 변수에 저장합니다.
function onSessionStarted(xrSession) {
xrSession.addEventListener('end', onSessionEnded);
let canvas = document.createElement('canvas');
webGLRenContext = canvas.getContext('webgl', { xrCompatible: true });
xrSession.updateRenderState({
baseLayer: new XRWebGLLayer(xrSession, webGLRenContext)
});
xrSession.requestReferenceSpace('local-floor')
.then((refSpace) => {
xrRefSpace = refSpace;
xrSession.requestAnimationFrame(onXRFrame);
});
}
참조 공간을 가져온 후 XRSession.requestAnimationFrame()을 호출합니다.
이는 프레임 루프에서 실행되는 가상 콘텐츠 표시의 시작입니다.
프레임 루프 실행
프레임 루프는 콘텐츠가 화면에 반복적으로 그려지는 사용자 에이전트 제어 무한 루프입니다. 콘텐츠는 프레임이라는 개별 블록으로 그려집니다. 프레임의 연속은 움직임의 착시를 만듭니다. VR 애플리케이션의 경우 초당 프레임 수는 60~144프레임일 수 있습니다. Android용 AR은 초당 30프레임으로 실행됩니다. 코드는 특정 프레임 속도를 가정해서는 안 됩니다.
프레임 루프의 기본 프로세스는 다음과 같습니다.
XRSession.requestAnimationFrame()을 호출합니다. 이에 따라 사용자 에이전트는 사용자가 정의한XRFrameRequestCallback을 호출합니다.- 콜백 함수 내부:
XRSession.requestAnimationFrame()을 다시 호출합니다.- 뷰어의 포즈를 가져옵니다.
XRWebGLLayer의WebGLFramebuffer를WebGLRenderingContext에 전달('바인딩')합니다.- 각
XRView객체를 반복하여XRWebGLLayer에서XRViewport를 가져오고WebGLRenderingContext에 전달합니다. - 프레임버퍼에 무언가를 그립니다.
이 도움말의 나머지 부분에서는 1단계와 2단계의 일부인 설정
및 XRFrameRequestCallback 호출을 설명합니다. 2단계의 나머지 항목은 2부에서 다룹니다.
XRFrameRequestCallback
XRFrameRequestCallback은 사용자가 정의합니다. DOMHighResTimeStamp와 XRFrame 인스턴스라는 두 가지 매개변수를 사용합니다. XRFrame 객체는 단일 프레임을 디스플레이에 렌더링하는 데 필요한 정보를 제공합니다. DOMHighResTimeStamp 인수는 향후 사용을 위한 것입니다.
다른 작업을 하기 전에 다음 애니메이션 프레임을 요청하겠습니다. 앞서 언급했듯이 프레임의 타이밍은 기본 하드웨어를 기반으로 사용자 에이전트에 의해 결정됩니다. 다음 프레임을 먼저 요청하면 콜백 중에 오류가 발생하더라도 프레임 루프가 계속됩니다.
function onXRFrame(hrTime, xrFrame) {
let xrSession = xrFrame.session;
xrSession.requestAnimationFrame(onXRFrame);
// Render a frame.
}
이제 뷰어를 위해 무언가를 그릴 시간입니다. 이는 2부에서 다룰 내용입니다. 그 전에 세션을 종료하는 방법을 보여드리겠습니다.
세션 종료
몰입형 세션은 XRSession.end() 호출을 통해 자체 코드로 종료하는 것을 비롯한 여러 가지 이유로 종료될 수 있습니다. 다른 원인으로는 헤드셋 연결이 끊어지거나 다른 애플리케이션이 헤드셋을 제어하는 경우가 있습니다. 이것이 제대로 작동하는 애플리케이션이 end 이벤트를 모니터링해야 하는 이유입니다. 이 이벤트가 발생하면 세션과 관련 렌더링 객체를 삭제합니다. 종료된 몰입형 세션은 재개할 수 없습니다. 몰입형 환경에 다시 참여하려면 앱에서 새 세션을 시작해야 합니다.
세션 시작에서 설정 중에
onend 이벤트 핸들러를 추가한 것을 기억하세요.
function onSessionStarted(xrSession) {
xrSession.addEventListener('end', onSessionEnded);
// More setup…
}
이벤트 핸들러 내에서 사용자가 세션을 시작하기 전의 앱 상태를 복원합니다.
function onSessionEnded(event) {
xrSession = null;
xrButton.textContent = 'Enter VR';
}
결론
Web XR 또는 AR 애플리케이션을 작성하는 데 필요한 모든 것을 설명하지는 않았습니다. 이 도움말을 통해 코드를 직접 이해하고 실험을 시작할 수 있기를 바랍니다. 다음 도움말에서는 콘텐츠가 화면에 그려지는 프레임 루프를 설명합니다.