1. 소개
가상 현실(VR) 및 증강 현실(AR) 애플리케이션을 가능하게 하는 하드웨어는 이제 소비자에게 널리 제공되고 있으며, 새로운 기회와 과제를 모두 갖춘 몰입형 컴퓨팅 플랫폼을 제공한다. 몰입형 하드웨어와 직접 상호작용할 수 있는 능력은 웹이 이 환경에서 일급 시민으로 동작할 수 있도록 보장하는 데 중요하다.
몰입형 컴퓨팅은 허용 가능한 경험을 제공하기 위해 고정밀, 저지연 통신에 대한 엄격한 요구 사항을 도입한다. 또한 웹과 같은 플랫폼에 고유한 보안 우려도 가져온다. WebXR Device API는 개발자가 다양한 하드웨어 폼 팩터 전반에서 웹상에 매력적이고, 편안하며, 안전한 몰입형 애플리케이션을 구축할 수 있도록 하는 데 필요한 인터페이스를 제공한다.
RelativeOrientationSensor
및 AbsoluteOrientationSensor와
같은
다른 웹 인터페이스는 제한된 상황에서 WebXR Device API를 폴리필하기 위해 일부 장치의 입력을
노출하도록 용도를 바꿀 수 있다. 그러나 이러한 인터페이스는 6DoF 추적,
헤드셋 주변 장치로의 프레젠테이션, 또는 추적되는 입력 장치와 같은 고급 몰입형 경험의 여러 기능을
지원할 수 없다.
1.1. 용어
이 문서는 가상 현실, 증강 현실 및 기타 관련 기술에 사용되는 하드웨어, 애플리케이션 및 기법의 스펙트럼을 가리키기 위해 전반적으로 약어 XR을 사용한다. 예시는 다음을 포함하지만 이에 한정되지 않는다.
-
불투명하거나, 투명하거나, 비디오 패스스루를 사용하는 헤드 마운트 디스플레이
-
위치 추적 기능을 갖춘 모바일 장치
-
공간 추적 기능을 갖춘 고정 디스플레이
이들 사이의 중요한 공통점은 가상 콘텐츠의 뷰를 시뮬레이션하는 데 사용할 수 있는 어느 정도의 공간 추적을 제공한다는 점이다.
"XR device", "XR application" 등과 같은 용어는 일반적으로 위의 모든 것에 적용되는 것으로 이해된다. 이 문서에서 이러한 장치의 하위 집합에만 적용되는 부분은 적절하게 이를 표시한다.
3DoF 및 6DoF라는 용어는 이 문서 전반에서 XR 장치의 추적 기능을 설명하는 데 사용된다.
-
3DoF 장치는 "Three Degrees of Freedom"의 약어로, 회전 움직임만 추적할 수 있는 장치이다. 이는 추적을 제공하기 위해 가속도계와 자이로스코프 판독값에만 의존하는 장치에서 흔하다. 3DoF 장치는 사용자의 병진 이동에 반응하지 않지만, 목이나 팔의 모델링을 기반으로 병진 변화를 추정하는 알고리즘을 사용할 수는 있다.
-
6DoF 장치는 "Six Degrees of Freedom"의 약어로, 회전과 병진을 모두 추적할 수 있어 공간에서 정밀한 1:1 추적을 가능하게 하는 장치이다. 이는 일반적으로 사용자의 환경에 대한 어느 정도의 이해를 필요로 한다. 이러한 환경 이해는 추적되는 장치 자체의 센서(예: 카메라 또는 깊이 센서)를 사용하여 장치의 위치를 결정하는 inside-out tracking을 통해 달성될 수 있으며, 또는 사용자의 환경에 배치된 외부 장치 (예: 카메라 또는 발광 장치)가 XR 장치가 자신의 위치를 결정하는 데 사용할 안정적인 기준점을 제공하는 outside-in tracking을 통해 달성될 수 있다.
1.2. 애플리케이션 흐름
WebXR Device API를 사용하는 대부분의 애플리케이션은 유사한 사용 패턴을 따른다.
-
navigator.xr.isSessionSupported()를 질의하여 원하는 유형의 XR 콘텐츠가 하드웨어와 UA에서 지원되는지 확인한다. -
그렇다면 XR 콘텐츠를 사용자에게 알린다.
-
window가 일시적 활성화를 가지기를 기다린다. 이는 가장 일반적으로 사용자가 XR 콘텐츠 보기를 시작하고 싶음을 나타내는 페이지의 버튼을 클릭하는 것으로 표시된다.
-
사용자 활성화 이벤트 내에서
navigator.xr.requestSession()으로XRSession을 요청한다. -
XRSession요청이 성공하면, 이를 사용하여 XR 입력에 응답하고 그 응답으로 XR 장치에 표시할 이미지를 생성하는 프레임 루프를 실행한다. -
UA에 의해 세션이 종료되거나 사용자가 XR 콘텐츠를 종료하고 싶음을 나타낼 때까지 프레임 루프를 계속 실행한다.
2. 모델
2.1. XR 장치
XR 장치는 사용자에게 몰입형 콘텐츠를 제공할 수 있는 물리적 하드웨어 단위이다. 콘텐츠가 사용자의 환경의 다양한 측면을 시뮬레이션하거나 증강하는 시각, 오디오, 햅틱 또는 기타 감각 출력을 생성하는 경우, 해당 콘텐츠는 "몰입형"으로 간주된다. 가장 흔히 이는 공간에서 사용자의 움직임을 추적하고 사용자의 움직임과 동기화된 출력을 생성하는 것을 포함한다. 데스크톱 클라이언트에서는 일반적으로 헤드셋 주변 장치이다. 모바일 클라이언트에서는 뷰어 하니스와 결합된 모바일 장치 자체를 나타낼 수 있다. 또한 스테레오 프레젠테이션 기능은 없지만 더 고급 추적 기능을 갖춘 장치를 나타낼 수도 있다.
XR 장치는 지원되는
모드 목록(list of strings)을 가지며, 이는 해당 contains the
enumeration values of XRSessionMode
that the XR device supports.
각 XR 장치는 해당
지원되는
모드 목록의 각 XRSessionMode에
대해
허가된 기능 집합을 가지며, 이는 처음에는 빈 set이어야 하는
기능 설명자의
set이다.
사용자 에이전트는 몰입형 XR 장치 목록(list of XR device)을 가지며, 이는 처음에는 빈 list여야 한다.
사용자 에이전트는 몰입형 XR 장치(null 또는 XR device)를 가지며, 이는 처음에는 null이고
몰입형
XR 장치 목록에서 활성 XR 장치를
나타낸다. 이 객체는 별도의 스레드에 존재할 수 있으며 비동기적으로 갱신될 수 있다.
사용자 에이전트는 기본 인라인 XR 장치를 가져야 하며, 이는 자신의 지원되는 모드 목록에
"inline"을
반드시 contain해야 하는
XR 장치이다. 기본 인라인 XR 장치는 어떤 포즈 정보도 보고해서는
안 되며,
pointer events에 의해 생성된 것 이외의 XR
입력
소스나 이벤트를 보고해서도 안 된다.
참고: 기본 인라인 XR 장치는 개발자를 위한 편의 목적으로만 존재하며, 인라인 콘텐츠와 몰입형 콘텐츠 모두에 동일한 렌더링 및 입력 로직을 사용할 수 있게 한다. 기본 인라인 XR 장치는 페이지의 다른 메커니즘(예: 입력을 위한 pointer events)을 통해 개발자가 이미 사용할 수 있는 정보 이외의 정보를 노출하지 않으며, 단지 해당 값을 XR 중심 형식으로 노출할 뿐이다.
사용자 에이전트는 인라인
XR 장치를 가져야 하며, 이는 자신의 지원되는 모드 목록에
"inline"을
반드시 contain해야 하는
XR 장치이다. 인라인 XR 장치는 지원되는 기본 뷰를
HTML 문서의 일부로 노출할 수 있다면 inline-stereo 기능 설명자를 지원할 수 있는 상태일 수 있다. 인라인 XR 장치는 제공하는 추적을 인라인
콘텐츠에 노출하는 것이 타당하다면
몰입형 XR 장치일 수 있고,
그렇지 않으면 기본
인라인 XR 장치일 수 있다.
참고: 휴대폰에서는 인라인 XR 장치가 자이로스코프 및 가속도계와 같은 휴대폰의 내부 센서에서 파생된 포즈 정보를 보고할 수 있다. 유사한 센서가 없는 데스크톱과 노트북에서는 인라인 XR 장치가 포즈를 보고할 수 없으므로 기본 인라인 XR 장치로 폴백해야 한다. 사용자 에이전트가 이미 XR 장치에서 실행 중인 경우, 인라인 XR 장치는 동일한 장치가 되며 여러 뷰를 지원할 수 있다. 기본 인라인 XR 장치가 노출하는 것을 넘어서는 추적 또는 입력 기능이 제공되기 전에 사용자 동의를 받아야 한다.
몰입형 XR 장치 목록, 인라인 XR 장치, 및 몰입형 XR 장치의 현재 값은 별도의 스레드에 존재할 수 있으며 비동기적으로 갱신될 수 있다. 이러한 객체는 in parallel로 실행되지 않는 단계에서 직접 접근해서는 안 된다.
3. 초기화
3.1. navigator.xr
partial interface Navigator { [SecureContext ,SameObject ]readonly attribute XRSystem xr ; };
xr 속성의 getter는 그와 연결된 XRSystem 객체를
반환해야 한다.
3.2. XRSystem
[SecureContext ,Exposed =Window ]interface :XRSystem EventTarget { // MethodsPromise <boolean >isSessionSupported (XRSessionMode ); [mode NewObject ]Promise <XRSession >requestSession (XRSessionMode ,mode optional XRSessionInit = {}); // Eventsoptions attribute EventHandler ondevicechange ; };
사용자 에이전트는 Navigator
객체가 생성될 때 XRSystem 객체를
생성하고 이를 해당 객체와 연결해야 한다.
XRSystem
객체는 API의 진입점으로, 사용자 에이전트에서 사용할 수 있는 XR 기능을 질의하고 XRSession 생성
을 통해 XR 하드웨어와의 통신을 시작하는 데 사용된다.
사용자 에이전트는 시스템에 연결된 몰입형 XR 장치를 열거할 수 있어야 하며, 이때 사용 가능한 각 장치는 몰입형 XR 장치 목록에 배치된다. 열거를 요청하는 후속 알고리즘은 캐시된 몰입형 XR 장치 목록을 재사용해야 한다. 장치를 열거하는 것은 장치 추적을 초기화해서는 안 된다. 첫 번째 열거 이후 사용자 에이전트는 장치 연결 및 연결 해제를 모니터링하기 시작해야 하며, 연결된 장치를 몰입형 XR 장치 목록에 추가하고 연결 해제된 장치를 제거해야 한다.
몰입형 XR 장치 목록이 변경될 때마다 사용자 에이전트는 다음 단계를 실행하여 몰입형 XR 장치를 선택해야 한다.
-
oldDevice를 몰입형 XR 장치로 둔다.
-
몰입형 XR 장치 목록이 빈 list라면, 몰입형 XR 장치를
null로 설정한다. -
몰입형 XR 장치 목록의 size가 하나라면, 몰입형 XR 장치를 몰입형 XR 장치 목록[0]으로 설정한다.
-
몰입형 XR 장치를 다음과 같이 설정한다.
- 활성
XRSession이 있고 몰입형 XR 장치 목록이 oldDevice를 contains하는 경우: -
몰입형 XR 장치를 oldDevice로 설정한다.
- 그렇지 않은 경우:
-
몰입형 XR 장치를 사용자 에이전트가 선택한 장치로 설정한다.
- 활성
-
사용자 에이전트는 적절하다면 인라인 XR 장치를 몰입형 XR 장치로 갱신할 수 있고, 그렇지 않으면 기본 인라인 XR 장치로 갱신할 수 있다.
-
장치가 처음으로 열거된 경우 또는 oldDevice가 몰입형 XR 장치와 같다면, 이 단계를 중단한다.
-
모든
WebGLRenderingContextBase인스턴스의 XR compatible boolean을false로 설정하기 위해 작업을 큐에 넣는다. -
작업을 큐에 넣어 이벤트를 발생시키되, 관련 Global 객체의
navigator의xr에서 devicechange라는 이름으로 발생시킨다. -
작업을 큐에 넣어 몰입형 XR 장치 또는 인라인 XR 장치의 변경에 영향을 받는 모든
XRPermissionStatus객체에서 적절한change이벤트를 발생시킨다.
참고: 이러한 단계는 항상 in parallel로 실행되어야 한다.
참고: 몰입형 XR 장치 목록에 여러 장치가 포함되어 있을 때 사용자 에이전트는 몰입형 XR 장치를 선택하기 위해 원하는 어떤 기준이든 사용할 수 있다. 예를 들어, 사용자 에이전트는 항상 목록의 첫 번째 항목을 선택하거나, 사용자가 장치 우선순위를 관리할 수 있는 설정 UI를 제공할 수 있다. 기본 장치를 선택하는 데 사용되는 알고리즘은 안정적이고 여러 브라우징 세션에 걸쳐 동일한 장치가 선택되는 결과를 낳는 것이 이상적이다.
사용자 에이전트는 다음 단계를 실행하여 몰입형 XR 장치가 선택되도록 보장할 수 있다.
-
몰입형 XR 장치를 반환한다.
참고: 이러한 단계는 항상 in parallel로 실행되어야 한다.
ondevicechange 속성은 Event handler IDL attribute로, devicechange 이벤트 유형을 위한 것이다.
isSessionSupported(mode) 메서드는
주어진 mode가 사용자 에이전트 및 장치 기능에 의해 지원될 수 있는지를 질의한다.
이 메서드가 호출되면 다음 단계를 실행해야 한다.
-
mode가 몰입형 세션 모드이고 요청하는 문서의 origin이 "xr-spatial-tracking" 권한 정책을 사용할 수 있도록 허용되지 않은 경우, promise를 "
SecurityError"DOMException으로 reject하고 이를 반환한다. -
세션 mode가 지원되는지 다음과 같이 확인한다.
- 사용자 에이전트와 시스템이 mode 세션을 절대 지원하지 않는 것으로 알려진 경우
-
promise를
false로 Resolve한다. - 사용자 에이전트와 시스템이 mode 세션을 보통 지원하는 것으로 알려진 경우
-
사용자 에이전트 문자열로 구별할 수 없는 이 사용자 에이전트의 모든 인스턴스가 여기에서 동일한 결과를 생성한다면, promise는
true로 resolved될 수 있다. - 그렇지 않은 경우
-
다음 단계를 in parallel로 실행한다.
-
device가 null이면, promise를
false로 resolve하고 이 단계를 중단한다. -
device의 지원되는 모드 목록이 mode를 contain하지 않으면, promise를
false로 resolve하도록 작업을 큐에 넣고 이 단계를 중단한다. -
mode가 mode와 같은XRSessionSupportedPermissionDescriptor로 강력한 기능 "xr-session-supported"을 사용하기 위한 권한을 요청한다. 이것이"denied"를 반환하면, promise를false로 resolve하도록 작업을 큐에 넣고 이 단계를 중단한다. 자세한 내용은 핑거프린팅 고려 사항을 참조하라. -
promise를
true로 resolve하도록 작업을 큐에 넣는다.
-
promise를 반환한다.
참고: isSessionSupported()의
목적은 사용자 에이전트가 XRSession을 생성할
수 있는지를
완벽한 정확도로 보고하는 것이 아니라, 주어진 모드의 세션을 생성할 수 있음을 페이지가 알리는 것이 권장되는지 여부를
알려 주는 것이다. 사용자 에이전트가 메서드를 resolve하기 전에 필요한 하드웨어/소프트웨어의 존재를 확인하는 경우에도,
어느 정도의 false-positive가 예상된다. (예를 들어, 적절한 하드웨어가 존재하더라도 세션이 요청될 때 다른 애플리케이션에
독점 접근 권한을 부여했을 수 있다.)
XR 콘텐츠가 있는 대부분의 페이지는 문서 생명주기의 초기에 isSessionSupported()를
호출할 것으로 예상된다. 따라서 isSessionSupported()
호출은
모달 또는 기타 방해가 되는 UI를 표시하는 것을 피해야 한다. isSessionSupported()
호출은
장치 선택 UI를 트리거해서는 안 되며, 시스템에서 실행 중인 XR 애플리케이션을 방해해서는 안 되며,
시스템 트레이나 스토어프런트와 같은 XR 관련 애플리케이션이 실행되도록 해서도 안 된다.
immersive-vr
세션이 지원되는지 확인한다.
const supported= await navigator. xr. isSessionSupported( 'immersive-vr' ); if ( supported) { // 'immersive-vr' sessions may be supported. // Page should advertise support to the user. } else { // 'immersive-vr' sessions are not supported. }
XRSystem
객체는 처음에는 false여야 하는 대기 중인 몰입형 세션 boolean, 처음에는 null이어야 하는
활성 몰입형 세션,
그리고 처음에는 비어 있어야 하는 인라인
세션 목록을 가진다.
requestSession(mode, options)
메서드는 가능한 경우 주어진 mode에 대해 XRSession을
초기화하려고 시도하며, 필요한 경우 몰입형 모드로 진입한다.
이 메서드가 호출되면 사용자 에이전트는 다음 단계를 실행해야 한다.
-
mode가 몰입형 세션 모드이면 immersive를
true로 두고, 그렇지 않으면false로 둔다. -
global object를 이 메서드가 호출된
XRSystem의 관련 Global 객체로 둔다. -
세션 요청이 허용되는지 다음과 같이 확인한다.
- immersive가
true인 경우: -
-
global object에 대해 몰입형 세션 요청이 허용되는지 확인하고, 그렇지 않다면 promise를 "
SecurityError"DOMException으로 reject하고 promise를 반환한다. -
대기 중인 몰입형 세션이
true이거나 활성 몰입형 세션이null이 아니면, promise를 "InvalidStateError"DOMException으로 reject하고 promise를 반환한다. -
대기 중인 몰입형 세션을
true로 설정한다.
-
- 그렇지 않은 경우:
-
global object에 대해 인라인 세션 요청이 허용되는지 확인하고, 그렇지 않다면 promise를 "
SecurityError"DOMException으로 reject하고 promise를 반환한다.
- immersive가
-
다음 단계를 in parallel로 실행한다.
-
requiredFeatures를 options의
requiredFeatures로 둔다. -
optionalFeatures를 options의
optionalFeatures로 둔다. -
device를 mode, requiredFeatures, 및 optionalFeatures에 대해 현재 장치를 얻은 결과로 설정한다.
-
다음 단계를 수행하도록 작업을 큐에 넣는다:
-
device가
null이거나 device의 지원되는 모드 목록이 mode를 contain하지 않으면, 다음 단계를 실행한다:-
promise를 "
NotSupportedError"DOMException으로 Reject한다. -
immersive가
true이면, 대기 중인 몰입형 세션을false로 설정한다. -
이 단계를 중단한다.
-
-
descriptor를 mode, requiredFeatures, 및 optionalFeatures로 초기화된
XRPermissionDescriptor로 둔다 -
status를 처음에는
null인XRPermissionStatus로 둔다 -
descriptor와 status로 xr 권한을 요청한다.
-
status의
state가"denied"이면 다음 단계를 실행한다:-
promise를 "
NotSupportedError"DOMException으로 Reject한다. -
immersive가
true이면, 대기 중인 몰입형 세션을false로 설정한다. -
이 단계를 중단한다.
-
-
session, mode, granted, 및 device로 세션을 초기화한다.
-
활성 몰입형 세션을 잠재적으로 다음과 같이 설정한다:
- immersive가
true인 경우: -
활성 몰입형 세션을 session으로 설정하고, 대기 중인 몰입형 세션을
false로 설정한다. - 그렇지 않은 경우:
-
session을 인라인 세션 목록에 추가한다.
- immersive가
-
promise를 session으로 Resolve한다.
-
다음 단계를 수행하도록 작업을 큐에 넣는다:
참고: 이러한 단계는 초기inputsourceschange이벤트가 초기 세션이 resolve된 후에 발생하도록 보장한다.-
session의 promise resolved 플래그를
true로 설정한다. -
sources를 session에 연결된 기존 입력 소스로 둔다.
-
sources가 비어 있지 않다면, 다음 단계를 수행한다:
-
session의 활성 XR 입력 소스 목록을 sources로 설정한다.
-
XRInputSourcesChangeEvent를inputsourceschange라는 이름으로 session에서 발생시키되,added를 sources로 설정한다.
-
-
-
-
-
promise를 반환한다.
XRSessionMode
mode, requiredFeatures, 및 optionalFeatures에 대해
현재
장치를 얻으려면 사용자 에이전트는 다음 단계를 실행해야 한다:
-
device를 다음과 같이 선택한다:
- mode가 몰입형 세션 모드인 경우:
-
device를 몰입형 XR 장치가 선택되도록 보장한 결과로 설정한다.
- 그렇지 않고 requiredFeatures 또는 optionalFeatures가 비어 있지 않은 경우:
-
device를 인라인 XR 장치로 설정한다.
- 그렇지 않은 경우:
-
device를 기본 인라인 XR 장치로 설정한다.
-
device를 반환한다.
참고: 이러한 단계는 항상 in parallel로 실행되어야 한다.
immersive-vr
XRSession을
가져오려고 시도한다.
const xrSession= await navigator. xr. requestSession( "immersive-vr" );
3.3. XRSessionMode
XRSessionMode
enum은 XRSession이
동작할 수 있는 모드를 정의한다.
enum {XRSessionMode "inline" ,"immersive-vr" ,"immersive-ar" };
-
inline세션 모드는 세션의 출력이 HTML 문서의 요소로 표시됨을 나타낸다.inline세션 콘텐츠는 세션에 대해 노출된 뷰 목록을 사용하여 표시되어야 한다. inline-stereo 기능이 활성화되지 않는 한, 이는 view 하나이며, 그 eye는"none"이다. 사용자 에이전트는inline세션이 생성될 수 있도록 허용해야 한다. -
immersive-vr세션 모드는 세션의 출력이 몰입형 XR 장치 디스플레이에 대한 독점 접근을 부여받으며, 콘텐츠가 사용자의 환경과 통합되도록 의도된 것이 아님을 나타낸다. -
immersive-ar세션 모드의 동작은 WebXR AR Module에서 정의되며, UA가 해당 모듈을 구현하지 않는 한 몰입형 XR 장치의 지원되는 모드 목록에 추가되어서는 안 된다.
이 문서에서 인라인 세션이라는 용어는
inline
세션을 가리키며, 몰입형 세션이라는
용어는 immersive-vr
또는 immersive-ar
세션을 가리킨다.
몰입형 세션은
어느 정도의 viewer 추적을 제공해야 하며,
콘텐츠는 사용자 및/또는 주변 환경에 상대적인 적절한 스케일로 표시되어야 한다.
또한 몰입형
세션은 몰입형 XR
장치에 대한 독점 접근을
부여받아야 한다. 이는 몰입형 세션이
"visible"인
동안 HTML 문서가 몰입형 XR
장치의 디스플레이에 표시되지 않으며, 다른 소스의 콘텐츠도
독점 접근을 가지지 않음을 의미한다. 독점
접근은 사용자 에이전트가 자체 UI를 오버레이하는 것을 막지는 않지만,
이 UI는 최소화되어야 한다.
참고: UA는 대체 입력 소스가 없을 때 보호 경계, 장애물 또는 사용자의 손과 같은 접근성 또는 안전을 위한 콘텐츠를 오버레이하도록 선택할 수 있다.
참고: 향후 명세 또는 모듈은 몰입형 세션의 정의를 추가 세션 모드를 포함하도록 확장할 수 있다.
참고: 독점 접근이 제공될 수 있는 방식의 예에는 가상 현실 헤드셋에 표시되는 스테레오 콘텐츠가 포함된다.
참고: 오버레이된 UI의 예로, 몰입형 세션에서 사용자 에이전트 또는 운영 체제가 렌더링된 콘텐츠 위에 알림을 표시할 수 있다.
참고: 몰입형 XR 장치의 디스플레이에는 몰입형 세션 동안 HTML 문서가 표시되지 않지만, 별도의 디스플레이에는 여전히 표시될 수 있다. 예를 들어 사용자가 자신의 몰입형 XR 장치에 연결된 컴퓨터의 2d 브라우저에서 몰입형 세션에 진입하는 경우가 그렇다.
3.4. 기능 의존성
XRSession의 일부
기능은
여러 이유로 보편적으로 사용할 수 없을 수 있으며, 그중 하나는 모든 XR 장치가 전체 기능 집합을 지원할 수 있는 것은
아니라는 점이다. 또 다른 고려 사항은 일부 기능이 민감한 정보를 노출하여 동작하기 전에
사용자 의도의 명확한 신호를
요구할 수 있다는 점이다.
기저 XR 플랫폼을 초기화하고 XRSession을 생성한
직후 애플리케이션이 올바르게 동작할 수 없음을 사용자에게 알리는 것은 나쁜 사용자 경험이므로, 개발자는
requestSession()에
XRSessionInit
dictionary를 전달하여 필수
기능을
표시할 수 있다. 이는 장치 제한으로 인해 또는 해당 기능과 관련된 민감한
정보를 노출하려는 사용자 의도의 명확한 신호가
없는 경우
필수
기능 중 하나라도 사용할 수 없으면 XRSession 생성이
차단되도록 한다.
또한 개발자는 더 유능한 장치에서 실행될 때 기능을 점진적으로 향상시키는 경험을 설계하도록 권장된다.
경험에 필수는 아니지만 사용 가능할 때 활용할 선택적 기능도 필요한 경우 기능을 활성화하기 전에
사용자
의도를 결정할 수 있도록 XRSessionInit
dictionary에 표시되어야 한다.
dictionary {XRSessionInit sequence <DOMString >requiredFeatures ;sequence <DOMString >optionalFeatures ; };
requiredFeatures 배열은 경험을 위한 모든
필수 기능을 포함한다.
목록의 어떤 값이 인식된 기능
설명자가 아니면 XRSession은
생성되지 않는다. requiredFeatures
배열에 나열된 어떤 기능이 XR
장치에서 지원되지 않거나, 필요한 경우
사용자 의도의 명확한 신호를 받지 못했다면
XRSession은
생성되지 않는다.
optionalFeatures 배열은 경험을 위한 모든
선택적 기능을 포함한다.
목록의 어떤 값이 인식된 기능
설명자가 아니면 무시된다.
optionalFeatures
배열에 나열된 기능은 XR
장치에서 지원되고, 필요한 경우
사용자 의도의 명확한 신호가 주어지면 활성화되지만,
존재하지 않더라도 XRSession 생성을
차단하지 않는다.
기능 목록에 주어진 값은 다음 중 하나인 경우 유효한 기능 설명자로 간주된다:
-
임의의
XRReferenceSpaceTypeenum 값의 문자열 표현 -
문자열 "tracked-sources"
-
문자열 "inline-stereo"
-
문자열 "secondary-views"
이 명세의 향후 반복판과 추가 모듈은 허용되는 기능 설명자 목록을 확장할 수 있다.
참고: 기능에 추가 초기화가 필요하다면,
XRSessionInit은
해당 기능을 위한 새 필드로 확장되어야 한다.
요청된 XRSessionMode에
따라, 특정 기능 설명자가 기본적으로
requiredFeatures
또는 optionalFeatures
목록에 추가된다. 다음 표는 각 세션 유형 및 기능 목록과 관련된 기본 기능을 설명한다:
| 기능 | 세션 | 목록 |
|---|---|---|
"viewer"
| 모든 세션 | requiredFeatures
|
"local"
| 몰입형 세션 | requiredFeatures
|
requiredFeatures
및 optionalFeatures가
제공하는 기능 설명자의 결합 목록은
XRSession에
대한
요청된 기능으로 집합적으로
간주된다.
요청된 기능 목록에 있을 때, 일부 기능 설명자는 권한 정책 및/또는 해당 기능을 사용하려는 사용자 의도가 명시적 동의 또는 묵시적 동의를 통해 잘 이해되어야 한다는 요구 사항의 적용을 받는다. 다음 표는 활성화되기 전에 충족되어야 하는 기능 요구 사항을 설명한다:
| 기능 | Permissions Policy 필요 여부 | 동의 필요 여부 |
|---|---|---|
"local"
| "xr-spatial-tracking" | 인라인 세션은 동의가 필요함 |
"local-floor"
| "xr-spatial-tracking" | 항상 동의가 필요함 |
"bounded-floor"
| "xr-spatial-tracking" | 항상 동의가 필요함 |
"unbounded"
| "xr-spatial-tracking" | 항상 동의가 필요함 |
참고: "local"은
몰입형 세션의
요청된 기능에 기본 기능으로 항상 포함되며,
따라서 몰입형
세션은 항상 명시적 동의 또는
묵시적 동의를 얻어야 한다.
inline-stereo 기능 설명자는 인라인 세션이 인라인
프레젠테이션을 위해 스테레오 기본 뷰를
노출하도록 요청한다. 활성화되면, 뷰 목록은 두 개의 기본 뷰를 포함해야 하며, 하나의 eye는 "left"이고,
다른 하나의 eye는 "right"이다.
inline-stereo 기능 설명자는
"inline"
세션에만 적용된다. 이는 몰입형 세션에
부여되어서는 안 된다.
요청된 기능은 XR 장치가 해당 기능을 지원할 수 있는 경우에만 세션에 대해 활성화될 수 있다. 이는 현재 구성이 아직 해당 기능을 지원하는 것으로 검증되지 않았더라도, 어떤 구성에서는 해당 기능이 XR 장치에서 지원되는 것으로 알려져 있음을 의미한다. 사용자 에이전트는 더 일관된 사용자 경험을 산출하기 위해 원한다면 더 엄격한 제약을 적용할 수 있다.
참고: 예를 들어, 여러 VR 장치는 사용자가 그 안에서
움직일 수 있는 안전 경계를 구성하거나, 경계 구성을 건너뛰고 사용자가 제자리에서 서 있을 것으로 예상되는 모드에서
동작하도록 구성하는 것 중 하나를 지원한다. 이러한 장치는 현재 안전 경계가 구성되어 있지 않더라도
"bounded-floor"
XRReferenceSpace를
지원할 수 있는
것으로 간주될 수 있다. 이는 경험이 이를 요구한다면 사용자가 장치를 적절히 구성할 수 있을 것으로 예상되기 때문이다.
이는 사용자 에이전트가 원한다면 요청된 기능을 resolve하기 전에 XR 장치를 완전히 초기화하거나 사용자의 환경이 인식되기를 기다리는
것을
피할 수 있도록 하기 위한 것이다. 그러나 사용자 에이전트가 추가 초기화 없이 세션이 요청되는 시점에 경계 상태를
알고 있다면, 안전 경계가 이미 구성되어 있지 않은 경우 "bounded-floor"
기능을 거부하도록 선택할 수 있다.
4. 세션
4.1. XRSession
XR 하드웨어와의 모든 상호작용은 XRSession
객체를 통해 이루어지며, 이 객체는 XRSystem 객체에서 requestSession()을 호출해야만 가져올 수 있다.
세션을 성공적으로 획득하면, 이를 사용하여 뷰어 포즈를 폴링하고,
사용자의 환경에 대한 정보를 질의하며, 사용자에게 이미지를 제시할 수 있다.
가능한 경우 사용자 에이전트는 XRSession이
획득되기 전까지 장치 추적 또는 렌더링 기능을 초기화해서는 안 된다.
이는 XR 하드웨어의 존재를 테스트하여 XR 기능을 알리려는 페이지로 처음 이동할 때 배터리 사용량 증가나 관련
유틸리티 애플리케이션 표시와 같이, XR 시스템이 실제로 사용되지 않는 동안 관여됨으로써 생기는 원치 않는 부작용을
방지하기 위한 것이다. 그러나 모든 XR 플랫폼이 추적을 초기화하지 않고 하드웨어의 존재를 감지하는 방법을
제공하는 것은 아니므로, 이는 강한 권고일 뿐이다.
enum {XRVisibilityState "visible" ,"visible-blurred" ,"hidden" , }; [SecureContext ,Exposed =Window ]interface :XRSession EventTarget { // Attributesreadonly attribute XRVisibilityState visibilityState ;readonly attribute float ?frameRate ;readonly attribute Float32Array ?supportedFrameRates ; [SameObject ]readonly attribute XRRenderState renderState ; [SameObject ]readonly attribute XRInputSourceArray inputSources ; [SameObject ]readonly attribute XRInputSourceArray trackedSources ;readonly attribute FrozenArray <DOMString >enabledFeatures ;readonly attribute boolean isSystemKeyboardSupported ; // Methodsundefined updateRenderState (optional XRRenderStateInit = {});state Promise <undefined >updateTargetFrameRate (float ); [rate NewObject ]Promise <XRReferenceSpace >requestReferenceSpace (XRReferenceSpaceType );type unsigned long requestAnimationFrame (XRFrameRequestCallback );callback undefined cancelAnimationFrame (unsigned long );handle Promise <undefined >end (); // Eventsattribute EventHandler onend ;attribute EventHandler oninputsourceschange ;attribute EventHandler onselect ;attribute EventHandler onselectstart ;attribute EventHandler onselectend ;attribute EventHandler onsqueeze ;attribute EventHandler onsqueezestart ;attribute EventHandler onsqueezeend ;attribute EventHandler onvisibilitychange ;attribute EventHandler onframeratechange ; };
각 XRSession은
XRSessionMode의
값 중 하나인 mode를 가진다.
각 XRSession은
animation frame을 가지며, 이는 active가 false로,
animationFrame이 true로, 그리고 session이 해당 XRSession으로
설정되어 초기화된 XRFrame이다.
각 XRSession은
허가된 기능 집합을 가지며, 이는 해당 XRSession에
허가된 기능 설명자에 대응하는
DOMString들의 set이다.
enabledFeatures 속성은
허가된 기능 집합의 기능들을 DOMString의 새 배열로 반환한다.
isSystemKeyboardSupported 속성은
XRSystem이
XRSession이
활성 상태인 동안 시스템 키보드를 표시할 수 있음을 나타낸다. isSystemKeyboardSupported가
true이면, 오버레이 키보드를 트리거하는 Web API(예: focus)는 시스템 키보드를
표시한다. XRSession은
키보드가 표시되는 동안 XRSession의
visibility state를 "visible-blurred"로 설정해야 한다.
session, mode, granted, 그리고 device가 주어졌을 때 세션을 초기화하려면, 사용자 에이전트는 다음 단계를 실행해야 한다:
-
session의 mode를 mode로 설정한다.
-
session의 XR 장치를 device로 설정한다.
-
session의 허가된 기능 집합을 granted로 설정한다.
-
렌더 상태를 초기화한다.
-
사용자 에이전트의 다른 기능이 아직 그렇게 하지 않았다면, 필요한 안내를 사용자에게 표시하는 것을 포함하여, 장치의 추적 및 렌더링 기능을 초기화하는 데 필요한 플랫폼별 단계를 수행한다.
참고: 일부 장치는 활성화를 위해 추가적인 사용자 안내가 필요하다. 예를 들어, 휴대폰 기반 헤드셋 장치에서 몰입형 모드로 들어가려면 휴대폰을 헤드셋에 삽입해야 하며, 외부 헤드셋에 연결된 데스크톱 브라우저에서 그렇게 하려면 헤드셋을 착용해야 한다. 이러한 안내가 표시되도록 보장하는 책임은 작성자가 아니라 사용자 에이전트에 있다.
여러 다른 상황에서 세션을
종료할 수 있으며, 이는 영구적이고 되돌릴 수 없다. 세션이
종료된 뒤 XR 장치의 추적 또는
렌더링 기능에 다시 접근하는 유일한 방법은
새 세션을 요청하는 것이다. 각 XRSession은
처음에 false로 설정되는 ended boolean을 가지며, 이는 해당 세션이 종료되었는지를
나타낸다.
XRSession
session이 종료되면 다음 단계가 실행된다:
-
session의 ended 값을
true로 설정한다. -
session을 인라인 세션 목록에서 제거한다.
-
end()가 반환한 promise를 제외하고, session이 반환한 미해결 promise를 모두InvalidStateError로 Reject한다. -
사용자 에이전트의 다른 기능이 이를 능동적으로 사용하고 있지 않다면, 장치의 추적 및 렌더링 기능을 종료하는 데 필요한 플랫폼별 단계를 수행한다. 여기에는 다음이 포함되어야 한다:
-
XRSessionEvent를end라는 이름으로 session에서 발생시키는 작업을 큐에 넣는다.
end() 메서드는 세션을 수동으로 종료하는 방법을 제공한다.
호출되면 다음 단계를 실행해야 한다:
-
this의 ended 값이
true이면, promise를 "InvalidStateError"DOMException으로 reject하고 promise를 반환한다. -
다음 단계를 수행하도록 작업을 큐에 넣는다:
-
세션 종료와 관련된 모든 플랫폼별 단계가 완료될 때까지 기다린다.
-
promise를 Resolve한다.
-
-
promise를 반환한다.
각 XRSession은
새 XRRenderState인 활성 렌더 상태와, 처음에는
null인 XRRenderState인 대기 중인 렌더 상태를 가진다.
renderState 속성은 XRSession의
활성 렌더
상태를 반환한다.
각 XRSession은
라디안 단위로 정의되는 최소
인라인 시야각과 최대 인라인 시야각을 가진다.
값은 사용자 에이전트가 결정해야 하며 0에서 PI 범위에 있어야 한다.
각 XRSession은
미터 단위로 정의되는 최소 near
clip plane과 최대 far clip plane을 가진다.
값은 사용자 에이전트가 결정해야 하며 음수가 아니어야 한다. 최소 near clip plane은
0.1보다 작아야 한다. 최대 far clip plane은 1000.0보다 커야 한다
(그리고 무한대일 수 있다).
사용자 에이전트가 XRSession
session 및 XRRenderStateInit
newState로 대기 중인 레이어 상태를 갱신하려고 할 때, 다음 단계를 실행해야 한다:
-
newState의
layers값이null이 아니면,NotSupportedError를 throw한다.
참고: WebXR layers module은 이 알고리즘에 새로운 의미를 도입할 것이다.
사용자 에이전트가 XRSession
session에 명목 프레임 속도 rate를 적용하려고 할 때, 다음 단계를 실행해야 한다:
-
rate가 session의 내부 명목 프레임 속도와 같으면, 이 단계를 중단한다.
-
session의 ended 값이
true이면, 이 단계를 중단한다. -
session의 내부 명목 프레임 속도를 rate로 설정한다.
-
XRSessionEvent이벤트를frameratechange라는 이름으로 session에서 발생시킨다.
updateTargetFrameRate(rate)
메서드는 목표 프레임 속도
rate를 XRSession에
전달한다.
이 메서드가 호출되면, 사용자 에이전트는 다음 단계를 실행해야 한다:
-
session을 this로 둔다.
-
session에 내부 명목 프레임 속도가 없으면, promise를 "
InvalidStateError"DOMException으로 reject하고 promise를 반환한다. -
session의 ended 값이
true이면, promise를 "InvalidStateError"DOMException으로 reject하고 promise를 반환한다. -
rate가
supportedFrameRates에 없으면, promise를 "TypeError"DOMException으로 reject하고 promise를 반환한다. -
session의 내부 목표 프레임 속도를 rate로 설정한다.
-
다음 단계를 수행하도록 작업을 큐에 넣는다:
-
XR Compositor는 rate를 사용하여 새 디스플레이 프레임 속도 및/또는 명목 프레임 속도를 계산할 수 있다.
-
newrate를 새 명목 프레임 속도로 둔다.
-
다음 단계를 수행하도록 작업을 큐에 넣는다:
-
newrate 및 session으로 명목 프레임 속도를 적용한다.
-
promise를 Resolve한다.
-
-
promise를 반환한다.
XR Compositor가 어떤
이유로든(예: "visible-blurred" 이벤트 중)
명목 프레임
속도를 변경하는 경우, 프레임 속도 변경을 일으킨 이벤트가 종료되면 내부 목표 프레임
속도를 사용해야 한다.
updateRenderState(newState)
메서드는 다음 프레임에 적용될 활성 렌더 상태 갱신을 큐에 넣는다. 이 메서드에 전달된 XRRenderStateInit
newState의 설정되지 않은 필드는 변경되지 않는다.
이 메서드가 호출되면, 사용자 에이전트는 다음 단계를 실행해야 한다:
-
session을 this로 둔다.
-
session의 ended 값이
true이면,InvalidStateError를 throw하고 이 단계를 중단한다. -
newState의
baseLayer가 session이 아닌XRSession으로 생성된 경우,InvalidStateError를 throw하고 이 단계를 중단한다. -
newState의
inlineVerticalFieldOfView가 설정되어 있고 session이 몰입형 세션인 경우,InvalidStateError를 throw하고 이 단계를 중단한다. -
newState의
depthNear,depthFar,inlineVerticalFieldOfView,baseLayer,layers중 어느 것도 설정되어 있지 않으면, 이 단계를 중단한다. -
session 및 newState로 대기 중인 레이어 상태 갱신을 실행한다.
-
activeState를 session의 활성 렌더 상태로 둔다.
-
session의 대기 중인 렌더 상태가
null이면, 이를 activeState의 복사본으로 설정한다. -
newState의
passthroughFullyObscured값이 설정되어 있으면, session의 대기 중인 렌더 상태의passthroughFullyObscured를 newState의passthroughFullyObscured로 설정한다. -
newState의
depthNear값이 설정되어 있으면, session의 대기 중인 렌더 상태의depthNear를 newState의depthNear로 설정한다. -
newState의
depthFar값이 설정되어 있으면, session의 대기 중인 렌더 상태의depthFar를 newState의depthFar로 설정한다. -
newState의
inlineVerticalFieldOfView가 설정되어 있으면, session의 대기 중인 렌더 상태의inlineVerticalFieldOfView를 newState의inlineVerticalFieldOfView로 설정한다. -
newState의
baseLayer가 설정되어 있으면, session의 대기 중인 렌더 상태의baseLayer를 newState의baseLayer로 설정한다.
요청되면, XRSession
session은 다음 단계를 실행하여 대기 중인 렌더 상태를 적용해야 한다:
-
activeState를 session의 활성 렌더 상태로 둔다.
-
newState를 session의 대기 중인 렌더 상태로 둔다.
-
session의 대기 중인 렌더 상태를
null로 설정한다. -
oldBaseLayer를 activeState의
baseLayer로 둔다. -
oldLayers를 activeState의
layers로 둔다. -
다음 단계를 수행하도록 작업을 큐에 넣는다:
-
activeState를 newState로 설정한다.
-
oldBaseLayer가 activeState의
baseLayer와 같지 않거나, oldLayers가 activeState의layers와 같지 않거나, 레이어 중 어느 하나의 치수가 변경되었다면, session에 대해 뷰포트를 갱신한다. -
activeState의
inlineVerticalFieldOfView가 session의 최소 인라인 시야각보다 작으면, activeState의inlineVerticalFieldOfView를 session의 최소 인라인 시야각으로 설정한다. -
activeState의
inlineVerticalFieldOfView가 session의 최대 인라인 시야각보다 크면, activeState의inlineVerticalFieldOfView를 session의 최대 인라인 시야각으로 설정한다. -
activeState의
depthNear가 session의 최소 near clip plane보다 작으면, activeState의depthNear를 session의 최소 near clip plane으로 설정한다. -
activeState의
depthFar가 session의 최대 far clip plane보다 크면, activeState의depthFar를 session의 최대 far clip plane으로 설정한다. -
baseLayer를 activeState의
baseLayer로 둔다. -
activeState의 composition enabled와 output canvas를 다음과 같이 설정한다:
- session이 인라인 세션이고 baseLayer가
composition enabled가
false로 설정된XRWebGLLayer의 인스턴스인 경우: -
activeState의 composition enabled boolean을
false로 설정한다.activeState의 output canvas를 baseLayer의 context의
canvas로 설정한다. - 그렇지 않은 경우:
-
activeState의 composition enabled boolean을
true로 설정한다.activeState의 output canvas를
null로 설정한다.
- session이 인라인 세션이고 baseLayer가
composition enabled가
-
requestReferenceSpace(type)
메서드는 가능한 경우 주어진 type의 새 XRReferenceSpace를 구성한다.
이 메서드가 호출되면, 사용자 에이전트는 다음 단계를 실행해야 한다:
-
다음 단계를 in parallel로 실행한다:
-
type과 session에 대해 reference space is supported를 실행한 결과가
false이면, promise를NotSupportedError로 reject하도록 작업을 큐에 넣고 이 단계를 중단한다. -
type 유형의 참조 공간을 추적하는 데 필요한 플랫폼 리소스를 설정한다.
사용자 에이전트는 이러한 참조 공간에 대한 추적이 수립될 때까지requestReferenceSpace()를 resolve하기를 기다릴 필요가 없다. 세션이 처음 추적을 수립하려고 시도하는 동안getViewerPose()가null을 반환해도 괜찮으며, 콘텐츠는 이 시간을 사용하여 스플래시 화면이나 다른 것을 표시할 수 있다. type이"bounded-floor"이고 경계가 아직 수립되지 않은 경우, 사용자 에이전트는 경계를 작은 초기 영역으로 설정하고 경계가 수립될 때reset이벤트를 사용할 수 있음에 유의하라. -
다음 단계를 실행하도록 작업을 큐에 넣는다:
-
type 및 session으로 참조 공간을 생성하고, referenceSpace로 둔다.
-
promise를 referenceSpace로 Resolve한다.
-
-
promise를 반환한다.
각 XRSession은
활성
XR 입력 소스 목록(XRInputSource의
list)과 활성 XR 추적 소스
목록(XRInputSource의
list)을 가지며, 둘 다
처음에는 빈 list여야 한다.
각 XRSession은
초기화 시 설정되는 XR 장치인 XR 장치를 가진다.
inputSources 속성은 XRSession의
활성 XR 입력 소스 목록을 반환한다.
trackedSources 속성은 XRSession의
활성 XR 추적 소스 목록을 반환한다. 활성 XR 추적 소스
목록은
tracked-sources가 허가된 기능 집합에
포함되어 있는 경우에만 채워져야 한다.
사용자 에이전트는 XR 장치와 관련된 모든 XR 입력 소스를 모니터링해야 하며, 여기에는 XR 입력 소스가 추가, 제거 또는 변경되는 때를 감지하는 것이 포함된다.
각 XRSession은
처음에는 false인 promise resolved 플래그를 가진다.
참고: 이 플래그의 목적은 사용자 코드가 실제로 이벤트 리스너를 연결할 기회를 얻기 전까지 입력 소스 추가, 입력 소스 제거, 및 입력 소스 변경 알고리즘이 실행되지 않도록 보장하는 것이다. 구현은 세션이 resolve된 후 입력 소스 변경을 듣기 시작하도록 선택한다면 이 플래그가 필요하지 않을 수 있다.
XRSession
session에 대해 새로운 XR 입력 소스가 사용
가능해지면, 사용자 에이전트는 다음 단계를 실행해야 한다:
-
session의 promise resolved 플래그가 설정되어 있지 않으면, 이 단계를 중단한다.
-
added primary sources를 새 list로 둔다.
-
added tracked sources를 새 list로 둔다.
-
각 새 XR 입력 소스에 대해:
-
inputSource를 이
XRSession의 관련 realm에 있는XRInputSource새 객체로 두고, 다음 단계를 수행한다:- inputSource가 기본 입력 소스인 경우:
-
inputSource를 added primary sources에 추가한다.
- 그렇지 않고, tracked-sources가 session의 허가된 기능 집합에 포함되어 있는 경우:
-
inputSource를 added tracked sources에 추가한다.
-
-
다음 단계를 수행하도록 작업을 큐에 넣는다:
-
session의 활성 XR 입력 소스 목록을 added primary sources로 Extend한다.
-
added primary sources가 비어 있지 않으면,
XRInputSourcesChangeEvent를inputsourceschange라는 이름으로 session에서 발생시키되,added를 added primary sources로 설정한다. -
session의 활성 XR 추적 소스 목록을 added tracked sources로 Extend한다.
-
added tracked sources가 비어 있지 않으면,
XRInputSourcesChangeEvent를trackedsourceschange라는 이름으로 session에서 발생시키되,added를 added tracked sources로 설정한다.
-
XRSession
session에 대해 이전에 추가된 XR 입력 소스가
더 이상 사용 가능하지 않게 되면,
사용자 에이전트는 다음 단계를 실행해야 한다:
-
session의 promise resolved 플래그가 설정되어 있지 않으면, 이 단계를 중단한다.
-
removed primary sources를 새 list로 둔다.
-
removed tracked sources를 새 list로 둔다.
-
더 이상 사용 가능하지 않은 각 XR 입력 소스에 대해:
-
inputSource를 해당 XR 입력 소스와 관련되어 있던, session의 활성 XR 입력 소스 목록 안의
XRInputSource로 두고, 다음 단계를 수행한다:- inputSource가 기본 입력 소스인 경우:
-
inputSource를 removed primary sources에 추가한다.
- 그렇지 않고, tracked-sources가 session의 허가된 기능 집합에 포함되어 있는 경우:
-
inputSource를 removed tracked sources에 추가한다.
-
-
다음 단계를 수행하도록 작업을 큐에 넣는다:
-
removed primary sources 안의 각
XRInputSource를 session의 활성 XR 입력 소스 목록에서 Remove한다. -
removed primary sources가 비어 있지 않으면,
XRInputSourcesChangeEvent를inputsourceschange라는 이름으로 session에서 발생시키되,removed를 removed primary sources로 설정한다. -
removed tracked sources 안의 각
XRInputSource를 session의 활성 XR 추적 소스 목록에서 Remove한다. -
removed tracked sources가 비어 있지 않으면,
XRInputSourcesChangeEvent를trackedsourceschange라는 이름으로 session에서 발생시키되,removed를 removed tracked sources로 설정한다.
-
참고: 사용자 에이전트는 입력 소스가 위치 및 방향 추적을 일시적으로 모두 잃었을 때 이 이벤트를 발생시킬 수 있다. 이는 물리적 핸드헬드 컨트롤러 입력 소스에 대해서만 수행하는 것이 권장된다. 추적되는 손 입력 소스에 대해 이러한 일이 발생할 때는 자주 발생하므로 이 이벤트를 발생시키는 것은 권장되지 않으며, 트래커 객체 입력 소스에 대해 이러한 일이 발생할 때도 애플리케이션이 정체성의 개념을 유지하기 더 어렵게 만들기 때문에 권장되지 않는다.
XRSession
session에 대해 어떤 XR 입력 소스의 handedness,
targetRayMode,
profiles,
gripSpace의 존재 여부,
또는 기본 입력
소스 혹은 추적 입력 소스로서의 상태가
변경되면, 사용자 에이전트는 다음 단계를 실행해야 한다:
-
session의 promise resolved 플래그가 설정되어 있지 않으면, 이 단계를 중단한다.
-
added primary sources를 새 list로 둔다.
-
removed primary sources를 새 list로 둔다.
-
added tracked sources를 새 list로 둔다.
-
removed tracked sources를 새 list로 둔다.
-
변경된 각 XR 입력 소스에 대해:
-
oldInputSource를 해당 XR 입력 소스와 이전에 관련되어 있던, session의 활성 XR 입력 소스 목록 안의
XRInputSource로 두고, 다음 단계를 수행한다:- oldInputSource가 기본 입력 소스이거나 그 상태가 기본 입력 소스에서 추적 입력 소스로 변경된 경우:
-
oldInputSource를 removed primary sources에 추가한다.
- 그렇지 않고, tracked-sources가 session의 허가된 기능 집합에 포함되어 있는 경우:
-
oldInputSource를 removed tracked sources에 추가한다.
-
newInputSource를 session의 관련 realm에 있는
XRInputSource새 객체로 두고, 다음 단계를 수행한다:- newInputSource가 기본 입력 소스이거나 그 상태가 추적 입력 소스에서 기본 입력 소스로 변경된 경우:
-
newInputSource를 added primary sources에 추가한다.
- 그렇지 않고, tracked-sources가 session의 허가된 기능 집합에 포함되어 있는 경우:
-
newInputSource를 added tracked sources에 추가한다.
-
-
다음 단계를 수행하도록 작업을 큐에 넣는다:
-
removed primary sources 안의 각
XRInputSource를 session의 활성 XR 입력 소스 목록에서 Remove한다. -
session의 활성 XR 입력 소스 목록을 added primary sources로 Extend한다.
-
added primary sources 또는 removed primary sources가 비어 있지 않으면,
XRInputSourcesChangeEvent를inputsourceschange라는 이름으로 session에서 발생시키되,added를 added primary sources로 설정하고removed를 removed primary sources로 설정한다. -
removed tracked sources 안의 각
XRInputSource를 session의 활성 XR 추적 소스 목록에서 Remove한다. -
session의 활성 XR 입력 소스 목록을 added tracked sources로 Extend한다.
-
added tracked sources 또는 removed tracked sources가 비어 있지 않으면,
XRInputSourcesChangeEvent를trackedsourceschange라는 이름으로 session에서 발생시키되,added를 added tracked sources로 설정하고removed를 removed tracked sources로 설정한다.
-
각 XRSession은
enum인 visibility state 값을 가진다. 인라인 세션의 경우
visibility state는 Document의 visibilityState를 반영해야 한다. 몰입형 세션의 경우
visibility state는 세션의 상태와 가장 잘 일치하는 다음 값 중 하나로
설정되어야 한다.
-
visible상태는XRSession이 렌더링한 이미지를 사용자가 볼 수 있으며,requestAnimationFrame()콜백이 XR 장치의 네이티브 새로고침 속도로 처리됨을 나타낸다. 입력은XRSession에 의해 정상적으로 처리된다. -
visible-blurred상태는XRSession이 렌더링한 이미지를 사용자가 볼 수는 있지만, 그것이 주된 초점은 아님을 나타낸다.requestAnimationFrame()콜백은 스로틀링될 수 있다. 입력은XRSession에 의해 처리되지 않는다. -
hidden상태는XRSession이 렌더링한 이미지를 사용자가 볼 수 없음을 나타낸다.requestAnimationFrame()콜백은 visibility state가 변경될 때까지 처리되지 않는다. 입력은XRSession에 의해 처리되지 않는다.
visibilityState 속성은 XRSession의
visibility state를 반환한다. onvisibilitychange 속성은 visibilitychange 이벤트 유형을 위한
이벤트 핸들러 IDL 속성이다.
visibility state는 XR animation frame을 처리하는 중이 아닌 때라면 언제든지 사용자 에이전트에 의해 변경될 수 있으며, 사용자 에이전트는 가능할 때 XR 플랫폼을 모니터링하여 세션 가시성이 사용자 에이전트 외부에서 영향을 받은 시점을 관찰하고 그에 따라 visibility state를 갱신해야 한다.
참고: XRSession의
visibility state가 반드시 HTML 문서의 가시성을 의미하는 것은 아니다.
시스템 구성에 따라 몰입형 세션이 활성
상태인 동안에도 페이지가 계속 보일 수 있다.
(예를 들어 PC에 연결된 헤드셋은 헤드셋이 몰입형 세션의 콘텐츠를 보는 동안에도 모니터에 페이지를 계속 표시할 수
있다.) 개발자는 페이지 가시성을 결정하기 위해 계속 Page Visibility에
의존해야 한다.
참고: XRSession의
visibility state는 몰입형 세션이 활성 상태인 동안에도 2D 콘텐츠가
여전히 보이는 테더링된 세션에서 마우스 동작에 영향을 주거나 이를 제한하지 않는다. 콘텐츠가 마우스 동작을 더 강하게
제어하고자 한다면 [pointerlock]
API 사용을 고려해야 한다.
XRSystem에는
프레임 속도를 설명할 수 있는 여러 정의가 있다:
-
명목 프레임 속도:
XRSystem이 명목 성능을 유지하기 위해 경험이 프레임을 렌더링하도록 요구하는 속도이다. 프레임을 놓치는 경험은 실제로 초당 이 횟수만큼requestAnimationFrame()호출을 받지 못할 수 있지만, 이것이XRSystem이 달성하려는 목표이다. -
유효 프레임 속도: 경험이 실제로 매초 처리하고 있는
requestAnimationFrame()호출 수에 대한 성능 측정이다. 이는 경험이XRSystem의 프레임 타이밍을 맞추는지 놓치는지에 따라 변동된다. -
목표 프레임 속도: 경험이 목표로 삼기를 선호하는 명목 프레임 속도가 무엇인지
XRSystem에 제공하는 힌트이다. -
디스플레이 프레임 속도: 프레임이 물리적 디스플레이에 그려지는 실제 속도이며, 경험의 명목 프레임 속도에서 파생될 수 있다. 이는 경험에 노출되지 않는 하드웨어 구현 세부 사항이다.
각 XRSession은
목표 프레임 속도인
internal target frameRate를 가질 수 있다.
각 XRSession은
명목 프레임 속도인
internal nominal frameRate를 가질 수 있다.
유효
프레임 속도가 명목 프레임
속도보다 낮으면, XR
Compositor는 경험을 개선하기 위해 reprojection 또는
기타 기법을 사용할 수 있다. 이는 선택 사항이며 인라인
세션에는 존재해서는 안 된다.
frameRate 속성은 내부
명목 프레임 속도를 반영한다. XRSession에
내부 명목 프레임 속도가 없으면
null을 반환한다.
onframeratechange 속성은 frameratechange 이벤트 유형을 위한
이벤트 핸들러 IDL 속성이다. 어떤 이유로든 XRSession의
명목 프레임 속도가
변경되면, 새 명목 프레임 속도 및 해당 XRSession으로
명목
프레임 속도를 적용해야 한다.
supportedFrameRates 속성은 지원되는
목표 프레임
속도 값의 목록을 반환한다. 이 속성은 선택 사항이며 인라인 세션이나 작성자가 프레임 속도를 제어하도록 허용하지
않는 XRSystem에는
존재해서는 안 된다. XRSession이
supportedFrameRates
속성을 지원한다면, frameRate도 지원해야 한다.
각 XRSession은
identity
transform origin offset을 가진 "viewer" 유형의 XRReferenceSpace인 viewer
reference space를 가진다.
각 XRSession은
XR 장치가 제공하는 뷰에
대응하는 view의 list인 뷰 목록을 가진다.
뷰 목록은
XRSession
동안 불변이며, 처음에는 active가
아닐 수 있는 보조 뷰를 포함하여 세션 중 노출될 수
있는 모든 뷰를 포함해야 한다.
뷰
목록의 기본 뷰는
XRSession의
mode 및 허가된 기능 집합에 의해 결정되어야 한다:
-
inline-stereo가 자신의 허가된 기능 집합에 포함되지 않은
"inline"세션의 경우, 뷰 목록은"none"인 eye를 가진 단일 기본 뷰를 포함해야 한다. -
inline-stereo가 자신의 허가된 기능 집합에 포함된
"inline"세션의 경우, 뷰 목록은 두 개의 기본 뷰를 포함해야 하며, 하나의 eye는"left"이고 다른 하나의 eye는"right"이다.
onend 속성은 end 이벤트 유형을 위한 이벤트 핸들러 IDL 속성이다.
oninputsourceschange 속성은 inputsourceschange 이벤트 유형을 위한
이벤트 핸들러 IDL 속성이다.
onselectstart 속성은 selectstart 이벤트 유형을 위한 이벤트 핸들러 IDL 속성이다.
onselectend 속성은 selectend 이벤트 유형을 위한 이벤트 핸들러 IDL 속성이다.
onselect 속성은 select 이벤트 유형을 위한 이벤트 핸들러 IDL 속성이다.
onsqueezestart 속성은 squeezestart 이벤트 유형을 위한 이벤트 핸들러 IDL 속성이다.
onsqueezeend 속성은 squeezeend 이벤트 유형을 위한 이벤트 핸들러 IDL 속성이다.
onsqueeze 속성은 squeeze 이벤트 유형을 위한 이벤트 핸들러 IDL 속성이다.
4.2. XRRenderState
XRRenderState는
XRSession의
출력이 합성되는 방식에 영향을 주는 구성 가능한 값들의 집합을 나타낸다. 주어진 XRSession의
활성 렌더 상태는 프레임 경계
사이에서만 변경될 수 있으며,
갱신은 updateRenderState()를
통해 큐에 넣을 수 있다.
dictionary {XRRenderStateInit double ;depthNear double ;depthFar boolean ;passthroughFullyObscured double ;inlineVerticalFieldOfView XRWebGLLayer ?;baseLayer sequence <XRLayer >?; }; [layers SecureContext ,Exposed =Window ]interface {XRRenderState readonly attribute double depthNear ;readonly attribute double depthFar ;readonly attribute boolean ?passthroughFullyObscured ;readonly attribute double ?inlineVerticalFieldOfView ;readonly attribute XRWebGLLayer ?baseLayer ; };
각 XRRenderState는
처음에 null로 설정되는 HTMLCanvasElement인
출력 캔버스를 가진다. 출력 캔버스는 인라인
세션에 대해 렌더링된 모든 콘텐츠를 표시할 DOM 요소이다.
각 XRRenderState는
또한 처음에는 true인 composition enabled boolean을 가진다. API가 제공하고
XR Compositor가 표시하는
표면에 대해 렌더링 명령이 수행되는 경우, XRRenderState는
composition enabled를 가진 것으로 간주된다. 렌더링이
인라인 세션에 대해
출력
캔버스 안에 직접 표시되는 방식으로 수행되는 경우,
XRRenderState의
composition enabled 플래그는 false여야 한다.
참고: 이 시점에서 XRRenderState는
composition
enabled가 false로 설정된 경우에만 출력 캔버스를 가지지만, 향후 명세 버전에서는 미러링 및 레이어 합성과 같은
더 고급 사용을 지원하고 composition이 필요한 출력 캔버스를 설정하는 메서드가 도입될 가능성이 높다.
XRRenderState
객체가 XRSession
session을 위해 생성될 때, 사용자 에이전트는 다음 단계를 실행하여 렌더 상태를 초기화해야 한다:
-
state를 session의 관련 realm에 있는
XRRenderState새 객체로 둔다. -
state의
depthNear를0.1로 초기화한다. -
state의
depthFar를1000.0로 초기화한다. -
state의
passthroughFullyObscured를false로 초기화한다. -
state의
inlineVerticalFieldOfView를 다음과 같이 초기화한다:- session이 인라인 세션인 경우:
-
state의
inlineVerticalFieldOfView를PI * 0.5로 초기화한다. - 그렇지 않은 경우:
-
state의
inlineVerticalFieldOfView를null로 초기화한다.
-
state의
baseLayer를null로 초기화한다.
depthNear 속성은 viewer로부터
near clip plane까지의 거리를 미터 단위로 정의한다. depthFar 속성은 viewer로부터
far clip plane까지의 거리를 미터 단위로 정의한다.
depthNear
및 depthFar는
XRView의
projectionMatrix
계산에 사용된다. 렌더링 중 projectionMatrix가
사용될 때, viewer까지의 거리가 depthNear와
depthFar
사이에 있는 지오메트리만 그려진다. 또한 이들은 XRWebGLLayer
깊이 버퍼의 값이 해석되는 방식을 결정한다. depthNear는
depthFar보다
클 수 있다.
참고: 일반적으로 렌더링을 위한 원근 투영 행렬을 구성할 때 개발자는 viewing frustum과 near 및 far clip plane을 지정한다. 몰입형 XR 장치에 표시할 때 올바른 viewing frustum은 사용되는 광학 장치, 디스플레이 및 카메라의 어떤 조합에 의해 결정된다. 그러나 near 및 far clip plane은 렌더링되는 콘텐츠의 유형에 따라 적절한 값이 달라지므로 애플리케이션이 수정할 수 있다.
passthroughFullyObscured 속성은
작성자가 뷰포트를 가상 콘텐츠로 완전히 덮으려는 의도를 나타내기 위해 XRSystem에
제공하는 힌트이다. 작성자는 뷰포트가 더 이상 불투명 픽셀로 덮이지 않으면 이 플래그를 false로 다시
설정해야 한다.
참고: XRSystem은
이를 passthrough를 일시적으로 비활성화하기 위한 힌트로 사용할 수 있다. see-through 광학 장치가 있는 장치에서는
사용자가 계속 자신의 환경을 보게 되며 이 플래그는 영향을 주지 않는다.
inlineVerticalFieldOfView 속성은
"inline"
XRSession에
대해 투영 행렬을 계산할 때 사용되는 기본 수직 시야각을 라디안 단위로 정의한다. 투영 행렬 계산은
출력
캔버스의
종횡비도 고려한다. inline-stereo가 활성화된 인라인 세션의 경우,
사용자 에이전트는 출력 캔버스 지오메트리를 사용하여 뷰별 투영 행렬을 계산해야 한다.
이 값은 몰입형 세션에서는
null이어야 한다.
baseLayer 속성은 XR compositor가
이미지를 가져올 XRWebGLLayer를
정의한다.
4.3. 애니메이션 프레임
XRSession이
XR 장치의 추적 상태에 대한
정보를 제공하는 주된 방법은
XRSession
인스턴스에서 requestAnimationFrame()을
호출하여 예약된 콜백을 통하는 것이다.
callback =XRFrameRequestCallback undefined (DOMHighResTimeStamp ,time XRFrame );frame
각 XRFrameRequestCallback
객체는 처음에 false로 설정되는 cancelled boolean을 가진다.
각 XRSession은
처음에는 비어 있는 애니메이션 프레임
콜백 목록, 역시 처음에는 비어 있는 현재 실행 중인
애니메이션 프레임 콜백 목록, 그리고 처음에는 0인 숫자인 애니메이션
프레임 콜백 식별자를 가진다.
requestAnimationFrame(callback)
메서드는 사용자 에이전트가 다음에 장치에 대해 애니메이션 프레임을 실행하려고 할 때 callback이
실행되도록 큐에 넣는다.
이 메서드가 호출되면, 사용자 에이전트는 다음 단계를 실행해야 한다:
-
session을 this로 둔다.
-
session의 ended 값이
true이면,0을 반환하고 이 단계를 중단한다. -
session의 애니메이션 프레임 콜백 식별자를 1 증가시킨다.
-
callback을 session의 애니메이션 프레임 콜백 목록에 추가하되, session의 애니메이션 프레임 콜백 식별자의 현재 값과 연결한다.
-
session의 애니메이션 프레임 콜백 식별자의 현재 값을 반환한다.
cancelAnimationFrame(handle)
메서드는 주어진 애니메이션 프레임 콜백 식별자
handle에 해당하는 기존 애니메이션 프레임 콜백을 취소한다.
이 메서드가 호출되면, 사용자 에이전트는 다음 단계를 실행해야 한다:
-
session을 this로 둔다.
-
session의 애니메이션 프레임 콜백 목록 또는 session의 현재 실행 중인 애니메이션 프레임 콜백 목록에서 handle 값과 연결된 항목을 찾는다.
-
그러한 항목이 있다면, 그 항목의 cancelled boolean을
true로 설정하고 session의 애니메이션 프레임 콜백 목록에서 제거한다.
renderState
state로 레이어
상태를 확인하려면, 사용자 에이전트는 다음 단계를 실행해야 한다:
-
state의
baseLayer가null이면,false를 반환한다. -
true를 반환한다.
참고: WebXR layers module은 이 알고리즘에 새로운 의미를 도입할 것이다.
XRSession
session에 대해 프레임이 렌더링되어야 하는지 판단하려면, 사용자 에이전트는 다음 단계를 실행해야 한다:
-
session의
renderState로 레이어 상태 확인을 수행한 결과가false이면,false를 반환한다. -
session이 인라인 세션이고 session의
renderState의 출력 캔버스가null이면,false를 반환한다. -
true를 반환한다.
XRSession
session이 XR 장치로부터
timestamp frameTime에 대한 갱신된 viewer 상태를 받으면, XR
animation frame을 실행하며, 이는 애니메이션 프레임 콜백 목록이 비어 있는지 여부와 관계없이
다음 단계를 실행해야 한다:
-
다음 단계를 수행하도록 작업을 큐에 넣는다:
-
now를 현재 고해상도 시간으로 둔다.
-
frame을 session의 animation frame으로 둔다.
-
frame의 time을 frameTime으로 설정한다.
-
frame의
predictedDisplayTime을 frameTime으로 설정한다. -
session이 몰입형 세션이면, frame의
predictedDisplayTime을 XR Compositor가 이 XR animation frame을 표시할 것으로 예상되는 평균 timestamp로 설정한다. -
뷰 목록의 각 view에 대해, view의 viewport modifiable 플래그를 true로 설정한다.
-
뷰 목록 안의 어떤 view의 active 플래그가 마지막 XR animation frame 이후 변경되었다면, 뷰포트를 갱신한다.
-
session에 대해 프레임이 렌더링되어야 한다면:
-
session의 현재 실행 중인 애니메이션 프레임 콜백 목록을 session의 애니메이션 프레임 콜백 목록으로 설정한다.
-
session의 애니메이션 프레임 콜백 목록을 빈 목록으로 설정한다.
-
frame의 active boolean을
true로 설정한다. -
frame에 대해 프레임 갱신을 적용한다.
-
session의 현재 실행 중인 애니메이션 프레임 콜백 목록 안의 각 entry에 대해, 순서대로:
-
entry의 cancelled boolean이
true이면, 다음 항목으로 계속한다. -
entry를 « now, frame » 및 "
report"로 Invoke한다. -
session의 현재 실행 중인 애니메이션 프레임 콜백 목록을 빈 list로 설정한다.
-
frame의 active boolean을
false로 설정한다.
-
-
session의 대기 중인 렌더 상태가
null이 아니면, 대기 중인 렌더 상태를 적용한다.
-
Window
인터페이스의 requestAnimationFrame()
메서드의 동작은 활성 XRSession의
존재로 변경되지 않으며, 어떤 XRSession에서
requestAnimationFrame()을
호출해도 Window의
requestAnimationFrame()과
어떤 식으로도 상호작용하지 않는다. 활성 몰입형 세션은 페이지가 가려지게 하는 경우
브라우징 컨텍스트의 렌더링 기회에 영향을 줄 수 있다. 활성 몰입형 세션 동안 2D 브라우저 뷰가 보이는
경우
(즉, 세션이 테더링된 헤드셋에서 실행 중인 경우), Window의
requestAnimationFrame()
및 requestIdleCallback()으로
실행되는 콜백의 타이밍은 세션의 requestAnimationFrame()과
일치하지 않을 수 있으며, 사용자는 XR 콘텐츠 렌더링을 위해 이에 의존해서는 안 된다.
참고: 활성 몰입형 세션이
브라우징 컨텍스트의 렌더링 기회에 영향을 주는 경우 이러한 콜백은 발생이 보장되지 않으며,
실행되더라도 올바른 타이밍을 가지지 않을 수 있으므로, 사용자 에이전트는 Window의
requestAnimationFrame()을
통해 예약된 콜백 중에 XRSession의
requestAnimationFrame()이
호출되면 개발자 콘솔에 경고를 표시하기를 원할 수 있다.
Window
requestAnimationFrame()에
제공된 콜백은 세션이 활성인 동안 처리되지 않을 수 있다. 이는 사용되는 장치의 유형에 따라 달라지며, 몰입형 콘텐츠가
HTML 문서를 완전히 가리는 모바일 또는 독립형 장치에서 발생할 가능성이 가장 높다. 따라서 개발자는 동일한 렌더링
로직을 공유하더라도 XRSession
requestAnimationFrame()
콜백을 예약하기 위해 Window
requestAnimationFrame()
콜백에 의존해서는 안 되며, 그 반대도 마찬가지이다. 이 지침을 따르지 않는 애플리케이션은 모든 플랫폼에서 제대로
실행되지 않을 수 있다. 이러한 두 유형의 애니메이션 루프 사이를 전환하려는 애플리케이션을 위한 더 효과적인 패턴은
아래에示되어 있다:
let xrSession= null ; function onWindowAnimationFrame( time) { window. requestAnimationFrame( onWindowAnimationFrame); // This may be called while an immersive session is running on some devices, // such as a desktop with a tethered headset. To prevent two loops from // rendering in parallel, skip drawing in this one until the session ends. if ( ! xrSession) { renderFrame( time, null ); } } // The window animation loop can be started immediately upon the page loading. window. requestAnimationFrame( onWindowAnimationFrame); function onXRAnimationFrame( time, xrFrame) { xrSession. requestAnimationFrame( onXRAnimationFrame); renderFrame( xrFrame. predictedDisplayTime, xrFrame); } function renderFrame( time, xrFrame) { // Shared rendering logic. } // Assumed to be called by a user gesture event elsewhere in code. async function startXRSession() { xrSession= await navigator. xr. requestSession( 'immersive-vr' ); xrSession. addEventListener( 'end' , onXRSessionEnded); // Do necessary session setup here. // Begin the session's animation loop. xrSession. requestAnimationFrame( onXRAnimationFrame); } function onXRSessionEnded() { xrSession= null ; }
HTML 문서로 렌더링하기 위해 인라인 세션을 사용하는 애플리케이션은 애니메이션 루프를 조정하기 위해 별도의 특별한 단계를 수행할 필요가 없다. 사용자 에이전트가 몰입형 세션이 활성인 동안 모든 인라인 세션의 애니메이션 루프를 자동으로 일시 중단하기 때문이다.
4.4. XR Compositor
사용자 에이전트는 XR 장치로의 프레젠테이션과 프레임 타이밍을 처리하는 XR Compositor를 유지해야 한다. compositor는 문서가 생성한 어떤 그래픽 컨텍스트의 상태와도 격리된 독립적인 렌더링 컨텍스트를 사용해야 한다. compositor는 페이지가 compositor 상태를 훼손하거나 다른 페이지 또는 애플리케이션의 콘텐츠를 다시 읽는 것을 방지해야 한다. 또한 compositor는 별도의 스레드 또는 프로세스에서 실행되어, 페이지의 성능과 적절한 프레임 속도로 사용자에게 새 이미지를 제시할 수 있는 능력을 분리해야 한다. compositor는 장치 메뉴와 같은 추가 장치 또는 사용자 에이전트 UI를 렌더링된 콘텐츠 위에 합성할 수 있다.
참고: 이 명세의 향후 확장은 같은 페이지에서 오는 여러 레이어를 합성하기 위해 compositor를 활용할 수도 있다.
5. 프레임 루프
5.1. XRFrame
XRFrame은
XRSession에
대해
추적되는 모든 객체 상태의 스냅샷을 나타낸다. 애플리케이션은 XRFrameRequestCallback과
함께 XRSession에서
requestAnimationFrame()을
호출하여 XRFrame을 획득할
수
있다. 콜백이 호출될 때 XRFrame이 전달된다.
select
이벤트와 같이 추적 상태를 전달해야 하는 이벤트도 XRFrame을 제공한다.
[SecureContext ,Exposed =Window ]interface { [XRFrame SameObject ]readonly attribute XRSession session ;readonly attribute DOMHighResTimeStamp predictedDisplayTime ;XRViewerPose ?getViewerPose (XRReferenceSpace );referenceSpace XRPose ?getPose (XRSpace ,space XRSpace ); };baseSpace
각 XRFrame은
처음에 false로 설정되는 active boolean과, 처음에 false로 설정되는 animationFrame boolean을 가진다.
session 속성은 XRFrame을 생성한
XRSession을
반환한다.
몰입형
세션의 경우 predictedDisplayTime 속성은
이 XRFrame이 장치의
디스플레이에 표시될 것으로 예상되는 평균 시점에 대응하는 DOMHighResTimeStamp를
반환해야 한다. 인라인 세션의 경우, predictedDisplayTime은
XRFrameRequestCallback에
전달된 timestamp와 같은 값을 반환해야 한다.
predictedDisplayTime은
애니메이션된 XR 장면을 requestAnimationFrame()
콜백이 예약되었거나 실행된 때가 아니라, 프레임이 표시될 때 있어야 할 상태로 렌더링할 수 있도록 하기 위한 것이다.
predictedDisplayTime은
애플리케이션이 렌더링에 사용할 수 있는 시간이 얼마나 되는지를 추론하는 데 사용되도록 의도된 것이 아니다. 이는
일반적으로 XR Compositor가 프레임이
제출된 후 추가 처리를 수행해야 하기 때문이다. 경험이 predictedDisplayTime까지
처리할 수 있다고 가정하면, XR
Compositor는
제출된 프레임을 활용할 수 없게 되고, 애플리케이션은 목표 프레임 속도를 달성하지 못할 것이다.
각 XRFrame은
주어진 time에 대한 모든 추적 객체의 상태를 나타내며,
이 상태에 관한 구체적인 정보를 해당 time에 저장하거나
질의할 수 있다.
getViewerPose(referenceSpace) 메서드는
XRFrame의
time에서,
referenceSpace에 상대적인 viewer의
포즈를 XRViewerPose로
제공한다.
이 메서드가 호출되면, 사용자 에이전트는 다음 단계를 실행해야 한다:
-
frame을 this로 둔다.
-
session을 frame의
session객체로 둔다. -
frame의 animationFrame boolean이
false이면,InvalidStateError를 throw하고 이 단계를 중단한다. -
pose를 session의 관련 realm에 있는
XRViewerPose새 객체로 둔다. -
frame이 나타내는 시간에 session의 viewer reference space의 포즈를 referenceSpace 안에서 pose에 채우되,
force emulation을true로 설정한다. -
pose가
null이면null을 반환한다. -
xrviews를 빈 list로 둔다.
-
offset을
0으로 둔다. -
session의 뷰 목록 안의 각 active view view에 대해 다음 단계를 수행한다:-
xrview의 underlying view를 view로 초기화한다.
-
xrview의
index를 offset으로 초기화한다. -
xrview의 frame을 frame으로 초기화한다.
-
xrview의 session을 session으로 초기화한다.
-
xrview의 reference space를 referenceSpace로 초기화한다.
-
viewtransform을 session의 관련 realm에서 view의 view offset과 같은
XRRigidTransform새 객체로 둔다. -
xrview의
transform속성을, session의 관련 realm에서XRViewerPose의transform에 viewtransform transform을 곱한 결과로 설정한다. -
xrview를 xrviews에 Append한다.
-
offset을
1만큼 증가시킨다.
-
pose의
views를 xrviews로 설정한다 -
pose를 반환한다.
getPose(space, baseSpace) 메서드는
XRFrame이
나타내는 시간에 baseSpace에 상대적인 space의 포즈를 XRPose로
제공한다.
이 메서드가 호출되면, 사용자 에이전트는 다음 단계를 실행해야 한다:
프레임 갱신은
XRFrame이 주어졌을 때
실행될 수 있는 알고리즘이며, 각 XRFrame마다
실행되도록 의도된다.
모든 XRSession은
프레임 갱신들의
list인
프레임 갱신 목록을 가지며, 처음에는 빈 list이다.
XRFrame
frame에 대해 프레임 갱신을 적용하려면, 사용자 에이전트는 다음 단계를 실행해야 한다:
참고: 이 명세는 어떤 프레임 갱신도 정의하지 않지만, 다른 명세가 일부를 추가할 수 있다.
6. 공간
WebXR Device API의 핵심 기능은 공간 추적을 제공하는 능력이다. 공간은 추적되는 엔티티들이 사용자의 물리적 환경 및 서로와 공간적으로 어떻게 관련되는지 애플리케이션이 추론할 수 있게 하는 인터페이스이다.
6.1. XRSpace
XRSpace는
물리적 위치에 대응하는 원점을 가진 가상 좌표계를 나타낸다. API에서 요청되거나 API에 제공되는 공간 데이터는 항상
특정 XRSpace에
상대적으로,
특정 XRFrame의 시점에서
표현된다. 포즈 위치와 같은 수치 값은 해당 공간에서 그 원점에 상대적인 좌표이다. 이 인터페이스는 의도적으로
불투명하다.
[SecureContext ,Exposed =Window ]interface :XRSpace EventTarget { };
각 XRSpace는
해당 XRSpace를 생성한
XRSession으로
설정되는 session을 가진다.
각 XRSpace는
공간 내의 위치와 방향인 native origin을 가진다. XRSpace의
native origin은
XR 장치의 underlying
tracking system에 의해 갱신될 수 있으며,
서로 다른 XRSpace들은
자신들의
native origin이
추적되고 갱신되는 방식에 관해 서로 다른 의미를 정의할 수
있다.
각 XRSpace는
해당 XRSpace의
좌표계의 기반인 effective origin을 가진다.
effective space에서 native origin의 공간으로의 transform은 origin
offset으로
정의되며, 이는 처음에 identity
transform으로 설정되는 XRRigidTransform이다.
달리 말하면, effective origin은
origin offset과
native origin을
곱하여 얻을 수 있다.
XRSpace의
effective
origin은 다른 XRSpace의 좌표계에서
XRPose로만
관찰될 수 있으며, 이는 XRFrame의
getPose()
메서드가 반환한다. XRSpace들 사이의
공간적 관계는 XRFrame들
사이에서
변경될 수 있다.
XRSpace
space의 포즈를, XRFrame
frame이 나타내는 시간에 XRSpace
baseSpace 안에서, XRPose
pose에 채우려면,
선택적인 force emulation 플래그와 함께, 사용자 에이전트는 다음 단계를 실행해야 한다:
-
frame의 active boolean이
false이면,InvalidStateError를 throw하고 이 단계를 중단한다. -
session을 frame의
session객체로 둔다. -
space의 session이 session과 같지 않으면,
InvalidStateError를 throw하고 이 단계를 중단한다. -
baseSpace의 session이 session과 같지 않으면,
InvalidStateError를 throw하고 이 단계를 중단한다. -
포즈가 보고될 수 있는지 확인하고, 그렇지 않다면
SecurityError를 throw하고 이 단계를 중단한다. -
session의
visibilityState가"visible-blurred"이고 space 또는 baseSpace가XRInputSource와 연결되어 있으면, pose를null로 설정하고 이 단계를 중단한다. -
limit를 space와 baseSpace 사이에서 포즈가 제한되어야 하는지의 결과로 둔다.
-
transform을 pose의
transform으로 둔다. -
frame의 time에서 baseSpace에 상대적인 space의 포즈를 XR 장치의 추적 시스템에 질의한 다음, 다음 단계를 수행한다:
- limit가
false이고 추적 시스템이 baseSpace에 상대적인 space의 포즈에 대해 위치가 능동적으로 추적되거나 정적으로 알려진 6DoF 포즈를 제공하는 경우: -
transform의
orientation을 baseSpace의 좌표계 안에서 space의 effective origin의 방향으로 설정한다.transform의
position을 baseSpace의 좌표계 안에서 space의 effective origin의 위치로 설정한다.지원된다면, pose의
linearVelocity를 baseSpace의 좌표계와 비교한 space의 effective origin의 선속도로 설정한다.지원된다면, pose의
angularVelocity를 baseSpace의 좌표계와 비교한 space의 effective origin의 각속도로 설정한다.pose의
emulatedPosition을false로 설정한다. - 그렇지 않고 limit가
false이며 추적 시스템이 3DoF 포즈 또는 baseSpace에 상대적인 space의 포즈에 대해 위치가 능동적으로 추적되지도 않고 정적으로 알려져 있지도 않은 6DoF 포즈를 제공하는 경우: -
transform의
orientation을 baseSpace의 좌표계 안에서 space의 effective origin의 방향으로 설정한다.transform의
position을 baseSpace의 좌표계 안에서 space의 effective origin 위치에 대한 추적 시스템의 최선의 추정값으로 설정한다. 여기에는 목 또는 팔 모델과 같은 계산된 offset이 포함될 수 있다. 위치 추정값을 사용할 수 없으면, 마지막으로 알려진 위치를 사용해야 한다.pose의
linearVelocity를null로 설정한다.pose의
angularVelocity를null로 설정한다.pose의
emulatedPosition을true로 설정한다. - 그렇지 않고 baseSpace에 상대적인 space의 포즈가 과거에 결정된 적이 있으며
force emulation이
true인 경우: -
transform의
position을 baseSpace의 좌표계 안에서 space의 effective origin의 마지막으로 알려진 위치로 설정한다.transform의
orientation을 baseSpace의 좌표계 안에서 space의 effective origin의 마지막으로 알려진 방향으로 설정한다.pose의
linearVelocity를null로 설정한다.pose의
angularVelocity를null로 설정한다.pose의
emulatedPositionboolean을true로 설정한다. - 그렇지 않은 경우:
-
pose를
null로 설정한다.
- limit가
참고: XRPose의
emulatedPosition
boolean은 baseSpace의 위치가 에뮬레이션되는지 여부를 나타내지 않으며, 단지 baseSpace에
상대적인 space의 위치를 평가하는 것이 에뮬레이션에 의존하는지 여부만 나타낸다. 예를 들어,
3DoF 추적을 가진 컨트롤러는 자신의
targetRaySpace
또는 gripSpace가
XRReferenceSpace에
대해 질의될 때 true인 emulatedPosition을
가진 포즈를 보고하지만, targetRaySpace의
포즈가 gripSpace
안에서 질의된 경우에는, 이 두 공간 사이의 관계가 정확히 알려져 있어야 하므로 false인
emulatedPosition을
보고한다.
6.2. XRReferenceSpace
XRReferenceSpace는
애플리케이션이 사용자의 물리적 환경과 공간적 관계를 수립하는 데 사용할 수 있는 여러 공통 XRSpace 중 하나이다.
XRReferenceSpace들은
일반적으로 XRSession 동안
정적으로 유지될 것으로 예상되며, 가장 흔한 예외는 사용자가 세션 중 재구성을 수행하는 경우이다. 모든 XRReferenceSpace의
native origin은
+X가
"Right", +Y가 "Up", -Z가 "Forward"로 간주되는 좌표계를 설명한다.
enum {XRReferenceSpaceType "viewer" ,"local" ,"local-floor" ,"bounded-floor" ,"unbounded" }; [SecureContext ,Exposed =Window ]interface :XRReferenceSpace XRSpace { [NewObject ]XRReferenceSpace getOffsetReferenceSpace (XRRigidTransform );originOffset attribute EventHandler onreset ; };
각 XRReferenceSpace는
XRReferenceSpaceType인
type을 가진다.
XRReferenceSpace는
가장 흔히 requestReferenceSpace()를
호출하여 얻으며, 이 메서드는 호출에 전달된 XRReferenceSpaceType
enum 값이 지원되는 경우 XRReferenceSpace
인스턴스(또는 이를 확장하는 인터페이스)를 생성한다. type은 reference space가 보일 추적 동작을 나타낸다:
-
viewer유형을 전달하면XRReferenceSpace인스턴스가 생성된다. 이는 viewer의 위치와 방향을 추적하는 native origin을 가진 추적 공간을 나타낸다. 모든XRSession은"viewer"XRReferenceSpace를 지원해야 한다. -
local유형을 전달하면XRReferenceSpace인스턴스가 생성된다. 이는 생성 시점의 viewer 근처에 native origin을 가진 추적 공간을 나타낸다. 정확한 위치와 방향은 underlying platform의 관례에 따라 초기화된다. 이 reference space를 사용할 때 사용자는 초기 위치에서 많이, 또는 전혀 벗어나지 않을 것으로 예상되며, 추적은 그 목적에 맞게 최적화된다. 6DoF 추적을 갖춘 장치의 경우,localreference space는 사용자의 환경에 상대적으로 origin을 안정적으로 유지하는 것을 강조해야 한다. -
local-floor유형을 전달하면XRReferenceSpace인스턴스가 생성된다. 이는 사용자가 서기에 안전한 위치의 바닥에 native origin을 가진 추적 공간을 나타낸다.Y축은 바닥 수준에서0과 같으며,X및Z위치와 방향은 underlying platform의 관례에 따라 초기화된다. 바닥 수준을 알 수 없는 경우, 어떤 추정 바닥 수준으로 추정해야 한다. 추정 바닥 수준이 기본값이 아닌 값으로 결정되면, 핑거프린팅을 방지할 수 있도록 충분히 반올림되어야 한다. 이 reference space를 사용할 때 사용자는 초기 위치에서 많이, 또는 전혀 벗어나지 않을 것으로 예상되며, 추적은 그 목적에 맞게 최적화된다. 6DoF 추적을 갖춘 장치의 경우,local-floorreference space는 사용자의 환경에 상대적으로 origin을 안정적으로 유지하는 것을 강조해야 한다.참고:
"local-floor"reference space의 바닥 수준이 핑거프린팅 방지를 위해 조정되는 경우, 가장 가까운 1cm로 반올림하는 것이 제안된다. -
bounded-floor유형을 전달하면XRBoundedReferenceSpace인스턴스가 생성된다. 이는 바닥에 native origin을 가진 추적 공간을 나타내며, 사용자는boundsGeometry로 주어진 미리 설정된 경계 안에서 움직일 것으로 예상된다.bounded-floorreference space의 추적은 native origin과boundsGeometry를 사용자의 환경에 상대적으로 안정적으로 유지하는 데 최적화된다. -
unbounded유형을 전달하면XRReferenceSpace인스턴스가 생성된다. 이는 사용자가 자신의 환경 주위를 자유롭게, 잠재적으로 시작 지점에서 먼 거리까지 이동할 것으로 예상되는 추적 공간을 나타낸다.unboundedreference space의 추적은 사용자의 현재 위치 주변 안정성에 최적화되며, 따라서 native origin은 시간이 지남에 따라 drift될 수 있다.
참고: reference space의 Y축에 관한 underlying platform의
관례는 여러 유형의 XRReferenceSpace들
사이에서 일관되게 유지된다고 가정한다. 달리 말하면, XR 시스템이 여러 reference space를 지원한다면, 그것들의
Y축은 서로 평행하고, 생성된 XRSession 동안
같은 방향을 가리킨다. 이는 "viewer"에는
적용되지 않는다. 이는 자신의 방향에 대해 underlying platform의 관례에 의존하지 않기 때문이다. "unbounded"
reference space는 origin이 가까이 있을 때 다른 reference space와 자신의 Y축을 정렬해야 하지만, 사용자가 큰 거리를
이동하면 벗어날 수 있다.
"local"
reference space를 지원하는 장치는 필요한 경우 에뮬레이션을 통해 "local-floor"
reference space를 지원해야 하며, 그 반대도 마찬가지이다.
onreset 속성은 reset
이벤트 유형을 위한 이벤트 핸들러 IDL 속성이다.
XRSession
session에 대해 XRReferenceSpaceType
type으로 XRReferenceSpace가
요청되면, 사용자 에이전트는 다음 단계를 실행하여 참조 공간을 생성해야 한다:
-
referenceSpace를 다음과 같이 초기화한다:
- type이
bounded-floor인 경우: -
referenceSpace를 session의 관련 realm에 있는
XRBoundedReferenceSpace새 객체로 둔다. - 그렇지 않은 경우:
-
referenceSpace를 session의 관련 realm에 있는
XRReferenceSpace새 객체로 둔다.
- type이
-
referenceSpace의 type을 type으로 초기화한다.
-
referenceSpace의 session을 session으로 초기화한다.
-
referenceSpace를 반환한다.
XRSession
session에 대해 reference space가 지원되는지 확인하려면, 다음 단계를 실행한다:
-
type이
viewer이면,true를 반환한다. -
type이
local또는local-floor이고, session이 몰입형 세션이면,true를 반환한다. -
type이
local또는local-floor이고, XR 장치가 방향 데이터 보고를 지원하면,true를 반환한다. -
type이
bounded-floor이고 session이 몰입형 세션이면, XR 장치가 bounded reference space를 지원하는지의 결과를 반환한다. -
type이
unbounded이고, session이 몰입형 세션이며, XR 장치가 사용자 근처에서 무제한 거리의 안정적인 추적을 지원하면,true를 반환한다. -
false를 반환한다.
getOffsetReferenceSpace(originOffset)
메서드는 호출되면 다음 단계를 수행해야 한다:
-
base를 이 메서드가 호출된
XRReferenceSpace로 둔다. -
offsetSpace를 다음과 같이 초기화한다:
- base가
XRBoundedReferenceSpace의 인스턴스인 경우: -
offsetSpace를 base의 관련 realm에 있는
XRBoundedReferenceSpace새 객체로 두고, offsetSpace의boundsGeometry를 base의boundsGeometry로 설정하되, 각 점에 originOffset의inverse를 곱한다. - 그렇지 않은 경우:
-
offsetSpace를 base의 관련 realm에 있는
XRReferenceSpace새 객체로 둔다.
- base가
-
offsetSpace의 origin offset을, base의 origin offset에 originOffset을 base의 관련 realm에서 곱한 결과로 설정한다.
-
offsetSpace를 반환한다.
참고: 일부 애플리케이션은 마우스, 키보드, 터치 또는 게임패드
입력을 기반으로 한 장면 탐색 제어를 구현하기 위해 getOffsetReferenceSpace()를
사용할 것으로 예상된다. 이로 인해 getOffsetReferenceSpace()가
활성 입력 기간 동안 적어도 프레임마다 한 번씩 자주 호출될 것이다. 따라서 UA는 getOffsetReferenceSpace()로
새 XRReferenceSpace를
생성하는 작업을 가벼운 작업으로 만들도록 강하게 권장된다.
6.3. XRBoundedReferenceSpace
XRBoundedReferenceSpace는
XRReferenceSpace를
확장하여 boundsGeometry를
포함하며, 이는 사용자의 공간에 대해 미리 구성된 경계를 나타낸다.
[SecureContext ,Exposed =Window ]interface :XRBoundedReferenceSpace XRReferenceSpace {readonly attribute FrozenArray <DOMPointReadOnly >boundsGeometry ; };
XRBoundedReferenceSpace의
원점은 바닥에 위치해야 하며, 따라서 Y 축은 바닥 수준에서 0과 같아야 한다.
X 및 Z 위치와 방향은 underlying platform의 관례를 기반으로 초기화되며,
일반적으로 논리적인 전방 방향을 바라보는 방 중앙 근처일 것으로 예상된다.
참고: 다른 XR 플랫폼에서는 때때로
bounded-floor
reference space가 제공하는 추적 유형을 "room scale" 추적이라고 부른다. XRBoundedReferenceSpace는
여러 방으로 이루어진 공간, 바닥 높이가 고르지 않은 영역, 또는 매우 큰 열린 영역을 설명하기 위한 것이 아니다.
그러한 시나리오를 처리해야 하는 콘텐츠는 unbounded
reference space를 사용해야 한다.
각 XRBoundedReferenceSpace는
사용자가 안전하게 그 안에서 움직일 수 있다고 기대할 수 있는, XRBoundedReferenceSpace
주변의 경계를 설명하는 native bounds geometry를 가진다. 다각형
경계는
DOMPointReadOnly의
배열로 주어지며, 안전 공간의 가장자리에 있는 점들의 루프를 나타낸다. 점들은 native
origin으로부터의 오프셋을 미터 단위로 설명한다. 점들은 위에서 내려다보며 Y축의 음의 끝을 향해 볼 때
시계 방향 순서로 주어져야 한다. 각 점의 y
값은 0이어야 하며, 각 점의 w
값은 1이어야 한다. bounds는 바닥에서 시작하여 무한히 위로 확장되는 것으로 간주할 수 있다.
그것이 설명하는 형태는 볼록하거나 오목할 수 있다.
native bounds geometry의 각 점은 reference space의 native origin으로부터 합리적인 거리로 제한되어야 한다.
참고: native bounds geometry의 점들은 모든 방향에서 native origin으로부터 15미터로 제한하는 것이 제안된다.
native bounds geometry의 각 점은 또한 핑거프린팅을 방지할 수 있도록 충분히 양자화되어야 한다. 사용자의 안전을 위해, 양자화된 점 값은 플랫폼이 보고한 bounds 밖에 위치해서는 안 된다.
참고: native bounds geometry의 점들은 가장 가까운 5cm로 양자화하는 것이 제안된다.
boundsGeometry 속성은
DOMPointReadOnly들의
배열이며, 각 항목은 XRBoundedReferenceSpace의
native bounds geometry 안의 항목에
origin
offset의 inverse를
미리 곱한 것과 같다. 달리 말하면, 이는 effective origin에 상대적인 XRBoundedReferenceSpace
좌표에서 같은 경계를 제공한다.
native bounds geometry를 일시적으로
사용할 수 없는 경우, 예를 들어 XR 장치 초기화 중, 장기간의 추적 손실, 또는 미리 구성된 공간들 사이의 이동 중에
발생할 수 있으며, boundsGeometry는
빈 배열을 보고해야 한다.
참고: reference space 요청 시점에 경계 또는 바닥 높이가 아직 해결되지 않았더라도, XR 장치가 이를 지원하는 것으로 알려져 있다면 bounded reference space가 반환될 수 있다.
참고: 콘텐츠는 사용자가
boundsGeometry
너머로 이동하도록 요구해서는 안 된다. 사용자의 물리적 주변 환경이 허용한다면 사용자가 bounds 밖으로 이동할 수
있으며, 그 결과 위치 값이 그들이 설명하는 다각형 밖에 있을 수 있다. 이는 오류 조건이 아니며 페이지 콘텐츠가
우아하게 처리해야 한다.
참고: 콘텐츠는 일반적으로
boundsGeometry의
시각화를 제공해서는 안 된다. 안전에 중요한 정보가 사용자에게 제공되도록 보장하는 것은 사용자 에이전트의 책임이기
때문이다.
7. 뷰
7.1. XRViewGeometry
XRViewGeometry
interface mixin을 포함하는 객체들은 XR 장치가 사용자에게 이미지를 제시하는 데 사용하는 디스플레이이거나,
실제 세계에 대한 시각 정보를 수집하는 데 사용하는 센서를 나타낸다. 이러한 객체는 view geometry를 포함한다.
view geometry는 viewer reference space의 좌표계 안의 점과 containing object의 screen space 안의 점 사이를 변환하는 데 사용되는 intrinsics 및 extrinsics 집합에 대응한다.
view geometry는 view geometry가 데이터를 포함하는 물리적 하드웨어 조각인 containing object를 가진다.
view geometry의 containing object는 연결된 screen space를 가지며, 이는 이 containing object가 데이터를 읽거나 렌더링하는 2D 평면으로 설명된다.
view geometry는
연결된 view offset을 가지며, 이는 viewer reference
space의 좌표계 안에서
containing
object의 위치와 방향을 설명하는 XRRigidTransform이다.
참고: view offset이 무엇일 수 있는지에 대한 제약은 없으며, view들은 서로 다른 방향을 가질 수 있다. 이는 눈 디스플레이가 각도를 두고 중심에 배치된 머리 착용 장치에서 나타날 수 있으며, CAVE 렌더링과 같은 더 극단적인 경우에도 나타날 수 있다. 이 때문에 z-sorting 및 culling 같은 기법은 눈별로 수행해야 할 수 있다.
view geometry는 underlying XR 장치가 제공하는 containing object로 렌더링할 때 사용할 projection을 설명하는 matrix인 연결된 projection matrix를 가진다. projection matrix는 projection이 단순한 frustum으로 정확히 설명되는 것을 방지하는 shearing과 같은 변환을 포함할 수 있다.
참고: 이 matrix의 inverse는 screen space에서 픽셀을 "읽고", 이를 containing object를 원점으로 하는 좌표계로 다시 변환하는 데 적합하다.
[SecureContext ,Exposed =Window ]interface mixin {XRViewGeometry readonly attribute Float32Array projectionMatrix ; [SameObject ]readonly attribute XRRigidTransform transform ; };
각 XRViewGeometry는
그 containing
object의 projection matrix를 저장하는 연결된
internal projection matrix를 가진다. 이는 처음에는
null이다.
참고: transform은
많은 렌더링 라이브러리에서 카메라 객체를 배치하는 데 사용할 수 있다. 애플리케이션에 더 전통적인 view matrix가
필요하다면 transform.inverse.matrix를 호출하여 얻을 수 있다.
projectionMatrix 속성은 underlying
view geometry의
projection matrix이다. 애플리케이션은 이 matrix를 수정하거나
분해하지 않고 사용하는 것이 강하게 권장된다. 렌더링할 때 제공된 projection matrix를 사용하지 않으면
제시된 프레임이 왜곡되거나 심하게 어긋나서, 사용자에게 다양한 정도의 불편함을 초래할 수 있다. 이 속성은
XRViewGeometry에
대해 projection matrix를 얻어 계산되어야 한다.
transform 속성은 객체의 XRRigidTransform이다.
이는 객체를 얻는 데 사용된 XRReferenceSpace
안에서 객체의 위치와 방향을 나타낸다.
주어진 XRViewGeometry
view geometry에 대해 projection matrix를 얻으려면:
-
view geometry의 internal projection matrix가
null이 아니면, 다음 단계를 수행한다:-
internal projection matrix에 대한
IsDetachedBuffer연산이false이면, view geometry의 internal projection matrix를 반환한다.
-
-
view geometry의 internal projection matrix를 view geometry의 관련 realm에 있는 matrix 새 객체로 설정하되, 이는 view geometry의 projection matrix와 같다.
-
view geometry의 internal projection matrix를 반환한다.
7.2. XRView
XRView는
주어진 프레임에 대해 XR 장면 안으로 들어가는 단일 view를
설명한다.
view는 XR 장치가 사용자에게
이미지를 제시하는 데 사용하는 디스플레이 또는 디스플레이의 일부에 대응한다. view는 시야각, eye offset, 기타
광학 속성을 포함하여, view의 물리적 출력 속성에 잘 정렬된 콘텐츠를 렌더링하는 데
필요한 모든 정보를
얻는 데 사용된다. View들은 사용자의 시야에서
겹치는 영역을 덮을 수 있다. XR 장치가 사용하는 view의 수나 순서에 대해서는
보장되지 않으며, view의 수가 XRSession
동안 일정할 필요도 없다.
view는 이 view가 어느 눈에 표시될 것으로
예상되는지를 설명하는 XREye인
연결된 eye를
가진다. view가 본질적으로 연결된 eye를 가지지 않는 경우(예를 들어 디스플레이가 단안인 경우), 이 값은 "none"으로
설정되어야 한다.
view는 XRSession의
생명 주기 동안 변경될 수 있는 active 플래그를 가진다.
Primary view들은 항상
active 플래그가
true로 설정되어 있어야 한다.
참고: 많은 HMD는 왼쪽 눈용 하나와 오른쪽 눈용 하나, 총 두 개의 view를 렌더링하도록 콘텐츠에 요청하지만, 대부분의 magic window 장치는 하나의 view만 요청한다. 그러나 애플리케이션은 특정 view 구성을 절대 가정해서는 안 된다. 예를 들어, magic window 장치는 stereo 출력을 할 수 있다면 두 개의 view를 요청할 수 있지만, stereo 출력 모드가 꺼져 있으면 성능상의 이유로 단일 view 요청으로 되돌아갈 수 있다. 마찬가지로 HMD는 넓은 시야각이나 서로 다른 픽셀 밀도의 디스플레이를 지원하기 위해 두 개보다 많은 view를 요청할 수 있다.
view는 세션의 이 시점에서 viewport scale이
requestViewportScale()
호출에 의해 변경될 수 있는지 나타내는 내부 viewport
modifiable 플래그를 가진다. 이는 animation frame 시작 시 true로 설정되고,
getViewport()가
호출될 때 false로 설정된다.
view는 이 view에 대해 요청된 viewport scale을
나타내는 내부 requested
viewport scale 값을 가진다. 이는 처음에 1.0으로 설정되며, 시스템이 dynamic viewport scaling을 지원하는 경우
requestViewportScale()
메서드에 의해 수정될 수 있다.
view는 시스템이 내부적으로 사용하는 이 view의
현재 viewport scale을 나타내는 내부 current viewport
scale 값을 가진다. 이는 처음에 1.0으로 설정된다. viewport 변경이 getViewport()
호출에 의해 성공적으로 적용되면, 이는 requested viewport
scale과 일치하도록 갱신된다.
view는 getViewerPose()에서
이 view를 얻는 데 사용된
XRReferenceSpace
공간인 reference space를
가진다.
참고: Dynamic viewport scaling은 애플리케이션이 각
animation frame마다 변경될 수 있는 scale factor를 사용하여 전체 크기 viewport의 하위 집합에 렌더링할 수 있게 한다.
이는 재할당 없이 프레임별로 효율적으로 수정 가능하도록 의도된다. 올바른 렌더링을 위해서는 XR 시스템과 애플리케이션이
active viewport에 대해 합의하는 것이 필수적이다. 애플리케이션은 하나의 animation frame 안에서 XRView에 대해
requestViewportScale()을
여러 번 호출할 수 있지만, 요청된 scale은 애플리케이션이 그 view에 대해 getViewport()를
호출할 때까지 적용되지 않는다. animation frame 안의 첫 번째 getViewport 호출은 변경을 적용하고
(현재 animation frame에 즉시 적용됨), 이 animation frame의 나머지 동안 view의 현재 scaled viewport를 고정하며,
그 scale을 향후 animation frame의 새 기본값으로 설정한다. 선택적으로, 시스템은 내부 성능 휴리스틱과 목표
프레임 속도를 기반으로 recommendedViewportScale
속성을 통해 제안 값을 제공할 수 있다.
enum {XREye ,"none" ,"left" }; ["right" SecureContext ,Exposed =Window ]interface {XRView readonly attribute XREye eye ;readonly attribute unsigned long index ;readonly attribute double ?recommendedViewportScale ;undefined requestViewportScale (double ?); };scale XRView includes XRViewGeometry ;
transform은
그 reference
space 안에서 주어진다.
eye 속성은 underlying view의 eye를
설명한다. 이 속성의 주된 목적은 미리 렌더링된 stereo
콘텐츠가 올바른 눈에 올바른 콘텐츠 부분을 제시할 수 있도록 보장하는 것이다.
index 속성은 이 XRView가
getViewerPose()에
의해 views
배열 안에서 반환될 때의 offset을 설명한다.
선택적 recommendedViewportScale 속성은 애플리케이션이
dynamic viewport scaling을 구성하기 위해 requestViewportScale()
호출에 사용할 수 있는 UA 권장 viewport scale 값을 포함한다. 시스템이 권장 scale을 결정하기 위한 휴리스틱이나
메서드를 구현하지 않는 경우 이는 null이다. null이 아닌 경우, 값은 0.0보다 크고 1.0 이하인
숫자 값이어야 하며, 상세한 성능 또는 GPU 사용률 데이터를 제공하지 않도록 양자화되어야 한다.
참고: 권장 viewport scale은 가능한 scale 값들의 짧은 목록에서 가장 가까운 값으로 반올림하고, 경계 값에 가까울 때 즉각적인 변경을 피하기 위해 hysteresis를 사용하여 양자화하는 것이 제안된다. (이는 시각적으로 산만하거나 불편할 수 있는 scale 값의 빠른 진동을 피하는 데도 도움이 된다.)
각 XRView는
이를 생성한 XRSession인
연결된 session을 가진다.
각 XRView는
이를 생성한 XRFrame인
연결된 frame을 가진다.
각 XRView는
그것이 나타내는 underlying view인 연결된 underlying view를 가진다.
requestViewportScale(scale)
메서드는 사용자 에이전트가 이 viewport의 requested viewport
scale을 요청된 값으로 설정해야 한다고 요청한다.
이 메서드가 XRView
xrview에서 호출되면, 사용자 에이전트는 다음 단계를 실행해야 한다:
-
scale이 null 또는 undefined이면, 이 단계를 중단한다.
-
scale이 0.0 이하이면, 이 단계를 중단한다.
-
scale이 1.0보다 크면, scale을 1.0으로 설정한다.
-
view를 xrview의 underlying view로 둔다.
-
view의 requested viewport scale 값을 scale로 설정한다.
참고: 이 메서드는 null 또는 undefined scale 값을
무시하므로, 애플리케이션은 권장 scale을 제공하지 않는 시스템에서도 안전하게
view.requestViewportScale(view.recommendedViewportScale)을 사용할 수 있다.
뷰 목록의
어떤 view의 active
플래그가 변경되면, 다음 단계를 수행하여 XRSession
session에 대한 viewport를
갱신할 수 있다:
-
layer를
renderState의baseLayer로 둔다. -
layer가
null이면 이 단계를 중단한다. -
layer의 viewport 객체 목록을 빈 list로 설정한다.
-
뷰 목록 안의 각 active view view에 대해:
-
viewport를 session에 대해 view와 연결된 전체 크기 viewport 목록에서 scaled viewport를 얻은 결과인
XRViewport로 둔다. -
viewport를 layer의 viewport 객체 목록에 Append한다.
-
XRSession
session에 대해 주어진 XRView
view의 scaled viewport를 얻으려면:
-
glFullSizedViewport를 view와 연결된 전체 크기 viewport 목록에서 가져온 WebGL viewport로 둔다.
-
scale을 view의 current viewport scale로 둔다.
-
사용자 에이전트는 최소 viewport scale factor를 적용하기 위해 scale을 clamp하도록 선택할 수 있다.
-
glViewport를 새 WebGL viewport로 둔다.
-
glViewport의
width를 glFullSizedViewport의width에 scale을 곱한 값 이하인 정수 값으로 설정한다. -
glViewport의
width가 1보다 작으면, 이를 1로 설정한다. -
glViewport의
height를 glFullSizedViewport의height에 scale을 곱한 값 이하인 정수 값으로 설정한다. -
glViewport의
height가 1보다 작으면, 이를 1로 설정한다. -
glViewport의
x구성 요소를 glFullSizedViewport의x구성 요소(포함)와 glFullSizedViewport의x구성 요소에 glFullSizedViewport의width를 더한 뒤 glViewport의width를 뺀 값(포함) 사이의 정수 값으로 설정한다. -
glViewport의
y구성 요소를 glFullSizedViewport의y구성 요소(포함)와 glFullSizedViewport의y구성 요소에 glFullSizedViewport의height를 더한 뒤 glViewport의height를 뺀 값(포함) 사이의 정수 값으로 설정한다. -
viewport를 session의 관련 realm에 있는
XRViewport새 객체로 둔다. -
viewport의
x를 glViewport의x구성 요소로 초기화한다. -
viewport의
y를 glViewport의y구성 요소로 초기화한다. -
viewport의
width를 glViewport의width로 초기화한다. -
viewport의
height를 glViewport의height로 초기화한다. -
viewport를 반환한다.
참고: 구체적인 정수 값 계산은 의도적으로 UA의 재량에
맡겨진다. width/height를 내림하고 x 및 y offset을 그대로 사용하는 간단한 방법은
유효하지만, UA는 효율성을 위해 viewport를 2의 거듭제곱 픽셀 그리드에 정렬하는 등 명시된 제약 안에서 약간
조정된 값을 선택할 수도 있다. scaled viewport는 전체 크기 viewport 안에 완전히 포함되어야 하지만, UA의 재량에
따라 전체 크기 viewport 안의 어느 위치에나 배치될 수 있다. 크기 및 위치 계산은 결정적이어야 하며, 세션 안에서
동일한 입력 값에 대해 일관된 결과를 반환해야 한다.
7.3. Primary 및 Secondary View
view는 XR 경험을 위해 그에 대한 렌더링이
필요한 경우 primary view이다. Primary
view들은 XRSession의
전체 기간 동안 active여야 한다.
view는 콘텐츠가 그에 렌더링하지 않기로 선택해도 동작하는 몰입형 경험을 만들 수 있는 경우 secondary view이다. 콘텐츠가 이러한 view에 렌더링하지 않기로 선택하면, 사용자 에이전트는 reprojection을 통해 이를 재구성할 수 있을 수 있다. Secondary view는 "secondary-views" 기능이 활성화되지 않는 한 active여서는 안 된다.
secondary view의 예에는 video capture에 사용되는 first-person observer view, 또는 눈마다 두 개의 view가 있고 해상도와 시야각이 서로 다른 "quad views"가 포함된다.
views
배열에 대해 잘못된 가정을 하고, 따라서 두 개보다 많은 view가 제시되면 깨질 것으로 예상한다.
사용자 에이전트는 콘텐츠 대신 이러한 secondary view에 렌더링하기 위해 reprojection 같은 메커니즘을 사용할 수 있으므로, 이러한 secondary view를 직접 처리할 계획인 콘텐츠와, 그러한 secondary view의 존재를 모르거나 이를 다루고 싶지 않은 콘텐츠를 구별할 수 있는 것이 바람직하다.
이를 제공하기 위해, secondary view를 노출하는 사용자 에이전트는 "secondary-views" feature descriptor를 힌트로 지원해야 한다. 이 기능을 활성화하는 콘텐츠는 다음을 수행할 것으로 예상된다:
-
views배열의 크기가 프레임마다 변경되는 것을 처리한다. 예를 들어 video capture가 활성화된 경우 이런 일이 발생할 수 있다
"secondary-views"가 활성화되면, 사용자 에이전트는
필요할 때 장치가 지원하는 모든 secondary
view를
XRSession에
노출할 수 있다. 사용자 에이전트는 이러한 경우 reprojection을 사용하여 secondary view를 재구성해서는 안 되며, 대신
콘텐츠가 렌더링하기로 결정한 것에 의존해야 한다.
참고: 최대 호환성을 보장하기 위해 콘텐츠가
optionalFeatures를
사용하여 "secondary-views"를 활성화할 것을 권장한다.
secondary view의
underlying frame rate가 더 낮은 경우, XRSession은
다음 중 하나 이상을 선택할 수 있다:
-
secondary view가 활성인 동안 애플리케이션의 전체 frame rate를 낮춘다.
-
views배열 안의 secondary view를 일부 프레임에서만 노출한다. 이를 수행하는 구현은 primary view가 존재하지 않는 프레임을 가져서는 안 된다. -
일부 프레임 동안 secondary view에 렌더링된 콘텐츠를 조용히 버린다.
7.4. XRViewport
XRViewport
객체는 그래픽 표면의 viewport, 즉 직사각형 영역을 설명한다.
[SecureContext ,Exposed =Window ]interface {XRViewport readonly attribute long x ;readonly attribute long y ;readonly attribute long width ;readonly attribute long height ; };
x 및 y 속성은 surface origin으로부터의
offset을 정의하고,
width 및 height 속성은 viewport의 직사각형 크기를 정의한다.
viewport 값의 정확한 해석은 해당 viewport가 연결된 그래픽 API의 관례에 따라 달라진다:
-
XRWebGLLayer와 함께 사용될 때,x및y속성은 픽셀 단위로 viewport rectangle의 왼쪽 아래 모서리를 지정하며, viewport rectangle은x의 오른쪽으로width픽셀,y의 위쪽으로height픽셀 확장된다. 이 값들은 WebGL viewport 함수에 직접 전달될 수 있다.
XRViewerPose의
모든 XRView를 반복하고,
각 view에 대해 XRWebGLLayer에서
XRViewport를
질의하며, 이를 사용하여 렌더링에 적절한 WebGL
viewport를 설정한다.
xrSession. requestAnimationFrame(( time, xrFrame) => { const viewer= xrFrame. getViewerPose( xrReferenceSpace); gl. bindFramebuffer( xrWebGLLayer. framebuffer); for ( xrViewof viewer. views) { let xrViewport= xrWebGLLayer. getViewport( xrView); gl. viewport( xrViewport. x, xrViewport. y, xrViewport. width, xrViewport. height); // WebGL draw calls will now be rendered into the appropriate viewport. } });
8. 기하 기본 요소
8.1. 행렬
WebXR은 matrix
형태로 다양한 transform을 제공한다. WebXR은 matrix를
전달할 때 WebGL 관례를 사용하며, 여기서 4x4 matrix는 column major storage를 가진 16 요소 Float32Array로
주어지고, 왼쪽에서 matrix를 premultiply하여 column vector에 적용된다. 이들은 WebGL의 uniformMatrix4fv
함수에 직접 전달되거나, 동등한 DOMMatrix를
생성하는 데 사용되거나, 다양한 서드파티 수학 라이브러리와 함께 사용될 수 있다.
Float32Array가
된다:
[a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15]
이 matrix를 다음과 같이 지정된 column vector에 transform으로 적용하면:
{x:X, y:Y, z:Z, w:1}
다음 결과가 생성된다:
a0 a4 a8 a12 * X = a0 * X + a4 * Y + a8 * Z + a12 a1 a5 a9 a13 Y a1 * X + a5 * Y + a9 * Z + a13 a2 a6 a10 a14 Z a2 * X + a6 * Y + a10 * Z + a14 a3 a7 a11 a15 1 a3 * X + a7 * Y + a11 * Z + a15
8.2. 정규화
vector 또는 quaternion을 normalize해야 하는 여러 알고리즘이 있으며, 이는 구성 요소들을 함께 갖는 magnitude가
1.0이 되도록 스케일링한다는 의미이다.
구성 요소 목록을 normalize하려면 UA는 다음 단계를 수행해야 한다:
-
length를 각 구성 요소 제곱의 합의 제곱근으로 둔다.
-
length가
0이면,InvalidStateError를 throw하고 이 단계를 중단한다. -
각 구성 요소를 length로 나누고 그 구성 요소를 설정한다.
8.3. XRRigidTransform
XRRigidTransform은
position
및 orientation으로
설명되는 transform이다. XRRigidTransform을
해석할 때, orientation은
항상 position보다
먼저 적용된다.
XRRigidTransform은
matrix인 internal matrix를 포함한다.
[SecureContext ,Exposed =Window ]interface {XRRigidTransform constructor (optional DOMPointInit = {},position optional DOMPointInit = {}); [orientation SameObject ]readonly attribute DOMPointReadOnly position ; [SameObject ]readonly attribute DOMPointReadOnly orientation ;readonly attribute Float32Array matrix ; [SameObject ]readonly attribute XRRigidTransform inverse ; };
XRRigidTransform(position, orientation)
constructor는 호출되면 다음 단계를 수행해야 한다:
-
transform을 current realm에 있는
XRRigidTransform새 객체로 둔다. -
transform의
position을 current realm에 있는DOMPointReadOnly새 객체로 둔다. -
position 또는 orientation의 값 중 하나 이상이
NaN이거나infinity같은 다른 비유한 숫자이면,TypeError를 throw하고 이 단계를 중단한다. -
transform의
position의x값을 position의 x dictionary member로,y값을 position의 y dictionary member로,z값을 position의 z dictionary member로, 그리고w값을 position의 w dictionary member로 설정한다. -
transform의
orientation을 current realm에 있는DOMPointReadOnly새 객체로 둔다. -
transform의
orientation의x값을 orientation의 x dictionary member로,y값을 orientation의 y dictionary member로,z값을 orientation의 z dictionary member로, 그리고w값을 orientation의 w dictionary member로 설정한다. -
transform의 internal matrix를
null로 둔다. -
transform을 반환한다.
position 속성은 transform의 translation 구성 요소를
설명하는 3차원 점이며, 미터 단위로 주어진다. position의
w
속성은 1.0이어야 한다.
orientation 속성은 transform의 rotational 구성 요소를
설명하는 quaternion이다. orientation은
길이가 1.0이 되도록 normalize되어야 한다.
matrix 속성은 position
및 orientation
속성이 설명하는 transform을 matrix로
반환한다. 이 속성은 XRRigidTransform에
대해 matrix를 얻어 계산되어야 한다.
참고: 이 matrix를 column vector에 premultiply하면
orientation이
설명하는 3D rotation으로 vector를 회전시킨 다음, 이를 position만큼
translate한다. 수학적으로 column-vector 표기법에서 이는 M = T * R이며, 여기서
T는 position에
대응하는 translation matrix이고, R은 orientation에
대응하는 rotation matrix이다.
주어진 XRRigidTransform
transform에 대해 matrix를 얻으려면:
-
transform의 internal matrix가
null이 아니면, 다음 단계를 수행한다:-
internal matrix에 대한
IsDetachedBuffer연산이false이면, transform의 internal matrix를 반환한다.
-
-
translation을
position에 대응하는 column-vector translation matrix인 새 matrix로 둔다. 수학적으로,position이(x, y, z)이면, 이 matrix는 다음과 같다 -
rotation을
orientation에 대응하는 column-vector rotation matrix인 새 matrix로 둔다. 수학적으로,orientation이 unit quaternion (qx, qy, qz, qw)이면, 이 matrix는 다음과 같다 -
transform의 internal matrix를 transform의 관련 realm에 있는
Float32Array새 객체로 설정하되, 이는 transform의 관련 realm에서 translation을 왼쪽에 두고 translation과 rotation을 곱한 결과(translation * rotation)로 설정된다. 수학적으로, 이 matrix는 다음과 같다 -
transform의 internal matrix를 반환한다.
XRRigidTransform
transform의 inverse 속성은
transform의 관련 realm 안에 있는
XRRigidTransform을
반환하며, 이는 이전에 transform에 의해 변환된 객체에 적용될 경우 transform을 되돌리고 객체를 초기
pose로 반환한다. 이 속성은 지연 평가되어야 한다. inverse가
반환한 XRRigidTransform은
자신의 inverse로
transform을 반환해야 한다.
position이
{ x: 0, y: 0, z: 0 w: 1 }이고, orientation이
{ x: 0, y: 0, z: 0, w: 1 }인 XRRigidTransform은
identity
transform으로 알려져 있다.
Realm
realm 안의 B 및 A라는 두
XRRigidTransform를
곱하려면, UA는 다음 단계를 수행해야 한다:
-
result를 realm 안의
XRRigidTransform새 객체로 둔다. -
result의
matrix를 realm 안의Float32Array새 객체로 설정하되, 이는 B의matrix를 왼쪽에서 A의matrix에 premultiply한 결과이다. -
result의
orientation을 realm 안의DOMPointReadOnly새 객체로 설정하되, 이는 result의matrix의 왼쪽 위 3x3 sub-matrix가 나타내는 rotation을 설명하는 quaternion이다. -
result의
position을 realm 안의DOMPointReadOnly새 객체로 설정하되, 이는 result의matrix의 네 번째 열이 제공하는 vector이다. -
result를 반환한다.
result는 A의 source space에서 B의 destination space로의 transform이다.
참고: 이는 A와 B의
orientation의 composition인 orientation과,
A의 position을
B의 orientation으로
회전시킨 뒤, B의 position에
더한 값과 같은 position을
가진 XRRigidTransform을
구성하는 것과 동등하다.
9. 포즈
9.1. XRPose
XRPose는
XRSpace에 상대적인
공간 내 위치와 방향을 설명한다.
[SecureContext ,Exposed =Window ]interface { [XRPose SameObject ]readonly attribute XRRigidTransform transform ; [SameObject ]readonly attribute DOMPointReadOnly ?linearVelocity ; [SameObject ]readonly attribute DOMPointReadOnly ?angularVelocity ;readonly attribute boolean emulatedPosition ; };
transform 속성은 base XRSpace에 상대적인
위치와 방향을 설명한다.
linearVelocity 속성은 base XRSpace에 상대적인
선속도를 초당 미터 단위로 설명한다. 사용자 에이전트가 이를 채울 수 없다면, null을 반환할 수 있다.
angularVelocity 속성은 base XRSpace에 상대적인
각속도를 초당 라디안 단위로 설명한다. 사용자 에이전트가 이를 채울 수 없다면, null을 반환할 수 있다.
emulatedPosition 속성은 transform이
센서 판독값을 기반으로 능동적으로 추적되는 6DoF
pose를 나타낼 때 false이고, 그 position
값이 목 또는 팔 모델이 제공하는 것과 같은 computed offset을 포함하는 경우 true이다. XRPose가 computed
offset을 포함하는지 결정할 때는 추정 바닥
수준을 고려해서는 안 된다.
9.2. XRViewerPose
XRViewerPose는
XR 장치가 추적하는 XR
장면의
viewer 상태를 설명하는 XRPose이다.
viewer는 추적되는 하드웨어 조각, 하드웨어에 상대적인 사용자의 관찰된
위치, 또는 XR 장면으로 들어가는 일련의 viewpoint를 계산하는 다른 수단을 나타낼 수 있다. XRViewerPose는
XRReferenceSpace에
상대적으로만 질의될 수 있다. 이는 XRPose 값에 더해,
viewpoint와 projection matrix를 나타내는 rigid transform을 포함하는 view들의
배열을 제공한다. 이러한 값들은 XR 장면의 프레임을 렌더링할 때 애플리케이션이 사용해야 한다.
[SecureContext ,Exposed =Window ]interface :XRViewerPose XRPose { [SameObject ]readonly attribute FrozenArray <XRView >views ; };
views 배열은 XR 장면의 viewpoint를 설명하는
XRView들의
sequence이며,
이는 XRViewerPose가
질의된 XRReferenceSpace에
상대적이다. 배열 안의 XR 장면의 모든 view는
XR 장치에서 올바르게
표시되도록
렌더링되어야 한다. 각 XRView는 viewpoint와
projection matrix를 나타내는 rigid transform을 포함하며, 필요할 때 layer에서 XRViewport를
질의하는 데 사용할 수 있다.
참고: XRViewerPose의
transform은
장면의 spectator view 또는 multi-user interaction을 위해 viewer의 그래픽 표현을 배치하는 데 사용할 수 있다.
10. 入力
10.1. XRInputSource
XRInputSource
は XR 入力ソースを表す。
これは、ユーザーが viewer と同じ
仮想空間内で対象指定されたアクションを実行できる任意の入力機構である。XR 入力ソースの例には、
ハンドヘルドコントローラー、光学的にトラッキングされる手、および viewer
のポーズ上で動作する視線ベースの入力方式などが含まれるが、
これらに限定されない。従来のゲームパッド、マウス、またはキーボードなど、XR
device と明示的に関連付けられていない入力機構は、
XR 入力ソースと
みなすべきではない。
enum {XRHandedness ,"none" ,"left" };"right" enum {XRTargetRayMode "gaze" ,"tracked-pointer" ,"screen" ,"transient-pointer" }; [SecureContext ,Exposed =Window ]interface {XRInputSource readonly attribute XRHandedness handedness ;readonly attribute XRTargetRayMode targetRayMode ; [SameObject ]readonly attribute XRSpace targetRaySpace ; [SameObject ]readonly attribute XRSpace ?gripSpace ; [SameObject ]readonly attribute FrozenArray <DOMString >profiles ;readonly attribute boolean skipRendering ; };
注: XRInputSource
インターフェイスは、WebXR Gamepads
Module によっても拡張される
handedness 属性は、XR 入力ソースが
どちらの手に関連付けられているかを、存在する場合に記述する。自然な利き手を持たない入力ソース
(ヘッドセット装着型コントロールなど)、または利き手が現在不明な入力ソースは、この属性を
"none"
に設定しなければならない。
targetRayMode 属性は、ターゲットレイを生成するために
使用される方法を記述し、望まれる場合にアプリケーションがターゲットレイをユーザーにどのように提示すべきかを示す。
-
gazeは、ターゲットレイが viewer を起点とし、 viewer が向いている方向に従うことを示す。(これは、ヘッドマウントディスプレイの文脈では一般に "gaze input" デバイスと呼ばれる。) -
tracked-pointerは、ターゲットレイが ハンドヘルドデバイスまたはその他のハンドトラッキング機構のいずれかから発生し、ユーザーが手または 保持されたデバイスをポインティングに使用していることを表すことを示す。トラッキング対象のオブジェクトに 相対するターゲットレイの向きは、利用可能な場合、プラットフォーム固有の人間工学ガイドラインに 従わなければならない。プラットフォーム固有の指針がない場合、ターゲットレイは、ユーザーの人差し指が 伸ばされていた場合と同じ方向を指すべきである。XRSystemが、ハンドヘルドデバイスの一部が現実世界の表面に接触することを意図している、または意図するように なる(ペン先など)と判断する場合、ターゲットレイはその点を起点としなければならない。 -
screenは、入力ソースが、マウスクリックや タッチイベントなど、inline session の出力コンテキストに関連付けられた canvas 要素とのインタラクションで あったことを示す。 -
transient-pointerは、入力ソースが 特定のハードウェアの一部ではなく、オペレーティングシステムのインタラクション意図の一部として 生成されたことを示す。例としては、視線など直接公開するには機微すぎる情報に基づくユーザー意図、 WebDriver からの合成入力、または支援技術によって生成された入力がある。これは、W3C の設計原則に 従って支援技術が使用されていることを不注意に示さないよう、主要な入力としても使用される場合にのみ、 支援技術に使用されるべきである。
targetRaySpace 属性は、XRInputSource
の望ましいポインティングレイ(その -Z 軸に沿う)の位置と向きをトラッキングする
native origin
を持つ XRSpace であり、
targetRayMode
によって定義される。
targetRayMode
が "transient-pointer"
である入力ソースについては、targetRaySpace
はインタラクション開始時のインタラクション対象へのレイを表す。このポーズは、この XRInput の gripSpace 内で
静的であるべきである。
gripSpace 属性は、仮想オブジェクトがユーザーの手に
保持されているように見えるようレンダリングするために使用されるべきポーズをトラッキングする
native origin
を持つ XRSpace である。
ユーザーがまっすぐな棒を握った場合、この XRSpace は、
native origin
を曲げた指の重心に置き、-Z 軸が棒の長さに沿って親指の方を指す位置に置く。
X 軸は記述対象の手の甲に垂直で、ユーザーの右手の甲は +X の方向を指し、
ユーザーの左手の甲は -X の方向を指す。Y 軸は X と
Z 軸の関係から含意され、+Y はおおよそユーザーの腕の方向を指す。
skipRendering 属性は、この入力が可視であり、
現在のセッションによってレンダリングする必要がない場合があることを示す。skipRendering
が true で、targetRayMode が "tracked-pointer" である場合、ユーザーエージェントは
XR 入力ソースの表現が常に
ユーザーに表示されることを保証しなければならない。
コントローラーがユーザーに表示される例には、コントローラーがディスプレイとユーザーの間にある場合、ディスプレイが 透明である場合、またはコントローラーがオペレーティングシステムによってレンダリングされる場合が含まれる。
skipRendering
は、コントローラーなどの入力ソースをレンダリングしないことについて開発者に与えるヒントである。ピックレイと
カーソルは引き続きレンダリングされるべきである。
targetRayMode
が "transient-pointer"
である入力ソースについては、gripSpace
は、存在する場合は関連付けられたユーザージェスチャーであるべきであり、そうでなければ ViewerSpace、
あるいは別の XRInput の gripSpace または targetRaySpace など、ユーザーが制御する別の空間であるべきである。
これは、ユーザーがなお targetRaySpace を操作できるようにするためである。
入力ソースが本質的にトラッキング可能でない場合、たとえば targetRayMode
が "gaze"
または "screen"
である入力ソースのような場合、gripSpace
は null でなければならない。
profiles 属性は、入力ソースの望ましい視覚表現と
振る舞いの両方を示す input profile
name の list である。
input profile name は、スペースを含まず、別々の単語を
ハイフン(-)文字で連結した ASCII 小文字の DOMString
である。可能な場合はデバイスベンダーの好ましい表現を用いて、説明的な名前を選ぶべきである。プラットフォームが
USB ベンダー ID および製品 ID などの適切な識別子を提供する場合、それを使用してもよい。シリアル番号など、
単一のデバイスを一意に識別する値は使用してはならない。input profile name は、デバイスの利き手を示す情報を
含んではならない。複数のユーザーエージェントが同じデバイスを公開する場合、それらは同じ
input profile name を報告するよう努めるべきである。
WebXR Input
Profiles Registry は、input profile
name を管理するための推奨場所である。
プロファイルは具体性の降順で与えられる。リストの最初のエントリーの後に与えられる任意の input profile name は、デバイスの代替表現を表すフォールバック値を提供すべきである。これには、より汎用的または 以前のバージョンのデバイス、十分に類似したより広く認識されているデバイス、またはデバイス種別の広い説明 ("generic-trigger-touchpad" など)が含まれうる。複数のプロファイルが与えられる場合、それらが記述する レイアウトはすべて、リスト内の他のすべてのプロファイルの上位集合または下位集合を表さなければならない。
XRSession が
inline session である場合、
profiles
は空リストでなければならない。
ユーザーエージェントは、その裁量により、適切な汎用の input profile name のみ、または空リストのみを報告することを選んでもよい。これが適切なシナリオとしては、入力デバイスを 信頼性をもって識別できない場合、既知の入力プロファイルが入力デバイスに一致しない場合、またはユーザーエージェントが 使用されている入力デバイスを隠したい場合などがある。
たとえば、Samsung HMD Odyssey のコントローラーは、標準的な Windows Mixed Reality コントローラーの
設計バリエーションである。両方のコントローラーは同じ入力レイアウトを共有する。その結果、Samsung HMD Odyssey
コントローラーの profiles
は次のようになりうる:
["samsung-odyssey", "microsoft-mixed-reality", "generic-trigger-squeeze-touchpad-thumbstick"].
コントローラーの外観はリスト内の最初のプロファイルによって最も正確に伝えられ、2 番目のプロファイルは許容可能な
代替を記述し、最後のプロファイルはデバイスを最も大まかな意味で記述する汎用フォールバックである。
(これはトリガー、スクイーズボタン、タッチパッド、およびサムスティックを持つコントローラーである。)
同様に、Valve Index コントローラーは HTC Vive コントローラーと後方互換性があるが、Index コントローラーには
追加のボタンと軸がある。その結果、Valve Index コントローラーの profiles
は次のようになりうる:
["valve-index", "htc-vive", "generic-trigger-squeeze-touchpad-thumbstick"]. この場合、
"valve-index" プロファイルによって記述される入力レイアウトは、"htc-vive"
プロファイルによって記述されるレイアウトの上位集合である。また、"valve-index" プロファイルは
コントローラーの正確な外観を示す一方、"htc-vive" コントローラーは大きく異なる外観を持つ。
この場合、UA はその差異を許容可能と判断したことになる。そして最初の例と同様に、最後のプロファイルは汎用の
フォールバックである。
(正確な文字列は例にすぎない。実際のプロファイル名は WebXR Input
Profiles Registry で管理される。)
注: XRSession の
inputSources
配列内の XRInputSource
は「ライブ」である。そのため、その内部の値はインプレースで更新される。これは、あるフレームで
XRInputSource
の属性への参照を保存し、状態変化を調べるために後続のフレームで同じ属性と比較しても機能しないことを意味する。
なぜなら、それらは同じオブジェクトになるためである。したがって、フレーム間で入力状態を比較したい開発者は、
問題となる状態の内容をコピーすべきである。
XR 入力ソースは、
primary action を
サポートする場合、primary input
source である。primary
action は、開始されると selectstart,
selectend,
および select
イベントを生成する、プラットフォーム固有のアクションである。可能な primary action の例は、トリガー、タッチパッド、またはボタンを押すこと、
コマンドを発話すること、または手のジェスチャーを行うことである。プラットフォームガイドラインが推奨される
primary input を定義している場合、それを primary
action として使用すべきであり、そうでなければユーザーエージェントは自由に 1 つを選択できる。
デバイスは少なくとも 1 つの primary input
source をサポートしなければならない。
XR 入力ソースは、 primary action をサポートしない場合、tracked input source である。これらの入力は主にポーズデータを提供することを意図している。 注: tracked input source の例としては、ユーザーの脚または小道具のための トラッキングアタッチメントが挙げられる。primary action を検出するためのジェスチャー認識が行われていない場合、トラッキングされた手も tracked input source とみなされることがある。
XRSession
session の XR
入力
ソース source がその primary action を開始したとき、UA は次の手順を実行しなければならない:
-
frame を、session の 関連するレルム内の 新しい
XRFrameとし、sessionに session を、time にアクションが発生した時刻を持たせる。 -
名前
selectstart, frame frame, および source source で 入力ソースイベントを発火するよう タスクをキューに入れる。
XRSession
session の XR
入力
ソース source がその primary action を終了したとき、UA は次の手順を実行しなければならない:
-
frame を、session の 関連するレルム内の 新しい
XRFrameとし、sessionに session を、time にアクションが発生した時刻を持たせる。 -
次の手順を実行するよう タスクをキューに入れる:
-
名前
select, frame frame, および source source で 入力ソースイベントを発火する。 -
名前
selectend, frame frame, および source source で 入力ソースイベントを発火する。
-
各 XR 入力ソースは、
primary
squeeze action を定義してもよい。primary squeeze action は、開始されると squeezestart,
squeezeend,
および squeeze
イベントを生成する、プラットフォーム固有のアクションである。primary squeeze action は、おおよそ握るまたはつかむことに対応する
アクションに使用されるべきである。可能な primary squeeze action の例は、
グリップトリガーを押すこと、またはつかむ手のジェスチャーを行うことである。プラットフォームガイドラインが
推奨される primary squeeze action を定義している場合、それを primary squeeze action として使用すべきであり、そうでなければ
ユーザーエージェントは 1 つを選択してもよい。
XRSession
session の XR
入力
ソース source がその primary squeeze action を開始したとき、UA は次の手順を
実行しなければならない:
-
frame を、session の 関連するレルム内の 新しい
XRFrameとし、sessionに session を、time にアクションが発生した時刻を持たせる。 -
名前
squeezestart, frame frame, および source source で 入力ソースイベントを発火するよう タスクをキューに入れる。
XRSession
session の XR
入力
ソース source がその primary squeeze action を終了したとき、UA は次の手順を
実行しなければならない:
-
frame を、session の 関連するレルム内の 新しい
XRFrameとし、sessionに session を、time にアクションが発生した時刻を持たせる。 -
次の手順を実行するよう タスクをキューに入れる:
-
名前
squeeze, frame frame, および source source で 入力ソースイベントを発火する。 -
名前
squeezeend, frame frame, および source source で 入力ソースイベントを発火する。
-
プラットフォーム固有の振る舞いによって、primary action または primary squeeze action が 中断またはキャンセルされることがある。たとえば、primary action または primary squeeze action が開始された後、それが終了する前に、XR 入力ソースが XR device から取り除かれることがある。
XRSession
session の XR
入力
ソース source の primary action がキャンセルされたとき、UA は次の手順を実行しなければならない:
-
frame を、session の 関連するレルム内の 新しい
XRFrameとし、sessionに session を、time にアクションが発生した時刻を持たせる。 -
名前
selectend, frame frame, および source source でXRInputSourceEventである 入力ソースイベントを発火するよう タスクをキューに入れる。
XRSession
session の XR
入力
ソース source の primary squeeze action がキャンセルされたとき、UA は次の手順を
実行しなければならない:
-
frame を、session の 関連するレルム内の 新しい
XRFrameとし、sessionに session を、time にアクションが発生した時刻を持たせる。 -
名前
squeezeend, frame frame, および source source でXRInputSourceEventである 入力ソースイベントを発火するよう タスクをキューに入れる。
10.2. 一時的入力
一部の XR device は 一時的入力ソースを サポートすることがある。そこでは、XR 入力ソースは transient action を 実行している間だけ意味を持つ。これは、primary input source の primary action であるか、tracked input source のためのデバイス固有の auxiliary action である。
一例として、inline session
に対するマウス、タッチ、またはスタイラス入力があり、
これは targetRayMode
が screen
に設定された一時的な XRInputSource
を生成しなければならず、primary pointer については primary action
として扱われ、非 primary pointer については非 primary の auxiliary action として扱われる。
別の例として、視線に基づくインタラクションなど、直接公開できない機微情報から得られる入力を伴う
オペレーティングシステムからの意図がある。これらは targetRayMode
が transient-pointer
に設定された一時的な XRInputSource
を生成し、primary
action として扱われる。
一時的入力ソースは、 transient action の継続時間中だけ、セッションの アクティブな XR 入力ソースのリストに存在する。
一時的入力ソースは、 非一時的な primary actions のための アルゴリズムの代わりに、transient actions を処理するとき、次のシーケンスに従う:
XRSession
session の 一時的入力ソース source がその
transient action
を開始したとき、UA は次の手順を実行しなければならない:
-
frame を、session の 関連するレルム内の 新しい
XRFrameとし、sessionに session を持たせ、アクションが発生した時刻のためのものとする。 -
次の手順を実行するよう タスクをキューに入れる:
-
必要に応じて、XR 入力ソースのアクションによって 生成される任意の
"pointerdown"イベントを発火する。 -
XR 入力ソースを追加して、アクティブな XR 入力ソースのリストに入れる。
-
transient action が primary action である場合、 名前
selectstart, frame frame, および source source で 入力ソースイベントを発火する。
-
XRSession
session の 一時的入力ソース source がその
transient action
を終了したとき、UA は次の手順を実行しなければならない:
-
frame を、session の 関連するレルム内の 新しい
XRFrameとし、sessionに session を持たせ、アクションが発生した時刻のためのものとする。 -
次の手順を実行するよう タスクをキューに入れる:
-
transient action が primary action である場合、 名前
select, frame frame, および source source で 入力ソースイベントを発火する。 -
必要に応じて、XR 入力ソースのアクションによって 生成される任意の
"click"イベントを発火する。 -
transient action が primary action である場合、 名前
selectend, frame frame, および source source で 入力ソースイベントを発火する。 -
XR 入力ソースを削除して、 アクティブな XR 入力ソースのリストから 取り除く。
-
必要に応じて、XR 入力ソースのアクションによって 生成される任意の
"pointerup"イベントを発火する。
-
XRSession
session の 一時的入力ソース source の
transient action
がキャンセルされたとき、UA は次の手順を実行しなければならない:
-
frame を、session の 関連するレルム内の 新しい
XRFrameとし、sessionに session を持たせ、アクションが発生した時刻のためのものとする。 -
次の手順を実行するよう タスクをキューに入れる:
-
transient action が primary action である場合、 名前
selectend, frame frame, および source source で 入力ソースイベントを発火する。 -
XR 入力ソースを削除して、 アクティブな XR 入力ソースのリストから 取り除く。
-
必要に応じて、XR 入力ソースのアクションによって 生成される任意の
"pointerup"イベントを発火する。
-
10.3. XRInputSourceArray
XRInputSourceArray
は XRInputSource
の list を表す。
これは、XRSession の
inputSources
属性のように、list
の内容が時間とともに変化することが
期待される場合に、frozen
array type に優先して使用される。
[SecureContext ,Exposed =Window ]interface {XRInputSourceArray iterable <XRInputSource >;readonly attribute unsigned long length ;getter XRInputSource (unsigned long ); };index
XRInputSourceArray
の length 属性は、XRInputSourceArray
内に含まれる XRInputSource
の数を示す。
XRInputSourceArray
の indexed property getter は、指定されたインデックスの
XRInputSource
を取得する。
11. レイヤー
注: この仕様は XRWebGLLayer
レイヤーのみを定義するが、将来の仕様拡張では追加のレイヤー種別と、それらが描画元とする画像ソースが追加されることが
期待される。
11.1. XRLayer
[SecureContext ,Exposed =Window ]interface :XRLayer EventTarget {};
XRLayer は、
XRWebGLLayer
および将来の拡張によって導入されるその他のレイヤー種別の基底クラスである。
11.2. XRWebGLLayer
XRWebGLLayer
は、レンダリング先となる WebGL フレームバッファを提供するレイヤーであり、ハードウェアアクセラレーションされた
3D グラフィックスのレンダリングを XR
device 上に提示できるようにする。
typedef (WebGLRenderingContext or WebGL2RenderingContext );XRWebGLRenderingContext dictionary {XRWebGLLayerInit boolean =antialias true ;boolean =depth true ;boolean =stencil false ;boolean =alpha true ;boolean =ignoreDepthValues false ;double = 1.0; }; [framebufferScaleFactor SecureContext ,Exposed =Window ]interface :XRWebGLLayer XRLayer {constructor (XRSession ,session XRWebGLRenderingContext ,context optional XRWebGLLayerInit = {}); // AttributeslayerInit readonly attribute boolean antialias ;readonly attribute boolean ignoreDepthValues ;attribute float ?fixedFoveation ; [SameObject ]readonly attribute WebGLFramebuffer ?framebuffer ;readonly attribute unsigned long framebufferWidth ;readonly attribute unsigned long framebufferHeight ; // MethodsXRViewport ?getViewport (XRView ); // Static Methodsview static double getNativeFramebufferScaleFactor (XRSession ); };session
各 XRWebGLLayer
は、最初は null である context オブジェクトを持ち、これは WebGLRenderingContext
または WebGL2RenderingContext
のいずれかのインスタンスである。
各 XRWebGLLayer
は、関連付けられた session を持ち、これはそれが作成されたときの XRSession
である。
XRWebGLLayer(session, context, layerInit)
コンストラクターは、呼び出されたとき次の手順を実行しなければならない:
-
layer を、session の 関連するレルム内の 新しい
XRWebGLLayerとする。 -
session の ended 値が
trueである場合、InvalidStateErrorを投げ、これらの手順を中止する。 -
context が lost である場合、
InvalidStateErrorを投げ、これらの手順を中止する。 -
session が immersive session であり、context の XR compatible 真偽値が
falseである場合、InvalidStateErrorを投げ、これらの手順を中止する。 -
layer の context を context に初期化する。
-
layer の session を session に初期化する。
-
layer の
ignoreDepthValuesを次のように初期化する:- layerInit の
ignoreDepthValues値がfalseであり、XR Compositor が depth 値を使用する場合: -
layer の
ignoreDepthValuesをfalseに初期化する。 - そうでない場合:
-
layer の
ignoreDepthValuesをtrueに初期化する。
- layerInit の
-
layer の composition enabled 真偽値を次のように初期化する:
- session が inline session である場合:
-
layer の composition enabled を
falseに初期化する。 - そうでない場合:
-
layer の composition enabled 真偽値を
trueに初期化する。
-
- layer の composition enabled 真偽値が
trueである場合: -
-
scaleFactor を layerInit の
framebufferScaleFactorとする。 -
ユーザーエージェントはここで、たとえば性能上の理由でバッファ寸法を 2 の累乗に収めたい場合など、 適切と考えるように scaleFactor をクランプまたは丸めることを選んでもよい。
-
framebufferSize を、幅と高さにそれぞれ scaleFactor を掛けた recommended WebGL framebuffer resolution とする。
-
layer の
framebufferを、context の 関連するレルム内の 新しいWebGLFramebufferに初期化する。これは context で作成された寸法 framebufferSize の opaque framebuffer であり、session は session に 初期化され、layerInit のdepth,stencil, およびalpha値を持つ。 -
layer の合成をサポートするために必要に応じて、GPU からアクセス可能な メモリバッファを含む、session の XR device と互換性のあるリソースを 割り当て、初期化する。
-
何らかの理由で layer のリソースを作成できなかった場合、
OperationErrorを投げ、これらの手順を中止する。
- そうでない場合:
-
-
layer の
antialiasを、layer のcontextの actual context parameters のantialias値に初期化する。 -
layer の
framebufferをnullに初期化する。
-
- layer の composition enabled 真偽値が
-
layer を返す。
注: XRWebGLLayer
の
composition enabled 真偽値が false に
設定されている場合、XRWebGLLayerInit
オブジェクト上のすべての値は無視される。これは WebGLRenderingContext
の
デフォルトフレームバッファが、すでにそのコンテキストの actual context parameters を使用して割り当てられており、上書きできないためである。
context 属性は、XRWebGLLayer
が作成されたときの WebGLRenderingContext
である。
各 XRWebGLLayer
は、最初 true に設定される composition enabled 真偽値を持つ。false
に
設定されている場合、それは XRWebGLLayer
が自身の WebGLFramebuffer
を割り当ててはならず、framebuffer
プロパティを反映する XRWebGLLayer
のすべてのプロパティは、代わりに context のデフォルトフレームバッファのプロパティを反映しなければならないことを示す。
XRWebGLLayer
の framebuffer 属性は、
composition
enabled が true である場合は opaque としてマークされた WebGLFramebuffer
のインスタンスであり、そうでない場合は null である。XRWebGLLayer
が作成された後、開発者は framebuffer
サイズを調整できない。
opaque
framebuffer は標準的な WebGLFramebuffer
と同一に機能するが、default
framebuffer により近く振る舞わせる次の変更を伴う:
-
opaque framebuffer は、WebGL 1.0 であってもアンチエイリアスをサポートしてもよい。
-
opaque framebuffer のアタッチメントは検査または変更できない。opaque framebuffer に対して
framebufferTexture2D,framebufferRenderbuffer,deleteFramebuffer, またはgetFramebufferAttachmentParameterを呼び出すと、INVALID_OPERATIONエラーを生成しなければならない。 -
opaque framebuffer は、関連する session を持ち、これはそれが 作成された対象の
XRSessionである。 -
opaque framebuffer は、
requestAnimationFrame()コールバックの外では不完全とみなされる。その session のrequestAnimationFrame()コールバック内でない場合、checkFramebufferStatusへの呼び出しはFRAMEBUFFER_UNSUPPORTEDエラーを生成しなければならず、opaque framebuffer をクリア、 描画、または読み取りしようとする試みは、INVALID_FRAMEBUFFER_OPERATIONエラーを生成しなければならない。 -
depthtrueで初期化された opaque framebuffer は、アタッチされた深度バッファを持つ。 -
stenciltrueで初期化された opaque framebuffer は、アタッチされたステンシルバッファを持つ。 -
opaque framebuffer のカラーバッファは、
alphaがtrueである場合に限り、アルファチャンネルを持つ。 -
XR Compositor は、 opaque framebuffer がプリマルチプライドアルファの色を含むと仮定する。 これは、
premultipliedAlphaの値がcontextの actual context parameters に設定されているかに関係なく真である。
注: ユーザーエージェントは、depth
および stencil
の true 値を尊重することを要求される。これは、drawing buffer を作成するときの WebGL の振る舞いに類似している。
opaque framebuffer
にアタッチされたバッファは、最初に作成されたとき、
または各 XR animation
frame の処理前に、下の表の値へ
クリアされなければならない。これは WebGL コンテキストの default
framebuffer の振る舞いと同一である。Opaque framebuffers は、関連付けられた WebGL コンテキストの
preserveDrawingBuffer
値に関係なく常にクリアされる。
| バッファ | クリア値 |
|---|---|
| 色 | (0, 0, 0, 0) |
| 深度 | 1.0 |
| ステンシル | 0 |
注: 実装は、開発者が別プロセスからバッファ内容へアクセスできないことが 保証できる限り、opaque framebuffer に必要な暗黙のクリア操作を最適化で省略してもよい。 たとえば、開発者が明示的なクリアを行う場合、暗黙のクリアは不要である。
alpha
が true に設定された状態で XRWebGLLayer
が作成された場合、framebuffer
は RGBA
色形式のテクスチャに裏付けられなければならない。
alpha
が false に設定された状態で XRWebGLLayer
が作成された場合、framebuffer
は RGB
色形式のテクスチャに裏付けられなければならない。
しかし、XR Compositor は、
framebuffer
の
バッキングのピクセルを、SRGB8_ALPHA8
または SRGB8
colorFormat
内にあるかのように扱わなければならない。
注: これは、XR Compositor が framebuffer
を裏付けるテクスチャを処理するとき、線形 RGBA
または RGB
からのガンマ変換を行ってはならないことを意味する。そうしないと、最終レンダリングのピクセルが明るすぎて
見えることになり、通常の 2D WebGLRenderingContext
コンテキスト上のレンダリングと一致しなくなる。
XRWebGLLayer
が immersive
session の baseLayer
として設定された場合、opaque
framebuffer の内容は、XR animation
frame が完了した直後に immersive XR device に提示されるが、
前回の XR animation
frame
以降に少なくとも次のいずれかが発生した場合に限られる:
-
immersive session の
baseLayerが変更された。 -
clear,drawArrays,drawElements, またはフレームバッファのカラー値に同様に影響するその他の任意のレンダリング操作が、XRWebGLLayerに関連付けられたWebGLRenderingContextの現在バインドされたフレームバッファとして opaque framebuffer がある間に呼び出された。
opaque framebuffer が immersive XR device に提示される前に、ユーザーエージェントは、 すべてのレンダリング操作が opaque framebuffer にフラッシュ済みであることを保証しなければならない。
各 XRWebGLLayer
は target framebuffer を持ち、これは composition
enabled が true である場合は
framebuffer
であり、そうでない場合は context の
デフォルトフレームバッファである。
framebufferWidth および framebufferHeight 属性は、それぞれ
target framebuffer のアタッチメントの幅と高さを返す。
antialias 属性は、target
framebuffer が UA の選択する技法を用いて
アンチエイリアスをサポートする場合は true であり、アンチエイリアスが実行されない場合は
false である。
ignoreDepthValues 属性は、
true である場合、XR
Compositor がレンダリング時に深度バッファアタッチメント内の値を
使用してはならないことを示す。この属性が false である場合、深度バッファアタッチメントの内容が
XR Compositor
によって使用され、レイヤー内にレンダリングされたシーンを
表すことが期待されることを示す。
バッファに格納される深度値は、0.0 から 1.0 の間であることが期待され、
0.0 は depthNear
の距離を表し、1.0 は depthFar
の距離を表し、中間値は線形に補間される。これは WebGL のデフォルトの振る舞いである。(追加の詳細については
depthRange
関数の文書を参照。)
注: シーンの深度バッファをコンポジターに利用可能にすることで、 一部のプラットフォームは改良された再投影など、品質と快適性の向上を提供できる。
fixedFoveation 属性は、XR
Compositor によって使用される foveation の量を制御する。ユーザーエージェントまたはデバイスがこの属性を
サポートしない場合、取得時には null を返すべきであり、設定は no-op であるべきである。
fixedFoveation
を 0 未満の値に設定すると 0 に設定され、1 より大きい値に設定すると
1 に設定される。0 は foveation の最小量を設定し、1 は最大量を設定する。
XR Compositor
がこれらの値をどのように解釈するかは
ユーザーエージェント次第である。fixedFoveation
レベルが変更された場合、それは次の XRFrame で効果を持つ。
注: Fixed foveation は、ユーザーの視野の端付近で コンテンツがレンダリングされる解像度を下げる技法である。GPU フィル性能によって制限される体験を大幅に改善できる。 電力消費を減らし、アプリケーションが目用テクスチャの解像度を上げることを可能にする。背景画像のような 低コントラストのテクスチャに最も有用であり、テキストや詳細画像のような高コントラストのものにはあまり有用ではない。 作者は、性能と視覚品質の最良のトレードオフを達成するため、フレームごとにレベルを調整できる。
各 XRWebGLLayer
は list of
full-sized viewports を持たなければならない。これは
XRSession が
公開しうる各 view について 1 つの WebGL
viewport を含む list であり、現在は
active でないが現在のセッションで
active になりうる secondary
views も含む。ビューポートは width
および height
が 0 より大きくなければならず、target framebuffer の境界を超えない矩形を記述しなければならない。
ビューポートは重なり合ってはならない。
composition enabled が false であり、
session の
list of
views が、eye が
"none"
である単一の view を含む場合、
list
of full-sized viewports は、
context の
デフォルトフレームバッファ全体を覆う単一の WebGL
viewport を含まなければならない。
composition enabled が false であり、
session の
list of
views が 2 つの primary
views、すなわち eye が
"left"
であるものと、eye が
"right"
であるものを含む場合、list of full-sized viewports は 2 つの
WebGL viewport を含まなければならない。1 つは "left"
view に関連付けられ、もう 1 つは "right"
view に関連付けられる。ユーザーエージェントは、
上記の制約に従って、これらのビューポートのサイズと位置を決定する。
注: この仕様は、ステレオ inline ビューポートについて、
横並びなど特定の詰め方を要求しない。作者はレイアウトを仮定するのではなく、各 XRView
について getViewport()
を使用すべきである。
各 XRWebGLLayer
は list of
viewport objects を持たなければならない。これは、XRSession が
現在公開している各 active な
view について 1 つの XRViewport
を含む list である。
getViewport()
は、与えられた XRView
がレイヤーへレンダリングするときに使用すべき XRViewport
を問い合わせる。
getViewport(view) メソッドは、
XRWebGLLayer
layer 上で呼び出されたとき、次の手順を実行しなければならない:
-
session を view の session とする。
-
frame を session の animation frame とする。
-
session が layer の session と等しくない場合、
InvalidStateErrorを投げ、これらの手順を中止する。 -
frame の active 真偽値が
falseである場合、InvalidStateErrorを投げ、これらの手順を中止する。 -
view の frame が frame と等しくない場合、
InvalidStateErrorを投げ、これらの手順を中止する。 -
viewport modifiable フラグが
trueであり、 view の requested viewport scale が current viewport scale と等しくない場合:-
list of viewport objects 内で、 view に関連付けられた
XRViewportを、session について view に関連付けられた list of full-sized viewports から scaled viewport を取得する結果のXRViewportに設定する。
-
view の viewport modifiable フラグを false に設定する。
-
viewport を、view に関連付けられた list of viewport objects からの
XRViewportとする。 -
viewport を返す。
注: viewport modifiable
フラグは、
current viewport
scale に変更がない場合でも、意図的に false に設定される。これにより、そのビューについて、アニメーションフレーム内の
getViewport(view) 呼び出しは常に一貫した結果を返し、最初に取得された値がフレームの残りの間
固定されることが保証される。アプリケーションが getViewport() の後に requestViewportScale()
を呼び出した場合、要求された値は、将来のフレームで getViewport() が再び呼び出されたときにのみ
後で適用される。
各 XRSession
は native
WebGL framebuffer resolution を識別しなければならない。
これは、XR device の
物理ピクセル解像度に一致するために必要な WebGL フレームバッファのピクセル解像度である。
XRSession
session の native WebGL framebuffer resolution は、
次の手順を実行することによって決定される:
-
session が inline session である場合、native WebGL framebuffer resolution を session の
renderStateの output canvas の物理ディスプレイピクセルでのサイズに 設定し、canvas のサイズが変化するたび、または output canvas が変更されるたびにこれらの手順を再評価し、これらの手順を中止する。 -
native WebGL framebuffer resolution を、 セッションのすべての
XRViewを 含むのに十分な大きさのフレームバッファのピクセルと、最も高い拡大率の下にあるディスプレイ領域の 物理スクリーンピクセルとの間で 1:1 の比率を持つために必要な解像度に設定する。記述されたように ネイティブ解像度を決定する方法が存在しない場合、recommended WebGL framebuffer resolution を使用してもよい。
さらに、XRSession
は recommended WebGL framebuffer resolution を
識別しなければならない。これは、平均的なアプリケーションに性能と品質の良好なバランスを提供しつつ、セッションの
すべての XRView を
含むのに十分な大きさの WebGL フレームバッファ解像度の最良推定を表す。これは
native WebGL framebuffer resolution より小さくても、
大きくても、等しくてもよい。新しい opaque framebuffer
はこの解像度で作成され、幅と高さはそれぞれ、提供された任意の XRWebGLLayerInit
の
framebufferScaleFactor
によってスケールされる。
注: ユーザーエージェントは、
recommended WebGL framebuffer resolution を
推定するために任意の方法を自由に使用できる。推奨サイズを問い合わせるためのプラットフォーム固有の方法がある場合、
それを使用することが推奨されるが、要求はされない。framebufferScaleFactor
および getNativeFramebufferScaleFactor()
によって使用されるスケール係数は幅と高さに別々に適用されるため、2 のスケール係数は全体のピクセル数を 4 倍にする。
プラットフォームがピクセル数に基づく面積ベースの render scale を公開する場合、ユーザーエージェントはそれを
WebXR スケール係数へ変換するために平方根を取る必要がある。
getNativeFramebufferScaleFactor(session)
メソッドは、呼び出されたとき次の手順を実行しなければならない:
-
session を this とする。
-
session の ended 値が
trueである場合、0.0を返し、 これらの手順を中止する。 -
session の recommended WebGL framebuffer resolution の幅と高さにそれぞれ掛けることで、session の native WebGL framebuffer resolution が 得られる値を返す。
11.3. WebGL 컨텍스트 호환성
WebGL 컨텍스트가 immersive XR imagery의 소스로 사용되려면, immersive XR device에 대한 호환 가능한
그래픽 어댑터에서 생성되어야 한다. 무엇이 compatible graphics
adapter로 간주되는지는 플랫폼에 따라 다르지만, graphics adapter가 과도한 지연 없이
immersive XR
device에 imagery를 제공할 수 있음을 의미하는 것으로
이해된다. WebGL 컨텍스트가 compatible graphics adapter에서 이미 생성되지 않았다면,
일반적으로 XRWebGLLayer와
함께 사용되기 전에 해당 adapter에서 다시 생성되어야 한다.
참고: 단일 GPU를 가진 XR 플랫폼에서는 GPU가 플랫폼이 알리는 immersive XR device와 호환된다고 안전하게 가정할 수 있으므로, 모든 hardware accelerated WebGL context 역시 호환된다. integrated GPU와 discrete GPU를 모두 가진 PC에서는 discrete GPU가 일반적으로 더 높은 성능의 chip이므로 compatible graphics adapter로 간주되는 경우가 많다. 여러 graphics adapter가 설치된 desktop PC에서는 immersive XR device가 물리적으로 연결된 adapter가 compatible graphics adapter로 간주될 가능성이 높다.
참고: Inline session은 canvas와 같은 graphics adapter를 사용하여 렌더링하므로,
xrCompatible
context가 필요하지 않다.
partial dictionary WebGLContextAttributes {boolean =xrCompatible false ; };partial interface mixin WebGLRenderingContextBase { [NewObject ]Promise <undefined >makeXRCompatible (); };
사용자 에이전트가 이 명세를 구현할 때, 모든 WebGLRenderingContextBase에
처음에는 false로 설정되는 XR compatible boolean을 설정해야 한다.
XR compatible boolean이
true로 설정되면, 그 context는 현재 immersive XR device에서 요청된 모든 XRSession에
대한 layer와 함께 사용할 수 있다.
참고: 이 flag는 느린 synchronous behavior를 도입하므로
권장되지 않는다. asynchronous solution으로 대신 makeXRCompatible()을
호출하는 것을 고려하라.
XR compatible boolean은
context 생성 시점이나 context 생성 이후에 설정할 수 있으며, 잠재적으로 context loss가 발생할 수 있다.
context 생성 시점에 XR compatible
boolean을 설정하려면, WebGL context를 요청할 때 xrCompatible
context creation attribute를 true로 설정해야 한다. 요청하는 document의 origin이 "xr-spatial-tracking" permissions
policy를 사용할 수 없다면, xrCompatible은
효과가 없다.
xrCompatible
flag가 true이면, WebGLContextAttributes에서
사용자 에이전트가 immersive
XR
device에 대한 compatible graphics adapter를 사용하여 WebGL
context를 생성하도록 요청함으로써 context creation에 영향을 준다. 사용자 에이전트가 이에 성공하면, 생성된
context의 XR compatible
boolean은 true로 설정된다.
immersive
XR device를 얻으려면, immersive XR device가 선택되도록 보장하는 것이
호출되어야 한다.
참고: Immersive XR device가 선택되도록 보장하는 작업은
in parallel로 실행되어야 하며, 이는 main thread에 느린 synchronous behavior를
도입한다. 사용자 에이전트는 대신 makeXRCompatible()을
사용하도록 요청하는 warning을 console에 출력해야 한다.
XRWebGLLayer를
생성한다.
function onXRSessionStarted( xrSession) { const glCanvas= document. createElement( "canvas" ); const gl= glCanvas. getContext( "webgl" , { xrCompatible: true }); loadWebGLResources(); xrSession. updateRenderState({ baseLayer: new XRWebGLLayer( xrSession, gl) }); }
context가 생성된 후 XR compatible
boolean을 설정하려면, makeXRCompatible()
메서드를 사용한다.
참고: 일부 시스템에서는 이 flag가 예를 들어
high powered discrete GPU를 켜거나 모든 command를 on-device GPU로 proxy할 수 있다. XR을 사용할 수도 있고
사용하지 않을 수도 있는 상황이라면, immersive session을 시작하려는 경우에만 makeXRCompatible()을
호출하는 것이 권장된다.
makeXRCompatible()
메서드는 WebGLRenderingContextBase가
immersive XR
device에 대한 compatible graphics adapter에서 실행되도록 보장한다.
이 메서드가 호출되면, 사용자 에이전트는 다음 단계를 실행해야 한다:
-
요청하는 document의 origin이 "xr-spatial-tracking" permissions policy를 사용할 수 없다면, promise를 resolve하고 반환한다. XR permissions policy가 비활성화된 경우, 이 경우에는 XR device가 없는 것처럼 동작하기를 원한다.
makeXRCompatible()은 set-and-forget method로 의도되었기 때문이다. -
promise를 이
WebGLRenderingContextBase의 Realm에서 생성된 새 Promise로 둔다. -
context를 this로 둔다.
-
다음 단계를 in parallel로 실행한다:
-
device를 immersive XR device가 선택되도록 보장한 결과로 둔다.
-
context의 XR compatible boolean을 다음과 같이 설정한다:
- context의 WebGL context lost flag가 설정된 경우:
-
context의 XR compatible boolean을
false로 설정하고,InvalidStateError로 promise를 reject하도록 task를 queue한다. - device가
null인 경우: -
context의 XR compatible boolean을
false로 설정하고,InvalidStateError로 promise를 reject하도록 task를 queue한다. - context의 XR compatible boolean이
true인 경우: -
promise를 resolve하도록 task를 queue한다.
- context가 device에 대한 compatible graphics adapter에서 생성된 경우:
-
context의 XR compatible boolean을
true로 설정하고 promise를 resolve하도록 task를 queue한다. - 그렇지 않으면:
-
다음 단계를 수행하도록 WebGL task source에 task를 queue한다:
-
context를 강제로 lost 상태로 만든다.
-
WebGL 명세에 설명된 대로 context loss를 처리한다:
-
canvas를 context의 canvas로 둔다.
-
context의 webgl context lost flag가 설정되어 있으면, 이 단계를 중단한다.
-
context의 webgl context lost flag를 설정한다.
-
context가 생성한 각
WebGLObjectinstance의 invalidated flag를 설정한다. -
"WEBGL_lose_context"를 제외한 모든 extension을 비활성화한다.
-
다음 단계를 수행하도록 WebGL task source에 task를 queue한다:
-
canvas에서 "webglcontextlost"라는 이름을 가진 WebGL context event e를
statusMessage가 ""로 설정된 상태로 fire한다. -
e의 canceled flag가 설정되어 있지 않으면,
AbortError로 promise를 reject하고 이 단계를 중단한다. -
다음 단계를 in parallel로 실행한다.
-
device에 대한 compatible graphics adapter에서 restorable drawing buffer를 기다린다.
-
다음 단계를 수행하도록 WebGL task source에 task를 queue한다:
-
device에 대한 compatible graphics adapter에서 context를 restore한다.
-
context의 XR compatible boolean을
true로 설정한다. -
promise를 resolve한다.
-
-
-
-
-
-
-
promise를 반환한다.
또한, WebGL context가 lost될 때마다 "webglcontextlost" event를 fire하기 전에 다음 단계를 실행한다:
-
context의 XR compatible boolean을
false로 설정한다.
XRWebGLLayer를
생성한다.
const glCanvas= document. createElement( "canvas" ); const gl= glCanvas. getContext( "webgl" ); loadWebGLResources(); glCanvas. addEventListener( "webglcontextlost" , ( event) => { // Indicates that the WebGL context can be restored. event. canceled= true ; }); glCanvas. addEventListener( "webglcontextrestored" , ( event) => { // WebGL resources need to be re-created after a context loss. loadWebGLResources(); }); async function onXRSessionStarted( xrSession) { // Make sure the canvas context we want to use is compatible with the device. // May trigger a context loss. await gl. makeXRCompatible(); xrSession. updateRenderState({ baseLayer: new XRWebGLLayer( xrSession, gl) }); }
12. 이벤트
별도로 지정되지 않는 한, 이 명세에서 queue된 모든 task source는 XR task source이다.
12.1. XRSessionEvent
XRSessionEvent는
XRSession의
상태 변경을 나타내기 위해 fire된다.
[SecureContext ,Exposed =Window ]interface :XRSessionEvent Event {(constructor DOMString ,type XRSessionEventInit ); [eventInitDict SameObject ]readonly attribute XRSession session ; };dictionary :XRSessionEventInit EventInit {required XRSession ; };session
session 속성은 event를 생성한 XRSession을
나타낸다.
12.2. XRInputSourceEvent
XRInputSourceEvent는
XRInputSource의
상태 변경을 나타내기 위해 fire된다.
[SecureContext ,Exposed =Window ]interface :XRInputSourceEvent Event {(constructor DOMString ,type XRInputSourceEventInit ); [eventInitDict SameObject ]readonly attribute XRFrame frame ; [SameObject ]readonly attribute XRInputSource inputSource ; };dictionary :XRInputSourceEventInit EventInit {required XRFrame ;frame required XRInputSource ; };inputSource
inputSource 속성은 이 event를 생성한 XRInputSource를
나타낸다.
frame 속성은 event가 발생한 시간에 대응하는 XRFrame이다.
이는 historical data를 나타낼 수 있다. getViewerPose()는
frame에서
호출될 때 exception을 throw해야 한다.
사용자 에이전트가 이름 name, XRFrame
frame, 및 XRInputSource
source로 input source event를 fire해야 하는 경우, 다음 단계를 실행해야 한다:
-
typename,frameframe, 및inputSourcesource를 가진XRInputSourceEventevent를 생성한다. -
frame의 active boolean을
true로 설정한다. -
frame에 대해 frame update를 적용한다.
-
frame의 active boolean을
false로 설정한다.
12.3. XRInputSourcesChangeEvent
XRInputSourcesChangeEvent는
XRSession에서
사용할 수 있는 active XR input source 목록의 변경을 나타내기 위해
fire된다.
[SecureContext ,Exposed =Window ]interface :XRInputSourcesChangeEvent Event {(constructor DOMString ,type XRInputSourcesChangeEventInit ); [eventInitDict SameObject ]readonly attribute XRSession session ; [SameObject ]readonly attribute FrozenArray <XRInputSource >added ; [SameObject ]readonly attribute FrozenArray <XRInputSource >removed ; };dictionary :XRInputSourcesChangeEventInit EventInit {required XRSession ;session required sequence <XRInputSource >;added required sequence <XRInputSource >; };removed
session 속성은 event를 생성한
XRSession을
나타낸다.
added 속성은 event 시점에
XRSession에
추가된 XRInputSource들의
list이다.
removed 속성은 event 시점에
XRSession에서
제거된 XRInputSource들의
list이다.
12.4. XRReferenceSpaceEvent
XRReferenceSpaceEvent는
XRReferenceSpace의
상태 변경을 나타내기 위해 fire된다.
[SecureContext ,Exposed =Window ]interface :XRReferenceSpaceEvent Event {(constructor DOMString ,type XRReferenceSpaceEventInit ); [eventInitDict SameObject ]readonly attribute XRReferenceSpace referenceSpace ; [SameObject ]readonly attribute XRRigidTransform ?transform ; };dictionary :XRReferenceSpaceEventInit EventInit {required XRReferenceSpace ;referenceSpace XRRigidTransform ?=transform null ; };
referenceSpace 속성은
이 event를 생성한 XRReferenceSpace를
나타낸다.
선택적 transform 속성은 event 전
coordinate system에서 referenceSpace의
native
origin의
event 후 위치와 orientation을 설명한다. XRSystem이
old coordinate system과 new coordinate system 사이의 delta를 결정할 수 없는 경우, 이 속성은 null일
수 있다.
참고: referenceSpace
또는 referenceSpace가
될 수 있는 상황은 headset이 두 개의 서로 다른 위치 사이에서 벗겨졌다가 다시 착용된 경우이다. 이러한 경우
experience가 world-locked content에 의존한다면, 사용자에게 경고하고 scene을 reset해야 한다.
12.5. XRVisibilityMaskChangeEvent
frustum이 rectangular display와 정확히 교차하지 않기 때문에, XRLayer의 전체 영역이
표시되지 않을 수 있다. 이 event는 사용자에게 표시되는 XRView의 region에
대해 experience에 알린다.
XRVisibilityMaskChangeEvent
event는 사용자 에이전트가 XRLayer의 표시되는
영역이 변경되었음을 experience에 알리고자 할 때 fire된다. experience는 해당 region만 draw하도록 선택할 수 있으며,
이는 performance에 도움이 될 수 있다.
참고: experience는 requestSession의
promise resolution 중에 이 event를 등록해야 한다. 그렇지 않으면 event가 fire되고 mask가 experience에 전달되지 않을
수 있다.
[SecureContext ,Exposed =Window ]interface :XRVisibilityMaskChangeEvent Event {(constructor DOMString ,type XRVisibilityMaskChangeEventInit ); [eventInitDict SameObject ]readonly attribute XRSession session ;readonly attribute XREye eye ;readonly attribute unsigned long index ; [SameObject ]readonly attribute Float32Array vertices ; [SameObject ]readonly attribute Uint32Array indices ; };dictionary :XRVisibilityMaskChangeEventInit EventInit {required XRSession ;session required XREye ;eye required unsigned long ;index required Float32Array ;vertices required Uint32Array ; };indices
session 속성은 event를
생성한 XRSession을
나타낸다.
eye 속성은 mask가 어떤
XREye에
적용되는지를 나타낸다.
index 속성은 이 mask가 적용되는
XRView의
view 목록
안에서의 offset을 나타낸다.
vertices 속성은
X, Y coordinate의 list이다.
experience는 Z coordinate가 -1이라고 가정해야 한다. 각 X,
Y, Z coordinate는 하나의 vertex를 설명한다.
이 array가 비어 있으면, XRView의 전체 region을
draw해야 한다.
indices 속성은 vertices가
설명하는 vertex list 안의 index를 설명하는 index들의 list이다.
이러한 index는 draw해야 하는 eye의 XRView region을
설명한다.
이 array가 비어 있으면, XRView의 전체 region을
draw해야 한다.
그 영역은 eye의
XRView의
projectionMatrix와
기본 XRRigidTransform을
사용하여 draw되어야 한다.
참고: 이는 그 영역이 eye의
현재 XRView의 XRRigidTransform을
사용해서는 안 된다는 뜻이다.
12.6. 이벤트 유형
사용자 에이전트는 다음 새 event를 제공해야 한다. event의 registration과 firing은 DOM Events의 일반적인 동작을 따라야 한다.
사용자 에이전트는 document의 origin이 "xr-spatial-tracking" permissions
policy를 사용할 수 없는 경우가 아니라면, immersive XR device의 availability가 변경되었음을 나타내기 위해
XRSystem
object에서
devicechange라는 이름의 event를 fire해야 한다.
사용자 에이전트는 XRSession의
visibility state가 변경될 때마다, XRSessionEvent를
사용하여 XRSession에서
visibilitychange라는 이름의 event를
fire해야 한다.
사용자 에이전트는 application 또는 user agent에 의해 session이 종료될 때, XRSessionEvent를
사용하여 XRSession에서
end라는 이름의 event를 fire해야 한다.
사용자 에이전트는 session의 active XR input source 목록이 변경될 때, XRInputSourcesChangeEvent를
사용하여 XRSession에서
inputsourceschange라는 이름의 event를
fire해야 한다.
사용자 에이전트는 session의 active XR tracked source 목록이 변경될 때, XRInputSourcesChangeEvent를
사용하여 XRSession에서
trackedsourceschange라는 이름의 event를
fire해야 한다. 이 event는 session의 granted
feature 집합에 tracked-sources가 포함되어 있는 경우에만 fire되어야 한다.
사용자 에이전트는 자신의 XRInputSource
중 하나가
자신의 primary action을
시작할 때, XRSession에서
XRInputSourceEvent를
사용하여 selectstart라는 이름의 이벤트를 fire해야 한다.
이벤트는 type . 이어야 한다.
사용자 에이전트는 자신의 XRInputSource
중 하나가
자신의 primary action을 끝내거나,
primary
action을 시작한 XRInputSource가
disconnected될 때, XRSession에서
XRInputSourceEvent를
사용하여 selectend라는 이름의 이벤트를 fire해야 한다.
사용자 에이전트는 자신의 XRInputSource
중 하나가
primary
action을 완전히 완료했을 때, XRSession에서
XRInputSourceEvent를
사용하여 select라는 이름의 이벤트를 fire해야 한다.
사용자 에이전트는 자신의 XRInputSource
중 하나가
자신의 primary
squeeze action을 시작할 때, XRSession에서
XRInputSourceEvent를
사용하여 squeezestart라는 이름의 이벤트를 fire해야 한다.
사용자 에이전트는 자신의 XRInputSource
중 하나가
자신의 primary
squeeze action을 끝내거나, primary squeeze action을 시작한 XRInputSource가
disconnected될 때, XRSession에서
XRInputSourceEvent를
사용하여 squeezeend라는 이름의 이벤트를 fire해야 한다.
사용자 에이전트는 자신의 XRInputSource
중 하나가
primary squeeze
action을 완전히 완료했을 때, XRSession에서
XRInputSourceEvent를
사용하여 squeeze라는 이름의 이벤트를 fire해야 한다.
사용자 에이전트는 XR Compositor가
XRSession의
internal nominal framerate를 변경할 때,
XRSession에서
XRSessionEvent를
사용하여 frameratechange라는 이름의 이벤트를 fire해야 한다.
사용자 에이전트는 XRSystem이
사용자에게 표시되는 XRView의
visible
region 변경을 signal하려는 경우, XRSession에서
XRVisibilityMaskChangeEvent를
사용하여 visibilitymaskchange라는 이름의 이벤트를
fire해야 한다.
사용자 에이전트는 사용자 환경에 상대적인 origin의 position 또는 orientation에 중대한 변경이 있는 경우, 즉
native origin
또는 effective origin의
discontinuity가 발생할 때, XRReferenceSpace에서
XRReferenceSpaceEvent를
사용하여 reset이라는 이름의 이벤트를 fire해야 한다.
(예: 사용자의 XR device recalibration 이후 또는 XR device가 tracking을 잃었다가 되찾은 뒤 자동으로 origin을
shift한 경우.) XRBoundedReferenceSpace의
boundsGeometry가
변경될 때에도 reset
이벤트가 dispatch되어야 한다.
viewer의 pose가 discontinuity를 겪지만 XRReferenceSpace의
origin physical mapping은 안정적으로 유지되는 경우, 예를 들어 viewer가 같은 tracking area 안에서 잠시 tracking을 잃었다가 되찾는 경우에는
reset
이벤트가 dispatch되어서는 안 된다. 또한 unbounded
reference space가 중대한 discontinuity가 발생하지 않은 경우, 사용자 근처의 space stability를 유지하기 위해
시간이 지남에 따라 native
origin에 작은 조정을 하는 경우에도 reset
이벤트가 dispatch되어서는 안 된다. 이벤트는 새 origin을 사용하는 모든 XR animation
frame이 실행되기 전에 dispatch되어야 한다. reset
이벤트는 reset
이벤트를 fire하는 reference space의 모든 offset reference space에서 dispatch되어야 하며, offset XRBoundedReferenceSpace의
boundsGeometry도
다시 계산되어야 한다.
참고: 이는 session이 reset
listener가 있는 모든 XRReferenceSpace에
대한 strong reference를 유지해야 함을 의미한다.
참고: viewer position의 jump는 애플리케이션이 emulatedPosition
boolean을 관찰하여 처리할 수 있다. viewer
position의 jump가 emulatedPosition이
true에서 false로 전환되는 것과 동시에 발생하면, 이는 viewer가 tracking을 되찾았고 그 새 position이 이전에 emulated된
값으로부터의 correction을 나타냄을 의미한다. viewer가
물리적으로 움직이지 않고도 virtual world를 이동할 수 있는 "teleportation" mechanic이 없는 experience의 경우, 이는
일반적으로 애플리케이션이 원하는 동작이다. 그러나 experience가 "teleportation" mechanic을 제공하는 경우, tracking
recovery 후 viewer의 position을 되돌리는 jump는
불필요하게
불편할 수 있다. 대신, 이러한 애플리케이션은 tracking을 recovery할 때, position의 갑작스러운 jump를 teleportation
offset에 흡수함으로써 virtual world에서 viewer의
현재 position에서 experience를 단순히 재개할 수 있다. 이를 위해 개발자는 getOffsetReferenceSpace()를
호출하여 이전 frame 이후 viewer의 position이 jump한
양만큼
effective
origin이 조정된 replacement reference space를 생성한다.
13. 보안, 개인정보 보호 및 편안함 고려 사항
WebXR Device API는 사용자 에이전트가 완화 조치를 취해야 하는 몇 가지 고유한 개인정보 보호, 보안 및 편안함 위험을 동반하는 강력한 새 기능을 제공한다.
13.1. 민감한 정보
XR의 맥락에서 민감한 정보에는
interpupillary distance (IPD)와 같은 사용자 설정 가능 데이터 및
XRPose와
같은 sensor 기반 데이터가 포함되지만 이에 한정되지는 않는다. 모든 immersive session은
무엇이든 렌더링하려면 사용자의 pose가 필요하기 때문에 어느 정도의 민감한 데이터를 노출한다.
그러나 일부 경우에는 동일한 민감한 정보가 inline
session을 통해서도 노출된다.
13.2. 사용자 의도
주어진 action에 대한 사용자 의도는 그러한 action이 의도적이었고 사용자의 consent를 가진다는 사용자로부터의 signal이다.
민감한 정보를 노출하거나 사용자 experience에 중대한 영향을 미치는 action을 허용하기 전에, user intent를 확실히 해야 하는 경우가 많다. 이 intent는 여러 방식으로 전달되거나 관찰될 수 있다.
참고: user intent를 판단하는 일반적인 방법은 UI control의 transient activation을 사용하는 것이며, 일반적으로 "enter VR" button이다. activation은 transient하므로, XR session을 요청하는 browsing context는 UI control을 포함하는 context의 ancestor이거나 same origin-domain descendant여야 하며, 최근에 browsing context의 active document였어야 한다.
13.2.1. 사용자 activation
Transient activation은 일부 scenario에서 user intent의 표시로 사용될 수 있다.13.2.2. 웹 애플리케이션 실행
일부 환경에서는 page가 application으로 제시되어 immersive content를 실행하려는 명시적 intent로 설치될 수 있다. 이 경우 웹 애플리케이션 실행 역시 user intent의 표시로 사용될 수 있다.13.2.3. 묵시적 및 명시적 동의
묵시적 동의는 사용자 에이전트가 사용자에게 명시적으로 묻지 않고 사용자의 consent에 대한 판단을 내리는 경우이다. 예를 들어 web application의 install status, 방문 빈도와 최근성, 또는 사용자가 immersive experience에 들어가기를 원한다는 intent를 명확히 signal하는 user agent defined action을 기반으로 할 수 있다. XR data의 민감성을 고려할 때, implicit signal에 의존할 때는 강한 주의가 권장된다.
명시적 동의는 사용자 에이전트가 사용자에게 명시적으로 물어본 것을 기반으로 사용자의 consent에 대한 판단을 내리는 경우이다. explicit consent를 수집할 때, 사용자 에이전트는 요청되는 것이 무엇인지 설명을 제시하고 사용자가 거부할 수 있는 option을 제공한다. user consent 요청은 보호되는 기능 및 user agent 선택에 따라 여러 visual form으로 제시될 수 있다. web application의 install status는 설치 시 어떤 형태의 explicit consent가 요청된다면 explicit consent의 signal로 간주될 수 있다.
13.2.4. 동의 기간
특정 origin에 대해 explicit consent가 부여되면, 이 consent는 browsing context가 종료될 때까지 지속되는 것이 권장된다. 사용자 에이전트는 user intent의 implicit 또는 explicit signal에 따라 이 consent duration을 늘리거나 줄일 수 있지만, 특히 implicit signal에 의존할 때는 이 권장 사항에서 벗어나는 경우 구현이 주의할 것을 권고한다. 예를 들어 immersive content를 실행하려는 명시적 intent로 설치된 web application에 대해서는 사용자의 consent를 지속시키는 것이 적절할 수 있지만, immersive content가 secondary feature인 설치된 web application에는 적절하지 않을 수 있다.사용자 에이전트가 사용자의 consent를 얼마나 오래 지속시키기로 선택하든 관계없이, sensitive information은
ended되지 않은
XRSession에
의해서만 노출되어야 한다.
13.3. Session 중간 동의
사용자 에이전트가 기능 사용을 위해 explicit consent를 요청하게 하는 non-XR API가 여러 개 있다. active immersive session이 있는 동안 사용자 에이전트가 사용자의 consent를 요청하려는 경우, 사용자 에이전트는 사용자에게 consent request를 표시하기 전에 session을 shut down해야 한다. 기능에 대한 사용자의 consent가 active immersive session이 생성되기 전에 이미 부여되었다면 session을 종료할 필요가 없다.
참고: 이 제한은 사용자 에이전트가 mid-session explicit consent를 어떻게 관리해야 하는지에 대한 합의가 이루어질 때까지 모든 사용자 에이전트 간의 behavioral parity를 보장하기 위한 것이다. 장기적 요구 사항일 것으로 예상되지는 않는다.
13.4. 데이터 조정
일부 경우 보안 및 개인정보 보호 위협은 throttling, quantizing, rounding, limiting 또는 XR device에서 보고되는 데이터를 그 외 방식으로 조작하는 것과 같은 data adjustment를 통해 완화될 수 있다. 이는 user intent가 확립된 상황에서도 fingerprinting을 피하기 위해 때때로 필요할 수 있다. 그러나 data adjustment 완화책은 사용자 discomfort를 초래하지 않는 상황에서만 사용되어야 한다.
13.4.1. Throttling
Throttling은 sensitive information이 가능한 것보다 낮은 frequency로 보고되는 경우이다. 이 완화책은 site가 user intent를 추론하거나, location을 추론하거나, user profiling을 수행하는 능력을 줄일 가능성이 있다. 그러나 적절히 사용되지 않으면 throttling은 사용자 discomfort를 유발할 상당한 위험이 있다. 또한 많은 상황에서 완전한 완화책을 제공하기에 불충분할 수 있다.13.4.2. Rounding, quantization 및 fuzzing
Rounding, quantization 및 fuzzing은 그렇지 않으면 개발자에게 반환될 raw data를 수정하는 세 가지 category의 완화책이다. Rounding은 데이터를 표현하는 데 사용되는 digit 수를 줄여 data의 precision을 낮춘다. Quantization은 continuous data를 discrete subset의 value로 보고하도록 제한한다. Fuzzing은 데이터에 작고 random한 error를 도입하는 것이다. 이러한 완화책들은 집합적으로 fingerprinting을 피하는 데 유용하며, 특히 그렇게 해도 user comfort에 noticeable impact를 일으키지 않는 경우 유용하다.13.4.3. Limiting
Limiting은 데이터가 특정 range 안에 있을 때만 보고되는 경우이다. 예를 들어, 사용자가 승인된 location에서 특정 distance 이상 벗어났을 때 positional pose data 보고를 편안하게 제한할 수 있다. 이 완화책을 사용할 때 user experience가 부정적으로 영향을 받지 않도록 주의해야 한다. range 끝에서 'hard stop'을 피하는 것이 바람직한 경우가 많으며, 이는 disruptive user experience를 유발할 수 있기 때문이다.13.5. 보호되는 기능
API가 노출하는 sensitive information은 threat profile과 그 threat에 대한 필요한 protection을 공유하는 category로 나눌 수 있다.
13.5.1. 몰입성
immersive session의 생성은 사용자 machine에 invasive change를 일으키기 때문에, 사용자는 immersive session이 언제 생성되는지 제어할 수 있어야 한다. 예를 들어 immersive session을 시작하면 XR device sensor가 작동하고, device display에 대한 access를 차지하며, XR hardware에 대한 다른 application의 access를 종료할 수 있는 immersive content를 presentation하기 시작한다. 또한 일부 system에서는 상당한 power 또는 performance overhead가 발생하거나 status tray 또는 storefront가 실행될 수 있다.주어진 global object에 대해 immersive session request가 허용되는지 판단하려면, 사용자 에이전트는 다음 단계를 실행해야 한다:
-
요청이 global object가 transient activation을 가진 동안 또는 web application을 실행할 때 이루어진 것이 아니면,
false를 반환한다 -
immersive session을 시작하려는 user intent가 explicit consent 또는 implicit consent를 통해 잘 이해되지 않는다면,
false를 반환한다 -
true를 반환한다
inline session을 시작하는 것은 immersive session을 시작하는 것과 동일한 요구 사항을 implicit하게 수반하지 않는다. 다만 session의 requested features에 따라 추가 요구 사항이 부과될 수 있다.
주어진 global object에 대해 inline session request가 허용되는지 판단하려면, 사용자 에이전트는 다음 단계를 실행해야 한다:
-
session request가 inline-stereo 이외의 required features 또는 optional features를 포함하면 requiresUserIntent를
true로 두고, 그렇지 않으면false로 둔다. -
requiresUserIntent가
true이고 요청이 global object가 transient activation을 가진 동안 또는 web application을 실행할 때 이루어진 것이 아니면,false를 반환한다. -
global object가
Window가 아니면,false를 반환한다. -
true를 반환한다.
13.5.2. Pose
sensor data를 기반으로 하는 경우,XRPose 및 XRViewerPose는
input sniffing, gaze tracking 또는 fingerprinting을 포함한 여러 방식으로 오용될 수 있는 sensitive
information을 노출한다.
XRSession
session에 pose가 보고될 수 있는지 판단하려면, 사용자 에이전트는 다음 단계를 실행해야 한다:
-
session의 relevant global object가 current global object가 아니면,
false를 반환한다. -
session의
visibilityState가이면,false를 반환한다. -
pose data를 반환할 수 있는지 다음과 같이 판단한다:
- pose data가 user agent에 의해 fingerprint 가능한 sensor data를 노출하지 않는 것으로 알려진 경우
-
true를 반환한다. - fingerprinting 또는 profiling을 방지하기 위해 underlying sensor data에 data adjustment가 적용될 경우
-
true를 반환한다. - user intent가 explicit consent 또는 implicit consent를 통해 잘 이해되는 경우
-
true를 반환한다. - 그렇지 않으면
-
false를 반환한다.
참고: pose가 fingerprint 가능한 data를 노출하지 않는다고 사용자 에이전트가 판단하는 방법은 사용자 에이전트의 재량에 맡겨진다.
XRViewerPose와
XRPose의 주된
차이는 XRView
information의
포함 여부이다. view가 둘 이상 존재하고 이 view들 사이의 physical relationship을 사용자가 구성할 수 있는 경우,
이 view들 사이의 relationship은 사용자를 fingerprint하거나 profile하는 데 사용될 수 있으므로 sensitive information으로 간주된다.
XRView들 사이의
relationship이 XR device를
고유하게 식별할 수 있다면, 사용자 에이전트는 fingerprinting을 방지하기 위해 XRView data를
anonymize해야 한다. anonymization 방법은 사용자 에이전트의 재량에 따른다.
참고: 또한 XRView들 사이의
relationship이 user-configured interpupillary distance (IPD)의 영향을 받는 경우, 사용자 에이전트가 session 생성
중, XRView data를
보고하기 전에 explicit
consent를 요구하는 것이 강하게 권장된다.
13.5.3. Reference space
사용되는 reference space에 따라 여러 다른 유형의 sensitive information이 application에 노출될 수 있다.-
6DoF tracking을 지원하는 device에서는
"local"reference space가 gait analysis를 수행하는 데 사용될 수 있으며, user profiling과 fingerprinting을 가능하게 한다. -
6DoF tracking을 지원하는 device에서는
"local-floor"reference space가 gait analysis를 수행하는 데 사용될 수 있으며, user profiling과 fingerprinting을 가능하게 한다. 또한"local-floor"reference space는 established floor level을 제공하므로, site가 사용자의 height를 추론할 수 있으며 user profiling과 fingerprinting을 가능하게 할 수 있다. -
"bounded-floor"reference space는 크기가 충분히 제한되어 있을 때 개발자가 geographic location을 결정할 수 있게 하지 않는다. 그러나 floor level이 established되어 있고 사용자가 걸어 다닐 수 있으므로, site가 사용자의 height를 추론하거나 gait analysis를 수행할 수 있으며, user profiling과 fingerprinting을 가능하게 할 수 있다. 또한 bounded reference space가 보고하는 bounds를 사용하여 fingerprinting을 수행할 수도 있다. -
"unbounded"reference space는 가장 많은 spatial data를 드러내며 user profiling과 fingerprinting을 초래할 수 있다. 예를 들어 이 data는 사용자의 specific geographic location을 결정하거나 gait analysis를 수행할 수 있게 할 수 있다.
그 결과 다양한 reference space type은 노출되는 sensitive information이 안전하게 처리되도록 하기 위해 생성에 제한이 부과된다:
대부분의 reference space는 reference space를 사용하려는 user intent가 explicit consent 또는 implicit consent를 통해 잘 이해될 것을 요구한다. 자세한 내용은 feature requirements 표를 참조하라.
서로 관련될 수 있는 "local",
"local-floor",
및 "bounded-floor"
reference space의 모든 group은 공통 native
origin을 공유해야 한다. 이 제한은 "unbounded"
reference space의 생성이 restricted된 경우에만 적용된다.
두 space인 space와 baseSpace 사이에서 pose가 제한되어야 하는지 판단하려면, 사용자 에이전트는 다음 단계를 실행해야 한다:
-
space 또는 baseSpace 중 하나가
XRBoundedReferenceSpace이고 다른 space의 native origin이 사용자 에이전트가 결정한 reasonable distance보다 native bounds geometry의 바깥으로 더 멀리 떨어져 있으면, true를 반환한다. -
space 또는 baseSpace 중 하나가
XRReferenceSpace이고 그 type이"local"또는"local-floor"이며, space들의 native origin 사이의 거리가 사용자 에이전트가 결정한 reasonable distance보다 크면,true를 반환한다. -
false를 반환한다.
참고: document visibility 요구 사항은 [DEVICE-ORIENTATION]에 기반한다.
참고: "local"
또는 "local-floor"
reference space에 상대적으로 보고되는 pose는 XRReferenceSpace의
native
origin에서 15 meter 거리로 limited되는
것이 제안된다.
참고: XRBoundedReferenceSpace에
상대적으로 보고되는 pose는 XRBoundedReferenceSpace의
native bounds geometry 바깥 1 meter 거리로
limited되는 것이 제안된다.
13.6. 신뢰할 수 있는 환경
Trusted UI는 사용자 에이전트가 제공하는 interface이며, 사용자는 상호작용할 수 있지만 page는 상호작용할 수 없다. 사용자 에이전트는 trusted UI 표시를 지원해야 한다.
trusted UI는 다음 property를 가져야 한다:
-
spoof 가능해서는 안 된다
-
표시되는 request/content가 어디에서 비롯되는지 나타낸다
-
사용자와의 shared secret에 의존하는 경우, 이 shared secret은 mixed reality capture에 의해 관찰될 수 없다 (예: camera에 보일 수 있는 gesture여서는 안 된다)
-
같은 UA 안의 immersive experience 사이에서 일관된다
넓게 말하면, trusted UI를 지원하려는 사용자 에이전트에는
두 가지 option이
있다. 하나의 option은 trusted
immersive UI이며, 이는
immersive mode를 종료하지 않는 trusted
UI이다. trusted
immersive UI를 구현하는 것은 어려울 수 있다. 이는
XRWebGLLayer buffer가 XR Device display를 채우고, User Agent가 일반적으로 자체 사용을 위해 pixel을
"reserve"하지 않기 때문이다. 사용자 에이전트는 trusted immersive UI를 지원할 필요는
없으며, 대신 immersive mode를 일시적으로 pause/exit하고 non-immersive trusted UI를 사용자에게 표시할 수 있다.
-
immersive mode가 아닐 때 표시되는 default 2D mode browser
-
spoofing을 방지하기 위해 reserved hardware button을 통해서만 상호작용할 수 있는 immersive mode 안의 prompt
-
immersive session을 pause하고 prompt를 표시할 수 있는 어떤 형태의 native system environment를 표시하는 것
pose와 input information을 읽을 수 있는 능력은 trusted UI의 integrity에 위험을 초래한다. page가 이 정보를
사용하여 trusted UI와 상호작용하는 동안 사용자가 내린
선택을 snoop할 수 있으며, 여기에는
keyboard input을 추측하는 것도 포함된다. 이 위험을 방지하기 위해 사용자 에이전트는 URL bar 또는 system dialog와
같은 trusted UI (immersive 또는
non-immersive)와 사용자가 상호작용할 때 모든
XRSession의
visibility state를
또는 "visible-blurred"로
설정해야 한다. 또한 malicious page가 다른 page의 input을 monitor할 수 없도록 하기 위해, 사용자 에이전트는
currently focused area가
XRSession을
생성한 document에 속하지 않는 경우, XRSession의
visibility state를 으로
설정해야 한다.
특정 trusted
UI instance에 대해
또는 "visible-blurred"
중
어느 것을 사용할지 선택할 때, 사용자 에이전트는 pose information이 security risk인지 고려해야 한다. 예를 들어
text input, 특히 password input을 포함하는 trusted UI는 사용자가 입력할 때의
움직임을 통해 typed text를 잠재적으로 leak할 수 있다. 사용자 에이전트는 이러한 경우 eye tracking 관련 information도
노출하지 않아야 한다.
사용자 에이전트는 permission prompt를 표시하기 위해 trusted UI를 사용해야 한다.
virtual environment가 사용자의 viewpoint를 낮은 latency와 높은 frame rate로 일관되게 update하지 않으면 사용자는 disoriented되거나 physically ill해질 수 있다. page가 일관되게 performant하고 correct한 content를 생성하도록 강제하는 것은 불가능하므로, 사용자 에이전트는 tracked, trusted environment와 page content와 비동기적으로 실행되는 XR Compositor를 제공해야 한다. compositor는 trusted content와 untrusted content를 compositing할 책임이 있다. content가 performant하지 않거나, frame을 submit하지 않거나, 예기치 않게 종료되는 경우에도 사용자 에이전트는 responsive한 trusted UI를 계속 표시할 수 있어야 한다.
또한 page content는 performance와 관련 없는 방식으로 사용자를 불편하게 만들 수 있다. 잘못 적용된 tracking, strobing color, 그리고 offend, frighten 또는 intimidate하려는 content는 사용자가 XR experience에서 빠르게 나가고 싶게 만들 수 있는 content의 예이다. 이런 경우 XR device를 제거하는 것이 항상 빠르거나 실용적인 option은 아닐 수 있다. 이를 수용하기 위해 사용자 에이전트는 reserved hardware button을 누르거나 gesture를 수행하는 것과 같이 WebXR content에서 벗어나 사용자 에이전트의 trusted UI를 표시하는 action을 사용자에게 제공해야 한다.
13.7. Context Isolation
trusted UI는 page가 사용하는 rendering context와 state가 isolated된 independent rendering context에 의해 그려져야 한다. (예: 모든 WebGL rendering context.) 이는 page가 trusted UI의 context state를 손상시켜 tracked environment를 제대로 렌더링하지 못하게 하는 것을 방지하기 위한 것이다. 또한 page가 trusted UI에서 imagery를 capture할 수 있는 가능성을 방지하며, 이는 private information이 leak되는 결과로 이어질 수 있다.
또한 CORS 관련 vulnerability를 방지하기 위해 각 browsing context는 API가 반환하는 object, 예를 들어 XRSession의
새 instance를 보게 된다. 한 relevant realm을 가진 XRWebGLLayer에
설정된 context와 같은
attribute는 same
origin을 가지지 않는 relevant realm을 가진 XRWebGLLayer를
통해 읽을 수 없어야 한다. 마찬가지로, API에서 호출된 method는 다른 browsing context에 observable state change를 일으켜서는 안 된다. 예:
system-level orientation reset을 가능하게 하는 method는 노출되지 않을 것이다. 이는 malicious page가 이를 반복적으로
호출하여 다른 page가 제대로 tracking하지 못하게 할 수 있기 때문이다. 그러나 사용자 에이전트는 user gesture 또는
system menu에 의해 trigger된 system-level orientation reset은 존중해야 한다.
참고: 이는 하나의 browsing context가 immersive mode에 들어가고, device에 대한 lock을 획득하며, 다른 browsing context에서 devicechange event를 잠재적으로 fire하여 발생하는 state change에는 적용되지 않는다.
13.8. Fingerprinting
API가 사용자가 이용할 수 있는 hardware와 그 capability를 설명한다는 점을 고려하면, fingerprinting을 위한 추가 surface area를 필연적으로 제공한다. 이를 완전히 피하는 것은 불가능하지만, 사용자 에이전트는 문제를 완화하기 위한 조치를 취해야 한다. 이 명세는 available hardware의 보고를 한 번에 단일 device로만 제한하며, 이는 여러 headset이 연결된 드문 경우를 fingerprinting signal로 사용하는 것을 방지한다. 또한 보고되는 device에는 string identifier가 없으며 XRSession이 생성되기 전까지 device capability에 대한 정보가 매우 적게 노출된다. XRSession 생성은 sensitive information이 노출될 때 추가 protection을 요구한다.
13.8.1. isSessionSupported()의
Fingerprinting 고려 사항
isSessionSupported()는
user activation 없이 호출될 수 있으므로 fingerprinting vector로 사용될 수 있다.
"xr-session-supported" powerful feature는 isSessionSupported()
API에 대한 access를 gate한다.
"xr-session-supported"의 permission-related algorithm과 type은 다음과 같이 정의된다:
- permission descriptor type
-
dictionary :XRSessionSupportedPermissionDescriptor PermissionDescriptor {XRSessionMode ; };mode
13.8.2. "xr-session-supported"를 자동으로 grant할 시점에 대한 고려 사항
Web에서는 privacy와 personalization 사이에 종종 긴장이 있다. 이 section은 그 tradeoff를 어디까지 제한할 수
있는지, 그리고 사용자 에이전트가 privacy reduction 없이 isSessionSupported()를
통해 browser의 WebXR capability를 site에 설명할 수 있는 시점에 대한 guidance를 제공한다.
"xr-session-supported"는 아래 criteria에 따라 일부 system에서 자동으로 grant될 수 있다. 이는 더 나은 user experience를 제공하고 permissions fatigue를 완화할 수 있다.
user agent들의 집합은 모두 동일한 userAgent
및 appVersion을
보고하면 user agent string으로 구별할 수 없음이다.
이러한 class는 일반적으로 실행 중인 browser version 및 platform/device에 의해 식별되지만, 연결된 외부 device의
status로는 구별될 수 없다. 우리는 user agent string으로 구별할 수 없는 user agent
concept를 사용하여 fingerprinting risk를 적절히 평가할 수 있다.
user agent string으로 구별할 수 없는 일부
user agent는 주어진 XRSessionMode의
session을 절대 지원하지
않을 것이다.
예: mobile AR support 요구 사항을 충족하지 않는 것으로 알려진 phone model에서 실행되는
user agent. 이런 경우 모든 그러한 device가 일관되게 같은 값을 보고하고 device type과 model은
userAgent와
같은 다른 방식으로 추론될 수 있다고 가정되므로, isSessionSupported()가
항상 해당 XRSessionMode가
지원되지 않는다고 보고하는 데 fingerprinting risk가 거의 없다. 따라서 그러한 system에서 사용자 에이전트는 관련
XRSessionMode에
대한 "xr-session-supported"를 자동으로 deny해야 한다.
user agent string으로 구별할 수 없는 다른
user agent는 주어진 XRSessionMode의
session을 대개 지원할
것이다.
예: VR headset 안에서만 실행되는, WebXR을 지원하는 것으로 알려진 user agent는 사용자가 특별히
block하지 않는 한 "immersive-vr"
session을 지원할 가능성이 높다. 이런 경우 해당 XRSessionMode가
지원되지 않는다고 보고하는 것은 accurate하더라도 사용자에 대한 더 uniquely identifying information을 제공할 것이다.
따라서 해당 XRSessionMode가
항상 available하다고 보고하고 requestSession()이
fail하도록 허용하는 것이 더 privacy-preserving하며, 사용자에게 혼란의 source가 되지 않을 가능성이 높다. 그러한
system에서 사용자 에이전트는 관련 XRSessionMode에
대해 "xr-session-supported"를 자동으로 grant해야 한다.
XR peripheral을 지원하는 desktop system처럼 XR capability의 availability가 매우 variable한 user agent string으로 구별할 수 없는 user agent는
가장 높은 fingerprinting risk를 제시한다. 이러한 device의 사용자 에이전트는 isSessionSupported()
API가 추가 fingerprinting bit를 제공할 수 있도록 하는 방식으로 "xr-session-supported"를 자동으로 grant해서는 안 된다.
-
isSessionSupported()가 호출될 때 "xr-session-supported"에 대해 항상 explicit consent를 판단하는 것 (potentially cached permissions prompt 또는 유사한 방식 사용). -
"xr-session-supported"를 자동으로 grant하지만, 적절한 hardware 또는 software가 존재하는지 여부와 관계없이 XR capability가 일관되게 available하지 않은 platform에서도
isSessionSupported()가 항상true를 보고하도록 하는 것. 이는 XR content를 볼 수 없는 사용자에게 page가 XR content를 advertise하게 만들기 때문에 user ergonomics라는 cost를 수반한다. -
적절한 hardware가 있을 때
isSessionSupported()가 "xr-session-supported"에 대한 explicit consent를 요청하도록 하고, 그러한 hardware가 존재하지 않을 때는 적절히 random한 시간 이후false를 반환하도록 하는 것. 그러한 구현에서 content는 사용자 에이전트가 XR hardware에 연결되어 있지 않은 경우와, 사용자 에이전트가 XR hardware에 연결되어 있었지만 사용자가 explicit consent 제공을 거부한 경우를 구별할 수 없어야 한다.
어떤 technique를 선택하든, explicit consent 없이 connected XR hardware에 대한 추가 knowledge를 드러내서는 안 된다.
14. 통합
14.1. Permissions Policy
이 명세는 spatial tracking 사용이 필요한 모든 XRSession이
requestSession()에
의해 반환될 수 있는지, 그리고 spatial tracking이 필요한 session mode 지원이 isSessionSupported()
또는 navigator.xr
object의 devicechange event에 의해 indicated될 수 있는지를 제어하는
policy-controlled feature를 정의한다.
이 feature의 feature identifier는 "xr-spatial-tracking"이다.
이 feature의 default allowlist는
["self"]이다.
참고: document의 origin이 "xr-spatial-tracking" permissions policy를 사용할 수 없는 경우, 모든 immersive session은
block된다.
이는 모든 immersive
session이 spatial tracking의 사용을 어느 정도 필요로 하기 때문이다. "inline"
session은 여전히 허용되지만, "viewer"
XRReferenceSpace만
사용하는 것으로 제한된다.
14.2. Permissions API 통합
[permissions] API는 website가 사용자에게 permission을 요청하고 어떤 permission이 granted되었는지 query하는 uniform한 방법을 제공한다.
"xr" powerful feature의 permission-related algorithm과 type은
다음과 같이 정의된다:
- permission descriptor type
-
dictionary :XRPermissionDescriptor PermissionDescriptor {XRSessionMode ;mode sequence <DOMString >;requiredFeatures sequence <DOMString >; };optionalFeatures nameforXRPermissionDescriptoris "xr". - permission result type
-
[
Exposed =Window ]interface :XRPermissionStatus PermissionStatus {attribute FrozenArray <DOMString >; };granted - permission query algorithm
-
XRPermissionDescriptordescriptor 및XRPermissionStatusstatus로 "xr" permission을 query하려면, UA는 다음 단계를 실행해야 한다:-
status의
state를 descriptor의 permission state로 설정한다. -
status의
state가"denied"이면, status의granted를 빈FrozenArray로 설정하고 이 단계를 중단한다. -
result를 descriptor의
requiredFeatures,optionalFeatures, 및mode가 주어졌을 때 requested feature를 resolve한 결과로 둔다. -
result가
null이면, 다음 단계를 실행한다:-
status의
granted를 빈FrozenArray로 설정한다. -
이 단계를 중단한다.
-
-
(consentRequired, consentOptional, granted)를 result의 field로 둔다.
-
status의
granted를 granted로 설정한다. -
consentRequired가 비어 있고 consentOptional도 비어 있으면, status의
state를"granted"로 설정하고 이 단계를 중단한다
-
- permission request algorithm
-
XRPermissionDescriptordescriptor 및XRPermissionStatusstatus로 "xr" permission을 request하려면, UA는 다음 단계를 실행해야 한다:-
status의
granted를 빈FrozenArray로 설정한다. -
requiredFeatures를 descriptor의
requiredFeatures로 둔다. -
optionalFeatures를 descriptor의
optionalFeatures로 둔다. -
device를 mode, requiredFeatures, 및 optionalFeatures에 대해 current device를 obtain한 결과로 둔다.
-
result를 requiredFeatures,optionalFeatures, 및
mode가 주어졌을 때 requested feature를 resolve한 결과로 둔다. -
result가
null이면, 다음 단계를 실행한다: -
(consentRequired, consentOptional, granted)를 result의 field로 둔다.
-
사용자 에이전트는 이 시점에서 calling algorithm이 consentRequired 및 consentOptional의 feature를 사용할 수 있도록 사용자 permission을 요청할 수 있다. 이러한 prompt의 결과는 이 feature를 enable하기 위한 user intent의 clear signal이 있는지 판단할 때 포함되어야 한다.
-
consentRequired 안의 각 feature에 대해 다음 단계를 수행한다:
-
사용자 에이전트는 이 시점에서 calling algorithm이 feature를 사용할 수 있도록 사용자 permission을 요청할 수 있다. 이러한 prompt의 결과는 feature를 enable하기 위한 user intent의 clear signal이 있는지 판단할 때 포함되어야 한다.
-
feature를 enable하기 위한 user intent의 clear signal이 판단되지 않은 경우, 다음 단계를 실행한다:
-
feature가 granted 안에 없으면, feature를 granted에 append한다.
-
-
consentOptional 안의 각 feature에 대해 다음 단계를 수행한다:
-
사용자 에이전트는 이 시점에서 calling algorithm이 feature를 사용할 수 있도록 사용자 permission을 요청할 수 있다. 이러한 prompt의 결과는 feature를 enable하기 위한 user intent의 clear signal이 있는지 판단할 때 포함되어야 한다.
-
feature를 enable하기 위한 user intent의 clear signal이 판단되지 않은 경우, 다음 entry로 continue한다.
-
feature가 granted 안에 없으면, feature를 granted에 append한다.
-
-
status의
granted를 granted로 설정한다. -
granted의 모든 element를 mode에 대한 device의 granted feature 집합에 추가한다.
참고: 사용자 에이전트는 user intent의 clear signal이 있는지 평가할 때, 요청된 모든 feature에 대한 permissions prompt를 batch로 묶을 자유가 있지만, 하나씩 표시하는 것도 허용된다.
참고: web application에 대한 user intent를 판단할 때, 사용자 에이전트는 그것이 web application으로서 사용자에 의해 명시적으로 launched 되었는지 확인해야 한다. 단지 origin이 설치된 web application의 origin과 일치하는지만 확인해서는 안 된다.
-
XRSessionMode
mode에 대해 requiredFeatures 및 optionalFeatures가 주어졌을 때
requested
feature를 resolve하려면, 사용자 에이전트는 다음 단계를 실행해야 한다:
-
device를 mode, requiredFeatures, 및 optionalFeatures에 대해 current device를 obtain한 결과로 둔다.
-
previouslyEnabled를 mode에 대한 device의 granted feature 집합으로 둔다.
-
device가
null이거나 device의 supported mode 목록이 mode를 contain하지 않으면, 다음 단계를 실행한다:-
tuple (consentRequired, consentOptional, granted)를 반환한다
-
-
mode와 연결된 default features table의 모든 feature descriptor를, 아직 존재하지 않는 경우 granted에 추가한다.
-
requiredFeatures 안의 각 feature에 대해 다음 단계를 수행한다:
-
feature가
null이면, 다음 entry로 continue한다. -
feature가 valid feature descriptor가 아니면,
null을 반환한다. -
feature가 이미 granted 안에 있으면, 다음 entry로 continue한다.
-
requesting document의 origin이 feature requirements table에 표시된 대로 feature가 요구하는 어떤 permissions policy도 사용할 수 없다면,
null을 반환한다. -
session의 XR device가 feature가 설명하는 기능을 support할 수 없거나 사용자 에이전트가 그 feature를 reject하기로 달리 판단한 경우,
null을 반환한다. -
feature가 설명하는 기능이 explicit consent를 요구하고 feature가 previouslyEnabled 안에 없으면, 이를 consentRequired에 append한다.
-
그렇지 않으면 feature를 granted에 append한다.
-
-
optionalFeatures 안의 각 feature에 대해 다음 단계를 수행한다:
-
feature가
null이면, 다음 entry로 continue한다. -
feature가 valid feature descriptor가 아니면, 다음 entry로 continue한다.
-
feature가 이미 granted 안에 있으면, 다음 entry로 continue한다.
-
requesting document의 origin이 feature requirements table에 표시된 대로 feature가 요구하는 어떤 permissions policy도 사용할 수 없다면, 다음 entry로 continue한다.
-
session의 XR device가 feature가 설명하는 기능을 support할 수 없거나 사용자 에이전트가 그 feature를 reject하기로 달리 판단한 경우, 다음 entry로 continue한다.
-
feature가 설명하는 기능이 explicit consent를 요구하고 feature가 previouslyEnabled 안에 없으면, 이를 consentOptional에 append한다.
-
그렇지 않으면 feature를 granted에 append한다.
-
-
tuple
(|consentRequired|, |consentOptional|, |granted|)를 반환한다
변경 사항
Candidate Recommendation Snapshot, 31 March 2022 이후 변경 사항
-
inline-stereo session feature 추가
-
XRSession의 granted feature 노출 (GitHub #1296)
-
isSystemKeyboardSupported attribute 지원 추가 (GitHub #1314)
-
visibile-blurred에서 getPose 동작 명확화 (GitHub #1332)
-
Transient intent 추가 (GitHub #1343)
-
XRInputSource가 다른 곳에서 visible임을 말하는 property를 추가하기 위한 첫 draft (GitHub #1353)
-
rgb vs srgb 동작 명확화 (GitHub #1359)
Working Draft 24 July 2020 이후 변경 사항
-
predictedDisplayTime 수정 및 inline 동작 정의 (GitHub #1230)
-
XRFrame.predictedDisplayTime 추가 (GitHub #1217)
-
targetFrameRate 및 supportedFrameRates 지원 추가 (GitHub #1201)
-
foveation 지원 추가 (
fixedFoveation(GitHub #1195) -
session이 명시적으로 request하거나 mode에 따라 implicit하게 granted된 feature만 사용할 수 있게 함 (GitHub #1189)
-
implicit user intent 예시 개선 (GitHub #1188)
-
angular 및 linear velocity 지원 추가 (GitHub #1182)
-
XRReferenceSpace에 대해 platform convention이 일관되게 유지되도록 보장 (GitHub #1180)
-
composition disabled flag를 composition enabled로 invert (GitHub #1172)
-
session이 이미 ended된 경우 end()에서 반환된 promise reject (GitHub #1170)
-
requestAnimationFrame 중 session이 ended되었는지 detect (GitHub #1169)
-
recommendedViewportScale에 quantization 요구 (GitHub #1151)
-
sessionsupported pref autogranting을 non-normative로 변경 (GitHub #1146)
-
nonvisual usage를 포함하는 XR device 정의 추가 (GitHub #927)
-
최근 privacy discussion의 결론 반영 (GitHub #1124)
-
isSessionSupported를 user intent 사용에서 permissions 사용으로 전환 (GitHub #1136)
-
minimum viewport scale이 변경될 수 있음을 명확화 (GitHub #1134)
-
fingerprinting PR 개선 (GitHub #1133)
-
requestViewportScale/recommendedViewportScale 추가 (GitHub #1132)
-
framebuffer scale factor가 width/height에 별도로 적용됨을 명확화 (GitHub #1131)
-
pending render state가 항상 적용되도록 보장 (GitHub #1128)
-
context XR compatibility를 xr-spatial-tracking permissions policy로 gate. (GitHub #1126)
-
updateRenderState 변경이 적용되는 timing 변경 (GitHub #1111)
Working Draft 10 October 2019 이후 변경 사항
새 기능:
-
secondary view를 위한 feature 추가 (GitHub #1083)
-
XRRenderStateInit을 layers sequence로 update (GitHub #999)
-
input source를 primary/auxiliary로 분리 (GitHub #929)
-
squeeze event 정의 (GitHub #893)
변경 사항:
-
Primary view는 항상 active여야 함 (GitHub #1105)
-
makeXRCompatible()에서 context loss를 올바르게 처리 (GitHub #1097)
-
active view 개념 도입 (GitHub #1096)
-
frame 및 viewport caching을 explicit하게 수정 (GitHub #1093)
-
다양한 object caching 허용 (GitHub #1088)
-
framebufferScaleFactor clamping 허용 (GitHub #1084)
-
"ensure an immersive device is selected"의 threading nature 명확화, xrCompatible deprecate (GitHub #1081)
-
native origin에 관한 일부 사항 명확화 (GitHub #1071)
-
document visibility check를 UA 선택으로 변경 (GitHub #1067)
-
'check the layers state' algorithm 추가 (GitHub #1064)
-
null 및 emulated pose 관련 다양한 변경 (GitHub #1058)
-
XRInputSource/frame에서 올바른 input frame semantics 언급 (GitHub #1053)
-
XRRigidTransform validation 추가 (GitHub #1043)
-
empty input profile array가 적절한 시점에 대한 minor change. (GitHub #1037)
-
trusted ui가 visible-blurred를 사용할 수 있게 하고 text input leakage에 대해 caution (GitHub #1034)
-
window.rAF()에 대한 일부 clarification (GitHub #1033)
-
task 및 promise 처리 방식 정리 (GitHub #1032)
-
render state가 전달되지 않으면 updateRenderState()를 short circuit (GitHub #1031)
-
responsible, active, focused document 사용 제거 (GitHub #1030)
-
context isolation에서 browsing context 및 realm 관련 상황 명확화 (GitHub #1029)
-
reset event가 offset space에서 동작함을 명시적으로 지정 (GitHub #1024)
-
각 object가 생성되는 realm을 명시적으로 지정 (GitHub #1023)
-
rAF() callback argument에 current timestamp 사용 (GitHub #1015)
-
session feature request가 더 이상 session parameter를 필요로 하지 않음 (GitHub #1012)
-
rAF 내부에서 rAF callback 취소 허용 (GitHub #1005)
-
opaque framebuffer가 특정 session에 대한 reference를 보유함을 언급 (GitHub #1004)
-
initial inputsourcechange event를 promise resolve 이후로 defer (GitHub #1002)
-
framebufferScaleFactor의 effect 문서화 (GitHub #993)
-
depth||stencil이 request되면 depth&&stencil result 허용 (GitHub #987)
-
isSessionSupported가 반환하는 것에 더 많은 flexibility 허용 (GitHub #986)
-
inline device를 통해 tracking/input data가 노출되는 시점 명확화 (GitHub #985)
-
viewport shape에 common sense restriction 추가 (GitHub #976)
-
preserveDrawingBuffer가 여기서는 권한이 없음을 지정 (GitHub #975)
-
inline session에 대한 visiblityState 동작 명확화 (GitHub #974)
-
opaque framebuffer가 dirty로 간주되는 시점 정의 (GitHub #970)
-
device 변경 시 inline device를 potentially update (GitHub #947)
-
bounded reference space behavior 명확화 (GitHub #938)
-
XR compatibility algorithm에 대한 multiple fix (GitHub #921)
-
trusted UI section 보완 (GitHub #875)
-
depthNear 및 depthFar가 사용되는 방식 더 잘 정의 (GitHub #888)
-
local-floor space가 estimated height를 사용할 때 emulatedPosition이 true가 아님을 명확화 (GitHub #871)
First Public Working Draft 5 Feburary 2019 이후 변경 사항
새 기능:
-
input profile name list를 위한 XRInputSource->profiles 추가 (GitHub #695)
-
XREye에 none variant 추가 (GitHub #641)
-
explicit inline XR device 추가 (GitHub #737)
-
data adjustment 및 protected functionality가 포함된 pose privacy consideration (GitHub #761)
-
Reference space privacy consideration (GitHub #762)
-
sensitive information 및 user intent 정의 (GitHub #757)
-
Required 및 optional features (Feature dependencies) (GitHub #749)
-
Tracking loss 및 tracking recovery (GitHub #559)
-
blur/focus를 visibilitychange로 변경 (GitHub #687)
-
input source의 event order 정의 (GitHub #629)
-
input source list가 유지되는 방식 설명 (GitHub #628)
-
origin offset을 immutable로 변경 (GitHub #612)
-
XRRenderState에 inlineVerticalFieldOfView 추가 (GitHub #519)
-
Gamepad integration 문서화 (GitHub #553)
-
XRWebGLLayer에 ignoreDepthValues attribute 추가 (GitHub #548)
-
XRSpace XREnvironmentBlendMode.viewerSpace 추가 (GitHub #522)
-
XRPose 및 관련 refactor를 spec에 추가 (GitHub #496)
제거된 기능:
-
canvas inline을 single로 변경, XRPresentationContext 제거 (GitHub #656)
-
XRLayer base type 제거 (GitHub #688)
-
XRWebGLLayer.requestViewportScaling() 제거 (GitHub #631)
-
XRWebGLLayer에서 context Attribute 제거 (GitHub #707)
-
requested value만 reflect하는 attribute 제거 (GitHub #574)
-
XRSessionCreationOptions 제거 (GitHub #566)
변경 사항:
-
XRWebGLLayer의 required clear behavior 설명 (GitHub #866)
-
XRWebGLLayer framebuffer가 항상 premultiplied alpha를 사용한다고 지정 (GitHub #840)
-
reset event의 transform direction 명확화 (GitHub #843)
-
feature requirement가 충족되는 방식 정의 (GitHub #839)
-
적절한 경우 session이 immersive가 아니라 inline인지 확인 (GitHub #834)
-
현재 stereo inline session disallow (GitHub #829)
-
projectionMatrix에서 detached buffer 처리 (GitHub #830)
-
makeXRCompatible()에서 immersive device가 selected되도록 보장 (GitHub #809)
-
feature를 'any'의 sequence로 변경 (GitHub #807)
-
'fire an input source' algorithm에 link하고 frame을 explicit하게 construct (GitHub #797)
-
spec 및 explainer에서 Environment blend mode 제거 (GitHub #804)
-
각 method에 대한 description 제공 (GitHub #798)
-
UA가 manual device activation step을 표시하도록 요구 (GitHub #799)
-
compositor를 약간 명확화 (GitHub #805)
-
rigid transform을 위한 matrix 획득의 matrix math 명확화 (GitHub #806)
-
UA가 clip plane을 constrain할 수 있게 허용 (GitHub #802)
-
getViewport()에서 stale XRView 사용 금지 (GitHub #796)
-
depth/alpha/stencil value가 어떻게 사용되는지 명시적으로 언급 (GitHub #800)
-
profile 변경 시 input source event fire (GitHub #795)
-
reset event가 fire되는 시점 명확화 (GitHub #637)
-
requestReferenceSpace()가 query를 reject할 수 있는 시점을 명시적으로 지정 (GitHub #651)
-
XRRay.matrix를 unique하게 만들고, 이를 획득하는 단계 추가 (GitHub #655)
-
promise 반환에 TAG recommendation 사용 (GitHub #700)
-
requestSession()의 racy part를 main thread로 이동 (GitHub #706)
-
exclusive access에서 small overlay UI가 허용됨을 명확화 (GitHub #709)
-
'end the session'과 'shut down the session' 병합, 명확화, onend event 추가 (GitHub #710)
-
inline session에 대해 XR compat flag를 check하지 않음 (GitHub #705)
-
position DOMPointInit validate (GitHub #568)
-
native origin을 명시적으로 spec화 (GitHub #621)
-
buttonIndex 제거 (GitHub #741)
-
"immersive-ar" 및 XRRay에 대한 reference 제거 (GitHub #784)
-
explainer 및 index.bs에서 XRInputSource.gamepad에 대한 reference 제거 (GitHub #782)
-
invalid view를 사용한 getViewport가 error를 throw (GitHub #771)
-
mid-session consent request block (GitHub #767)
-
XRPresentationContext creation spec화 (GitHub #501)
-
inputSources getter를 method에서 attrib로 변경 (GitHub #624)
-
required gamepad index를 -1로 변경 (GitHub #690)
-
detached array 처리 (GitHub #684)
-
sensitive UI가 WebXR content를 숨기도록 요구 (GitHub #742)
-
xr-standard gamepad mapping을 더 rigid하게 만듦 (GitHub #735)
-
XRRay.matrix를 compute하는 algorithm 수정 (GitHub #728)
-
XRRay.matrix algorithm의 detached array 수정 (GitHub #716)
-
requestSession()에서 unsupported mode 처리 단순화 (GitHub #714)
-
XRRenderState 관련 일부 clarification (GitHub #703)
-
'pending render state 목록'을 'pending render state'로 대체 (GitHub #701)
-
gamepad placeholder button 및 axis를 더 잘 정의 (GitHub #661)
-
touchpad가 touched되지 않았을 때 report해야 하는 value 명확화 (GitHub #660)
-
getPose arg referenceSpace->baseSpace rename (GitHub #659)
-
transform multiplication order 수정 (GitHub #649)
-
local 및 local-floor tracking에 대한 assumption 명확화 (GitHub #648)
-
available space 단순화 (GitHub #626)
-
requestSession: user activation 먼저 check (GitHub #685)
-
boundsGeometry가 effective origin에 상대적으로 동작하게 함 (GitHub #613)
-
views array가 populate되는 방식을 명시적으로 지정 (GitHub #614)
-
Gamepad id가 unknown이어야 하는 case 식별 (GitHub #615)
-
XRSpace, get(Viewer)Pose definition overhaul (GitHub #609)
-
supportsSessionMode를 supportsSession으로 rename (GitHub #595)
-
reference space type 및 interface consolidate (GitHub #587)
-
inverse attribute가 항상 같은 object를 반환 (GitHub #586)
-
session shut down 시 outstanding promise reject (GitHub #585)
-
projection matrix가 shear를 포함할 수 있음을 지정 (GitHub #575)
-
updateRenderState가 throw할 수 있는 exception 설명 (GitHub #511)
-
requestSession() 편집 및 session 초기화 (GitHub #601)
-
XRRigidTransform inverse를 method에서 attribute로 변경 (GitHub #560)
-
compositing이 depth value를 사용하는 시점 표시 (GitHub #563)
-
Stationary subtype support는 all-or-nothing (GitHub #537)
-
outputContext를 XRRenderState로 이동 (GitHub #536)
-
getViewerPose가 non-rAF XRFrame에 대해 error를 throw한다고 지정 (GitHub #535)
-
viewMatrix 제거 및 XRTransform.inverse() 추가 (GitHub #531)
-
XRHandedness enum이 '' 대신 'none'을 사용하도록 변경 (GitHub #526)
-
tracked-pointer ray의 preferred ergonomics 표시 (GitHub #524)
-
XRRay constructor 명확화 및 normalization 정의 (GitHub #521)
-
identity reference space를 위한 spec text (GitHub #520)
-
immersive session이 reject되는 시점 명확화 (GitHub #360)
-
base layer 없이는 frame callback이 호출되지 않는다고 지정 (GitHub #512)
15. 감사의 말
WebXR Device API specification에 기여한 다음 개인들에게 감사한다:
그리고 이 모든 모험을 시작하게 해 준 Vladimir Vukicevic (Unity)에게 특별한 감사를 전한다!