1. Introduction
The spec adds support of `composition` layers to the WebXR spec. The benefits of layers are as follows:
-
Performance and judder Composition layers are presented at the frame rate of the compositor (i.e. native refresh rate of HMD) rather than at the application frame rate. Even when the application is not updating the layer’s rendering at the native refresh rate of the compositor, the compositor might be able to re-project the existing rendering to the proper pose. This results in smoother rendering and less judder. Another feature of layers is that each of them can have different resolution. This allows the application to scale down the main eye buffer resolution on low performance systems, but keeping essential information, such as text or a map, in its own layer at a higher resolution.
-
Legibility/visual fidelity The resolution for eye-buffers for 3D world rendering can be set to relatively low values especially on low performance systems. It would be impossible to render high fidelity content, such as text, in this case. Each layer may have its own resolution and it will be re-sampled only once by the compositor (in contrary to the traditional approach with rendering layers via WebGL where the layer’s content got re-sampled at least twice: once when rendering into WebGL eye-buffer (and losing a lot of details due to limited eye-buffer resolution) and the second time by the compositor).
-
Power consumption / battery life Due to reduced rendering pipeline, the lack of double sampling and no need to update the layer’s rendering each frame, the power consumption is expected to be improved.
-
Latency Pose sampling for composition layers may occur at the very end of the frame and then certain reprojection techniques could be used to update the layer’s pose to match it with the most recent HMD pose. This may significantly reduce the effective latency for the layers' rendering and as a result improve overall experience.
1.1. Terminology
1.2. Application flow
If an author wants to use GL layers, they have to go through these steps:
-
For any layer type other than
XRProjectionLayer
request support throughrequiredFeatures
oroptionalFeatures
inrequestSession()
. -
Create an
XRWebGLBinding
orXRMediaBinding
. -
Create layers with these objects.
-
Add the layers to
XRRenderStateInit
and callupdateRenderState()
. -
During
requestAnimationFrame()
for webgl layers, draw content each WebGL layer.
2. Initialization
If an application wants to create layers other than of type XRProjectionLayer
during a session,
the session MUST be requested with an appropriate feature descriptor. The string "layers" is introduced
by this module as a new valid feature descriptor for the WebXR Layers feature.
Layers of type XRProjectionLayer
MUST always be supported, regardless if the feature descriptor was requested.
navigator. xr. requestSession( 'immersive-vr' , { optionalFeatures: [ 'layers' ] }
Layers are only supported for XRSessions created with XRSessionMode of "immersive-vr"
or "immersive-ar"
. "inline"
sessions MUST not support layers.
The "layers" feature descriptor has a feature requirement that it cannot be enabled when there is an active immersive session.
NOTE: This means that executing the request(permissionDesc)
API with "layers" will
not enable layers support for the current active session.
3. Layer types
3.1. Mono and stereo layers
A stereo layer MUST supply anXRSubImage
to render to for each view.
A mono layer MUST supply a single XRSubImage
which is shown to each view.
The XR Compositor MUST ensure that layers are presented correctly in stereo to the observer.
3.2. XRLayerLayout
TheXRLayerLayout
enum defines the layout of the layer.
enum {
XRLayerLayout "default" ,"mono" ,"stereo" ,"stereo-left-right" ,"stereo-top-bottom" };
-
A layout of
default
indicates that the layer can accomodate all the views of session’s list of views. -
A layout of
mono
indicates that the layer is mono. -
A layout of
stereo
indicates that the layer is stereo. -
A layout of
stereo-left-right
indicates that the layer is stereo and divided left to right. -
A layout of
stereo-top-bottom
indicates that the layer is stereo and divided top to bottom.
NOTE: If an XRCompositionLayer
is created with a "default"
or "stereo"
XRLayerLayout
, it is highly recommended
that it is allocated with an "texture-array"
texture type.
Note: The "stereo-left-right"
and "stereo-top-bottom"
layouts are designed to minimize draw
calls for content that is already in stereo (for example stereo videos or images). Experiences that don’t require such assets types
should use the "default"
or "stereo"
layout.
3.3. XRCompositionLayer
XRCompositionLayer defines a set of common attributes and behaviors across certain layer types.[Exposed =Window ]interface :
XRCompositionLayer XRLayer {readonly attribute XRLayerLayout layout ;attribute boolean blendTextureSourceAlpha ;attribute boolean ?chromaticAberrationCorrection ;readonly attribute unsigned long mipLevels ;readonly attribute boolean needsRedraw ;undefined (); };
destroy
The layout
attribute returns the layout of the layer.
The blendTextureSourceAlpha
attribute enables the layer’s texture alpha channel.
The chromaticAberrationCorrection
attribute is a hint for the XR Compositor to
enable optical chromatic aberration correction for the layer. If the user agent or device does not support this attribute, they
should return null
on getting, and setting should be a no-op
.
If the chromaticAberrationCorrection
was changed, it will take effect at the next XRFrame
.
The needsRedraw
attribute signals that the XRCompositionLayer
should be
rerendered in the next XR animation frame. It MAY be set when the underlying resources of a layer are lost or
when the XR Compositor can no longer reproject the layer. Failing to redraw the content in the next XR animation frame might cause flickering or other side effects.
The mipLevels
attribute returns the depth of the mip chain. This MUST be equal
or smaller than the value requested in mipLevels
.
NOTE: some platforms don’t support mip levels. Authors should query mipLevels
to determine if they can
target a certain mip level and not rely on the value they passed in mipLevels
.
XRCompositionLayer
layer,
the user agent MUST run the following steps:
-
Set layer’s
needsRedraw
totrue
. -
If layer is not an
XRProjectionLayer
, queue a task to fire an event namedredraw
on layer.
destroy()
will delete the underlying attachments. If there are no attachments, this function does nothing.
To intialize a composition layer with a XRSession
session and an optional instance of a WebGLRenderingContext
or a WebGL2RenderingContext
context, the user agent MUST run the following steps:
-
Set this
blendTextureSourceAlpha
totrue
. -
Initialize this
chromaticAberrationCorrection
as follows:- If the user agent supports chromatic aberration correction
- Set this
chromaticAberrationCorrection
totrue
orfalse
depending on the user agent’s preference. - Otherwise
- Set this
chromaticAberrationCorrection
tonull
.
When calling destroy()
, the user agent MUST run the following steps:
-
Set this colorTextures array to an empty array.
-
Set this depthStencilTextures array to an empty array.
-
Destroy the underlying GL attachments.
Each XRCompositionLayer
has a context object which is an instance
of either null or a WebGLRenderingContext
or a WebGL2RenderingContext
and a media object which is an instance of null or a HTMLVideoElement
.
Each XRCompositionLayer
has an associated session, which is the XRSession
it was created with.
When setting the space on a layer with XRSpace
space and XRCompositionLayer
layer, the user agent MUST run the following steps to validate if the space is valid:
XRCompositionLayer
has an internal boolean isStatic that indicates that the author can only draw
to this layer when needsRedraw
is true
.
NOTE: if isStatic is true
the author can only draw into the layer once after creation or once after
a redraw event. This allows the UA to only allocate a single GPU buffer.
When a writeable attribute is set on an XRCompositionLayer
or any of its derived classes,
reading that attribute MUST return that value.
At the end of the requestAnimationFrame()
callback, the value MUST be sent to
the underlying XR Compositor. The XR Compositor MUST apply the value next time it presents
the XRFrame
that was passed to the requestAnimationFrame()
callback.
NOTE: this means that the values must be applied when the XR Compositor redraws the scene using
the new XRFrame
, even if there was no change in the colorTexture
associated
with the XRCompositionLayer
or the videoframe associated with a media layer. If the XR Compositor redraws the scene with the previous XRFrame
's state, it must not use the new
values.
3.4. XRProjectionLayer
AnXRProjectionLayer
is a layer that fills the entire view of the observer.
Projection layers should be refreshed close to the device’s native frame rate.
[Exposed =Window ]interface :
XRProjectionLayer XRCompositionLayer {readonly attribute unsigned long textureWidth ;readonly attribute unsigned long textureHeight ;readonly attribute unsigned long textureArrayLength ;readonly attribute boolean ignoreDepthValues ;attribute float ?fixedFoveation ; };
The textureWidth
attribute returns the width in pixels of
the colorTextures textures of this layer.
The textureHeight
attribute returns the height in pixels of
the colorTextures textures of this layer.
The textureArrayLength
attribute returns the number of layers of
the colorTextures textures of this layer if the XRProjectionLayer
was initialized with a textureType
of "texture-array"
. Otherwise it will return 1
.
The fixedFoveation
attribute controls the amount of foveation used by the XR Compositor. If the user agent or device does not support this attribute, they
should return null
on getting, and setting should be a no-op
.
Setting fixedFoveation
to a value less than 0
will set it to 0
and setting it to
a value higher than 1
will set it to 1
. 0
sets the minimum amount of foveation while 1
set the maximum. It is up to the user agent how the XR Compositor interprets these values.
If the fixedFoveation
level was changed, it will take effect at the next XRFrame
.
The ignoreDepthValues
attribute, if true
, indicates that the XR Compositor MUST NOT make use of values in the depth buffer attachment when rendering. When the attribute
is false
it indicates that the content of the depth buffer attachment will be used by the XR Compositor and is expected to be representative of the scene rendered into the layer.
3.5. XRQuadLayer
AnXRQuadLayer
renders a layer that takes up a flat rectangular space in the virtual environment.
Only the front of the layer MUST be visible; the back face MUST not be drawn by the XR Compositor.
A XRQuadLayer has no thicknes. It is a two-dimensional object positioned and oriented in 3D space. The position of a quad refers to the center of the quad.
[Exposed =Window ]interface :
XRQuadLayer XRCompositionLayer {attribute XRSpace space ;attribute XRRigidTransform transform ;attribute float width ;attribute float height ; // Eventsattribute EventHandler onredraw ; };
The transform
attributes sets and returns the offset and orientation relative to the space
attribute. The transform
and space
attributes
establish the spatial relationship of the layer within the user’s physical environment.
When setting the space
, first run the steps for setting the space on a layer.
The width
and height
attributes
set and return the width and height of the layer in meters.
XRQuadLayer
layer with an XRQuadLayerInit
init, the user agent MUST run the following steps:
-
Initialize layer’s
transform
as follows:- If init’s
transform
is set - Let layer’s
transform
be a newXRRigidTransform
in the relevant realm of layer initialized withposition
andorientation
of init’stransform
. - Otherwise
- Let layer’s
transform
be a newXRRigidTransform
in the relevant realm of layer initialized with aDOMPointInit
position of{ x: 0.0, y: 0.0, z: 0.0, w: 1.0 }
.
- If init’s
The onredraw
attribute is an Event handler IDL attribute for the redraw
event type.
3.6. XRCylinderLayer
AnXRCylinderLayer
renders a layer that takes up a curved rectangular space in the virtual environment.
Only the front of the layer MUST be visible; the back face MUST not be drawn by the XR Compositor.
A XRCylinderLayer has no thicknes. It is a two-dimensional object positioned and oriented in 3D space. The position of the cylinder refers to the center of the quad.
[Exposed =Window ]interface :
XRCylinderLayer XRCompositionLayer {attribute XRSpace space ;attribute XRRigidTransform transform ;attribute float radius ;attribute float centralAngle ;attribute float aspectRatio ; // Eventsattribute EventHandler onredraw ; };
The transform
attribute sets and returns the offset and orientation relative to the space
attribute. The transform
and space
attributes
establish the spatial relationship of the layer within the user’s physical environment.
When setting the space
, first run the steps for setting the space on a layer.
The radius
attribute controls the radius in meters of the cylinder.
The centralAngle
attribute controls the angle in radians of the visible section of the cylinder.
It grows symmetrically around the 0 angle.
The aspectRatio
attribute controls the ratio of the visible cylinder section. It is the ratio of the width of the visible section of the cylinder divided by its height. The width is calculated by multiplying the radius
with the centralAngle
.
XRCylinderLayer
layer with an XRCylinderLayerInit
init, the user agent MUST run the following steps:
-
Initialize layer’s
centralAngle
to init’scentralAngle
. -
Initialize layer’s
aspectRatio
to init’saspectRatio
. -
Initialize layer’s
transform
as follows:- If init’s
transform
is set - Let layer’s
transform
be a newXRRigidTransform
in the relevant realm of layer initialized withposition
andorientation
of init’stransform
. - Otherwise
- Let layer’s
transform
be a newXRRigidTransform
in the relevant realm of layer initialized with aDOMPointInit
position of{ x: 0.0, y: 0.0, z: 0.0, w: 1.0 }
.
- If init’s
The onredraw
attribute is an Event handler IDL attribute for the redraw
event type.
3.7. XREquirectLayer
AnXREquirectLayer
renders a layer where the XR Compositor MUST map an equirectangular coded data onto the inside of a sphere.
this section needs clarification
[Exposed =Window ]interface :
XREquirectLayer XRCompositionLayer {attribute XRSpace ;
space attribute XRRigidTransform transform ;attribute float radius ;attribute float centralHorizontalAngle ;attribute float upperVerticalAngle ;attribute float lowerVerticalAngle ; // Eventsattribute EventHandler onredraw ; };
The transform
attribute sets and returns the offset and orientation relative to space
. The transform
attribute and the space
establish the spatial relationship of the layer within the user’s physical environment.
The radius
attribute is the non-negative radius in meters of the sphere. Values of zero
or infinity
are treated as an infinite sphere.
Setting radius
to a value less than 0
will set it to 0
.
The centralHorizontalAngle
, upperVerticalAngle
and lowerVerticalAngle
attributes set and return how the texture is mapped to the sphere.
Setting centralHorizontalAngle
to a value less than 0 will set it to 0 and setting it to
a value higher than 2π will set it to 2π.
Setting upperVerticalAngle
or lowerVerticalAngle
to a value less than -π/2 will set it
to -π/2 and setting it to a value higher than π/2 will set it to π/2.
When assigning an XRSpace
to the space
attribute, first run the following steps.
When setting the space on an equirect layer with XRSpace
space and XREquirectLayer
layer, the user agent MUST run the following steps to validate if the space is valid:
-
If init’s
space
is not an instance of typeXRReferenceSpace
, throwTypeError
and abort these steps. -
If init’s
space
has a type of"viewer"
, throwTypeError
and abort these steps. -
Run setting the space on a layer with space and layer.
XREquirectLayer
layer with an XREquirectLayerInit
init, the user agent MUST run the following steps:
-
Initialize layer’s
centralHorizontalAngle
to init’scentralHorizontalAngle
. -
Initialize layer’s
upperVerticalAngle
to init’supperVerticalAngle
. -
Initialize layer’s
lowerVerticalAngle
to init’slowerVerticalAngle
. -
Initialize layer’s
transform
as follows:- If init’s
transform
is set - Let layer’s
transform
be a newXRRigidTransform
in the relevant realm of layer initialized withposition
andorientation
of init’stransform
. - Otherwise
- Let layer’s
transform
be a newXRRigidTransform
in the relevant realm of layer.
- If init’s
The onredraw
attribute is an Event handler IDL attribute for the redraw
event type.
3.8. XRCubeLayer
AXRCubeLayer
renders a layer where the XR Compositor renders directly from a cubemap.
this section needs clarification
[Exposed =Window ]interface :
XRCubeLayer XRCompositionLayer {attribute XRSpace space ;attribute DOMPointReadOnly orientation ; // Eventsattribute EventHandler onredraw ; };
The orientation
attribute sets and returns the orientation relative to the space
attribute. The orientation
and space
attributes
establish the spatial relationship of the layer within the user’s physical environment.
When placing the XRCubeLayer
only the orientation of the space
is considered. The cube layer will always be rendered
with the view point at the center.
When assigning an XRSpace
to the space
attribute, first run the following steps.
When setting the space on an cube layer with XRSpace
space and XRCubeLayer
layer, the user agent MUST run the following steps to validate if the space is valid:
-
If init’s
space
is not an instance of typeXRReferenceSpace
, throwTypeError
and abort these steps. -
If init’s
space
has a type of"viewer"
, throwTypeError
and abort these steps. -
Run setting the space on a layer with space and layer.
The onredraw
attribute is an Event handler IDL attribute for the redraw
event type.
4. Spaces
XRProjectionLayer
and XRWebGLLayer
don’t have associated an XRSpace
because they render to the full frame.
XRCubeLayer
and XREquirectLayer
MUST only support XRReferenceSpaces
that are not of type "viewer"
.
XRQuadLayer
and XRCylinderLayer
MUST support all XRSpace
types.
Generally, developers should not use of "viewer"
space to stabilize layers, as this will almost always defeat positional or
rotational reprojection and result in a loss in stability of the rendered content relative to the world. The exception being small UI elements
like a gaze cursor or targeting reticle.
Following are some best practices of spaces to use with a layer type:
-
XRQuadLayer
with"viewer"
space: Head-locked constant-size reticle in center of screen. -
XRQuadLayer
orXRCylinderLayer
in"local"
,"unbounded"
space: springy body-locked UI. -
XRQuadLayer
orXRCylinderLayer
in"local"
,"local-floor"
,"unbounded"
,"bounded-floor"
or anchor space: world-locked video, placed by the user. -
XREquirectLayer
orXRCubeLayer
in"local"
space: 360-degree video or skybox.
5. Rendering
5.1. XRSubImage
TheXRSubImage
object represents what viewport of the GPU texture to use.
[Exposed =Window ]interface { [
XRSubImage SameObject ]readonly attribute XRViewport viewport ; };
NOTE: this class is designed to accomodate future extensions
The viewport
attribute returns the XRViewport
to use when rendering the sub image.
5.2. XRWebGLSubImage
TheXRWebGLSubImage
object is used during rendering of the layer.
[Exposed =Window ]interface :
XRWebGLSubImage XRSubImage { [SameObject ]readonly attribute WebGLTexture colorTexture ; [SameObject ]readonly attribute WebGLTexture ?depthStencilTexture ;readonly attribute unsigned long ?imageIndex ;readonly attribute unsigned long textureWidth ;readonly attribute unsigned long textureHeight ; };
The colorTexture
attribute returns the color opaque texture for the XRCompositionLayer
.
The depthStencilTexture
attribute returns the depth/stencil opaque texture for the XRCompositionLayer
.
If the layer was created without depth/stencil, this attribute returns null.
The imageIndex
attribute returns the offset into the texture array. Valid only for layers
that were requested with texture-array
.
The textureWidth
and textureHeight
attributes
return the width and height in pixels of the GL attachments, respectively.
5.3. XRTextureType
TheXRTextureType
enum defines what type of texture is allocated.
enum {
XRTextureType "texture" ,"texture-array" };
-
A texture type of
texture
indicates that the textures ofXRWebGLSubImage
MUST be of typeTEXTURE_2D
-
A texture type of
texture-array
indicates that the textures ofXRWebGLSubImage
MUST be of typeTEXTURE_2D_ARRAY
6. GPU layer and view creation
6.1. Overview
When a layer is created it is backed by a GPU resource, typically a texture, provided by one of the Web platform’s graphics APIs. In order to
specify which API is providing the layer’s GPU resources an XRWebGLBinding
for the API in question must be created.
Each graphics API may have unique requirements that must be satisfied before a context can be used in the creation of a layer. For example,
a WebGLRenderingContext
must have its xrCompatible flag set prior to being passed to the constructor of the XRWebGLBinding
instance.
Any interaction between the XRSession
the graphics API, such as allocating or retrieving textures, will go through this XRWebGLBinding
instance, and the exact mechanics
of the interaction will typically be API specific. This allows the rest of the WebXR API to be
graphics API agnostic and more easily adapt to future advances in rendering techniques.
Once an XRWebGLBinding
instance has been acquired, it can be used to create a variety of XRCompositionLayer
. Any layers created by that instance will then be able
to query the associated GPU resources each frame, generally expected to be the native API’s texture interface.
The various layer types are created with the create____Layer series of methods on the XRWebGLBinding
instance. Information about the graphics resources required,
such as whether or not to allocate a depth buffer or alpha channel, are passed in at layer creation time and will be immutable for the lifetime of the layer.
The method will return the associated XRCompositionLayer type.
Some layer types may not be supported by the XRSession
. If a layer type isn’t supported the method will throw an exception. XRProjectionLayer
MUST be supported by all XRSession
s.
6.2. Opaque textures
When using WebXR GPU layers, theXRWebGLBinding
object will return instances of an opaque texture for the color and depth/stencil attachments.
An opaque texture functions identically to a standard WebGLTexture
with the following changes:
-
An opaque texture is considered invalid outside of a
requestAnimationFrame()
callback for its session. -
An opaque texture is invalid until it is returned by the
getSubImage()
orgetViewSubImage()
calls. -
The XR Compositor MUST assume that the opaque texture for the color attachment contains colors with premultiplied alpha.
-
At the end of the
requestAnimationFrame()
callback the texture MUST be unbounded and detached from allWebGLShader
objects. -
An opaque texture MUST behave as though it was allocated with texStorage2D or texStorage3D, as appropriate, even when using a WebGL 1.0 context.
-
A call to
deleteTexture
with an opaque texture MUST generate anINVALID_OPERATION
error.
The buffers attached to an opaque texture MUST be cleared to the values in the table below during the processing of the first call to getViewSubImage()
or getSubImage()
in each XR animation frame.
Buffer | Clear Value |
---|---|
Color | (0, 0, 0, 0) |
Depth | 1.0 |
Stencil | 0 |
If the opaque texture was created with 2
or more mipLevels
,
the author SHOULD populate all the mip levels. The user agent MUST NOT assume that it should create the mip levels.
NOTE: the opaque textures are allocated when the layer is contructed using the allocate color textures and allocate depth textures algoritms. The side effect of this pre-allocation is that calling getSubImage()
and getViewSubImage()
with the same parameters will always return the same texture objects.
NOTE: Changes to the dimensions or format of the opaque textures are not allowed. GL commands may only alter the texel values and texture parameters. Using any of the following commands with the WebGLTexture will result in an INVALID_OPERATION error being generated, even if it does not affect the dimensions or format: TexImage*, CompressedTexImage*, CopyTexImage* and TexStorage*. The "Immutable-Format Texture Images" section in the OpenGL ES 3.0 spec defines these limitations in more detail.
Allocation of the resources for layers (such as memory) MUST be done through the same mechanism as WebGL.
6.3. XRProjectionLayerInit
TheXRProjectionLayerInit
dictionary represents a set of configurable values that describe how an XRProjectionLayer
is initialized.
dictionary {
XRProjectionLayerInit XRTextureType textureType = "texture";GLenum colorFormat = 0x1908; // RGBAGLenum depthFormat = 0x1902; // DEPTH_COMPONENTdouble scaleFactor = 1.0; };
The textureType
attribute defines the type of texture that the layer will have.
The colorFormat
attribute defines the data type of the color texture data.
This is the list of color formats for projection layers that the XR Compositor MUST support:
-
SRGB_ALPHA_EXT
for contexts with the 'EXT_sRGB
' extension enabled
For WebGL2 contexts these additional formats are supported:
The depthFormat
attribute defines the data type of the depth texture data.
If depthFormat
is 0
the layer will not provide a depth/stencil texture.
This is the list of depth formats for projection layers that the XR Compositor MUST support:
For WebGLRenderingContext
contexts with the 'WEBGL_depth_texture
' extension enabled or WebGL2 contexts:
If the extension was not enabled, the request for a depth texture is ignored.
NOTE: this could be confusing to authors because they might expect a depth texture. If possible, provide a warning with the reason why the texture was not created.
For WebGL2RenderingContext
contexts these additional formats are supported:
The scaleFactor
attribute defines the value that the session’s recommended WebGL framebuffer resolution MUST be multiplied by determining the resolution of the layer’s attachments.
NOTE: the XRProjectionLayerInit
dictionary does not have support to configure mipLevels
like XRLayerInit
. If a user agent wants to support mipmapping on projection layers, it is free to allocate the texture with mips.
In that case the user agent (and not the author) is responsible for generating all the mip levels.
6.4. XRLayerInit
TheXRLayerInit
dictionary represents a set of common configurable values for XRQuadLayer
, XRCylinderLayer
, XREquirectLayer
and XRCubeLayer
.
dictionary {
XRLayerInit required XRSpace space ;GLenum colorFormat = 0x1908; // RGBAGLenum ?depthFormat ;unsigned long mipLevels = 1;required unsigned long viewPixelWidth ;required unsigned long viewPixelHeight ;XRLayerLayout layout = "mono";boolean =
isStatic false ; };
The space
attribute defines the spatial relationship with the user’s physical environment.
The colorFormat
attribute defines the data type of the color texture data.
This is the list of color formats for non-projection layers that the XR Compositor MUST support:
-
SRGB_ALPHA_EXT
for contexts with the 'EXT_sRGB
' extension enabled
For WebGL2 contexts these additional formats are supported:
For contexts with the 'WEBGL_compressed_texture_etc
' extension enabled these additional formats are supported:
For contexts with the 'WEBGL_compressed_texture_astc
' extension enabled all the formats of that extension are supported.
The depthFormat
attribute defines the data type of the depth texture data.
If depthFormat
is not supplied, the layer will not provide a depth/stencil texture.
This is the list of depth formats for non-projection layers that the XR Compositor MUST support:
For WebGLRenderingContext
contexts with the 'WEBGL_depth_texture
' extension enabled or WebGL2 contexts:
For WebGL2RenderingContext
contexts these additional formats are supported:
The mipLevels
attribute defines the desired number of mip levels in the color and texture data.
If the user agent can’t create the requested number, it can create less. Authors MUST query mipLevels
to determine
the actual number of mip levels.
The viewPixelWidth
and viewPixelHeight
attributes define
the rectangular dimensions of the XRCompositionLayer
.
The layout
attribute defines the layout of the layer.
6.5. XRQuadLayerInit
The XRQuadLayerInit
dictionary represents a set of configurable values that describe how an XRQuadLayer
is initialized.
dictionary :
XRQuadLayerInit XRLayerInit {XRTextureType = "texture";
textureType XRRigidTransform ?;
transform float = 1.0;
width float = 1.0; };
height
6.6. XRCylinderLayerInit
The XRCylinderLayerInit
dictionary represents a set of configurable values that describe how an XRCylinderLayer
is initialized.
dictionary :
XRCylinderLayerInit XRLayerInit {XRTextureType = "texture";
textureType XRRigidTransform ?;
transform float = 2.0;
radius float = 0.78539;
centralAngle float = 2.0; };
aspectRatio
The default value of centralAngle
is π / 4.
6.7. XREquirectLayerInit
The XREquirectLayerInit
dictionary represents a set of configurable values that describe how an XREquirectLayer
is initialized.
dictionary :
XREquirectLayerInit XRLayerInit {XRTextureType = "texture";
textureType XRRigidTransform ?;
transform float = 0;
radius float = 6.28318;
centralHorizontalAngle float = 1.570795;
upperVerticalAngle float = -1.570795; };
lowerVerticalAngle
The default value of centralHorizontalAngle
is 2π.
The default value of upperVerticalAngle
is π/2.
The default value of lowerVerticalAngle
is -π/2.
6.8. XRCubeLayerInit
The XRCubeLayerInit
dictionary represents a set of configurable values that describe how an XRCubeLayer
is initialized.
dictionary :
XRCubeLayerInit XRLayerInit {DOMPointReadOnly ?; };
orientation
6.9. XRWebGLBinding
TheXRWebGLBinding
object is used to create layers that have a GPU backend.
[Exposed =Window ]interface {
XRWebGLBinding constructor (XRSession ,
session XRWebGLRenderingContext );
context readonly attribute double nativeProjectionScaleFactor ;readonly attribute boolean usesDepthValues ;XRProjectionLayer createProjectionLayer (optional XRProjectionLayerInit = {});
init XRQuadLayer createQuadLayer (optional XRQuadLayerInit = {});
init XRCylinderLayer createCylinderLayer (optional XRCylinderLayerInit = {});
init XREquirectLayer createEquirectLayer (optional XREquirectLayerInit = {});
init XRCubeLayer createCubeLayer (optional XRCubeLayerInit = {});
init XRWebGLSubImage getSubImage (XRCompositionLayer ,
layer XRFrame ,
frame optional XREye = "none");
eye XRWebGLSubImage getViewSubImage (XRProjectionLayer ,
layer XRView ); };
view
the init dictionaries shouldn’t be optional. This is bikeshed issue 1566.
Each XRWebGLBinding
has a context object of type XRWebGLRenderingContext
which is an instance
of either a WebGLRenderingContext
or a WebGL2RenderingContext
.
Each XRWebGLBinding
has an associated session, which is the XRSession
it was created with.
NOTE: It is possible to create more than one XRWebGLBinding
. Any layer created with an instance of XRWebGLBinding
can
be used with another instance of XRWebGLBinding
as long as both were created with the same session and the same context. The lifetime of layers or instances of XRWebGLSubImage
is not tied to the lifetime of the XRWebGLBinding
that created them.
Each XRCompositionLayer
created through XRWebGLBinding
has an internal colorTextures array which is an array of WebGLTextures
for color textures and
an internal depthStencilTextures which is an array of opaque textures for depth/stencil textures.
Each XRProjectionLayer
created through XRWebGLBinding
has an internal colorTextures for secondary views array which is an array of opaque textures for color textures and an internal depthStencilTextures for secondary views array which is an array of opaque textures for depth/stencil textures that are used to render the secondary views.
The XRWebGLBinding(session, context)
constructor
MUST perform the following steps when invoked:
-
Let binding be a new
XRWebGLBinding
in the relevant realm of session. -
If session’s ended value is
true
, throw anInvalidStateError
and abort these steps. -
If context is lost, throw an
InvalidStateError
and abort these steps. -
If session is not an immersive session, throw an
InvalidStateError
and abort these steps. -
If context’s XR compatible boolean is
false
, throw anInvalidStateError
and abort these steps. -
Initialize binding’s context to context.
-
Initialize binding’s session to session.
-
Return binding.
The nativeProjectionScaleFactor
function returns the value that the session’s recommended WebGL framebuffer resolution MUST be multiplied by to yield the session’s native WebGL framebuffer resolution.
special case UA behavior if the size causes the layout to change (ie if the requested width exceeds a limit with "stereo-left-right"
)
The usesDepthValues
attribute, if false
, indicates that the XR Compositor MUST NOT make use of values if there is a depth buffer attachment. When the attribute
is true
it indicates that the content of the depth buffer attachment will be used by the XR Compositor and is expected to be representative of the scene rendered into the layer.
To determine the layout attribute using an XRTextureType
textureType, an XRWebGLRenderingContext
context and an XRLayerLayout
layout, the user agent MUST run the following steps:
-
If context is not an
WebGL2RenderingContext
and textureType is"texture-array"
, throwTypeError
and abort these steps. -
If textureType is
"texture-array"
and not all of the session’s views in the list of views have the same recommended WebGL texture resolution, throw aNotSupportedError
and abort these steps. -
If layout is
"mono"
, return layout and abort these steps. -
If layout is
"default"
, run the following steps:-
If the size of list of views is
1
, return"mono"
and abort these steps. -
If textureType is
"texture-array"
, return layout and abort these steps.
-
-
If layout is
"default"
or"stereo"
and textureType is"texture"
, run the following steps:-
If the user agent prefers
"stereo-left-right"
layout, return"stereo-left-right"
and abort these steps. -
If the user agent prefers
"stereo-top-bottom"
layout, return"stereo-top-bottom"
and abort these steps.
-
-
return layout.
To determine the maximum scalefactor using an XRSession
session, an XRWebGLRenderingContext
context and an XRLayerLayout
layout, the user agent MUST run the following steps:
-
Let largest width be the largest width of the recommended WebGL texture resolution from the session’s list of views excluding the secondary views.
-
Let largest height be the largest height of the recommended WebGL texture resolution from the session’s list of views excluding the secondary views.
-
If layout is
"stereo-left-right"
layout, multiply largest width by2
. -
If layout is
"stereo-top-bottom"
layout, multiply largest height by2
. -
Let largest view dimension be the largest of largest width or largest height.
-
Let largest texture dimension be the largest dimension of a
WebGLTexture
created by context. -
return largest texture dimension divided by largest view dimension.
To allocate color textures for projection layers using an XRProjectionLayer
layer, an XRTextureType
textureType, a GLenum
textureFormat and a float scaleFactor, the user agent MUST run the following steps:
-
Let array be a new array in the relevant realm of context.
-
Let context be layer’s context.
-
Let session be layer’s session.
-
Let numViews be the number of the session’s list of views excluding the secondary views.
-
Let view be the first entry in the session’s list of views that is not a secondary views.
-
Let width be the width of view’s recommended WebGL texture resolution multiplied by scaleFactor.
-
Let height be the height of view’s recommended WebGL texture resolution multiplied by scaleFactor.
-
If textureFormat is not in the list of color formats for projection layers, throw a
NotSupportedError
and abort these steps. -
If layer’s
layout
is"mono"
or"default"
:- If textureType is
"texture-array"
: - If the session’s views in the list of views don’t all have the same recommended WebGL texture resolution excluding the secondary views, throw a
NotSupportedError
and abort these steps.- Initialize array with 1 new instance of an opaque texture in the relevant realm of context created as a
TEXTURE_2D_ARRAY
texture with numViews layers using context, textureFormat, width and height.- Return array and abort these steps.
- Initialize array with 1 new instance of an opaque texture in the relevant realm of context created as a
- Otherwise
-
For each view in the session’s list of views:
-
If view is a secondary view, continue.
-
Let width be the width of view’s recommended WebGL texture resolution multiplied by scaleFactor.
-
Let height be the height of view’s recommended WebGL texture resolution multiplied by scaleFactor.
-
let texture be a new instance of an opaque texture in the relevant realm of context created as a
TEXTURE_2D
texture with context, textureFormat, width and height. -
Append texture to array.
- Return array and abort these steps.
-
- If textureType is
-
If the session’s views in the list of views don’t all have the same recommended WebGL texture resolution excluding the secondary views, throw a
NotSupportedError
and abort these steps. -
If layer’s
layout
isstereo-left-right
, initialize array with 1 new instance of opaque texture in the relevant realm of context created as a textureType texture using context , textureFormat, numViews multiplied by width and height. -
If layer’s
layout
isstereo-top-bottom
, initialize array with 1 new instance of opaque texture in the relevant realm of context created as a textureType texture using context , textureFormat, width and numViews multiplied by height. -
return array.
To allocate depth textures for projection layers using an XRProjectionLayer
layer, an XRTextureType
textureType, a GLenum
textureFormat and a float scaleFactor, the user agent MUST run the following steps:
-
Let array be a new array in the relevant realm of context.
-
Let context be layer’s context.
-
Let session be layer’s session.
-
If textureFormat is
0
, return array and abort these steps. -
If context is a
WebGLRenderingContext
and theWEBGL_depth_texture
extension is not enabled in context, return array and abort these steps. -
If textureFormat is not in the list of depth formats for projection layers, throw a
NotSupportedError
and abort these steps. -
let numViews be the number of the session’s list of views excluding the secondary views.
-
Let view be the first entry in the session’s list of views that is not a secondary view.
-
Let width be the width of view’s recommended WebGL texture resolution multiplied by scaleFactor.
-
Let height be the height of view’s recommended WebGL texture resolution multiplied by scaleFactor.
-
If layer’s
layout
is"mono"
or"default"
:- If textureType is
"texture-array"
: - Initialize array with 1 new instance of an opaque texture in the relevant realm of context created as a
TEXTURE_2D_ARRAY
texture with numViews layers using context, textureFormat, stencil, width and height.- Return array and abort these steps.
- Otherwise
-
For each view in the session’s list of views:
-
If view is a secondary view, continue.
-
Let width be the width of view’s recommended WebGL texture resolution multiplied by scaleFactor.
-
Let height be the height of view’s recommended WebGL texture resolution multiplied by scaleFactor.
-
let texture be a new instance of an opaque texture in the relevant realm of context created as a
TEXTURE_2D
texture with context, textureFormat, stencil, width and height. -
Append texture to array.
- Return array and abort these steps.
-
- If textureType is
-
If the session’s views in the list of views don’t all have the same recommended WebGL texture resolution excluding the secondary views, throw a
NotSupportedError
and abort these steps. -
If layer’s
layout
isstereo-left-right
, initialize array with 1 new instance of an opaque texture in the relevant realm of context created as a textureType texture using context, textureFormat, stencil, numViews multiplied by width and height. -
If layer’s
layout
isstereo-top-bottom
, initialize array with 1 new instance of an opaque texture in the relevant realm of context created as a textureType texture using context, textureFormat, stencil, width and numViews multiplied by height. -
return array.
To allocate the color textures for the secondary views using an XRProjectionLayer
layer, an XRTextureType
textureType, a GLenum
textureFormat and a float scaleFactor, the user agent MUST run the following steps:
-
Let context be layer’s context.
-
Let session be layer’s session.
-
Let array be a new array in the relevant realm of context.
-
If textureFormat is not in the list of color formats for projection layers, throw a
NotSupportedError
and abort these steps. -
For each view in the session’s list of views:
-
If view is not a secondary view, continue.
-
Let width be the width of view’s recommended WebGL texture resolution multiplied by scaleFactor.
-
Let height be the height of view’s recommended WebGL texture resolution multiplied by scaleFactor.
-
Initialize texture as follows:
- If textureType is
"texture-array"
: - Let texture be a new instance of an opaque texture in the relevant realm of context created as a
TEXTURE_2D_ARRAY
texture with context, textureFormat, width and height. - Otherwise
- Let texture be a new instance of an opaque texture in the relevant realm of context created as a
TEXTURE_2D
texture with context, textureFormat, width and height.
- If textureType is
-
Append texture to array.
-
-
Return array and abort these steps.
To allocate the depth textures for the secondary views using an XRProjectionLayer
layer, an XRTextureType
textureType, a GLenum
textureFormat and a float scaleFactor, the user agent MUST run the following steps:
-
Let context be layer’s context.
-
Let session be layer’s session.
-
If textureFormat is
0
, return array and abort these steps. -
If context is a
WebGLRenderingContext
and theWEBGL_depth_texture
extension is not enabled in context, return array and abort these steps. -
If textureFormat is not in the list of depth formats for projection layers, throw a
NotSupportedError
and abort these steps. -
Let array be a new array in the relevant realm of context.
-
For each view in the session’s list of views:
-
If view is not a secondary view, continue.
-
Let width be the width of view’s recommended WebGL texture resolution multiplied by scaleFactor.
-
Let height be the height of view’s recommended WebGL texture resolution multiplied by scaleFactor.
-
Initialize texture as follows:
- If textureType is
"texture-array"
: - Let texture be a new instance of an opaque texture in the relevant realm of context created as a
TEXTURE_2D_ARRAY
texture with context, textureFormat, stencil, width and height. - Otherwise
- Let texture be a new instance of an opaque texture in the relevant realm of context created as a
TEXTURE_2D
texture with context, textureFormat, stencil, width and height.
- If textureType is
-
Append texture to array.
-
-
Return array and abort these steps.
the scaleFactor needs to be recalculated for the secondary views.
To allocate color textures using an XRCompositionLayer
layer, an XRTextureType
textureType and an XRLayerInit
init, the user agent MUST run the following steps:
-
let array be a new array in the relevant realm of context.
-
let context be layer’s context.
-
If init’s
colorFormat
is not in the list of color formats for non-projection layers, throw aNotSupportedError
and abort these steps. -
If init’s
mipLevels
is smaller than1
, throw aInvalidStateError
and abort these steps. -
If init’s
mipLevels
is larger than1
andviewPixelWidth
andviewPixelHeight
are not powers of2
, throw aInvalidStateError
and abort these steps -
- If textureType is
"texture-array"
: - Initialize array with 1 new instance of an opaque texture in the relevant realm of this context created as a
TEXTURE_2D_ARRAY
texture with 1 internal texture using context and init’scolorFormat
,mipLevels
,viewPixelWidth
andviewPixelHeight
values. - Otherwise
-
Initialize array with 1 new instance of an opaque texture in the relevant realm of context created as a
TEXTURE_2D
texture with context and init’scolorFormat
,mipLevels
,viewPixelWidth
andviewPixelHeight
values.
- If textureType is
-
If layer’s
layout
is"stereo"
:- If textureType is
"texture-array"
: - Initialize array with 1 new instance of an opaque texture in the relevant realm of context created as a
TEXTURE_2D_ARRAY
texture with 2 layers using context and init’scolorFormat
,mipLevels
,viewPixelWidth
andviewPixelHeight
values.- Return array and abort these steps.
- Otherwise
- Initialize array with 2 new instances of an opaque texture in the relevant realm of context created as a
TEXTURE_2D
texture with context and init’scolorFormat
,mipLevels
,viewPixelWidth
andviewPixelHeight
values.- Return array and abort these steps.
- If textureType is
-
If layer’s
layout
isstereo-left-right
, initialize array with 1 new instance of an opaque texture in the relevant realm of context created as a textureType texture using context and init’scolorFormat
,mipLevels
, double ofviewPixelWidth
andviewPixelHeight
values. -
If layer’s
layout
isstereo-top-bottom
, initialize array with 1 new instance of an opaque texture in the relevant realm of context created as a textureType texture using context and init’scolorFormat
,mipLevels
,viewPixelWidth
and double ofviewPixelHeight
values. -
return array.
To allocate depth textures using an XRCompositionLayer
layer, an XRTextureType
textureType and an XRLayerInit
init, the user agent MUST run the following steps:
-
let array be a new array in the relevant realm of context.
-
let context be layer’s context.
-
If init’s
depthFormat
is not set, return array and abort these steps. -
If init’s
depthFormat
is not in the list of depth formats for non-projection layers, throw aNotSupportedError
and abort these steps. -
If init’s
mipLevels
is smaller than1
, throw aInvalidStateError
and abort these steps. -
If init’s
mipLevels
is larger than1
andviewPixelWidth
andviewPixelHeight
are not powers of2
, throw aInvalidStateError
and abort these steps. -
- If textureType is
"texture-array"
: - Initialize array with 1 new instance of an opaque texture in the relevant realm of context created as a
TEXTURE_2D_ARRAY
texture with 1 internal texture using context and init’sdepthFormat
,mipLevels
,viewPixelWidth
andviewPixelHeight
values. - Otherwise
- Initialize array with 1 new instance of an opaque texture in the relevant realm of context created as a
TEXTURE_2D
texture with context and init’sdepthFormat
,mipLevels
,viewPixelWidth
andviewPixelHeight
values.
- If textureType is
-
If layer’s
layout
is"stereo"
:- If textureType is
"texture-array"
: - Initialize array with 1 new instance of an opaque texture in the relevant realm of context created as a
TEXTURE_2D_ARRAY
texture with 2 layers using context and init’sdepthFormat
,mipLevels
,viewPixelWidth
andviewPixelHeight
values.- Return array and abort these steps.
- Otherwise
- Initialize array with 2 new instances of an opaque texture in the relevant realm of context created as a
TEXTURE_2D
texture with context and init’sdepthFormat
,mipLevels
,viewPixelWidth
andviewPixelHeight
values.- Return array and abort these steps.
- If textureType is
-
If layer’s
layout
isstereo-left-right
, initialize array with 1 new instance of an opaque texture in the relevant realm of context created as a textureType texture using context and init’sdepthFormat
,mipLevels
, double ofviewPixelWidth
andviewPixelHeight
values. -
If layer’s
layout
isstereo-top-bottom
, initialize array with 1 new instance of an opaque texture in the relevant realm of context created as a textureType texture using context and init’sdepthFormat
,mipLevels
,viewPixelWidth
and double ofviewPixelHeight
values. -
return array.
createProjectionLayer(optional XRProjectionLayerInit init)
method creates a new XRProjectionLayer
layer.
When this method is invoked, the user agent MUST run the following steps:
-
Let layer be a new
XRProjectionLayer
in the relevant realm of this. -
If session’s ended value is
true
, throwInvalidStateError
and abort these steps. -
If context is lost, throw
InvalidStateError
and abort these steps. -
Run intialize a composition layer on layer with session and context.
-
Initialize layer’s isStatic to
false
. -
Initialize layer’s
ignoreDepthValues
as follows:- If init’s
depthFormat
isfalse
and the XR Compositor will make use of depth values - Initialize layer’s
ignoreDepthValues
tofalse
- Otherwise
- Initialize layer’s
ignoreDepthValues
totrue
- If init’s
-
Initialize layer’s
fixedFoveation
to0
. -
let layout be the result of determining the layout attribute with init’s
textureType
, context and"default"
. -
Let maximum scalefactor be the result of determining the maximum scalefactor with session, context and layout.
-
If
scaleFactor
is larger than maximum scalefactor, setscaleFactor
to maximum scalefactor. -
Initialize layer’s
layout
to layout. -
Initialize layer’s
needsRedraw
totrue
. -
let layer’s colorTextures be the result of allocating color textures for projection layers with layer, init’s
textureType
, init’scolorFormat
and init’sscaleFactor
. -
let layer’s depthStencilTextures be the result of allocating depth textures for projection layers with layer, init’s
textureType
, init’sdepthFormat
and init’sscaleFactor
. -
Initialize the colortextures for secondary views as follows:
- If the session was created with "secondary-views" enabled
- Let colortextures for secondary views be the result of allocate the color textures for the secondary views with layer, init’s
textureType
, init’scolorFormat
and init’sscaleFactor
. - Otherwise
- Let colortextures for secondary views be
null
.
-
Initialize the depthstenciltextures for secondary views as follows:
- If the session was created with "secondary-views" enabled
- Let depthstenciltextures for secondary views be the result of allocate the depth textures for the secondary views with layer, init’s
textureType
, init’sdepthFormat
and init’sscaleFactor
. - Otherwise
- Let depthstenciltextures for secondary views be
null
.
-
If the XR Compositor knows that it will be unable to create the resources for the layer for any reason, throw an
OperationError
and abort these steps. -
Return layer.
createQuadLayer(XRQuadLayerInit init)
method creates a new XRQuadLayer
layer.
When this method is invoked, the user agent MUST run the following steps:
-
If session was not created with "layers" enabled, throw a
NotSupportedError
and abort these steps. -
If session’s ended value is
true
, throwInvalidStateError
and abort these steps. -
If context is lost, throw
InvalidStateError
and abort these steps. -
If layout is
"default"
, throwTypeError
and abort these steps. -
Let layer be a new
XRQuadLayer
in the relevant realm of this. -
Run intialize a composition layer on layer with session and context.
-
Run initialize a quad layer with layer and init.
-
let layout be the result of determining the layout attribute with init’s
textureType
, context and init’slayout
. -
Initialize layer’s
layout
to layout. -
Initialize layer’s
needsRedraw
totrue
. -
let layer’s colorTextures be the result of allocating color textures with layer, init’s
textureType
and init. -
let layer’s depthStencilTextures be the result of allocating depth textures with layer, init’s
textureType
and init. -
If the XR Compositor knows that it will be unable to create the resources for the layer for any reason, throw an
OperationError
and abort these steps. -
return layer.
createCylinderLayer(XRCylinderLayerInit init)
method creates a new XRCylinderLayer
layer.
When this method is invoked, the user agent MUST run the following steps:
-
If session was not created with "layers" enabled, throw a
NotSupportedError
and abort these steps. -
If session’s ended value is
true
, throwInvalidStateError
and abort these steps. -
If context is lost, throw
InvalidStateError
and abort these steps. -
If layout is
"default"
, throwTypeError
and abort these steps. -
Let layer be a new
XRCylinderLayer
in the relevant realm of this. -
Run intialize a composition layer on layer with session and context.
-
Run initialize a cylinder layer with layer and init.
-
let layout be the result of determining the layout attribute with init’s
textureType
, context and init’slayout
. -
Initialize layer’s
layout
to layout. -
Initialize layer’s
needsRedraw
totrue
. -
let layer’s colorTextures be the result of allocating color textures with layer, init’s
textureType
and init. -
let layer’s depthStencilTextures be the result of allocating depth textures with layer, init’s
textureType
and init. -
If the XR Compositor knows that it will be unable to create the resources for the layer for any reason, throw an
OperationError
and abort these steps. -
return layer.
createEquirectLayer(XREquirectLayerLayerInit init)
method creates a new XREquirectLayer
layer.
When this method is invoked, the user agent MUST run the following steps:
-
If session was not created with "layers" enabled, throw a
NotSupportedError
and abort these steps. -
If session’s ended value is
true
, throwInvalidStateError
and abort these steps. -
If context is lost, throw
InvalidStateError
and abort these steps. -
If layout is
"default"
, throwTypeError
and abort these steps. -
If init’s
space
is not an instance of typeXRReferenceSpace
, throwTypeError
and abort these steps. -
If init’s
space
has a type of"viewer"
, throwTypeError
and abort these steps. -
Let layer be a new
XREquirectLayer
in the relevant realm of this. -
Run intialize a composition layer on layer with session and context.
-
Run initialize a equirect layer with layer and init.
-
let layout be the result of determining the layout attribute with init’s
textureType
, context and init’slayout
. -
Initialize layer’s
layout
to layout. -
Initialize layer’s
needsRedraw
totrue
. -
let layer’s colorTextures be the result of allocating color textures with layer, init’s
textureType
and init. -
let layer’s depthStencilTextures be the result of allocating depth textures with layer, init’s
textureType
and init. -
If the XR Compositor knows that it will be unable to create the resources for the layer for any reason, throw an
OperationError
and abort these steps. -
return layer.
createCubeLayer(XRCubeLayerInit init)
method creates a new XRCubeLayer
layer.
When this method is invoked, the user agent MUST run the following steps:
-
If session was not created with "layers" enabled, throw a
NotSupportedError
and abort these steps. -
If session’s ended value is
true
, throwInvalidStateError
and abort these steps. -
If context is not a
WebGL2RenderingContext
context, throwInvalidStateError
and abort these steps. -
If context is lost, throw
InvalidStateError
and abort these steps. -
If init’s
space
is not an instance of typeXRReferenceSpace
, throwTypeError
and abort these steps. -
If init’s
space
has a type of"viewer"
, throwTypeError
and abort these steps. -
Let layer be a new
XRCubeLayer
in the relevant realm of this. -
Run intialize a composition layer on layer with session and context.
-
Initialize layer’s
orientation
as follows:- If init’s
orientation
is set - Let layer’s
orientation
be the result of runningfromPoint
with init’sorientation
. - Otherwise
- Let layer’s
orientation
be a newDOMPointReadOnly
in the relevant realm of this.
- If init’s
-
let layout be init’s
layout
. -
Initialize layer’s
needsRedraw
totrue
. -
If layout is
"default"
or"stereo-left-right"
or"stereo-top-bottom"
, throwTypeError
and abort these steps. -
Let layer’s colorTextures be a new array in the relevant realm of this
XRCubeLayer
. -
Initialize layer’s colorTextures as follows, based on the value of layout:
-
"mono"
: - Initialize colorTextures with 1 new instance of an opaque texture in the relevant realm of this
XRCubeLayer
created as aTEXTURE_CUBE_MAP
texture with context and init’scolorFormat
,viewPixelWidth
andviewPixelHeight
values. - Otherwise
- Initialize colorTextures with 2 new instances of an opaque texture in the relevant realm of this
XRCubeLayer
created as aTEXTURE_CUBE_MAP
texture with context and init’scolorFormat
,viewPixelWidth
andviewPixelHeight
values.
-
-
Let layer’s depthStencilTextures be a new array in the relevant realm of this
XRCubeLayer
. -
If init’s
depthFormat
is set, initialize layer’s depthStencilTextures as follows:- If context is not a
WebGL2RenderingContext
and theWEBGL_depth_texture
extension is not enabled in context - Throw
TypeError
and abort these steps. - Else if layout is
"mono"
- Initialize depthStencilTextures with 1 new instance of an opaque texture in the relevant realm of this
XRCubeLayer
created as aTEXTURE_CUBE_MAP
texture with context and init’sdepthFormat
,viewPixelWidth
andviewPixelHeight
values. - Otherwise
- Initialize depthStencilTextures with 2 new instances of an opaque texture in the relevant realm of this
XRCubeLayer
created as aTEXTURE_CUBE_MAP
texture with context and init’sdepthFormat
,viewPixelWidth
andviewPixelHeight
values.
- If context is not a
-
If the XR Compositor knows that it will be unable to create the resources for the layer for any reason, throw an
OperationError
and abort these steps. -
return layer.
Define how cubemap sizes are determined.
How should space be handled. Can you walk to the edge of a cubemap?
determine the initial state of orientation
.
To validate the state of the XRWebGLSubImage creation function of an XRWebGLBinding
binding with parameters of XRCompositionLayer
layer and XRFrame
frame, the user agent MUST run the following steps:
-
If frame’s
session
is not equal to layer’s session, returnfalse
and abort these steps. -
If frame’s active boolean is
false
, returnfalse
and abort these steps. -
If frame’s animationFrame boolean is
false
, returnfalse
and abort these steps. -
If binding’s session is not equal to layer’s session, return
false
and abort these steps. -
If binding’s context is not equal to layer’s context, return
false
and abort these steps. -
If the layer’s colorTextures array is empty or missing, return
false
and abort these steps. -
If the layer’s isStatic is
true
and layer’sneedsRedraw
isfalse
, returnfalse
and abort these steps. -
return
true
.
To initialize the viewport of an XRViewport
viewport with a opaque texture texture, a XRLayerLayout
layout, an integer offset and a integer num, the user agent MUST run the following steps:
-
Set viewport’s
x
to0
. -
Set viewport’s
y
to0
. -
Set viewport’s
width
to the pixel width of texture. -
Set viewport’s
height
to the pixelh eight of texture. -
Update viewport as follows:
- If layout is
"stereo-left-right"
- Set viewport’s
x
to the pixel width of texture multiplied by offset and divided by num.- Set viewport’s
width
to the pixel width of subimage’s texture divided by num. - Set viewport’s
- Else if layout is
"stereo-top-bottom"
- Set viewport’s
y
to the pixel height of texture multiplied by offset and divided by num.- Set viewport’s
height
to the pixel height of subimage’s texture divided by num. - Set viewport’s
- If layout is
getSubImage(XRCompositionLayer layer, XRFrame frame, optional XREye eye = "none"
)
method creates a new XRWebGLSubImage
.
When this method is invoked on an XRWebGLBinding
binding, it MUST run the following steps:
-
Initialize subimage as follows:
- If
getSubImage()
was called previously with the same binding, layer and eye, the user agent MAY - Let subimage be the same
XRWebGLSubImage
object as returned by an earlier call with the same arguments. - Otherwise
- Let subimage be a new
XRWebGLSubImage
in the relevant realm of this.- Let subimage’s
viewport
be a newXRViewport
in the relevant realm of this. - Let subimage’s
- If
-
If layer is not in the session’s
layers
array, throw aTypeError
and abort these steps. -
If layer’s type is
XRProjectionLayer
, throw aTypeError
and abort these steps. -
If layer’s
layout
attribute is"default"
, throw aTypeError
and abort these steps. -
Let index be
0
. -
If validate the state of the XRWebGLSubImage creation function with layer and frame is
false
, throw anInvalidStateError
and abort these steps. -
Initialize subimage’s
imageIndex
as follows:- If the layer was created with a textureType of
"texture-array"
- Initialize subimage’s
imageIndex
with index. - Otherwise
- Initialize subimage’s
imageIndex
with0
.
- If the layer was created with a textureType of
-
Initialize subimage’s
colorTexture
as follows:- If the layer was created with a textureType of
"texture"
- Initialize subimage’s
colorTexture
with the element at offset index of the layer’s colorTextures array. - Otherwise
- Initialize subimage’s
colorTexture
with the first element of the layer’s colorTextures array.
- If the layer was created with a textureType of
-
Initialize subimage’s
depthStencilTexture
as follows:- If the layer’s depthStencilTextures is an empty array
- Initialize subimage’s
depthStencilTexture
withnull
. - Else the layer was created with a textureType of
"texture"
- Initialize subimage’s
depthStencilTexture
with the element at offset index of the layer’s depthStencilTextures array. - Otherwise
- Initialize subimage’s
depthStencilTexture
with the first element of layer’s depthStencilTextures array.
-
Set subimage’s
textureWidth
to the pixel width of subimage’scolorTexture
. -
Set subimage’s
textureHeight
to the pixel height of subimage’scolorTexture
. -
Let viewsPerTexture be
1
. -
If layer’s
layout
attribute is"stereo-left-right"
or"stereo-top-bottom"
, set viewsPerTexture to2
. -
Run initialize the viewport on subimage’s
viewport
with subimage’scolorTexture
, layer’slayout
, index and viewsPerTexture. -
Queue a task to set
needsRedraw
tofalse
. -
return subimage.
getViewSubImage(XRProjectionLayer layer, XRView view)
method creates a new XRWebGLSubImage
.
When this method is invoked on an XRWebGLBinding
binding, it MUST run the following steps:
-
Initialize subimage as follows:
- If
getViewSubImage()
was called previously with the same binding, layer and view, the user agent MAY - Let subimage be the same
XRWebGLSubImage
object as returned by an earlier call with the same arguments. - Otherwise
- Let subimage be a new
XRWebGLSubImage
in the relevant realm of this.- Let subimage’s
viewport
be a newXRViewport
in the relevant realm of this. - Let subimage’s
- If
-
Let frame be view’s
frame
. -
If validate the state of the XRWebGLSubImage creation function with layer and frame is
false
, throw anInvalidStateError
and abort these steps. -
If layer is not in the session’s
layers
array, throw aTypeError
and abort these steps. -
If view’s active flag is
false
, throw anInvalidStateError
and abort these steps. -
Initialize index as follows:
- If view is a secondary view from session’s list of views
- Let index be the offset of view’s view in session’s list of views excluding the primary views.
- Otherwise
- Let index be the offset of view’s view in session’s list of views excluding the secondary views.
-
Initialize subimage’s
imageIndex
as follows:- If the layer was created with a textureType of
"texture-array"
: - Initialize subimage’s
imageIndex
with index. - Otherwise
- Initialize subimage’s
imageIndex
to0
.
- If the layer was created with a textureType of
-
Initialize subimage’s
colorTexture
as follows:- If view is a secondary view from session’s list of views
- Initialize subimage’s
colorTexture
with the element at offset index of the layer’s colorTextures for secondary views. - Else if the layer’s
layout
is"default"
and the layer was created with a textureType of"texture"
- Initialize subimage’s
colorTexture
with the element at offset index of the layer’s colorTextures array. - Otherwise
- Initialize subimage’s
colorTexture
with the first element of the layer’s colorTextures array.
-
Initialize subimage’s
depthStencilTexture
as follows:- If the layer’s depthStencilTextures is an empty array
- Initialize subimage’s
depthStencilTexture
withnull
. - Else if view is a secondary view from session’s list of views
- Initialize subimage’s
colorTexture
with the element at offset index of the layer’s depthStencilTextures for secondary views. - Else if the layer’s
layout
is"default"
and the layer was created with a textureType of"texture"
- Initialize subimage’s
depthStencilTexture
with the element at offset index of the layer’s depthStencilTextures array. - Otherwise
- Initialize subimage’s
depthStencilTexture
with the first element of layer’s depthStencilTextures array.
-
Set subimage’s
textureWidth
to the pixel width of subimage’scolorTexture
. -
Set subimage’s
textureHeight
to the pixel height of subimage’scolorTexture
. -
Run initialize the viewport on subimage’s
viewport
with subimage’scolorTexture
, layer’slayout
, index and the number of the session’s list of views. -
Set
needsRedraw
tofalse
. -
return subimage
NOTE: The session should try to defer calls to getSubImage()
and getViewSubImage()
to the time that the experience starts drawing using WebGL.
Typically that would be after the game logic runs. On certain user agents having distinct stages for CPU and GPU dependent code allows them to dynamically optimize system resources.
When an XRLayer
is a member of the layers
array, it MUST be presented to the immersive XR device immediately after
an XR animation frame completes, but only if at least one of the following has occurred since the previous XR animation frame:
-
The
XRLayer
was added tolayers
since the previous XR animation frame. -
XRLayer
is anXRWebGLLayer
andclear
,drawArrays
,drawElements
, or any other rendering operation which similarly affects the framebuffer’s color values has been called while the opaque framebuffer is the currently bound framebuffer of theWebGLRenderingContext
associated with theXRWebGLLayer
. -
XRLayer
is anXRCompositionLayer
andgetSubImage()
orgetViewSubImage()
was called and any rendering operation has been called that affects the color value of thecolorTexture
texture.
Before the opaque framebuffer or colorTexture
texture are presented to the immersive XR device the user agent MUST ensure that all rendering operations have been flushed.
7. Video layer creation
7.1. XRMediaLayerInit
TheXRMediaLayerInit
dictionary represents a set of configurable values that describe how an XRCompositionLayer
containing a video
is initialized.
dictionary {
XRMediaLayerInit required XRSpace space ;XRLayerLayout layout = "mono";boolean invertStereo =false ; };
The space
attribute defines the spatial relationship with the user’s physical environment.
The layout
attribute defines the layout of the video in the XRCompositionLayer
.
The invertStereo
attribute defines if the natural location of each view in the video
should be inverted.
7.2. XRMediaQuadLayerInit
TheXRMediaQuadLayerInit
dictionary represents a set of configurable values that describe how an XRQuadLayer
containing a video
is initialized.
dictionary :
XRMediaQuadLayerInit XRMediaLayerInit {XRRigidTransform ?;
transform float ?;
width float ?; };
height
7.3. XRMediaCylinderLayerInit
TheXRMediaCylinderLayerInit
dictionary represents a set of configurable values that describe how an XRCylinderLayer
containing a video
is initialized.
dictionary :
XRMediaCylinderLayerInit XRMediaLayerInit {XRRigidTransform ?;
transform float = 2.0;
radius float = 0.78539;
centralAngle float ?; };
aspectRatio
7.4. XRMediaEquirectLayerInit
TheXRMediaEquirectLayerInit
dictionary represents a set of configurable values that describe how an XREquirectLayer
containing a video
is initialized.
dictionary :
XRMediaEquirectLayerInit XRMediaLayerInit {XRRigidTransform ?;
transform float = 0.0;
radius float = 6.28318;
centralHorizontalAngle float = 1.570795;
upperVerticalAngle float = -1.570795; };
lowerVerticalAngle
7.5. XRMediaBinding
TheXRMediaBinding
object is used to create layers that display the content of an HTMLVideoElement
.
[Exposed =Window ]interface {
XRMediaBinding constructor (XRSession );
session XRQuadLayer createQuadLayer (HTMLVideoElement ,
video optional XRMediaQuadLayerInit = {});
init XRCylinderLayer createCylinderLayer (HTMLVideoElement ,
video optional XRMediaCylinderLayerInit = {});
init XREquirectLayer createEquirectLayer (HTMLVideoElement ,
video optional XRMediaEquirectLayerInit = {}); };
init
the init dictionaries shouldn’t be optional. This is bikeshed issue 1566.
Each XRMediaBinding
has an associated session, which is the XRSession
it was created with.
NOTE: It is possible to create more than one XRMediaBinding
. The lifetime of a layer is not tied
to the lifetime of the XRMediaBinding
that created it.
Each layer created through XRMediaBinding
has an internal HTMLVideoElement
media.
If the layer is part of the session’s renderState
, it will display the current frame of the video. The
layer is update at the native framerate of the XR device or the video, whichever is less.
NOTE: only the video frames will be displayed in the layer. Video controls should be implemented by the author and must be drawn in another layer.
more clarification is needed on how the video is blitted to the layers.
XRCompositionLayer
layer with a HTMLVideoElement
media needs to be rendered, the user agent
MUST run the following steps:
-
Let usability be the result of checking the usability of media.
-
If usability is
bad
, then fill the layer with opaque black and abort these steps. -
Fill the layer with the content of the media element.
add a better algorithm to describe the drawing.
The XRMediaBinding(XRSession session)
constructor
MUST perform the following steps when invoked:
-
If session’s ended value is
true
, throw anInvalidStateError
and abort these steps. -
If session is not an immersive session, throw an
InvalidStateError
and abort these steps. -
Let binding be a new
XRMediaBinding
in the relevant realm of session. -
Initialize binding’s session to session.
-
Return binding.
HTMLVideoElement
video and an XRLayerLayout
layout, run the following steps:
-
Let width be the video’s
videoWidth
. -
Let height be the video’s
videoHeight
. -
If layout is
"stereo-left-right"
, divide width by2
. -
If layout is
"stereo-top-bottom"
, divide height by2
. -
Return width divided by height.
createQuadLayer(HTMLVideoElement video, XRMediaQuadLayerInit init)
method creates a new XRQuadLayer
layer.
When this method is invoked, the user agent MUST run the following steps:
-
If session was not created with "layers" enabled, throw a
NotSupportedError
and abort these steps. -
If session’s ended value is
true
, throwInvalidStateError
and abort these steps. -
If init’s
layout
is"default"
, throw aTypeError
and abort these steps. -
Let layer be a new
XRQuadLayer
in the relevant realm of this. -
Run intialize a composition layer on layer with session.
-
Initialize layer’s media to video.
-
Initialize layer’s
needsRedraw
tofalse
. -
Let aspectRatio be the result of calculate the aspect ratio with video and init’s
layout
. -
If init’s
height
isundefined
, setheight
towidth
divided by aspectRatio. -
If init’s
width
isundefined
, setwidth
toheight
multiplied by aspectRatio. -
Run initialize a quad layer with layer and init.
-
If the XR Compositor knows that it will be unable to create the resources for the layer for any reason, throw an
OperationError
and abort these steps. -
return layer.
createCylinderLayer(HTMLVideoElement video, XRMediaCylinderLayerInit init)
method creates a new XRCylinderLayer
layer.
When this method is invoked, the user agent MUST run the following steps:
-
If session was not created with "layers" enabled, throw a
NotSupportedError
and abort these steps. -
If session’s ended value is
true
, throwInvalidStateError
and abort these steps. -
If init’s
layout
is"default"
, throw aTypeError
and abort these steps. -
Let layer be a new
XRCylinderLayer
in the relevant realm of this. -
Run intialize a composition layer on layer with session.
-
Initialize layer’s media to video.
-
Initialize layer’s
needsRedraw
tofalse
. -
Let aspectRatio be the result of calculate the aspect ratio with video and init’s
layout
. -
If init’s
aspectRatio
isundefined
, setaspectRatio
to aspectRatio. -
Run initialize a cylinder layer with layer and init.
-
If the XR Compositor knows that it will be unable to create the resources for the layer for any reason, throw an
OperationError
and abort these steps. -
return layer.
createEquirectLayer(HTMLVideoElement video, XRMediaEquirectLayerInit init)
method creates a new XREquirectLayer
layer.
When this method is invoked, the user agent MUST run the following steps:
-
If session was not created with "layers" enabled, throw a
NotSupportedError
and abort these steps. -
If session’s ended value is
true
, throwInvalidStateError
and abort these steps. -
If init’s
layout
is"default"
, throw aTypeError
and abort these steps. -
If init’s
space
is not an instance of typeXRReferenceSpace
, throwInvalidStateError
and abort these steps. -
If init’s
space
has a type of"viewer"
, throwInvalidStateError
and abort these steps. -
Let layer be a new
XREquirectLayer
in the relevant realm of this. -
Run intialize a composition layer on layer with session.
-
Initialize layer’s media to video.
-
Initialize layer’s
needsRedraw
tofalse
. -
Run initialize a equirect layer with layer and init.
-
If the XR Compositor knows that it will be unable to create the resources for the layer for any reason, throw an
OperationError
and abort these steps. -
return layer.
define how the XREquirectLayer
's parameters affect the video display.
8. Events
8.1. XRLayerEvent
XRLayerEvent
is fired to indicate changes to the state of an XRLayer
.
[SecureContext ,Exposed =Window ]interface :
XRLayerEvent Event {(
constructor DOMString ,
type XRLayerEventInit ); [
eventInitDict SameObject ]readonly attribute XRLayer layer ; };dictionary :
XRLayerEventInit EventInit {required XRLayer ; };
layer
The layer
attribute indicates the XRLayer
that generated the event.
8.2. Event Types
The user agent MUST provide the following new events. Registration for and firing of the events must follow the usual behavior of DOM4 Events.
The user agent MAY fire a redraw
event on the XRLayer
object when the underlying resources of a layer are lost or
when the XR Compositor can no longer reproject the layer.
The author SHOULD redraw the content of the layer at the next XR animation frame. The event must be of type XRLayerEvent
.
9. Depth sorting between layers
By default, thelayers
array defines the order of the composition of the layers and each layer is drawn on top of the previous layer.
If an application wants to have layers that are sorted by depth, it MUST request a session with the "depth-sorted-layers" feature descriptor.
If an XRSession
is created with the "depth-sorted-layers" feature descriptor, XRProjectionLayer
, XRQuadLayer
and XRCylinderLayer
layers MUST be displayed based on their depth as opposed to the location in the layers
array.
Other layers types MUST continue to be sorted as before.
XRQuadLayer
and XRCylinderLayer
layers MUST be sorted by their dimensions (for instance width
or centralAngle
), transform and space.
XRProjectionLayer
layers MUST be sorted according to the values in their depthStencilTexture
. This also implies that if "depth-sorted-layers" is enabled, the XR Compositor MUST make use of depth values and ignoreDepthValues
MUST be set to `true`.
10. WebXR Device API Integration
10.1. XRRenderState changes
This module extends theXRRenderStateInit
and XRRenderState
interfaces with a new optional array layers
containing
instances of XRLayer
.
[SecureContext ,Exposed =Window ]partial interface XRRenderState {readonly attribute FrozenArray <XRLayer >layers ; };
The layers
attribute returns an array containing
the instances of XRLayer
that are displayed by the XR Compositor.
By default, the layers
array defines the order of the composition of the layers. The XR Compositor MUST draw each layer
in order of its position in the array using source-over blending. Unless the "depth-sorted-layers" feature descriptor is enabled, the XR Compositor MUST NOT apply any depth sorting of the layers.
NOTE: this means that each layer can potentially overwrite the previous layers whether or not the previous layers are virtually closer to the viewer.
XRRenderState
object state is created for an XRSession
session, the user agent MUST initialize the render state by running the following steps:
-
Initialize state by running the original steps to initialize the render state.
-
Initialize state’s
layers
with a new empty array in the relevant realm of session.
10.2. updateRenderState changes
This module replaces the steps given by "update the pending layers state" from the WebXR specification. Instead when the user agent will update the pending layers state with XRSession
session and XRRenderStateInit
newState, it must run the following steps:
-
If both newState’s
baseLayer
and newState’slayers
are set, throw aNotSupportedError
and abort these steps. -
Let activeState be session’s active render state.
-
If newState’s
baseLayer
is set:-
If session’s pending render state is
null
, set it to a copy of activeState. -
Set session’s pending render state's
layers
tonull
.
-
-
If newState’s
layers
is set:-
If session was not created with "layers" enabled and newState’s
layers
contains more than1
instance, throw aNotSupportedError
and abort these steps. -
If session’s pending render state is
null
, set it to a copy of activeState. -
If newState’s
layers
contains duplicate instances, throw aTypeError
and abort these steps. -
For each layer in newState’s
layers
:-
If layer is an
XRCompositionLayer
and layer’s session is different from session, throw aTypeError
and abort these steps. -
If layer is an
XRWebGLLayer
and layer’s session is different from session, throw aTypeError
and abort these steps.
-
-
Set session’s pending render state's
baseLayer
tonull
. -
Set session’s pending render state's
layers
to newState’slayers
.
-
10.3. XRCompositor changes
The XR Compositor MUST be extended so allXRLayer
instances from the layers
array are composited
at the same time. All other requirements for WebXR MUST continue to apply.
If the XR Compositor is rendering to a view with an XREye
of "none"
and drawing an XRCompositionLayer
which is NOT an XRProjectionLayer
and does NOT have a layout
of "mono"
, the XR Compositor MUST render that layer
as if the view had an XREye
of "left"
.
NOTE: This means that the side for the right eye of the layer is ignored. This enables authors to use the same assets for stereoscopic and monoscopic devices.
10.4. XRView changes
Each view MUST define a recommended WebGL texture resolution which represents a best estimate of the WebGL texture resolution large enough to contain the view.10.5. Animation frames changes
renderState
state, the user agent MUST run the following steps:
11. Security and Privacy Considerations
11.1. Timing of the composition
Composition timing MUST be independent of the content that is rendered. Moreover, content in a layer MUST not be observable in other layers.
If possible, composition of layers should happen outside the browser to reduce risk of timing attacks or other security vulnerabilities.
11.2. Allocation of layers
The user agent MAY put limits on any resource allocation such as the maximum pixel size or the number of layers to reduce the identifiability of the GPU hardware.