在 Jetpack XR SDK 中,空间环境是您可以添加到应用中的沉浸式环境,用于自定义虚拟场景的背景。只有当应用处于全沉浸空间时,空间环境才可见。
空间环境概览
SpatialEnvironment 用于管理应用的空间环境偏好设置。它由独立的 Skybox 图片和 glTF 指定的几何图形组成。一次只能设置一个天空盒图片和一个 glTF 几何图形文件。
天空盒代表用户在虚拟场景中看到的周围图像,营造出远处的背景环境(如天空、山脉或城市景观)的错觉。用户无法与天空盒互动,也无法靠近天空盒。Jetpack XR SDK 支持 OpenEXR 标准中的球形天空盒。除了为应用提供沉浸式背景外,EXR 天空盒还为应用加载的 3D 模型提供基于图像的光照 (IBL)。如需了解详情,请参阅使用 3D 模型的指南。
空间环境还可以包含 glTF 标准的 3D 几何内容。以这种方式加载的环境几何图形将自动与现实世界中的地面保持一致。环境几何图形是一种很好的方式,可以通过前景和中景元素为环境增添真实感,这些元素通过视差效果融入天空盒。
在空间环境设计指南中,您可以了解可用于创建空间环境的不同类型的资源,以及如何创建安全且令人愉悦的空间环境。
您可以将应用的空间环境设置为以下三种配置之一:
- 天空盒图片和 glTF 几何图形的组合。
- 透视表面,其中显示的环境是设备朝外摄像头的实时画面。在完全不透明的情况下,此透视表面会完全遮挡天空盒和几何图形。
- 混合配置,其中透视表面既不完全不透明,也不完全透明。在这种情况下,透视表面会变为半透明,并与天空盒及其背后的几何图形进行 Alpha 混合。
适用于空间环境的空间功能
SpatialCapability:表示当前会话的空间功能。某些空间功能与空间环境相关。SpatialCapability.PASSTHROUGH_CONTROL:指示 activity 当前是否可以启用或停用直通。SpatialCapability.APP_ENVIRONMENT:指示 activity 当前是否可以设置自己的空间环境。
导入和加载空间环境资源
空间环境的 glTF 和 EXR 资源通过使用 Session 类异步加载。
创建 glTF 资源
glTF 资源可以创建为 GltfModel,其中 glTF 是从本地文件加载的。GltfModel 可用作空间应用环境的一部分。
val environmentGeometry = GltfModel.create(session, Paths.get("DayGeometry.glb"))
创建基于图片的照明资源
基于图像的光照资源可以创建为 ImageBasedLightingAsset,其中光照是从本地文件加载的。ImageBasedLightingAsset 可与 cmgen 搭配使用,为天空盒创建 IBL 的 ZIP 文件。如需了解详情,请参阅有关优化环境资源的指南。
val lightingForSkybox = ImageBasedLightingAsset.createFromZip(session, Paths.get("BlueSkyboxLighting.zip"))
为应用设置 SpatialEnvironmentPreference
preferredSpatialEnvironment 属性用于控制应用的首选空间环境。使用此属性设置偏好设置时,除非 isPreferredSpatialEnvironmentActive 已为 true,否则不会立即生效。当设备进入可以更改 XR 背景的状态,并且 SpatialCapability.APP_ENVIRONMENT 功能可用时,系统会自动显示应用的首选空间环境。
将该偏好设置设为 null 会停用应用的首选空间环境,这意味着系统会改为显示默认系统环境。
如果给定的 SpatialEnvironmentPreference 不为 null,但其所有属性均为 null,则空间环境将由黑色天空盒组成,且不包含几何图形。
如需在 SpatialEnvironment 状态发生变化时收到通知,请使用 addOnSpatialEnvironmentChangedListener。
基本用法
此代码段会创建环境几何图形和天空盒资源,然后设置空间环境偏好。系统会记住此偏好设置,并在应用能够设置自己的环境时应用该设置。
val spatialEnvironmentPreference = SpatialEnvironment.SpatialEnvironmentPreference(lightingForSkybox, environmentGeometry) session.scene.spatialEnvironment.preferredSpatialEnvironment = spatialEnvironmentPreference if (session.scene.spatialEnvironment.isPreferredSpatialEnvironmentActive) { // The environment was successfully updated and is now visible, and any listeners // specified using addOnSpatialEnvironmentChangedListener will be notified. } else { // The passthrough opacity preference was successfully set, but not // immediately visible. The passthrough opacity change will be applied // when the activity has the SPATIAL_CAPABILITY_APP_ENVIRONMENT capability. // Then, any listeners specified using addOnSpatialEnvironmentChangedListener // will be notified. }
高级用法
对于需要更精细地控制环境的更高级用例,您可以纳入 SpatialCapability 检查并实现 addOnSpatialEnvironmentChangedListener,以确定何时设置空间环境偏好设置。
为应用的空间环境设置 PassthroughOpacityPreference
应用的沉浸式虚拟背景的组件之一是透视表面。在这种情况下,显示的背景是设备外向摄像头的实时画面。
setPassthroughOpacityPreference 用于设置应用的首选透视不透明度。此方法仅设置偏好设置,不会立即生效,除非 SpatialCapability.PASSTHROUGH_CONTROL 功能可用。当设备进入可以更改透视不透明度的状态,并且 SpatialCapability.PASSTHROUGH_CONTROL 功能可用时,系统会自动应用应用的首选透视不透明度。
透视不透明度偏好设置的值范围为 0.0f(零不透明度,透视表面不可见)到 1.0f(完全不透明,透视表面会隐藏空间环境)。setPassthroughOpacityPreference 参数是可为 null 的浮点数。将该值设置为 null 表示应用没有透视不透明度偏好设置,并将透视控制权交还给系统。
基本用法
此代码段用于设置透视不透明度偏好设置。系统会记住此偏好设置,并在应用能够设置透视不透明度时应用该设置。
session.scene.spatialEnvironment.preferredPassthroughOpacity = 1.0f if (session.scene.spatialEnvironment.currentPassthroughOpacity == 1.0f) { // The passthrough opacity request succeeded and should be visible now, and any listeners // specified using addOnPassthroughOpacityChangedListener will be notified. } else { // The passthrough opacity preference was successfully set, but not // immediately visible. The passthrough opacity change will be applied // when the activity has the // SpatialCapabilities.SPATIAL_CAPABILITY_PASSTHROUGH_CONTROL capability. // Then, any listeners specified using addOnPassthroughOpacityChangedListener // will be notified. }
高级用法
对于需要更精细地控制透视不透明度的更高级用例,您可以纳入 SpatialCapability 检查,并使用 addOnPassthroughOpacityChangedListener 添加监听器,以确定何时设置透视不透明度偏好设置。
资源优化
在为用户设置 SpatialEnvironment 时创建资源时,请确保资源达到高分辨率,同时保持合理的文件大小。如需了解详情,请参阅有关优化环境素材资源的指南。
确定当前的透视不透明度
val currentPassthroughOpacity = session.scene.spatialEnvironment.currentPassthroughOpacity