WebXR 原始摄像头访问模块

社区组报告草案,

关于此文档的更多详细信息
此版本:
https://immersive-web.github.io/raw-camera-access/
问题跟踪:
GitHub
规范内嵌
编辑:
(Google)
前任编辑:
(Google)
参与:
提交问题未解决的问题
邮件列表归档
W3C 的 #immersive-web IRC
解释文档:
GitHub 上的 explainer.md

摘要

本规范提供了一种访问显示在 immerisve-ar 会话背后的原始摄像头图像的方式, 当该设备负责渲染该摄像头图像时。

本文档的状态

1. 简介

本规范引入了新的 WebXR Device API 能力,即 Raw Camera Access API。新引入的 API 使基于 WebXR 的应用能够访问摄像头图像像素,从而允许它们利用这些新信息 计算自定义的逐帧视觉效果,或拍摄叠加了摄像头图像的应用渲染内容快照。

注:本文档中指定的 API 形态 主要解决以智能手机为中心的场景。有关上下文,请参见 issue #2

1.1. 术语

本文档使用缩写 AR 表示增强现实,使用 VR 表示虚拟现实。

2. 初始化

2.1. 特性描述符

应用可以通过传递适当的特性描述符,请求在 XRSession 上启用原始摄像头访问。本模块引入新字符串——camera-access,作为原始 摄像头访问特性的新的有效特性描述符。

如果设备暴露原生摄像头 能力,则该设备能够支持原始摄像头访问特性。内联 XR 设备不得被视为能够 支持原始摄像头访问特性。

原始摄像头访问特性受权限 策略约束,并要求请求文档的源允许 "xr-spatial-tracking" 策略。 此外,请求文档的源还必须允许 "camera" 权限 策略

以下代码演示了如何请求一个需要 Raw Camera Access API 的会话:
const session = await navigator.xr.requestSession("immersive-ar", {
  requiredFeatures: ["camera-access"],
});

3. 访问摄像头纹理

3.1. XRView

partial interface XRView {
  [SameObject] readonly attribute XRCamera? camera;
};

XRView 被扩展为包含一个 camera 属性,该属性引用一个 XRCamera 实例, 其中包含与此视图相关的摄像头图像信息。当第一次在给定 XRView 实例上访问 camera 属性时,用户代理必须运行取得摄像头算法。对同一 XRView 实例的后续访问必须返回相同的 XRCamera 实例 (如果曾返回过一个),否则返回 null

为了为 XRView view 取得 摄像头,用户代理必须运行以下步骤:

  1. sessionview会话

  2. 如果 camera-access 特性描述符未被包含session已授予特性集中,则返回 null 并中止这些步骤。

  3. frameview

  4. 如果 frameactive 布尔值为 false,则抛出 InvalidStateError 并中止这些步骤。

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

  6. camera image 包含一个大小为 widthheight 纹素的摄像头图像缓冲区,该缓冲区由原生摄像头返回,并且对 frame时间有效。

  7. 如果 camera imagenull,则返回 null 并中止这些步骤。

  8. 确保 camera image 包含与 view 对齐的数据,包括适当调整 widthheight。如果无法做到这一点,则返回 null 并中止这些步骤。

  9. viewcamera imagewidthheight 调用创建摄像头实例算法,并返回其 结果。

3.2. XRCamera

[SecureContext, Exposed=Window]
interface XRCamera {
  readonly attribute unsigned long width;
  readonly attribute unsigned long height;
};

XRCamera 接口被引入,用作暴露可从 XRWebGLBinding 取得的摄像头纹理相关信息的一种方式。

XRCamera 包含 width 属性,该属性包含摄像头图像的宽度(以纹素为单位)。

XRCamera 包含 height 属性,该属性包含摄像头图像的高度(以纹素为单位)。

每个 XRCamera 都有一个关联的 视图实例,其中包含返回该 XRCamera 实例所来自的 XRView

每个 XRCamera 都有一个关联的 摄像头图像数据缓冲区。

为了从 XRView viewcamera imagewidthheight 创建摄像头实例,用户代理必须运行 以下步骤:
  1. resultXRCamera 接口的一个新实例。

  2. result视图设为 view

  3. result摄像头图像设为 camera image

  4. resultwidth 设为 width

  5. resultheight 设为 height

  6. 返回 result

3.3. XRWebGLBinding

partial interface XRWebGLBinding {
  WebGLTexture? getCameraImage(XRCamera camera);
};

getCameraImage(camera) 方法在被调用时,可用于从 XRWebGLBinding 取得摄像头图像。 返回的 WebGLTexture 如果非 null,则为不透明 纹理

为了从 XRWebGLBinding bindingXRCamera camera 取得 摄像头图像,用户代理必须运行以下步骤:
  1. sessionbinding会话

  2. viewcamera视图

  3. 如果 view会话session 不匹配,则抛出 InvalidStateError 并中止这些步骤。

  4. frameview

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

  6. 如果 frameanimationFrame 布尔值为 false,则抛出 InvalidStateError 并中止这些步骤。

  7. contextbinding上下文

  8. camera imagecamera摄像头图像

  9. result 为一个在 context 上创建的 WebGLTexture, 其中包含 camera image 的数据。 result 是一个不透明纹理

  10. 返回 result

用户代理可以缓存对 getCameraImage(camera) 调用的结果,以供该方法的后续调用返回,前提是缓存以绑定和摄像头实例为键。 即使使用缓存,用户代理也必须通过运行到取得摄像头图像算法的第 6 步(含)来执行初始验证。 由于允许这种缓存,应用应将返回的 WebGLTexture 视为只读。

注:允许缓存是因为用户代理 保留对返回的 WebGLTexture 生命周期的所有权(因为它被视为不透明 纹理),并且因为在同一 requestAnimationFrame() 回调内多次调用此方法(通过使用 XRCamera,以及 因此传递性地使用 XRFrame 作为缓存键的一部分来保证),并在同一绑定上调用(通过使用 XRWebGLBinding 作为缓存键的一部分来保证),将得到内容相同的纹理。

如果从调用 getCameraImage(camera) 返回的 WebGLTexture 支持透明度,则它必须包含预乘 alpha 的颜色。

我们是否应该指定更多 有关返回的 WebGLTexture 的信息? 例如:它是否可作为颜色渲染目标、纹理格式是什么等。

4. 原生设备概念

4.1. 原生摄像头

Raw Camera API 规范假定实现该 API 所基于的原生设备 提供一种以动画帧同步的方式访问摄像头图像的方法。这样的设备被称为 支持原生 摄像头能力。

除了设备能够提供摄像头图像外,Raw Camera Access API 只能 提供与请求它们的 XRView 对齐的摄像头图像纹理。如果摄像头姿态与 XRView 的姿态相同,并且摄像头的视锥体与 XRView 的视锥体形状相同,则称该摄像头图像与该 XRView 对齐。如果由原生摄像头返回的摄像头图像覆盖的视锥体完全包含 XRView 的视锥体,则只要该操作会使视锥体形状完全匹配,用户代理就可以裁剪摄像头图像。

5. 隐私与安全考量

Raw Camera Access API 在目前所有可用的 WebXR 能力中具有最高的隐私影响,因为它是唯一允许应用直接观察用户 环境的 API。鉴于此,用户代理应在允许创建启用了 camera-access 特性的会话 之前征求用户同意。有关更多详细信息,请参阅 WebXR Device API § securityWebXR Device API § user-intention 章节,以及下方的 § 5.1 用户 体验§ 5.2 隐私指示器章节。

要求所提供的摄像头图像与 XRView 对齐,为减轻该 API 对用户隐私的影响提供了部分缓解。 此要求的一个结果是,根据 XR 合成器混合技术,摄像头图像将包含用户可能已经看到的相同信息, 从而直接反馈环境中哪些部分对网站可见。请注意,在某些情况下,网站可能会 抑制此信息(例如在智能手机上渲染一个覆盖整个视图的不透明对象, 从而遮挡由合成器渲染的环境)。

除了要求用户代理征求用户同意之外,还强烈鼓励应用开发者 如果存在其他方式实现其用例,则不要请求 camera-access 特性。

5.1. 用户体验

如上所述,由于 Raw Camera Access API 的隐私影响,用户代理应在创建启用了 camera-access 特性的会话之前征求用户 同意。这可以通过多种方式实现,其中一些方式需要直接与用户交互。

直接与用户交互的一些示例包括:

  1. 显示权限提示,允许用户选择向站点暴露信息的精细程度。 此类提示的模型如下所示。

  1. 显示一系列权限提示,这些提示会考虑创建包含应用传递给 requestSession() 调用的所请求和可选特性的会话所需的各种用户同意级别。

本规范的意图是确保用户代理不会鼓励应用开发者 在他们想要提供的体验并非绝对需要时请求 camera-access 特性。由于该特性的隐私影响,当站点请求访问摄像头图像时,用户代理可以 引入额外阻力,希望这能激励应用不要无谓地请求该特性。

用户代理应考虑为强大特性“camera” 复用权限 UI(或该源已授予的权限),该特性定义于 强大特性

5.2. 隐私指示器

每当创建了一个带有 camera-accessXRSession 且该会话尚未 ended 时, 用户代理必须显示隐私指示器。如果将来可以在会话创建后修改会话的已 授予特性集,则只要 camera-access 特性描述符被包含在该会话的已授予特性集中,就应显示该指示器。

显示给用户的指示器应传达设备摄像头正在使用且站点可访问该摄像头这一事实, 因而用户应格外注意,确保落入摄像头视野内的内容是他们愿意与该站点分享的。 这在公共场所尤其如此,因为可能存在未同意被记录的旁观者。

示例指示器包括(但不限于):

6. 致谢

以下个人为 WebXR Raw Camera Access 规范的设计做出了贡献:

一致性

文档 约定

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

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

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

这是一个资料性示例的示例。

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

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

索引

由本 规范定义的术语

由引用 定义的术语

引用

规范性引用

[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 标准. Living Standard. URL: https://infra.spec.whatwg.org/
[RFC2119]
S. Bradner. 用于在 RFC 中 指示要求级别的关键词. 1997年3月. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[WEBGL-2]
Dean Jackson; Jeff Gilbert. WebGL 2.0 规范. 2017年8月12日. URL: https://www.khronos.org/registry/webgl/specs/latest/2.0/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL 标准. Living Standard. URL: https://webidl.spec.whatwg.org/

资料性引用

[PERMISSIONS]
Marcos Caceres; Mike Taylor. 权限. URL: https://w3c.github.io/permissions/
[WEBXR]
Brandon Jones; Manish Goregaokar; Rik Cabanier. WebXR Device API. URL: https://immersive-web.github.io/webxr/

IDL 索引

partial interface XRView {
  [SameObject] readonly attribute XRCamera? camera;
};

[SecureContext, Exposed=Window]
interface XRCamera {
  readonly attribute unsigned long width;
  readonly attribute unsigned long height;
};

partial interface XRWebGLBinding {
  WebGLTexture? getCameraImage(XRCamera camera);
};

问题索引

我们是否应该指定更多有关返回的 WebGLTexture 的信息? 例如:它是否可作为颜色渲染目标、纹理格式是什么等。