WebXR 层 API 第 1 级

W3C 工作草案,

关于此文档的更多详细信息
此版本:
https://www.w3.org/TR/2026/WD-webxrlayers-1-20260811/
最新发布版本:
https://www.w3.org/TR/webxrlayers-1/
编辑草案:
https://immersive-web.github.io/layers/
先前版本:
历史:
https://www.w3.org/standards/history/webxrlayers-1/
反馈:
GitHub
规范内嵌议题
编辑:
(Meta)
参与:
提交议题 (开放议题)
邮件列表归档
W3C 的 #immersive-web IRC

摘要

本规范描述了对 WebXR 会话中使用的各种层类型的支持。

本文档状态

本节描述的是本文档在发布时的状态。当前 W3C 出版物列表以及本 技术报告的最新修订版,可在 W3C 标准和草案索引中找到。

沉浸式 Web 工作组维护着一份 该组尚未处理的所有错误 报告列表。此草案突出了部分待处理议题,这些议题 仍需在工作组中讨论。对于这些议题的结果,包括其是否有效, 尚未作出决定。 强烈鼓励为未解决议题提交带有拟议规范文本的拉取请求。

本文档由沉浸式 Web 工作组作为工作草案发布,并使用 推荐标准 轨道。本文档预期成为 W3C 推荐标准。

作为工作草案发布并不意味着获得 W3C 及其成员的认可。本文档是草案文档,可能 随时被其他文档更新、替换或废弃。除作为进行中的工作外,不应引用本文档。

本文档由一个依据 W3C 专利政策运作的组制作。 W3C 维护着一份与该组交付物相关的任何 专利 披露的公开列表;该页面还包括 披露专利的说明。实际知晓某项专利,且该个人 认为该专利包含 必要 权利要求的个人,必须根据 W3C 专利政策第 6 节披露该信息。

本文档受 2025 年 8 月 18 日 W3C 流程文档约束。

1. 简介

本规范为 WebXR 规范添加对 `composition` 层的支持。层的优点如下:

1.1. 术语

1.2. 应用流程

如果作者想使用 GL 层,则必须执行以下步骤:

  1. 对于除 XRProjectionLayer 之外的任何层类型,通过 requiredFeaturesoptionalFeaturesrequestSession() 中请求支持。

  2. 创建一个 XRWebGLBindingXRMediaBinding

  3. 使用这些对象创建层。

  4. 将层添加到 XRRenderStateInit 并调用 updateRenderState()

  5. 在用于 webgl 层的 requestAnimationFrame() 期间,绘制每个 WebGL 层的内容。

2. 初始化

如果应用想在会话期间创建 XRProjectionLayer 类型之外的层, 则必须使用适当的特性 描述符来请求该会话。本模块引入字符串 "layers", 作为 WebXR Layers 特性的新的有效特性描述符

XRProjectionLayer 类型的层必须始终受支持,无论是否请求了该特性 描述符

以下代码将 layers 作为可选特性请求。
navigator.xr.requestSession('immersive-vr', {
    optionalFeatures: ['layers']
  }

层仅支持用于以 "immersive-vr""immersive-ar" 的 XRSessionMode 创建的 XRSession。 "inline" 会话不得支持层。

"layers" 特性 描述符有一个特性要求:当存在活动的沉浸式会话时,不能启用它。

注: 这意味着,使用 "layers" 执行 request(permissionDesc) API 不会 为当前活动会话启用层支持。

3. 层类型

3.1. 单目和立体层

立体层必须为每个视图提供一个 XRSubImage 以供渲染。

单目层必须提供一个单独的 XRSubImage, 该图像会显示给每个视图。

XR Compositor 必须确保层以正确的立体方式呈现给观察者。

3.2. XRLayerLayout

XRLayerLayout 枚举定义层的布局。
enum XRLayerLayout {
  "default",
  "mono",
  "stereo",
  "stereo-left-right",
  "stereo-top-bottom"
};

注: 如果使用 "default""stereo" XRLayerLayout 创建 XRCompositionLayer, 强烈建议 使用 "texture-array" 纹理类型来分配它。

注: "stereo-left-right""stereo-top-bottom" 布局旨在最大限度减少已经是立体的内容(例如立体视频或图像)的绘制 调用。不需要此类资源类型的体验 应使用 "default""stereo" 布局。

3.3. XRLayerQuality

XRLayerQuality 枚举定义层的显示质量。
enum XRLayerQuality {
  "default",
  "text-optimized",
  "graphics-optimized"
};

注: text-optimizedgraphics-optimized 标志可能会导致 XR Compositor 进行额外处理,这可能会影响性能。

3.4. XRCompositionLayer

XRCompositionLayer 定义一组在某些层类型之间共享的公共属性和行为。
[Exposed=Window] interface XRCompositionLayer : XRLayer {
  readonly attribute XRLayerLayout layout;

  attribute boolean blendTextureSourceAlpha;
  attribute boolean forceMonoPresentation;
  attribute float opacity;
  readonly attribute unsigned long mipLevels;
  attribute XRLayerQuality quality;

  readonly attribute boolean needsRedraw;

  undefined destroy();
};

layout 属性返回层的布局。

blendTextureSourceAlpha 属性 启用层的纹理 alpha 通道。

forceMonoPresentation 属性 强制右眼使用与左眼相同的层配置。这必须向 XR Compositor 发送信号,以 移除此 XRCompositionLayerstereo 效果。 在 mono 层上将其设置为 true 没有任何效果。

注: 此属性对 XRSession 返回的其他信息没有其他副作用。 只有 XR Compositor 的操作会受到此设置影响,体验应该 继续绘制到双眼。

opacity 属性设置应用于 层像素的不透明度。XR Compositor 必须 将每个像素(在预乘空间中)乘以此值。 opacity 默认为 1.0。将 opacity 设置为小于 0 的值会将其设置为 0,设置为大于 1.0 的值会将其设置为 1.0

needsRedraw 属性发出信号,表示 XRCompositionLayer 应该在下一个 XR 动画帧中 重新渲染。当层的底层资源 丢失,或当 XR Compositor 无法再重投影该层时,可以设置它。未能在下一个 XR 动画帧 中重绘内容可能会导致闪烁或其他副作用。

mipLevels 属性返回 mip 链的深度。这必须等于 或小于 mipLevels 中请求的值。

注: 某些平台不支持 mip 级别。作者 应查询 mipLevels 以确定是否可以 目标到某个 mip 级别,而不应依赖其传入 mipLevels 的值。

quality 属性设置并返回 XRCompositionLayer 的质量。 default 是初始值。

XRCompositionLayer layer层的底层资源丢失时, 用户代理必须运行以下步骤:
  1. layerneedsRedraw 设置为 true

  2. 如果 layer 不是 XRProjectionLayer, 则排入一个任务,以在 layer 上使用 XRLayerEvent 触发 一个事件,其名称为 redraw

每个 XRCompositionLayer 都有一个关联的 destroyed 布尔值,初始值为 false

destroy() 会立即将该层标记为已销毁,并使其图形资源无法用于 未来的渲染。 对一个已经销毁的层调用 destroy() 不会执行任何操作。 即使在应用待处理的渲染状态更新时,该层仍存在于 layers 数组中,已销毁的层也不得由 XR 合成器呈现。

如果调用某个方法来获取已销毁层的 XRSubImage, 则该方法必须抛出 InvalidStateError

当其层被销毁时,先前返回的 XRSubImage 对象本身不会被销毁。它们的属性会继续返回相同的 对象和值,但这些对象公开的任何图形资源都必须失效,不能用于未来的 渲染操作。在资源失效之前排队的 GPU 工作可以完成。

要使用一个 XRCompositionLayer layer 销毁层的资源,用户代理必须运行以下步骤:

  1. 对于 layercolorTexturesdepthStencilTexturesmotionVectorTextures 数组中存在的每个不透明 纹理,将该纹理标记为待删除,就像已经在 layer上下文上以该纹理为参数调用了 deleteTexture 一样。这是用户代理的内部操作,不得生成 INVALID_OPERATION 错误。

  2. 如果 layerXRProjectionLayer

    1. 如果 layer辅助视图的 colorTextures 不是 null,则对于该 数组中的每个不透明纹理,以相同方式将该纹理标记为待删除。

    2. 如果 layer辅助视图的 depthStencilTextures 不是 null,则对于该 数组中的每个不透明纹理,以相同方式将该纹理标记为待删除。

  3. 如果 layer 有一个 colorTextures 数组,则将其设置为空数组。

  4. 如果 layer 有一个 depthStencilTextures 数组,则将其设置为空数组。

  5. 如果 layer 有一个 motionVectorTextures 数组,则将其设置为空数组。

  6. 如果 layerXRProjectionLayer, 则将其辅助视图的 colorTextures辅助视图的 depthStencilTextures 设置为空数组。

  7. 对于 layer 的每个底层资源,一旦在资源失效之前排队的所有 GPU 工作 均已完成,并且 XR 合成器不再访问该资源,用户代理就可以实际释放该资源。

要使用一个 XRSession session 和一个可选的 WebGLRenderingContextWebGL2RenderingContext 实例 context 初始化合成层,用户代理必须运行以下步骤:

  1. 此对象会话设置为 session

  2. 如果定义了 context,则将此对象上下文设置为 context

  3. 此对象destroyed 设置为 false

  4. 此对象blendTextureSourceAlpha 设置为 true

  5. 此对象opacity 设置为 1.0

当在一个 XRCompositionLayer layer 上调用 destroy() 时,用户代理必须运行以下步骤:

  1. 如果 layerdestroyedtrue,则返回。

  2. layerdestroyed 设置为 true

  3. 使用 layer 运行销毁层的资源

  4. sessionlayer会话

  5. 如果 session待处理渲染状态null

    1. 如果 session活动渲染状态layers 不包含 layer,则返回。

    2. session待处理渲染状态设置为 session活动渲染状态的副本。

  6. statesession待处理渲染状态

  7. 如果 statelayersnull 或不包含 layer,则返回。

  8. statelayers 设置为一个新的冻结数组,其中按顺序包含 statelayers 中除 layer 之外的每个条目。

每个 XRCompositionLayer 都有一个 context 对象,它是 null 或 WebGLRenderingContextWebGL2RenderingContext 的实例,并且还有一个 media 对象,它是 null 或 HTMLVideoElement 的实例。

每个 XRCompositionLayer 都有一个关联的 session,即创建它时使用的 XRSession

当使用 XRSpace spaceXRCompositionLayer layer 设置 层上的空间时,用户代理必须运行以下步骤,以验证 space 是否 有效:

  1. 如果 spacenull,则抛出 TypeError 并中止这些步骤。

  2. 如果 space会话不等于 layer会话,则抛出 TypeError 并中止这些步骤。

XRCompositionLayer 有一个内部布尔值 isStatic,它表示作者只能在 needsRedrawtrue 时向 此层绘制内容。

注:如果 isStatictrue,作者只能在创建后向该层绘制一次,或者在 redraw 事件后绘制一次。这使用户代理只需分配一个 GPU 缓冲区。

当在 XRCompositionLayer 或其任何派生类上设置一个可写属性时, 读取该属性必须返回该值。 在 requestAnimationFrame() 回调结束时,该值必须发送给 底层的 XR 合成器XR 合成器必须 在下一次呈现传递给 requestAnimationFrame() 回调的 XRFrame 时应用该值。

注:这意味着,当 XR 合成器使用新的 XRFrame 重绘场景时,即使与 XRCompositionLayer 关联的 colorTexture 或与媒体层关联的视频帧没有发生变化,也必须应用这些值。如果 XR 合成器使用前一个 XRFrame 的 状态重绘场景,则不得使用这些新 值。

3.5. XRProjectionLayer

An XRProjectionLayer 是一个填充观察者整个视图的层。 投影层应以接近设备原生帧率的频率刷新。

投影层的表示

[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;
  attribute XRRigidTransform? deltaPose;
};

textureWidth 属性返回 此层的 colorTextures 纹理的 像素宽度。

textureHeight 属性返回 此层的 colorTextures 纹理的 像素高度。

textureArrayLength 属性返回 此层的 colorTextures 纹理的 层数,前提是 XRProjectionLayer 使用 textureType"texture-array" 进行初始化。 否则它将返回 1

fixedFoveation 属性控制 XR 合成器使用的注视点渲染程度。如果用户代理或设备不支持此属性,则 获取时应返回 null,设置时应为 no-op。 将 fixedFoveation 设置为小于 0 的值会将其设置为 0,而设置为 大于 1 的值会将其设置为 10 设置最小的 注视点渲染程度,而 1 设置最大的程度。由用户代理决定 XR 合成器 如何解释这些值。 如果 fixedFoveation 级别发生更改,它将在下一个 XRFrame 生效。

ignoreDepthValues 属性如果为 true,则表示 XR 合成器在渲染时不得使用深度缓冲区附件中的值。当该 属性 为 false 时,表示深度缓冲区附件的内容将由 XR 合成器使用,并且预期它能够代表渲染到该层中的场景。

deltaPose 属性描述自上一帧以来影响视图的、 由应用程序应用的增量变换(如果有)。 如果用户代理或设备不支持此属性,或者未请求“space-warp特性描述符,则用户代理在获取时应返回 null,设置时应为 no-opnull 值表示未提供由应用程序应用的变换。 deltaPose 的值会一直保持,直到作者更改它;用户代理不会在 requestAnimationFrame() 回调结束时将其重置。 当人工移动在帧之间将世界从一个应用程序姿态变换为另一个应用程序姿态时,将 deltaPose 设置为这些姿态之间的差值,有助于 XR 合成器 合成缺失的帧。 当该变换发生变化时,作者应更新 deltaPose, 并且对于未发生由应用程序应用的变换的帧,将其设置为 null 或恒等变换。

3.6. XRQuadLayer

An XRQuadLayer 渲染一个在虚拟环境中占据平坦矩形空间的层。 只有该层的正面必须可见;背面不得由 XR 合成器绘制。

XRQuadLayer 没有厚度。它是一个在 3D 空间中定位和定向的二维对象。四边形的 位置 是指四边形的中心。

四边形层的表示

[Exposed=Window] interface XRQuadLayer : XRCompositionLayer {
  attribute XRSpace space;
  attribute XRRigidTransform transform;

  attribute float width;
  attribute float height;

  // 事件
  attribute EventHandler onredraw;
};

transform 属性设置并返回相对于 space 属性的偏移和 方向。transformspace 属性 建立层在用户物理环境中的空间关系。 设置 space 时,首先运行设置层上的空间的步骤。

widthheight 属性 设置并返回层的宽度和高度,单位为米。

当使用 XRQuadLayerInit init初始化 XRQuadLayer layer 时,用户代理必须运行以下步骤:
  1. layerwidth 初始化为 initwidth

  2. layerheight 初始化为 initheight

  3. layerspaceinitspace

  4. 按如下方式初始化 layertransform

    如果设置了 inittransform
    layertransform 为在 layer相关 Realm新建XRRigidTransform, 并使用 inittransformpositionorientation 初始化。
    否则
    layertransform 为在 layer相关 Realm新建XRRigidTransform, 并使用 DOMPointInit position { x: 0.0, y: 0.0, z: 0.0, w: 1.0 } 初始化。
  5. layerisStatic 初始化为 initisStatic

onredraw 属性是 redraw 事件类型的事件处理器 IDL 属性。

3.7. XRCylinderLayer

An XRCylinderLayer 渲染一个在虚拟环境中占据弯曲矩形空间的层。 只有该层的正面必须可见;背面不得由 XR 合成器绘制。

圆柱层的表示

XRCylinderLayer 没有厚度。它是一个在 3D 空间中定位和定向的二维对象。圆柱的 位置 是指四边形的中心。

[Exposed=Window] interface XRCylinderLayer : XRCompositionLayer {
  attribute XRSpace space;
  attribute XRRigidTransform transform;

  attribute float radius;
  attribute float centralAngle;
  attribute float aspectRatio;

  // 事件
  attribute EventHandler onredraw;
};

transform 属性设置并返回相对于 space 属性的偏移 和方向。transformspace 属性 建立层在用户物理环境中的空间关系。 设置 space 时,首先运行设置层上的空间的步骤。

radius 属性控制圆柱的 半径,单位为米。

centralAngle 属性控制圆柱可见部分的角度, 单位为弧度。 它围绕 0 角对称增长。

aspectRatio 属性控制 可见圆柱部分的比例。它是圆柱可见部分的宽度除以其 高度的比值。宽度通过将 radius 乘以 centralAngle 计算得出。

圆柱层参数的描述

当使用 XRCylinderLayerInit init初始化 XRCylinderLayer layer 时,用户代理必须运行以下步骤:
  1. layerradius 初始化为 initradius

  2. layercentralAngle 初始化为 initcentralAngle

  3. layeraspectRatio 初始化为 initaspectRatio

  4. layerspaceinitspace

  5. 按如下方式初始化 layertransform

    如果设置了 inittransform
    layertransform 为在 layer相关 Realm新建XRRigidTransform, 并使用 inittransformpositionorientation 初始化。
    否则
    layertransform 为在 layer相关 Realm新建XRRigidTransform, 并使用 DOMPointInit position { x: 0.0, y: 0.0, z: 0.0, w: 1.0 } 初始化。
  6. layerisStatic 初始化为 initisStatic

onredraw 属性是 redraw 事件类型的事件处理器 IDL 属性。

3.8. XREquirectLayer

一个 XREquirectLayer 渲染一个层,其中 XR 合成器必须将等距柱状投影编码的数据映射到 球体的内表面。

等距柱状投影层的表示

本节需要 澄清

[Exposed=Window] interface XREquirectLayer : XRCompositionLayer {
  attribute XRSpace space;
  attribute XRRigidTransform transform;

  attribute float radius;
  attribute float centralHorizontalAngle;
  attribute float upperVerticalAngle;
  attribute float lowerVerticalAngle;

  // 事件
  attribute EventHandler onredraw;
};

transform 属性设置并返回相对于 space 的偏移和方向。 transform 属性和 space 建立层在用户物理环境中的空间关系。

radius 属性是球体的非负半径,单位为米。 zeroinfinity 值被视为无限球体。

radius 设置为小于 0 的值会将其设置为 0

centralHorizontalAngleupperVerticalAnglelowerVerticalAngle 属性设置并 返回纹理如何映射到球体。

centralHorizontalAngle 设置为小于 0 的值会将其设置为 0,而设置为 大于 2π 的值会将其设置为 2π。

upperVerticalAnglelowerVerticalAngle 设置为小于 -π/2 的值会将其 设置为 -π/2,而设置为大于 π/2 的值会将其设置为 π/2。

等矩形层参数的描述

XRSpace 分配给 space 属性时,首先运行以下步骤。

当使用 XRSpace spaceXREquirectLayer layer 设置等矩形层上的空间时,用户代理必须运行以下步骤来验证 space 是否 有效:

  1. 如果 initspace 不是 XRReferenceSpace 类型的实例, 则抛出 TypeError 并中止这些步骤。

  2. 如果 initspace 具有 "viewer"type, 则抛出 TypeError 并中止这些步骤。

  3. 使用 spacelayer 运行设置层上的空间

当使用 XREquirectLayerInit init初始化 XREquirectLayer layer 时,用户代理必须运行以下步骤:
  1. layerradius 初始化为 initradius

  2. layercentralHorizontalAngle 初始化为 initcentralHorizontalAngle

  3. layerupperVerticalAngle 初始化为 initupperVerticalAngle

  4. layerlowerVerticalAngle 初始化为 initlowerVerticalAngle

  5. layerspaceinitspace

  6. 按如下方式初始化 layertransform

    如果设置了 inittransform
    layertransform 为在 layer相关 Realm新建XRRigidTransform, 并使用 inittransformpositionorientation 初始化。
    否则
    layertransform 为在 layer相关 Realm新建XRRigidTransform
  7. layerisStatic 初始化为 initisStatic

onredraw 属性是 redraw 事件类型的事件处理器 IDL 属性。

3.9. XRCubeLayer

一个 XRCubeLayer 渲染一个层,其中 XR 合成器直接从立方体贴图进行渲染。

立方体层的表示

本节需要 澄清

[Exposed=Window] interface XRCubeLayer : XRCompositionLayer {
  attribute XRSpace space;
  attribute DOMPointReadOnly orientation;

  // 事件
  attribute EventHandler onredraw;
};

orientation 属性设置并返回相对于 space 属性的方向。orientationspace 属性 建立层在用户物理环境中的空间关系。 放置 XRCubeLayer 时,仅考虑 space 的方向。立方体层将始终以 视点位于中心的方式渲染。

XRSpace 分配给 space 属性时,首先运行以下步骤。

当使用 XRSpace spaceXRCubeLayer layer 设置立方体层上的空间时,用户代理必须运行以下步骤来验证 space 是否 有效:

  1. 如果 initspace 不是 XRReferenceSpace 类型的实例, 则抛出 TypeError 并中止这些步骤。

  2. 如果 initspace 具有 "viewer"type, 则抛出 TypeError 并中止这些步骤。

  3. 使用 spacelayer 运行设置层上的空间

onredraw 属性是 redraw 事件类型的事件处理器 IDL 属性。

4. 空间

XRProjectionLayerXRWebGLLayer 没有关联的 XRSpace, 因为它们渲染到完整帧。

XRCubeLayerXREquirectLayer 必须仅支持非 "viewer" 类型的 XRReferenceSpaces

XRQuadLayerXRCylinderLayer 必须支持所有 XRSpace 类型。

通常,开发者不应使用 "viewer" 空间来稳定层,因为这几乎总会破坏位置或 旋转重投影,并导致渲染内容相对于世界的稳定性下降。 例外是一些小型 UI 元素, 例如凝视光标或瞄准标线。

以下是与层类型一起使用的空间的一些最佳实践:

5. 渲染

5.1. XRSubImage

XRSubImage 对象表示要使用颜色 GPU 纹理的哪个视口。
[Exposed=Window] interface XRSubImage {
  [SameObject] readonly attribute XRViewport viewport;
};

注意: 此类旨在容纳未来的扩展

viewport 属性返回在渲染子图像的颜色附件时要使用的 XRViewport

5.2. XRWebGLSubImage

XRWebGLSubImage 对象在层的渲染期间使用。
[Exposed=Window] interface XRWebGLSubImage : XRSubImage {
  [SameObject] readonly attribute WebGLTexture colorTexture;
  [SameObject] readonly attribute WebGLTexture? depthStencilTexture;
  [SameObject] readonly attribute WebGLTexture? motionVectorTexture;

  readonly attribute unsigned long? imageIndex;
  readonly attribute unsigned long colorTextureWidth;
  readonly attribute unsigned long colorTextureHeight;
  readonly attribute unsigned long? depthStencilTextureWidth;
  readonly attribute unsigned long? depthStencilTextureHeight;
};

The colorTexture 属性返回用于 XRCompositionLayer 的颜色不透明纹理viewport 描述 colorTexture 中与所请求视图对应的区域。它不描述 depthStencilTexturemotionVectorTexture 的区域。

depthStencilTexture 属性返回 XRCompositionLayer 的深度/模板不透明 纹理。 如果该层创建时没有深度/模板,则此属性返回 null。

motionVectorTexture 属性返回 XRProjectionLayer 的运动不透明纹理。 如果 XRSession 创建时没有 space-warp 特性 描述符,或者该层不是 XRProjectionLayer, 则此属性必须返回 null。

imageIndex 属性返回纹理 数组中的偏移量。仅对请求时使用 texture-array 的层有效。

colorTextureWidthcolorTextureHeight 属性 返回 GL 颜色附件的像素宽度和高度。

depthStencilTextureWidthdepthStencilTextureHeight 属性 返回 GL 深度/模板附件的像素宽度和高度。如果该层创建时没有 深度/模板,则这些属性返回 null。

5.3. XRTextureType

XRTextureType 枚举定义分配何种类型的纹理。
enum XRTextureType {
  "texture",
  "texture-array"
};

6. GPU 层和视图创建

6.1. 概述

创建层时,它由一个 GPU 资源作为后备,通常是纹理,由 Web 平台的某个图形 API 提供。为了 指定由哪个 API 提供该层的 GPU 资源,必须为相关 API 创建一个 XRWebGLBinding。 每个图形 API 可能都有独特的要求,在上下文可用于 创建层之前必须满足这些要求。例如, WebGLRenderingContext 在传递给 XRWebGLBinding 实例的构造函数之前,必须设置其 xrCompatible 标志。

XRSession 与图形 API 之间的任何交互,例如分配或取回纹理,都将通过这个 XRWebGLBinding 实例进行,并且该交互的确切机制 通常会是 API 特定的。这使 WebXR API 的其余部分能够与 图形 API 无关,并更容易适应未来渲染技术的发展。

一旦获得了 XRWebGLBinding 实例,它就可用于创建各种 XRCompositionLayer。 由该实例创建的任何层随后都能够 在每一帧查询关联的 GPU 资源,通常预期该资源是原生 API 的纹理 接口。

各种层类型是通过 XRWebGLBinding 实例上的 create____Layer 系列方法创建的。关于所需图形资源的信息, 例如是否分配深度缓冲区或 alpha 通道,会在创建层时传入, 并且在层的生命周期内保持不可变。 该方法将返回关联的 XRCompositionLayer 类型。

如果 XRSession 是使用 “layers特性 描述符创建的,则它必须支持所有层类型。 如果某个层类型不受支持,则其创建方法必须抛出异常。XRProjectionLayer 必须被所有 XRSession 支持, 无论它是否是使用 “layers特性 描述符创建的。

6.2. 不透明纹理

When using WebXR GPU layers, the XRWebGLBinding 对象将为颜色和深度/模板附件返回不透明纹理的实例。

不透明纹理的功能 与标准 WebGLTexture 完全相同,但有以下变化:

clearOnAccesstrue 时,在每个 XR 动画帧中第一次调用 getViewSubImage()getSubImage() 的处理期间,必须将附加到不透明纹理的缓冲区清除为下表中的值。 如果 clearOnAccessfalse,则附加到不透明纹理的缓冲区必须在首次访问时清除。 后续帧中的再次访问可以不清除缓冲区。

缓冲区 清除值
颜色 (0, 0, 0, 0)
深度 1.0
模板 0

如果不透明纹理 创建时具有 2 个或更多 mipLevels, 作者应填充所有 mip 级别。用户代理不得假定其应创建这些 mip 级别。

注:不透明纹理是在构造层时使用 分配颜色 纹理分配深度纹理算法进行分配的。这种 预分配的副作用是,使用相同参数调用 getSubImage()getViewSubImage() 将始终返回相同的纹理对象。

注:不允许更改不透明纹理的尺寸或格式。GL 命令 只能修改纹素值和纹理参数。对 WebGLTexture 使用以下任何 命令都会导致生成 INVALID_OPERATION 错误, 即使该命令不会影响尺寸或格式也是如此:TexImage*、CompressedTexImage*、 CopyTexImage* 和 TexStorage*。 OpenGL ES 3.0 规范中的 “不可变格式 纹理图像” 一节更详细地定义了这些限制。

层资源(例如内存)的分配必须通过与 WebGL 相同的机制完成。

如果一个 XRLayer 使用 RGBARGB colorFormat 进行分配, 则其 colorTextures 必须以 RGBARGB 的形式公开给 WebGLRenderingContext 上下文。 但是,XR 合成器必须将 colorTextures 的像素视为采用 SRGB8_ALPHA8SRGB8 colorFormat

注:这意味着 XR 合成器在处理 colorTextures 时,不得对线性的 RGBARGB 执行任何伽马转换。否则,最终渲染中的像素会显得 过亮,这与常规 2D WebGLRenderingContext 上下文中的渲染结果不匹配。

6.3. XRProjectionLayerInit

The XRProjectionLayerInit 字典表示一组可配置的值,用于描述如何初始化 XRProjectionLayer
dictionary XRProjectionLayerInit {
  XRTextureType textureType = "texture";
  GLenum colorFormat = 0x1908; // RGBA
  GLenum depthFormat = 0x1902; // DEPTH_COMPONENT
  double scaleFactor = 1.0;
  boolean clearOnAccess = true;
};

textureType 属性定义 该层所具有的纹理类型。

colorFormat 属性定义 颜色纹理数据的数据类型。

以下是 XR 合成器必须支持的投影层颜色格式列表

对于 WebGL2 上下文,还支持以下格式:

depthFormat 属性定义 深度纹理数据的数据类型。 如果 depthFormat0,则该层不会提供深度/模板纹理。

以下是 XR 合成器必须支持的投影层深度格式列表

对于启用了“WEBGL_depth_texture扩展WebGLRenderingContext 上下文,或 WebGL2 上下文:

如果未启用该扩展,则对深度纹理的请求将被忽略。

注:这可能会让作者感到困惑,因为他们 可能期望获得深度纹理。如果可能,请提供警告,说明纹理未 创建的原因。

对于 WebGL2RenderingContext 上下文,还支持以下格式:

scaleFactor 属性定义 在确定该层附件的分辨率时,session推荐的 WebGL 帧缓冲区分辨率必须 乘以的值。

clearOnAccess 属性 定义与此层关联的纹理是应在初始帧中清除,还是在每一帧中清除。

注:XRProjectionLayerInit 字典不像 XRLayerInit 那样支持配置 mipLevels。 如果用户代理希望在投影层上支持 mipmapping,则可以自由地为纹理分配 mip。 在这种情况下,由用户代理(而不是作者)负责生成所有 mip 级别。

6.4. XRLayerInit

XRLayerInit 字典表示一组通用可配置值,用于 XRQuadLayerXRCylinderLayerXREquirectLayerXRCubeLayer
dictionary XRLayerInit {
  required XRSpace space;
  XRTextureType textureType = "texture";
  GLenum colorFormat = 0x1908; // RGBA
  GLenum? depthFormat;
  unsigned long mipLevels = 1;
  required unsigned long viewPixelWidth;
  required unsigned long viewPixelHeight;
  XRLayerLayout layout = "mono";
  boolean isStatic = false;
  boolean clearOnAccess = true;
};

space 属性定义与 用户物理环境的空间关系。

textureType 属性定义层的 纹理类型。XR Compositor 必须支持:

对于 WebGL2RenderingContext, 还支持这些附加类型:

colorFormat 属性定义 颜色纹理数据的数据类型。

这是 XR Compositor 必须支持的非投影 层颜色格式列表

对于 WebGL2 上下文,还支持以下附加格式:

对于启用了 'WEBGL_compressed_texture_etc' 扩展的上下文,支持以下附加格式:

对于启用了 'WEBGL_compressed_texture_astc' 扩展的上下文,支持该扩展的所有格式。

depthFormat 属性定义 深度纹理数据的数据类型。 如果未提供 depthFormat, 则该层不会提供深度/模板纹理。

这是 XR Compositor 必须支持的非投影 层深度格式列表

对于启用了 'WEBGL_depth_texture' 扩展WebGLRenderingContext 上下文或 WebGL2 上下文:

对于 WebGL2RenderingContext 上下文,支持以下附加格式:

mipLevels 属性定义颜色和纹理数据中期望的 mip 级别数量。 如果用户代理无法创建请求的数量,则可以创建更少的数量。作者必须查询 mipLevels 以确定 实际的 mip 级别数量。

viewPixelWidthviewPixelHeight 属性定义 XRCompositionLayer 的矩形尺寸。

layout 属性定义层的布局。

clearOnAccess 属性定义与此层 关联的纹理应在初始帧中清除,还是在每一帧中清除。

6.5. XRQuadLayerInit

XRQuadLayerInit 字典表示一组可配置值,这些值描述如何初始化 XRQuadLayer

dictionary XRQuadLayerInit : XRLayerInit {
  XRRigidTransform? transform;
  float width = 1.0;
  float height = 1.0;
};

6.6. XRCylinderLayerInit

XRCylinderLayerInit 字典表示一组可配置值,这些值描述如何初始化 XRCylinderLayer

dictionary XRCylinderLayerInit : XRLayerInit {
  XRRigidTransform? transform;
  float radius = 2.0;
  float centralAngle = 0.78539;
  float aspectRatio = 2.0;
};

centralAngle 的默认值为 π / 4。

6.7. XREquirectLayerInit

XREquirectLayerInit 字典表示一组可配置值,这些值描述如何初始化 XREquirectLayer

dictionary XREquirectLayerInit : XRLayerInit {
  XRRigidTransform? transform;
  float radius = 0;
  float centralHorizontalAngle = 6.28318;
  float upperVerticalAngle = 1.570795;
  float lowerVerticalAngle = -1.570795;
};

centralHorizontalAngle 的默认值为 2π。 upperVerticalAngle 的默认值为 π/2。 lowerVerticalAngle 的默认值为 -π/2。

6.8. XRCubeLayerInit

XRCubeLayerInit 字典表示一组可配置值,这些值描述如何初始化 XRCubeLayer

dictionary XRCubeLayerInit : XRLayerInit {
  DOMPointReadOnly? orientation;
};

6.9. XRWebGLBinding

XRWebGLBinding 对象用于创建具有 GPU 后端的层。
[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 eye = "none");
  XRWebGLSubImage getViewSubImage(XRProjectionLayer layer, XRView view);

  undefined foveateBoundTexture(GLenum target, float fixed_foveation);
};

init 字典 不应是可选的。这是 Bikeshed issue 1566。

每个 XRWebGLBinding 都有一个类型为 XRWebGLRenderingContextcontext 对象,它是 WebGLRenderingContextWebGL2RenderingContext 的实例。

每个 XRWebGLBinding 都有一个关联的 session,即创建它时使用的 XRSession

每个 XRWebGLBinding 都有一个内部 WeakSet foveatedTextures,其中保存 在调用 foveateBoundTexture 时绑定到指定目标的纹理的弱引用。

注:可以创建多个 XRWebGLBinding。 使用一个 XRWebGLBinding 实例创建的任何层, 只要二者使用相同的session 和相同的 context 创建, 就可以与另一个 XRWebGLBinding 实例一起使用。层或 XRWebGLSubImage 实例的生命周期并不与创建它们的 XRWebGLBinding 的生命周期绑定。

每个通过 XRWebGLBinding 创建的 XRCompositionLayer 都有一个内部 colorTextures 数组,它是一个由用于颜色纹理的 WebGLTextures 构成的 array; 一个内部 depthStencilTextures,它是一个由用于 深度/模板纹理的不透明纹理 构成的 array;以及 一个内部 motionVectorTextures,它是一个由用于运动 纹理的不透明纹理构成的 array

每个通过 XRWebGLBinding 创建的 XRProjectionLayer 都有一个内部 辅助视图的 colorTextures 数组,它是一个由用于颜色纹理的不透明纹理构成的 array;以及一个内部 辅助视图的 depthStencilTextures 数组,它是一个由用于渲染辅助视图的深度/模板纹理的不透明纹理构成的 array

XRWebGLBinding(session, context) 构造函数 在调用时必须执行以下步骤:

  1. bindingsession相关领域中的一个 XRWebGLBinding

  2. 如果 sessionended 值为 true,则抛出 InvalidStateError 并中止这些步骤。

  3. 如果 context 已丢失,则抛出 InvalidStateError 并中止这些步骤。

  4. 如果 session 不是沉浸式会话,则抛出 InvalidStateError 并中止这些步骤。

  5. 如果 contextXR 兼容布尔值为 false,则抛出 InvalidStateError 并中止这些步骤。

  6. bindingcontext 初始化为 context

  7. bindingsession 初始化为 session

  8. binding 添加到 sessionbindings

  9. 返回 binding

nativeProjectionScaleFactor 函数返回一个值,session推荐的 WebGL 帧缓冲区分辨率 必须乘以该值,才能得到 session原生 WebGL 帧缓冲区分辨率

如果尺寸导致布局发生变化, 则需特殊处理用户代理行为(例如在 "stereo-left-right" 下请求的宽度超过限制时)

usesDepthValues 属性如果为 false,则表示存在深度缓冲区附件时, XR 合成器不得使用其中的值。当该属性 为 true 时,表示深度缓冲区附件的内容将由 XR 合成器使用,并且预期它能够代表渲染到该层中的场景。

要使用一个 XRTextureType textureType、一个 XRWebGLRenderingContext context 和一个 XRLayerLayout layout 确定 layout 属性,用户代理必须运行以下步骤:

  1. 如果 context 不是 WebGL2RenderingContexttextureType"texture-array", 则抛出 TypeError 并中止这些步骤。

  2. 如果 textureType"texture-array" 且会话视图列表中的所有视图并非都具有相同的推荐的 WebGL 颜色纹理 分辨率,则抛出 NotSupportedError 并中止这些步骤。

  3. 如果 layout"mono", 则返回 layout 并中止这些步骤。

  4. 如果 layout"default", 则运行以下步骤:

    1. 如果视图列表的大小为 1,则返回 "mono" 并中止这些步骤。

    2. 如果 textureType"texture-array", 则返回 layout 并中止这些步骤。

  5. 如果 layout"default""stereo"textureType"texture", 则运行以下步骤:

    1. 如果用户代理偏好 "stereo-left-right" 布局,则返回 "stereo-left-right" 并中止这些步骤。

    2. 如果用户代理偏好 "stereo-top-bottom" 布局,则返回 "stereo-top-bottom" 并中止这些步骤。

  6. 返回 layout

要使用一个 XRSession session、一个 XRWebGLRenderingContext context 和一个 XRLayerLayout layout 确定最大 scaleFactor,用户代理必须运行以下步骤:

  1. largest widthsession视图列表中除辅助视图之外各视图的推荐的 WebGL 颜色纹理 分辨率中的最大宽度。

  2. largest heightsession视图列表中除辅助视图之外各视图的推荐的 WebGL 颜色纹理 分辨率中的最大高度。

  3. 如果 layout"stereo-left-right" 布局,则将 largest width 乘以 2

  4. 如果 layout"stereo-top-bottom" 布局,则将 largest height 乘以 2

  5. largest view dimensionlargest widthlargest height 中较大的值。

  6. largest texture dimension 为由 context 创建的 WebGLTexture 的最大尺寸。

  7. 返回 largest texture dimension 除以 largest view dimension 的结果。

要使用一个 XRProjectionLayer layer、一个 XRTextureType textureType、一个 GLenum textureFormat 和一个 float scaleFactor 为投影层分配颜色纹理,用户代理必须运行以下 步骤:

  1. arraycontext相关领域中的一个数组。

  2. contextlayercontext

  3. sessionlayersession

  4. numViewssession视图列表中除辅助视图之外的视图数量。

  5. viewsession视图列表中第一个不是辅助视图的条目。

  6. widthview推荐的 WebGL 颜色纹理 分辨率的宽度乘以 scaleFactor

  7. heightview推荐的 WebGL 颜色纹理 分辨率的高度乘以 scaleFactor

  8. 如果 textureFormat 不在投影层颜色格式 列表中,则抛出 NotSupportedError 并中止这些步骤。

  9. 如果 layerlayout"mono""default"

    如果 textureType"texture-array"
    如果会话的视图列表中的视图在排除辅助视图后并非都具有相同的推荐的 WebGL 颜色纹理 分辨率,则抛出 NotSupportedError 并中止这些步骤。
    使用 1 个不透明 纹理实例初始化 array,该实例位于 context相关领域中,并使用 contexttextureFormatwidthheight 创建为一个具有 numViews 个层的 TEXTURE_2D_ARRAY 纹理。
    如果由于任何原因无法创建该不透明 纹理,则抛出 OperationError 并中止这些步骤。
    返回 array 并中止这些步骤。
    否则
    对于 session视图列表中的每个 view
    1. 如果 view辅助视图,则继续。

    2. widthview推荐的 WebGL 颜色纹理分辨率的宽度乘以 scaleFactor

    3. heightview推荐的 WebGL 颜色纹理分辨率的高度乘以 scaleFactor

    4. texturecontext相关领域中的一个 不透明纹理实例, 使用 contexttextureFormatwidthheight 创建为 TEXTURE_2D 纹理。

    5. 如果由于任何原因无法创建 texture,则抛出 OperationError 并中止这些步骤。

    6. texture 追加到 array

    返回 array 并中止这些步骤。
  10. 如果会话视图列表中的视图在排除辅助 视图后并非都具有相同的推荐的 WebGL 颜色纹理 分辨率,则抛出 NotSupportedError 并中止这些步骤。

  11. 如果 layerlayoutstereo-left-right, 则使用位于 context相关领域中的 1 个不透明纹理 实例初始化 array,该实例使用 contexttextureFormatnumViews 乘以 width 以及 height 创建为 textureType 纹理。

  12. 如果 layerlayoutstereo-top-bottom, 则使用位于 context相关领域中的 1 个不透明纹理 实例初始化 array,该实例使用 contexttextureFormatwidth 以及 numViews 乘以 height 创建为 textureType 纹理。

  13. 如果由于任何原因无法创建该不透明 纹理,则抛出 OperationError 并中止这些步骤。

  14. 返回 array

要使用一个 XRProjectionLayer layer、一个 XRTextureType textureType、一个 GLenum textureFormat 和一个 float scaleFactor 为投影层分配深度纹理,用户代理必须运行以下 步骤:

  1. contextlayercontext

  2. arraycontext相关领域中的一个数组。

  3. sessionlayersession

  4. 如果 textureFormat0,则返回 array 并中止这些步骤。

  5. 如果 contextWebGLRenderingContextWEBGL_depth_texture 扩展未在 context 中启用,则返回 array 并中止这些步骤。

  6. 如果 textureFormat 不在投影层深度格式 列表中,则抛出 NotSupportedError 并中止这些步骤。

  7. numViewssession视图列表中除辅助视图之外的视图数量。

  8. viewsession视图列表中第一个不是辅助视图的条目。

  9. recommendedDepthResolutionview推荐的 WebGL 深度纹理 分辨率

  10. 如果 session 创建时使用了“space-warp特性描述符,则将 recommendedDepthResolution 设置为 view推荐的运动矢量纹理 分辨率

  11. widthrecommendedDepthResolution 的宽度乘以 scaleFactor

  12. heightrecommendedDepthResolution 的高度乘以 scaleFactor

  13. 如果 layerlayout"mono""default"

    如果 textureType"texture-array"
    使用 1 个不透明 纹理实例初始化 array,该实例位于 context相关领域中,并使用 contexttextureFormatstencilwidthheight 创建为一个具有 numViews 个层的 TEXTURE_2D_ARRAY 纹理。
    如果由于任何原因无法创建该不透明 纹理,则抛出 OperationError 并中止这些步骤。
    返回 array 并中止这些步骤。
    否则
    对于 session视图列表中的每个 view
    1. 如果 view辅助视图,则继续。

    2. recommendedDepthResolutionview推荐的 WebGL 深度纹理分辨率

    3. 如果 session 创建时使用了“space-warp特性描述符,则将 recommendedDepthResolution 设置为 view推荐的 运动矢量纹理分辨率

    4. widthrecommendedDepthResolution 的宽度乘以 scaleFactor

    5. heightrecommendedDepthResolution 的高度乘以 scaleFactor

    6. texturecontext相关领域中的一个 不透明纹理实例, 使用 contexttextureFormatstencilwidthheight 创建为 TEXTURE_2D 纹理。

    7. 如果由于任何原因无法创建 texture,则抛出 OperationError 并中止这些步骤。

    8. texture 追加到 array

    返回 array 并中止这些步骤。
  14. 如果 session 创建时使用了“space-warp特性描述符,并且会话视图列表中的视图 在排除辅助 视图后并非都具有相同的推荐的运动矢量纹理 分辨率,则抛出 NotSupportedError 并中止这些步骤。

  15. 如果 session 创建时未使用“space-warp特性描述符,并且会话视图列表中的视图 在排除辅助 视图后并非都具有相同的推荐的 WebGL 深度纹理 分辨率,则抛出 NotSupportedError 并中止这些步骤。

  16. 如果 layerlayoutstereo-left-right, 则使用位于 context相关领域中的 1 个不透明纹理 实例初始化 array,该实例使用 contexttextureFormatstencilnumViews 乘以 width 以及 height 创建为 textureType 纹理。

  17. 如果 layerlayoutstereo-top-bottom, 则使用位于 context相关领域中的 1 个不透明纹理 实例初始化 array,该实例使用 contexttextureFormatstencilwidth 以及 numViews 乘以 height 创建为 textureType 纹理。

  18. 如果由于任何原因无法创建该不透明 纹理,则抛出 OperationError 并中止这些步骤。

  19. 返回 array

要使用一个 XRProjectionLayer layer、一个 XRTextureType textureType 和一个 float scaleFactor 为投影层分配运动矢量纹理,用户代理必须运行以下步骤:

  1. contextlayercontext

  2. arraycontext相关领域中的一个数组。

  3. sessionlayersession

  4. 如果 session 创建时未使用“space-warp特性描述符,则返回 array 并中止 这些步骤。

  5. 如果 contextWebGLRenderingContextWEBGL_depth_texture 扩展未在 context 中启用,则返回 array 并中止这些步骤。

  6. numViewssession视图列表中除辅助视图之外的视图数量。

  7. viewsession视图列表中第一个不是辅助视图的条目。

  8. widthview推荐的运动矢量纹理 分辨率的宽度乘以 scaleFactor

  9. heightview推荐的运动矢量纹理 分辨率的高度乘以 scaleFactor

  10. 如果 layerlayout"mono""default"

    如果 textureType"texture-array"
    使用 1 个不透明 纹理实例初始化 array,该实例位于 context相关领域中,并使用 contextRGBA16Fwidthheight 创建为一个具有 numViews 个层的 TEXTURE_2D_ARRAY 纹理。
    如果由于任何原因无法创建该不透明 纹理,则抛出 OperationError 并中止这些步骤。
    返回 array 并中止这些步骤。
    否则
    对于 session视图列表中的每个 view
    1. 如果 view辅助视图,则继续。

    2. widthview推荐的 运动矢量纹理分辨率的宽度乘以 scaleFactor

    3. heightview推荐的 运动矢量纹理分辨率的高度乘以 scaleFactor

    4. texturecontext相关领域中的一个 不透明纹理实例, 使用 contextRGBA16Fwidthheight 创建为 TEXTURE_2D 纹理。

    5. 如果由于任何原因无法创建 texture,则抛出 OperationError 并中止这些步骤。

    6. texture 追加到 array

    返回 array 并中止这些步骤。
  11. 如果会话视图列表中的视图在排除辅助 视图后并非都具有相同的推荐的运动矢量纹理 分辨率,则抛出 NotSupportedError 并中止这些步骤。

  12. 如果 layerlayoutstereo-left-right, 则使用位于 context相关领域中的 1 个不透明纹理 实例初始化 array,该实例使用 contextRGBA16FnumViews 乘以 width 以及 height 创建为 textureType 纹理。

  13. 如果 layerlayoutstereo-top-bottom, 则使用位于 context相关领域中的 1 个不透明纹理 实例初始化 array,该实例使用 contextRGBA16Fwidth 以及 numViews 乘以 height 创建为 textureType 纹理。

  14. 如果由于任何原因无法创建该不透明 纹理,则抛出 OperationError 并中止这些步骤。

  15. 返回 array

要使用一个 XRProjectionLayer layer、一个 XRTextureType textureType、一个 GLenum textureFormat 和一个 float scaleFactor 为 辅助视图分配颜色纹理,用户代理必须运行以下 步骤:

  1. contextlayercontext

  2. sessionlayersession

  3. arraycontext相关领域中的一个数组。

  4. 如果 textureFormat 不在投影层颜色格式 列表中,则抛出 NotSupportedError 并中止这些步骤。

  5. 对于 session视图列表中的每个 view

    1. 如果 view 不是辅助视图,则继续。

    2. widthview推荐的 WebGL 颜色 纹理分辨率的宽度乘以 scaleFactor

    3. heightview推荐的 WebGL 颜色 纹理分辨率的高度乘以 scaleFactor

    4. 按如下方式初始化 texture

      如果 textureType"texture-array"
      texturecontext相关领域中的一个 不透明纹理实例, 使用 contexttextureFormatwidthheight 创建为 TEXTURE_2D_ARRAY 纹理。
      否则
      texturecontext相关领域中的一个 不透明纹理实例, 使用 contexttextureFormatwidthheight 创建为 TEXTURE_2D 纹理。
    5. 如果由于任何原因无法创建 texture,则抛出 OperationError 并中止这些步骤。

    6. texture 追加到 array

  6. 返回 array 并中止这些步骤。

要使用一个 XRProjectionLayer layer、一个 XRTextureType textureType、一个 GLenum textureFormat 和一个 float scaleFactor 为 辅助视图分配深度纹理,用户代理必须运行以下 步骤:

  1. contextlayercontext

  2. sessionlayersession

  3. 如果 textureFormat0,则返回 array 并中止这些步骤。

  4. 如果 contextWebGLRenderingContextWEBGL_depth_texture 扩展未在 context 中启用,则返回 array 并中止这些步骤。

  5. 如果 textureFormat 不在投影层深度格式 列表中,则抛出 NotSupportedError 并中止这些步骤。

  6. arraycontext相关领域中的一个数组。

  7. 对于 session视图列表中的每个 view

    1. 如果 view 不是辅助视图,则继续。

    2. widthview推荐的 WebGL 深度 纹理分辨率的宽度乘以 scaleFactor

    3. heightview推荐的 WebGL 深度 纹理分辨率的高度乘以 scaleFactor

    4. 按如下方式初始化 texture

      如果 textureType"texture-array"
      texturecontext相关领域中的一个 不透明纹理实例, 使用 contexttextureFormatstencilwidthheight 创建为 TEXTURE_2D_ARRAY 纹理。
      否则
      texturecontext相关领域中的一个 不透明纹理实例, 使用 contexttextureFormatstencilwidthheight 创建为 TEXTURE_2D 纹理。
    5. texture 追加到 array

  8. 返回 array 并中止这些步骤。

需要针对辅助视图 重新计算 scaleFactor。

要使用一个 XRCompositionLayer layer、一个 XRTextureType textureType 和一个 XRLayerInit init 分配颜色 纹理,用户代理必须运行以下步骤:

  1. arraycontext相关领域中的一个数组。

  2. contextlayercontext

  3. 如果 initcolorFormat 不在非投影层颜色格式 列表中,则抛出 NotSupportedError 并中止这些步骤。

  4. 如果 initmipLevels 小于 1,则抛出 InvalidStateError 并中止这些步骤。

  5. 如果 initmipLevels 大于 1,并且 viewPixelWidthviewPixelHeight 不是 2 的幂,则抛出 InvalidStateError 并中止这些步骤

  6. 如果 layerlayout"mono"

    如果 textureType"texture-array"
    使用位于此 context相关领域中的 1 个不透明 纹理实例初始化 array,该实例使用 contextinitcolorFormatmipLevelsviewPixelWidthviewPixelHeight 值创建为一个具有 1 个内部纹理的 TEXTURE_2D_ARRAY 纹理。
    否则
    使用位于 context相关领域中的 1 个不透明 纹理实例初始化 array,该实例使用 contextinitcolorFormatmipLevelsviewPixelWidthviewPixelHeight 值创建为 TEXTURE_2D 纹理。
  7. 如果 layerlayout"stereo"

    如果 textureType"texture-array"
    使用位于 context相关领域中的 1 个不透明 纹理实例初始化 array,该实例使用 contextinitcolorFormatmipLevelsviewPixelWidthviewPixelHeight 值创建为一个具有 2 个层的 TEXTURE_2D_ARRAY 纹理。
    返回 array 并中止这些步骤。
    否则
    使用位于 context相关领域中的 2 个不透明 纹理实例初始化 array,这些实例使用 contextinitcolorFormatmipLevelsviewPixelWidthviewPixelHeight 值创建为 TEXTURE_2D 纹理。
    返回 array 并中止这些步骤。
  8. 如果 layerlayoutstereo-left-right, 则使用位于 context相关领域中的 1 个不透明纹理 实例初始化 array,该实例使用 contextinitcolorFormatmipLevels、 两倍的 viewPixelWidthviewPixelHeight 值创建为 textureType 纹理。

  9. 如果 layerlayoutstereo-top-bottom, 则使用位于 context相关领域中的 1 个不透明纹理 实例初始化 array,该实例使用 contextinitcolorFormatmipLevelsviewPixelWidth 和两倍的 viewPixelHeight 值创建为 textureType 纹理。

  10. 返回 array

要使用一个 XRCompositionLayer layer、一个 XRTextureType textureType 和一个 XRLayerInit init 分配深度 纹理,用户代理必须运行以下步骤:

  1. arraycontext相关领域中的一个数组。

  2. contextlayercontext

  3. 如果未设置 initdepthFormat, 则返回 array 并中止这些步骤。

  4. 如果 initdepthFormat 不在非投影层深度格式 列表中,则抛出 NotSupportedError 并中止这些步骤。

  5. 如果 initmipLevels 小于 1,则抛出 InvalidStateError 并中止这些步骤。

  6. 如果 initmipLevels 大于 1,并且 viewPixelWidthviewPixelHeight 不是 2 的幂,则抛出 InvalidStateError 并中止这些步骤。

  7. 如果 layerlayout"mono"

    如果 textureType"texture-array"
    使用位于 context相关领域中的 1 个不透明 纹理实例初始化 array,该实例使用 contextinitdepthFormatmipLevelsviewPixelWidthviewPixelHeight 值创建为一个具有 1 个内部纹理的 TEXTURE_2D_ARRAY 纹理。
    否则
    使用位于 context相关领域中的 1 个不透明 纹理实例初始化 array,该实例使用 contextinitdepthFormatmipLevelsviewPixelWidthviewPixelHeight 值创建为 TEXTURE_2D 纹理。
  8. 如果 layerlayout"stereo"

    如果 textureType"texture-array"
    使用位于 context相关领域中的 1 个不透明 纹理实例初始化 array,该实例使用 contextinitdepthFormatmipLevelsviewPixelWidthviewPixelHeight 值创建为一个具有 2 个层的 TEXTURE_2D_ARRAY 纹理。
    返回 array 并中止这些步骤。
    否则
    使用位于 context相关领域中的 2 个不透明 纹理实例初始化 array,这些实例使用 contextinitdepthFormatmipLevelsviewPixelWidthviewPixelHeight 值创建为 TEXTURE_2D 纹理。
    返回 array 并中止这些步骤。
  9. 如果 layerlayoutstereo-left-right, 则使用位于 context相关领域中的 1 个不透明纹理 实例初始化 array,该实例使用 contextinitdepthFormatmipLevels、 两倍的 viewPixelWidthviewPixelHeight 值创建为 textureType 纹理。

  10. 如果 layerlayoutstereo-top-bottom, 则使用位于 context相关领域中的 1 个不透明纹理 实例初始化 array,该实例使用 contextinitdepthFormatmipLevelsviewPixelWidth 和两倍的 viewPixelHeight 值创建为 textureType 纹理。

  11. 返回 array

createProjectionLayer(optional XRProjectionLayerInit init) 方法创建一个新的 XRProjectionLayer layer

调用此方法时,用户代理必须运行以下步骤:

  1. session此对象session

  2. context此对象context

  3. layer此对象相关领域中的一个 XRProjectionLayer

  4. 如果 sessionended 值为 true,则抛出 InvalidStateError 并中止这些步骤。

  5. 如果 context 已丢失,则抛出 InvalidStateError 并中止这些步骤。

  6. 使用 sessioncontextlayer 上运行初始化合成层

  7. layerisStatic 初始化为 false

  8. 按如下方式初始化 layerignoreDepthValues

    如果 session 创建时使用了“space-warp特性描述符
    layerignoreDepthValues 初始化为 false
    如果 initdepthFormatfalseXR 合成器将使用深度值
    layerignoreDepthValues 初始化为 false
    否则
    layerignoreDepthValues 初始化为 true
  9. layerfixedFoveation 初始化为 0

  10. layout 为使用 inittextureTypecontext"default" 确定 layout 属性的结果。

  11. maximum scalefactor 为使用 sessioncontextlayout 确定最大 scaleFactor的结果。

  12. 如果 scaleFactor 大于 maximum scalefactor,则将 scaleFactor 设置为 maximum scalefactor

  13. layerlayout 初始化为 layout

  14. layerneedsRedraw 初始化为 true

  15. layercolorTextures 为使用 layerinittextureTypeinitcolorFormatinitscaleFactor 为投影层分配颜色纹理的结果。

  16. layerdepthStencilTextures 为使用 layerinittextureTypeinitdepthFormatinitscaleFactor 为投影层分配深度纹理的结果。

  17. layermotionVectorTextures 为使用 layerinittextureTypeinitscaleFactor 为投影层分配运动矢量 纹理的结果。

  18. 按如下方式初始化辅助视图的 colorTextures

    如果 session 创建时启用了“secondary-views
    辅助视图的 colorTextures 为使用 layerinittextureTypeinitcolorFormatinitscaleFactor 为辅助视图分配颜色 纹理的结果。
    否则
    辅助视图的 colorTexturesnull
  19. 按如下方式初始化辅助视图的 depthStencilTextures

    如果 session 创建时启用了“secondary-views
    辅助视图的 depthStencilTextures 为使用 layerinittextureTypeinitdepthFormatinitscaleFactor 为辅助视图分配深度 纹理的结果。
    否则
    辅助视图的 depthStencilTexturesnull
  20. 如果 XR 合成器知道由于任何原因无法为 layer 创建资源,则抛出 OperationError 并中止这些步骤。

  21. 返回 layer

createQuadLayer(XRQuadLayerInit init) 方法创建一个新的 XRQuadLayer layer

调用此方法时,用户代理必须运行以下步骤:

  1. session此对象session

  2. 如果 session 创建时未启用“layers”, 则抛出 NotSupportedError 并中止这些步骤。

  3. context此对象context

  4. 如果 sessionended 值为 true,则抛出 InvalidStateError 并中止这些步骤。

  5. 如果 context 已丢失,则抛出 InvalidStateError 并中止这些步骤。

  6. 如果 layout"default", 则抛出 TypeError 并中止这些步骤。

  7. layer此对象相关领域中的一个 XRQuadLayer

  8. 使用 sessioncontextlayer 上运行初始化合成层

  9. 使用 layerinit 运行初始化四边形层

  10. layout 为使用 inittextureTypecontextinitlayout 确定 layout 属性的结果。

  11. layerlayout 初始化为 layout

  12. layerneedsRedraw 初始化为 true

  13. layercolorTextures 为使用 layerinittextureTypeinit 分配颜色 纹理的结果。

  14. layerdepthStencilTextures 为使用 layerinittextureTypeinit 分配深度纹理的结果。

  15. layermotionVectorTexturescontext相关领域中的一个数组。

  16. 如果 XR 合成器知道由于任何原因无法为 layer 创建资源,则抛出 OperationError 并中止这些步骤。

  17. 返回 layer

createCylinderLayer(XRCylinderLayerInit init) 方法创建一个新的 XRCylinderLayer layer

调用此方法时,用户代理必须运行以下步骤:

  1. session此对象session

  2. 如果 session 创建时未启用“layers”, 则抛出 NotSupportedError 并中止这些步骤。

  3. context此对象context

  4. 如果 sessionended 值为 true,则抛出 InvalidStateError 并中止这些步骤。

  5. 如果 context 已丢失,则抛出 InvalidStateError 并中止这些步骤。

  6. 如果 layout"default", 则抛出 TypeError 并中止这些步骤。

  7. layer此对象相关领域中的一个 XRCylinderLayer

  8. 使用 sessioncontextlayer 上运行初始化合成层

  9. 使用 layerinit 运行初始化圆柱层

  10. layout 为使用 inittextureTypecontextinitlayout 确定 layout 属性的结果。

  11. layerlayout 初始化为 layout

  12. layerneedsRedraw 初始化为 true

  13. layercolorTextures 为使用 layerinittextureTypeinit 分配颜色 纹理的结果。

  14. layerdepthStencilTextures 为使用 layerinittextureTypeinit 分配深度纹理的结果。

  15. layermotionVectorTexturescontext相关领域中的一个数组。

  16. 如果 XR 合成器知道由于任何原因无法为 layer 创建资源,则抛出 OperationError 并中止这些步骤。

  17. 返回 layer

createEquirectLayer(XREquirectLayerLayerInit init) 方法创建一个新的 XREquirectLayer layer

调用此方法时,用户代理必须运行以下步骤:

  1. session此对象session

  2. 如果 session 创建时未启用“layers”, 则抛出 NotSupportedError 并中止这些步骤。

  3. context此对象context

  4. 如果 sessionended 值为 true,则抛出 InvalidStateError 并中止这些步骤。

  5. 如果 context 已丢失,则抛出 InvalidStateError 并中止这些步骤。

  6. 如果 layout"default", 则抛出 TypeError 并中止这些步骤。

  7. 如果 initspace 不是 XRReferenceSpace 类型的实例,则抛出 TypeError 并中止这些步骤。

  8. 如果 initspace类型"viewer", 则抛出 TypeError 并中止这些步骤。

  9. layer此对象相关领域中的一个 XREquirectLayer

  10. 使用 sessioncontextlayer 上运行初始化合成层

  11. 使用 layerinit 运行初始化等距柱状投影层

  12. layout 为使用 inittextureTypecontextinitlayout 确定 layout 属性的结果。

  13. layerlayout 初始化为 layout

  14. layerneedsRedraw 初始化为 true

  15. layercolorTextures 为使用 layerinittextureTypeinit 分配颜色 纹理的结果。

  16. layerdepthStencilTextures 为使用 layerinittextureTypeinit 分配深度纹理的结果。

  17. layermotionVectorTexturescontext相关领域中的一个数组。

  18. 如果 XR 合成器知道由于任何原因无法为 layer 创建资源,则抛出 OperationError 并中止这些步骤。

  19. 返回 layer

createCubeLayer(XRCubeLayerInit init) 方法创建一个新的 XRCubeLayer layer

调用此方法时,用户代理必须运行以下步骤:

  1. session此对象session

  2. 如果 session 创建时未启用“layers”, 则抛出 NotSupportedError 并中止这些步骤。

  3. context此对象context

  4. 如果 sessionended 值为 true,则抛出 InvalidStateError 并中止这些步骤。

  5. 如果 context 不是 WebGL2RenderingContext 上下文,则抛出 InvalidStateError 并中止这些步骤。

  6. 如果 context 已丢失,则抛出 InvalidStateError 并中止这些步骤。

  7. 如果 initspace 不是 XRReferenceSpace 类型的实例,则抛出 TypeError 并中止这些步骤。

  8. 如果 initspace类型"viewer", 则抛出 TypeError 并中止这些步骤。

  9. layer此对象相关领域中的一个 XRCubeLayer

  10. 使用 sessioncontextlayer 上运行初始化合成层

  11. layerspaceinitspace

  12. layerisStatic 初始化为 initisStatic

  13. 按如下方式初始化 layerorientation

    如果设置了 initorientation
    layerorientation 为使用 initorientation 运行 fromPoint 的结果。
    否则
    layerorientation此对象相关领域中的一个 DOMPointReadOnly
  14. layoutinitlayout

  15. textureTypeinittextureType

  16. layerneedsRedraw 初始化为 true

  17. 如果 layout"default""stereo-left-right""stereo-top-bottom", 则抛出 TypeError 并中止这些步骤。

  18. layercolorTextures 为此 XRCubeLayer相关领域中的一个数组。

  19. 根据 layout 的值,按如下方式初始化 layercolorTextures

    1. 如果 layerlayout"mono"

      如果 textureType"texture-array"
      使用位于此 XRCubeLayer相关领域中的 1 个不透明纹理实例初始化colorTextures,该实例使用 contextinitcolorFormatmipLevelsviewPixelWidthviewPixelHeight 值创建为一个具有 6 个层的 TEXTURE_2D_ARRAY 纹理。
      否则
      使用位于此 XRCubeLayer相关领域中的 1 个不透明纹理实例初始化colorTextures,该实例使用 contextinitcolorFormatviewPixelWidthviewPixelHeight 值创建为 TEXTURE_CUBE_MAP 纹理。
    2. 否则,如果 layerlayout"stereo"

      如果 textureType"texture-array"
      使用位于此 XRCubeLayer相关领域中的 1 个不透明纹理实例初始化colorTextures,该实例使用 contextinitcolorFormatmipLevelsviewPixelWidthviewPixelHeight 值创建为一个具有 12 个层的 TEXTURE_2D_ARRAY 纹理。
      否则
      使用位于此 XRCubeLayer相关领域中的 2 个不透明纹理实例初始化colorTextures,这些实例使用 contextinitcolorFormatviewPixelWidthviewPixelHeight 值创建为 TEXTURE_CUBE_MAP 纹理。
  20. layerdepthStencilTextures 为此 XRCubeLayer相关领域中的一个数组。

  21. layermotionVectorTextures 为此 XRCubeLayer相关领域中的一个数组。

  22. 如果设置了 initdepthFormat, 则按如下方式初始化 layerdepthStencilTextures

    1. 如果 context 不是 WebGL2RenderingContextWEBGL_depth_texture 扩展未在 context 中启用,则抛出 TypeError 并中止这些步骤。

    2. 如果 layerlayout"mono"

      如果 textureType"texture-array"
      使用位于此 XRCubeLayer相关领域中的 1 个不透明纹理实例初始化 depthStencilTextures,该实例使用 contextinitdepthFormatmipLevelsviewPixelWidthviewPixelHeight 值创建为一个具有 6 个层的 TEXTURE_2D_ARRAY 纹理。
      否则
      使用位于此 XRCubeLayer相关领域中的 1 个不透明纹理实例初始化 depthStencilTextures,该实例使用 contextinitdepthFormatviewPixelWidthviewPixelHeight 值创建为 TEXTURE_CUBE_MAP 纹理。
    3. 否则,如果 layerlayout"stereo"

      如果 textureType"texture-array"
      使用位于此 XRCubeLayer相关领域中的 1 个不透明纹理实例初始化 depthStencilTextures,该实例使用 contextinitdepthFormatmipLevelsviewPixelWidthviewPixelHeight 值创建为一个具有 12 个层的 TEXTURE_2D_ARRAY 纹理。
      否则
      使用位于此 XRCubeLayer相关领域中的 2 个不透明纹理实例初始化 depthStencilTextures,这些实例使用 contextinitdepthFormatviewPixelWidthviewPixelHeight 值创建为 TEXTURE_CUBE_MAP 纹理。
  23. 如果 XR 合成器知道由于任何原因无法为 layer 创建资源,则抛出 OperationError 并中止这些步骤。

  24. 返回 layer

当使用值为 "texture-array"textureType 时,XRCubeLayer 必须使用 6 个纹理层按以下顺序存储立方体贴图的各个面: [TEXTURE_CUBE_MAP_POSITIVE_X, TEXTURE_CUBE_MAP_NEGATIVE_X, TEXTURE_CUBE_MAP_POSITIVE_Y, TEXTURE_CUBE_MAP_NEGATIVE_Y, TEXTURE_CUBE_MAP_POSITIVE_Z, TEXTURE_CUBE_MAP_NEGATIVE_Z]

当使用值为 "texture-array"textureType 和值为 "stereo"layout 时,左眼的内容必须从层索引 0 开始存储,而右眼的内容 必须从层索引 6 开始存储。

定义如何确定立方体贴图的 尺寸。

应如何处理 space。 可以走到立方体贴图的边缘吗?

确定 orientation 的初始状态。

要使用参数 XRCompositionLayer layerXRFrame frame 验证 XRWebGLBinding binding 的 XRWebGLSubImage 创建函数的状态,用户代理必须运行以下步骤:

  1. 如果 framesession 不等于 layersession,则返回 false 并中止 这些步骤。

  2. 如果 frameactive 布尔值为 false,则返回 false 并中止这些步骤。

  3. 如果 frameanimationFrame 布尔值为 false,则返回 false 并中止这些步骤。

  4. 如果 bindingsession 不等于 layersession,则返回 false 并中止 这些步骤。

  5. 如果 bindingcontext 不等于 layercontext,则返回 false 并中止 这些步骤。

  6. 如果 layercolorTextures 数组为空或缺失,则返回 false 并中止这些步骤。

  7. 如果 layerisStatictrue,且 layerneedsRedrawfalse,则返回 false 并中止这些步骤。

  8. 返回 true

要使用一个不透明纹理 texture、一个 XRLayerLayout layout、一个整数 offset 和一个整数 num 初始化 XRViewport viewport,用户代理必须运行以下步骤:

  1. viewportx 设置为 0

  2. viewporty 设置为 0

  3. viewportwidth 设置为 texture 的像素宽度。

  4. viewportheight 设置为 texture 的像素高度。

  5. 按如下方式更新 viewport

    如果 layout"stereo-left-right"
    viewportx 设置为 texture 的像素宽度乘以 offset 再除以 num
    viewportwidth 设置为 subimagetexture 的像素宽度除以 num
    否则,如果 layout"stereo-top-bottom"
    viewporty 设置为 texture 的像素高度乘以 offset 再除以 num
    viewportheight 设置为 subimagetexture 的像素高度除以 num
getSubImage(XRCompositionLayer layer, XRFrame frame, optional XREye eye = "none") 方法创建一个新的 XRWebGLSubImage

当在 XRWebGLBinding binding 上调用此方法时,它必须运行以下步骤:

  1. 按如下方式初始化 subimage

    如果此前曾使用相同的 bindinglayereye 调用 getSubImage(), 则用户代理可以
    subimage 为之前使用相同参数调用时返回的同一个 XRWebGLSubImage 对象。
    否则
    subimage此对象相关领域中的一个 XRWebGLSubImage
    subimageviewport此对象相关领域中的一个 XRViewport
  2. session此对象session

  3. 如果 layerdestroyedtrue,则抛出 InvalidStateError 并中止这些步骤。

  4. 如果 layer 不在 sessionlayers 数组中,则抛出 TypeError 并中止这些步骤。

  5. 如果 layer 的类型为 XRProjectionLayer, 则抛出 TypeError 并中止这些步骤。

  6. 如果 layerlayout 属性为 "default", 则抛出 TypeError 并中止这些步骤。

  7. index0

  8. 如果 layerlayout 属性为 "stereo"

    1. 如果 eye"none", 则抛出 TypeError 并中止这些步骤。

    2. 如果 eye"right"

      如果 layer 的类型为 XRCubeLayer
      index 设置为 6
      否则
      index 设置为 1
  9. 如果使用 layerframe 验证 XRWebGLSubImage 创建函数的状态的结果为 false,则抛出 InvalidStateError 并中止这些步骤。

  10. 按如下方式初始化 subimageimageIndex

    如果 layer 创建时使用的 textureType 为 "texture-array"
    使用 index 初始化 subimageimageIndex
    否则
    使用 0 初始化 subimageimageIndex
  11. 按如下方式初始化 subimagecolorTexture

    如果 layer 创建时使用的 textureType 为 "texture"
    使用 layercolorTextures 数组中偏移量为 index 的元素 初始化 subimagecolorTexture
    否则
    使用 layercolorTextures 数组中的第一个元素 初始化 subimagecolorTexture
  12. 按如下方式初始化 subimagedepthStencilTexture

    如果 layerdepthStencilTextures 是空数组
    使用 null 初始化 subimagedepthStencilTexture
    否则,如果 layer 创建时使用的 textureType 为 "texture"
    使用 layerdepthStencilTextures 数组中偏移量为 index 的元素 初始化 subimagedepthStencilTexture
    否则
    使用 layerdepthStencilTextures 数组中的第一个元素 初始化 subimagedepthStencilTexture
  13. 使用 null 初始化 subimagedepthStencilTextureWidthdepthStencilTextureHeightmotionVectorTexture

  14. subimagecolorTextureWidth 设置为 subimagecolorTexture 的像素宽度。

  15. subimagecolorTextureHeight 设置为 subimagecolorTexture 的像素高度。

  16. 如果 subimagedepthStencilTexture 不为 null,则将 subimagedepthStencilTextureWidth 设置为 depthStencilTexture 数组中第一个纹理的像素宽度。

  17. 如果 subimagedepthStencilTexture 不为 null,则将 subimagedepthStencilTextureHeight 设置为 depthStencilTexture 数组中第一个纹理的像素高度。

  18. viewsPerTexture1

  19. 如果 layerlayout 属性为 "stereo-left-right""stereo-top-bottom", 则将 viewsPerTexture 设置为 2

  20. 使用 subimagecolorTexturelayerlayoutindexviewsPerTexture,在 subimageviewport 上运行初始化视口

  21. 排入一个任务,将 needsRedraw 设置为 false

  22. 返回 subimage

getViewSubImage(XRProjectionLayer layer, XRView view) 方法创建一个新的 XRWebGLSubImage

当在 XRWebGLBinding binding 上调用此方法时,它必须运行以下步骤:

  1. 按如下方式初始化 subimage

    如果此前曾使用相同的 bindinglayerview 调用 getViewSubImage(), 则用户代理可以
    subimage 为之前使用相同参数调用时返回的同一个 XRWebGLSubImage 对象。
    否则
    subimage此对象相关领域中的一个 XRWebGLSubImage
    subimageviewport此对象相关领域中的一个 XRViewport
  2. frameviewframe

  3. session此对象session

  4. 如果 layerdestroyedtrue,则抛出 InvalidStateError 并中止这些步骤。

  5. 如果使用 layerframe 验证 XRWebGLSubImage 创建函数的状态的结果为 false,则抛出 InvalidStateError 并中止这些步骤。

  6. 如果 layer 不在 sessionlayers 数组中,则抛出 TypeError 并中止这些步骤。

  7. 如果 viewactive 标志为 false,则抛出 InvalidStateError 并中止这些步骤。

  8. 按如下方式初始化 index

    如果 viewsession视图列表中的辅助视图
    indexsession视图列表中排除主视图后,view视图的偏移量。
    否则
    indexsession视图列表中排除辅助视图后,view视图的偏移量。
  9. 按如下方式初始化 subimageimageIndex

    如果 layer 创建时使用的 textureType 为 "texture-array"
    使用 index 初始化 subimageimageIndex
    否则
    subimageimageIndex 初始化为 0
  10. 按如下方式初始化 subimagecolorTexture

    如果 viewsession视图列表中的辅助视图
    使用 layer辅助视图的 colorTextures 中偏移量为 index 的元素 初始化 subimagecolorTexture
    否则,如果 layerlayout"default"layer 创建时使用的 textureType 为 "texture"
    使用 layercolorTextures 数组中偏移量为 index 的元素 初始化 subimagecolorTexture
    否则
    使用 layercolorTextures 数组中的第一个元素 初始化 subimagecolorTexture
  11. 按如下方式初始化 subimagedepthStencilTexture

    如果 layerdepthStencilTextures 是空数组
    使用 null 初始化 subimagedepthStencilTexture
    否则,如果 viewsession视图列表中的辅助视图
    使用 layer辅助视图的 depthStencilTextures 中偏移量为 index 的元素 初始化 subimagecolorTexture
    否则,如果 layerlayout"default"layer 创建时使用的 textureType 为 "texture"
    使用 layerdepthStencilTextures 数组中偏移量为 index 的元素 初始化 subimagedepthStencilTexture
    否则
    使用 layerdepthStencilTextures 数组中的第一个元素 初始化 subimagedepthStencilTexture
  12. 按如下方式初始化 subimagemotionVectorTexture

    如果 layermotionVectorTextures 是空数组,或者 viewsession视图列表中的辅助视图
    使用 null 初始化 subimagemotionVectorTexture
    否则,如果 layer 创建时使用的 textureType 为 "texture"
    使用 layermotionVectorTextures 数组中偏移量为 index 的元素 初始化 subimagemotionVectorTexture
    否则
    使用 layermotionVectorTextures 数组中的第一个元素初始化 subimagemotionVectorTexture
  13. subimagecolorTextureWidth 设置为 subimagecolorTexture 的像素宽度。

  14. subimagecolorTextureHeight 设置为 subimagecolorTexture 的像素高度。

  15. 使用 null 初始化 subimagedepthStencilTextureWidthdepthStencilTextureHeight

  16. 如果 subimagedepthStencilTexture 不为 null,则将 subimagedepthStencilTextureWidth 设置为 depthStencilTexture 数组中第一个纹理的像素宽度。

  17. 如果 subimagedepthStencilTexture 不为 null,则将 subimagedepthStencilTextureHeight 设置为 depthStencilTexture 数组中第一个纹理的像素高度。

  18. 使用 subimagecolorTexturelayerlayoutindexsession视图列表中的视图数量,在 subimageviewport 上运行初始化视口

  19. needsRedraw 设置为 false

  20. 返回 subimage

注:会话应尽量将对 getSubImage()getViewSubImage() 的调用推迟到体验开始使用 WebGL 绘制时。 通常,这会发生在游戏逻辑运行之后。对于某些用户代理,将依赖 CPU 和 GPU 的代码划分为不同阶段,可以让它们动态优化系统资源。

foveateBoundTexture(GLenum target, float fixed_foveation) 对当前绑定的纹理或纹理数组应用注视点渲染。

当在 XRWebGLBinding binding 上调用此方法时,它必须运行以下步骤:

  1. 如果 target 的类型不是 TEXTURE_2DTEXTURE_2D_ARRAY, 则抛出 InvalidStateError 并中止这些步骤。

  2. 如果用户代理或设备不支持注视点渲染,则中止这些步骤。

  3. 如果 fixed_foveation 小于 0,则将其设置为 0

  4. 如果 fixed_foveation 大于 1,则将其设置为 1

  5. 如果 bindingcontext中没有纹理绑定到 target,则抛出 InvalidStateError 并中止这些步骤。

  6. 使用 bindingcontext,采用与 fixedFoveation 相同的算法,将 fixed_foveation 应用于 target

  7. 将通过 bindingcontext绑定到 target 的纹理添加到foveatedTextures

注:注视点渲染的效果将立即生效。

当一个 XRLayerlayers 数组的成员时,在一个XR 动画帧完成后,它必须立即呈现给沉浸式 XR 设备,但前提是自上一个XR 动画 帧以来至少发生了以下情况之一:

在将不透明帧缓冲区colorTexture 纹理呈现给沉浸式 XR 设备之前,用户代理必须确保所有渲染 操作都已刷新。

7. 视频层创建

7.1. XRMediaLayerInit

XRMediaLayerInit 字典表示一组可配置的值,用于描述包含视频的 XRCompositionLayer 如何 初始化。
dictionary XRMediaLayerInit {
  required XRSpace space;
  XRLayerLayout layout = "mono";
  boolean invertStereo = false;
};

space 属性定义与 用户物理环境的空间关系。

layout 属性定义视频在 XRCompositionLayer 中的布局。

invertStereo 属性定义视频中每个视图的自然 位置 是否应反转。

7.2. XRMediaQuadLayerInit

XRMediaQuadLayerInit 字典表示一组可配置值,用于描述包含视频的 XRQuadLayer 如何初始化。
dictionary XRMediaQuadLayerInit : XRMediaLayerInit {
  XRRigidTransform? transform;
  float? width;
  float? height;
};

7.3. XRMediaCylinderLayerInit

XRMediaCylinderLayerInit 字典表示一组可配置值,用于描述包含视频的 XRCylinderLayer 如何初始化。
dictionary XRMediaCylinderLayerInit : XRMediaLayerInit {
  XRRigidTransform? transform;
  float radius = 2.0;
  float centralAngle = 0.78539;
  float? aspectRatio;
};

7.4. XRMediaEquirectLayerInit

XRMediaEquirectLayerInit 字典表示一组可配置值,用于描述包含视频的 XREquirectLayer 如何初始化。
dictionary XRMediaEquirectLayerInit : XRMediaLayerInit {
  XRRigidTransform? transform;
  float radius = 0.0;
  float centralHorizontalAngle = 6.28318;
  float upperVerticalAngle = 1.570795;
  float lowerVerticalAngle = -1.570795;
};

7.5. XRMediaBinding

XRMediaBinding 对象用于创建显示 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 = {});
};

init 字典 不应是可选的。这是 bikeshed 议题 1566。

每个 XRMediaBinding 都有关联的 session,即 创建它时使用的 XRSession

注: 可以创建多个 XRMediaBinding。 层的生命周期并不绑定到创建它的 XRMediaBinding 的生命周期。

每个通过 XRMediaBinding 创建的层都有一个内部 HTMLVideoElement media。 如果该层是会话的 renderState 的一部分,则它会显示视频的当前帧。该层会以 XR 设备或视频的原生帧率 进行更新,取两者中较低者。

注: 层中只会显示视频帧。视频控件应由作者实现,并且必须 绘制在另一个层中。

需要进一步说明 如何将视频 blit 到层中。

当带有 HTMLVideoElement mediaXRCompositionLayer layer 需要渲染时,用户代理 必须运行以下步骤:
  1. usability检查 media 的可用性的结果。

  2. 如果 usabilitybad,则用透明 黑色填充 layer 并中止这些步骤。

  3. 使用 media 元素的内容填充 layer

添加一个更好的算法来 描述绘制过程。

XRMediaBinding(XRSession session) 构造函数 在调用时必须执行以下步骤:

  1. 如果 sessionended 值为 true,则抛出 InvalidStateError 并中止这些步骤。

  2. 如果 session 不是沉浸式会话,则抛出 InvalidStateError 并中止这些步骤。

  3. bindingsession相关领域中的一个 XRMediaBinding

  4. bindingsession 初始化为 session

  5. 返回 binding

要计算一个 HTMLVideoElement video 和一个 XRLayerLayout layout宽高比,运行以下步骤:
  1. widthvideovideoWidth

  2. heightvideovideoHeight

  3. 如果 layout"stereo-left-right", 则将 width 除以 2

  4. 如果 layout"stereo-top-bottom", 则将 height 除以 2

  5. 返回 width 除以 height 的结果。

createQuadLayer(HTMLVideoElement video, XRMediaQuadLayerInit init) 方法创建一个新的 XRQuadLayer layer

调用此方法时,用户代理必须运行以下步骤:

  1. session此对象session

  2. 如果 session 创建时未启用“layers”, 则抛出 NotSupportedError 并中止这些步骤。

  3. 如果 sessionended 值为 true,则抛出 InvalidStateError 并中止这些步骤。

  4. 如果 initlayout"default", 则抛出 TypeError 并中止这些步骤。

  5. layer此对象相关领域中的一个 XRQuadLayer

  6. 使用 sessionlayer 上运行初始化合成层

  7. layermedia 初始化为 video

  8. layerneedsRedraw 初始化为 false

  9. aspectRatio 为使用 videoinitlayout 计算 宽高比的结果。

  10. 如果 initwidthheight 都为 undefined,则将 width 设置为 1

  11. 如果 initheightundefined,则将 height 设置为 width 除以 aspectRatio

  12. 如果 initwidthundefined,则将 width 设置为 height 乘以 aspectRatio

  13. 使用 layerinit 运行初始化四边形层

  14. 如果 XR 合成器知道由于任何原因无法为 layer 创建资源,则抛出 OperationError 并中止这些步骤。

  15. 返回 layer

createCylinderLayer(HTMLVideoElement video, XRMediaCylinderLayerInit init) 方法创建一个新的 XRCylinderLayer layer

调用此方法时,用户代理必须运行以下步骤:

  1. session此对象session

  2. 如果 session 创建时未启用“layers”, 则抛出 NotSupportedError 并中止这些步骤。

  3. 如果 sessionended 值为 true,则抛出 InvalidStateError 并中止这些步骤。

  4. 如果 initlayout"default", 则抛出 TypeError 并中止这些步骤。

  5. layer此对象相关领域中的一个 XRCylinderLayer

  6. 使用 sessionlayer 上运行初始化合成层

  7. layermedia 初始化为 video

  8. layerneedsRedraw 初始化为 false

  9. aspectRatio 为使用 videoinitlayout 计算 宽高比的结果。

  10. 如果 initaspectRatioundefined,则将 aspectRatio 设置为 aspectRatio

  11. 使用 layerinit 运行初始化圆柱层

  12. 如果 XR 合成器知道由于任何原因无法为 layer 创建资源,则抛出 OperationError 并中止这些步骤。

  13. 返回 layer

createEquirectLayer(HTMLVideoElement video, XRMediaEquirectLayerInit init) 方法创建一个新的 XREquirectLayer layer

调用此方法时,用户代理必须运行以下步骤:

  1. session此对象session

  2. 如果 session 创建时未启用“layers”, 则抛出 NotSupportedError 并中止这些步骤。

  3. 如果 sessionended 值为 true,则抛出 InvalidStateError 并中止这些步骤。

  4. 如果 initlayout"default", 则抛出 TypeError 并中止这些步骤。

  5. 如果 initspace 不是 XRReferenceSpace 类型的实例,则抛出 InvalidStateError 并中止这些步骤。

  6. 如果 initspace类型"viewer", 则抛出 InvalidStateError 并中止这些步骤。

  7. layer此对象相关领域中的一个 XREquirectLayer

  8. 使用 sessionlayer 上运行初始化合成层

  9. layermedia 初始化为 video

  10. layerneedsRedraw 初始化为 false

  11. 使用 layerinit 运行初始化等距柱状投影层

  12. 如果 XR 合成器知道由于任何原因无法为 layer 创建资源,则抛出 OperationError 并中止这些步骤。

  13. 返回 layer

定义 XREquirectLayer 的 参数如何影响视频显示。

8. 事件

8.1. XRLayerEvent

XRLayerEvent 会被触发,以指示 XRLayer 状态的变化。

[SecureContext, Exposed=Window] interface XRLayerEvent : Event {
  constructor(DOMString type, XRLayerEventInit eventInitDict);
  [SameObject] readonly attribute XRLayer layer;
};

dictionary XRLayerEventInit : EventInit {
  required XRLayer layer;
};

layer 属性指示生成该事件的 XRLayer

8.2. 事件类型

用户代理必须提供以下新事件。事件的注册和触发必须遵循 DOM4 Events 的通常行为。

层的底层资源丢失XR Compositor 无法再重投影该层时,用户代理可以在 XRLayer 对象上触发一个 redraw 事件。

作者应该在下一个 XR 动画 帧重新绘制该层的内容。该事件必须属于 XRLayerEvent 类型。

9. 层之间的深度排序

默认情况下,layers 数组定义层的合成顺序,并且每一层都绘制在前一层之上。 如果应用程序想要拥有按深度排序的层,则必须使用 "depth-sorted-layers" 特性 描述符请求会话。

如果 XRSession 是使用 "depth-sorted-layers" 特性 描述符创建的,则 XRProjectionLayerXRQuadLayerXRCylinderLayer 层必须基于它们的深度来显示,而不是基于其在 layers 数组中的位置。 其他层类型必须继续像以前一样排序。

XRQuadLayerXRCylinderLayer 层必须按其维度(例如 widthcentralAngle)、 变换和空间进行排序。

XRProjectionLayer 层必须根据其 depthStencilTexture 中的值进行排序。 这也意味着,如果启用了 "depth-sorted-layers",则 XR Compositor 必须使用深度值,并且 ignoreDepthValuesusesDepthValues 必须被设置为 `true`。

10. 空间扭曲

空间扭曲是一种 改善 XR 合成器重投影的技术。 通过同时提交 motionVectorTexturedepthStencilTextureXR 合成器可以执行高质量的帧外推和重投影, 从而允许用户代理以较低的帧率运行,同时仍为用户提供流畅的体验。 requestAnimationFrame() 回调的传递频率可能低于显示器的原生刷新率。XR 合成器将 使用体验提供的运动矢量和深度信息合成缺失的帧。

要启用空间扭曲XRSession 必须使用“space-warp特性 描述符创建。 如果启用了“space-warp”,则 XR 合成器必须 使用深度值,ignoreDepthValues 必须设置为 `false`,并且 usesDepthValues 必须设置为 `true`。

当启用 space-warp 特性 描述符时,体验应为其提交的每个 XRProjectionLayer 将具有代表性的深度值渲染到 depthStencilTexture 中。 depthStencilTexturemotionVectorTexture 将具有相同的尺寸,该尺寸可能不同于 colorTexture 的尺寸。 作者可以使用 depthStencilTextureWidthdepthStencilTextureHeight 来确定深度/模板附件和运动矢量附件二者的尺寸。 作者应在这些附件的完整范围内渲染深度/模板和运动矢量信息, 而不是渲染到 viewport

注:由于深度/模板和运动矢量 附件的尺寸可能不同于颜色附件,因此它们并不打算附加到 用于渲染到 colorTexture 的帧缓冲区。 作者应按照各自附件的尺寸分别渲染深度/模板和运动矢量信息。

motionVectorTexture 必须采用 RGBA16F 格式。作者应使用该区域的二维屏幕空间运动矢量填充此纹理的 RG 分量, 该运动矢量表示为当前帧与上一帧之间归一化设备坐标NDC)中的增量。 运动矢量计算为 `(currentClipPos / currentW) - (prevClipPos / prevW)`,其中 `currentClipPos` 和 `prevClipPos` 分别是片段在当前帧和上一帧中的裁剪空间位置。 红色通道对应 NDC X(水平方向)的增量,而绿色通道对应 NDC Y(垂直方向)的增量。蓝色通道可以包含 NDC Z(深度)的增量,而 alpha 通道 不使用。

如果在处理 XRFrame 期间未提交 motionVectorTexturedepthStencilTexture, 则 XR 合成器必须像未启用空间扭曲一样处理该 XRFrame

11. WebXR 设备 API 集成

11.1. XRRenderState 变更

此模块扩展了 XRRenderStateInitXRRenderState 接口,新增一个可选的 layers 数组,其中包含 XRLayer
[SecureContext, Exposed=Window] partial interface XRRenderState {
  readonly attribute FrozenArray<XRLayer> layers;
};

layers 属性返回一个数组,其中包含 由 XR 合成器显示的 XRLayer 实例。

默认情况下,layers 数组定义各层的合成顺序。XR 合成器必须 按照每个层在数组中的位置顺序绘制它们,并使用 source-over 混合。除非启用了“depth-sorted-layers特性 描述符,否则 XR 合成器不得对各层应用任何深度排序。

注:这意味着每个层都有可能 覆盖之前的层,无论之前的层在虚拟空间中是否更靠近观察者。

此模块替换了初始化渲染状态给出的步骤。相反,当为一个 XRSession session 创建一个 XRRenderState 对象 state 时,用户代理必须通过运行以下步骤来初始化渲染状态
  1. 通过运行原始的初始化渲染状态步骤来初始化 state

  2. 使用位于 session相关领域中的一个空数组初始化 statelayers

11.2. updateRenderState 变更

此模块替换了 WebXR 规范中“更新待处理的层状态”给出的步骤。相反,当用户代理要使用 XRSession sessionXRRenderStateInit newState 更新待处理的层状态时,必须运行以下步骤:

  1. 如果 newStatebaseLayernewStatelayers 都已设置,则抛出 NotSupportedError 并中止这些步骤。

  2. activeStatesession活动渲染状态

  3. 如果设置了 newStatebaseLayer

    1. 如果 session待处理渲染状态null, 则将其设置为 activeState 的副本。

    2. session待处理渲染状态layers 设置为 null

  4. 如果设置了 newStatelayers

    1. 如果 newStatelayers 包含一个其destroyed 布尔值为 trueXRCompositionLayer, 则抛出 InvalidStateError 并中止这些步骤。

    2. 如果 session 创建时未启用“layers”,且 newStatelayers 包含多于 1 个实例,则抛出 NotSupportedError 并中止这些步骤。

    3. 如果 newStatelayers 包含多于 maxRenderLayers 个条目,则抛出 NotSupportedError 并中止这些步骤。

    4. 如果 session待处理渲染状态null, 则将其设置为 activeState 的副本。

    5. 如果 newStatelayers 包含重复实例,则抛出 TypeError 并中止这些步骤。

    6. 对于 newStatelayers 中的每个 layer

      1. 如果 layerXRCompositionLayerlayersessionsession 不同,则抛出 TypeError 并中止这些步骤。

      2. 如果 layerXRWebGLLayerlayersessionsession 不同,则抛出 TypeError 并中止这些步骤。

    7. session待处理渲染状态baseLayer 设置为 null

    8. session待处理渲染状态layers 设置为 newStatelayers

11.3. XRCompositor 变更

必须扩展 XR 合成器,使 XRLayer layers 数组中的所有实例都能同时进行合成。 WebXR 的所有其他要求必须继续

如果 XR 合成器正在渲染到一个 视图,其 XREye"none", 并且正在绘制一个不是 XRProjectionLayer 且其 layout 不为 "mono"XRCompositionLayer, 则 XR 合成器必须像该视图XREye"left" 一样渲染该层。

注:这意味着该层中供右眼使用的一侧 会被忽略。这使作者能够为立体显示设备和 单目显示设备使用相同的资源。

11.4. XRView 变更

每个 视图必须定义一个 推荐 WebGL 颜色纹理分辨率,它 表示足以包含该视图的 WebGL 纹理 分辨率的最佳估计。

如果 XRSession 是使用“space-warp特性 描述符创建的,则每个 视图必须定义一个推荐运动矢量纹理分辨率, 该分辨率基于推荐 WebGL 颜色纹理 分辨率

每个 视图还必须 定义一个 推荐 WebGL 深度纹理分辨率, 它表示足以包含该视图的 WebGL 深度纹理 分辨率的最佳估计。 如果 XRSession 是使用“space-warp特性 描述符创建的,则推荐 WebGL 深度纹理分辨率 必须等于推荐运动矢量纹理 分辨率

如果启用了“depth-sorted-layers特性描述符,则推荐 WebGL 深度纹理 分辨率必须等于推荐 WebGL 颜色纹理 分辨率

11.5. 动画帧变更

此模块替换了 WebXR 规范中“检查层状态”给出的步骤。相反,要使用 renderState state 检查层 状态,用户代理必须运行以下步骤:
  1. 如果 statebaseLayer 不为 null,则返回 true

  2. 对于 statelayers 中的每个 layer

    1. 如果 layer 不是 XRCompositionLayerlayerdestroyed 布尔值为 false,则返回 true

  3. 返回 false

11.6. XRSession 更改

此模块扩展了 XRSession 接口并向其中添加以下内容:
[SecureContext, Exposed=Window] partial interface XRSession {
  readonly attribute unsigned long maxRenderLayers;
};

maxRenderLayers 表示 合成器必须处理的最大层数,因此也是任何 XRRenderStateInitlayers 数组的最大大小。在给定时间内,应当能够创建超过此数量的层。

注:此指导并非旨在限制 用户代理可分配的层数量,如层的分配中所述。例如,用户代理可以允许创建 20 个层, 同时仅允许一次通过 updateRenderState() 设置 10 个。还值得注意的是,由于不同的层可能需要不同数量的后端处理能力或 对象,用户代理在设置 `maxRenderLayers` 值时具有一定的裁量权,以确保至少 可以渲染那么多层。但是,当传入更多层时,用户代理仍然需要拒绝,并且在向 updateRenderState 传入更少的层时不能拒绝。

每个 XRSession 都有一个内部 WeakSet bindings,其中保存 使用该会话创建的每个 XRWebGLBinding 的弱引用。

此模块向 WebXR 规范中的“关闭 会话”添加一个步骤。 将以下内容添加到列表中:

  1. 对于 session|bindings中的每个 binding

    1. 对于 bindingfoveatedTextures中的每个 texture

    2. 移除 texture 的注视点渲染。

12. 安全和隐私考量

12.1. 合成的时序

合成时序必须独立于所渲染的内容。 此外,一个层中的内容不得在其他层中被观察到。

如果可能,层的合成应该在浏览器之外进行,以降低时序攻击或 其他安全漏洞的风险。

12.2. 层的分配

用户代理可以限制任何资源分配,例如最大像素大小或 层数,以降低 GPU 硬件的可识别性。

变更

2020 年 12 月 3 日第一份公开工作 草案以来的变更

新特性:

变更:

一致性

文档 约定

一致性要求通过 描述性断言 与 RFC 2119 术语的组合来表达。 本文档规范性部分中的关键字 “MUST”、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、“SHOULD”、“SHOULD NOT”、“RECOMMENDED”、 “MAY” 和 “OPTIONAL” 应按 RFC 2119 中的描述来解释。 但是,为提高可读性, 这些词在本规范中并不全都以大写字母出现。

本规范的所有文本均为规范性内容, 但明确标记为非规范性的章节、示例和注释除外。 [RFC2119]

本规范中的示例以 “for example” 等词引入,或通过 class="example" 与规范性文本分隔开, 如下所示:

这是一个资料性示例。

资料性注释以 “Note” 开头,并通过 class="note" 与规范性文本分隔开, 如下所示:

注,这是一个资料性注释。

一致性 算法

作为算法一部分以祈使语气表述的要求 (例如 "strip any leading space characters" 或 "return false and abort these steps") 应按引入该算法时所使用的关键字 ("must"、"should"、"may" 等) 的含义来解释。

以算法或具体步骤表述的一致性要求 可以以任何方式实现, 只要最终结果等价即可。 特别是,本规范中定义的算法 旨在易于理解, 并不旨在具有高性能。 鼓励实现者进行优化。

索引

由本 规范定义的术语

由引用定义的术语

参考文献

规范性参考文献

[COMPOSITING-1]
Chris Harrelson. 合成与混合级别 1. 2024年3月21日. CRD. URL: https://www.w3.org/TR/compositing-1/
[DOM]
Anne van Kesteren. DOM 标准. 现行标准. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript 语言规范. URL: https://tc39.es/ecma262/multipage/
[GEOMETRY-1]
Sebastian Zartner; Yehonatan Daniv. 几何接口 模块级别 1. 2025年12月4日. CRD. URL: https://www.w3.org/TR/geometry-1/
[HTML]
Anne van Kesteren; et al. HTML 标准. 现行标准. URL: https://html.spec.whatwg.org/multipage/
[RFC2119]
S. Bradner. 用于 RFC 中表示 要求级别的关键词. 1997年3月. 当前最佳实践. URL: https://datatracker.ietf.org/doc/html/rfc2119
[WEBGL-2]
Kelsey Gilbert. WebGL 2.0 规范. URL: https://www.khronos.org/registry/webgl/specs/latest/2.0/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL 标准. 现行 标准. URL: https://webidl.spec.whatwg.org/
[WEBXR]
Brandon Jones; Manish Goregaokar; Rik Cabanier. WebXR 设备 API. 2026年6月9日. CRD. URL: https://www.w3.org/TR/webxr/
[WEBXR-AR-MODULE-1]
Brandon Jones; Manish Goregaokar; Rik Cabanier. WebXR 增强现实模块 - 级别 1. 2025年4月25日. CRD. URL: https://www.w3.org/TR/webxr-ar-module-1/

资料性参考文献

[PERMISSIONS-REQUEST]
Requesting Permissions. 社区组报告草案. URL: https://wicg.github.io/permissions-request/

IDL 索引

enum XRLayerLayout {
  "default",
  "mono",
  "stereo",
  "stereo-left-right",
  "stereo-top-bottom"
};

enum XRLayerQuality {
  "default",
  "text-optimized",
  "graphics-optimized"
};

[Exposed=Window] interface XRCompositionLayer : XRLayer {
  readonly attribute XRLayerLayout layout;

  attribute boolean blendTextureSourceAlpha;
  attribute boolean forceMonoPresentation;
  attribute float opacity;
  readonly attribute unsigned long mipLevels;
  attribute XRLayerQuality quality;

  readonly attribute boolean needsRedraw;

  undefined destroy();
};

[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;
  attribute XRRigidTransform? deltaPose;
};

[Exposed=Window] interface XRQuadLayer : XRCompositionLayer {
  attribute XRSpace space;
  attribute XRRigidTransform transform;

  attribute float width;
  attribute float height;

  // Events
  attribute EventHandler onredraw;
};

[Exposed=Window] interface XRCylinderLayer : XRCompositionLayer {
  attribute XRSpace space;
  attribute XRRigidTransform transform;

  attribute float radius;
  attribute float centralAngle;
  attribute float aspectRatio;

  // Events
  attribute EventHandler onredraw;
};

[Exposed=Window] interface XREquirectLayer : XRCompositionLayer {
  attribute XRSpace space;
  attribute XRRigidTransform transform;

  attribute float radius;
  attribute float centralHorizontalAngle;
  attribute float upperVerticalAngle;
  attribute float lowerVerticalAngle;

  // Events
  attribute EventHandler onredraw;
};

[Exposed=Window] interface XRCubeLayer : XRCompositionLayer {
  attribute XRSpace space;
  attribute DOMPointReadOnly orientation;

  // Events
  attribute EventHandler onredraw;
};

[Exposed=Window] interface XRSubImage {
  [SameObject] readonly attribute XRViewport viewport;
};

[Exposed=Window] interface XRWebGLSubImage : XRSubImage {
  [SameObject] readonly attribute WebGLTexture colorTexture;
  [SameObject] readonly attribute WebGLTexture? depthStencilTexture;
  [SameObject] readonly attribute WebGLTexture? motionVectorTexture;

  readonly attribute unsigned long? imageIndex;
  readonly attribute unsigned long colorTextureWidth;
  readonly attribute unsigned long colorTextureHeight;
  readonly attribute unsigned long? depthStencilTextureWidth;
  readonly attribute unsigned long? depthStencilTextureHeight;
};

enum XRTextureType {
  "texture",
  "texture-array"
};

dictionary XRProjectionLayerInit {
  XRTextureType textureType = "texture";
  GLenum colorFormat = 0x1908; // RGBA
  GLenum depthFormat = 0x1902; // DEPTH_COMPONENT
  double scaleFactor = 1.0;
  boolean clearOnAccess = true;
};

dictionary XRLayerInit {
  required XRSpace space;
  XRTextureType textureType = "texture";
  GLenum colorFormat = 0x1908; // RGBA
  GLenum? depthFormat;
  unsigned long mipLevels = 1;
  required unsigned long viewPixelWidth;
  required unsigned long viewPixelHeight;
  XRLayerLayout layout = "mono";
  boolean isStatic = false;
  boolean clearOnAccess = true;
};

dictionary XRQuadLayerInit : XRLayerInit {
  XRRigidTransform? transform;
  float width = 1.0;
  float height = 1.0;
};

dictionary XRCylinderLayerInit : XRLayerInit {
  XRRigidTransform? transform;
  float radius = 2.0;
  float centralAngle = 0.78539;
  float aspectRatio = 2.0;
};

dictionary XREquirectLayerInit : XRLayerInit {
  XRRigidTransform? transform;
  float radius = 0;
  float centralHorizontalAngle = 6.28318;
  float upperVerticalAngle = 1.570795;
  float lowerVerticalAngle = -1.570795;
};

dictionary XRCubeLayerInit : XRLayerInit {
  DOMPointReadOnly? orientation;
};

[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 eye = "none");
  XRWebGLSubImage getViewSubImage(XRProjectionLayer layer, XRView view);

  undefined foveateBoundTexture(GLenum target, float fixed_foveation);
};

dictionary XRMediaLayerInit {
  required XRSpace space;
  XRLayerLayout layout = "mono";
  boolean invertStereo = false;
};

dictionary XRMediaQuadLayerInit : XRMediaLayerInit {
  XRRigidTransform? transform;
  float? width;
  float? height;
};

dictionary XRMediaCylinderLayerInit : XRMediaLayerInit {
  XRRigidTransform? transform;
  float radius = 2.0;
  float centralAngle = 0.78539;
  float? aspectRatio;
};

dictionary XRMediaEquirectLayerInit : XRMediaLayerInit {
  XRRigidTransform? transform;
  float radius = 0.0;
  float centralHorizontalAngle = 6.28318;
  float upperVerticalAngle = 1.570795;
  float lowerVerticalAngle = -1.570795;
};

[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 = {});
};

[SecureContext, Exposed=Window] interface XRLayerEvent : Event {
  constructor(DOMString type, XRLayerEventInit eventInitDict);
  [SameObject] readonly attribute XRLayer layer;
};

dictionary XRLayerEventInit : EventInit {
  required XRLayer layer;
};

[SecureContext, Exposed=Window] partial interface XRRenderState {
  readonly attribute FrozenArray<XRLayer> layers;
};

[SecureContext, Exposed=Window] partial interface XRSession {
  readonly attribute unsigned long maxRenderLayers;
};

议题索引

本节需要澄清
本节需要澄清
init 字典不应是可选的。这是 bikeshed 议题 1566。
如果尺寸导致布局变化,则需要特殊处理 UA 行为(即,如果请求的宽度 超过 "stereo-left-right" 的限制)
需要为辅助视图重新计算 scaleFactor。
定义立方体贴图尺寸如何确定。
应如何处理 space。能否走到立方体贴图的边缘?
确定 orientation 的初始状态。
init 字典不应是可选的。这是 bikeshed 议题 1566。
需要进一步说明如何将视频 blit 到层中。
添加一个更好的算法来描述绘制。
定义 XREquirectLayer 的参数 如何影响视频显示。