在應用程式中新增空間環境

在 Jetpack XR SDK 中,空間環境是指可新增至應用程式,用於自訂虛擬場景背景的沉浸式環境。只有在應用程式處於全螢幕模式時,才能看到空間環境。

空間環境總覽

SpatialEnvironment 可用於管理應用程式的空間環境偏好設定。它是獨立天空盒圖像和 glTF 指定幾何圖形的複合圖像。一次只能設定單一天空盒圖片和單一 glTF 幾何圖檔案。

天空盒代表使用者在虛擬場景中看到的周圍影像,可營造天空、山脈或城市景觀等遠景背景環境的錯覺。使用者無法與天空盒互動或靠近天空盒。Jetpack XR SDK 支援 OpenEXR 標準中的球形天空盒。除了為應用程式提供沉浸式背景,EXR 天空盒還會為應用程式載入的 3D 模型提供影像式光照 (IBL)。詳情請參閱3D 模型操作指南

空間環境也可以包含 glTF 標準中的 3D 幾何圖形內容。以這種方式載入的環境幾何圖形會自動與實際地板對齊。環境幾何圖形是一種絕佳的方式,可透過前景和中景元素,以視差效果融入天空盒,為環境增添真實感。

空間環境設計指南中,您可以瞭解可用來建立空間環境的不同類型素材資源,以及如何建立安全且令人愉悅的空間環境。

您可以將應用程式的空間環境設為下列三種設定之一:

  • 結合天空盒圖片和 glTF 幾何圖形。
  • 透過介面,顯示裝置外向鏡頭的即時影像。在完全不透明的情況下,這個穿透式表面會完全遮蔽天空盒和幾何圖形。
  • 混合設定,其中傳遞表面不處於完全不透明,也不處於完全不透明。在這種情況下,傳送途徑表面會變成半透明,並與天空盒和其後方的幾何圖形進行 Alpha 混合。

空間環境的空間功能

匯入及載入空間環境資源

空間環境的 glTF 和 EXR 資源會在 Session 類別中以非同步方式載入。這些檔案必須儲存在「assets」資料夾中。

建立 glTF 資源

您可以將 glTF 資源建立為 GltfModel,其中 glTF 會從本機檔案載入。GltfModel 可用於空間應用程式環境。

// assume that session is a Session that has been previously created
val environmentGeometryFuture = session.createGltfResourceAsync("DayGeometry.glb")

val environmentGeometry = environmentGeometryFuture.await()

建立 EXR 圖像資源

您可以建立 EXR 圖像資源,做為 ExrImage,其中 EXR 會從本機檔案載入。ExrImage 可用於繪製天空盒,做為空間應用程式環境的一部分。

// assume that session is a Session that has been previously created
val skyboxExrFuture = session.createExrImageResourceAsync("BlueSkybox.exr")

val skyboxExr = skyboxExrFuture.await()

為應用程式設定 SpatialEnvironmentPreference

setSpatialEnvironmentPreference 用於設定應用程式的偏好空間環境。這個方法只會設定偏好設定,不會立即變更,除非 isSpatialEnvironmentPreferenceActive 已為 true。裝置進入可變更 XR 背景的狀態,且 SpatialCapabilities.SPATIAL_CAPABILITY_APP_ENVIRONMENT 功能可用時,系統會自動顯示應用程式偏好的空間環境。

將偏好設定設為空值會為應用程式停用偏好的空間環境,也就是說,系統會改為顯示預設系統環境。

如果指定的 SpatialEnvironmentPreference 並非空值,但其所有屬性均為空值,則空間環境將包含黑色天空盒,且沒有幾何圖形。

如要接收 SpatialEnvironment 狀態變更通知,請使用 addOnSpatialEnvironmentChangedListener

基本用法

這個程式碼片段會建立環境幾何圖形和天空盒資源,然後設定空間環境偏好設定。系統會記住這項偏好設定,並在應用程式能夠設定自身環境時套用。

// Assume that session is a Session that has been previously created

// Create a GLTFResource
val environmentGeometry = session.createGltfResourceAsync("DayGeometry.glb").await()

// Create an ExrImage for the skybox
val skyboxExr = session.createExrImageResourceAsync("BlueSkybox.exr").await()

val spatialEnvironmentPreference = SpatialEnvironmentPreference(skyboxExr, environmentGeometry)

val preferenceResult = session.spatialEnvironment.setSpatialEnvironmentPreference(spatialEnvironmentPreference)

if (preferenceResult ==  SpatialEnvironment.SetSpatialEnvironmentPreferenceChangeApplied()) {
   // The environment was successfully updated and is now visible, and any listeners
   // specified using addOnSpatialEnvironmentChangedListener will be notified.
} else if (preferenceResult == SpatialEnvironment.SetSpatialEnvironmentPreferenceChangePending()) {
    // The environment is in the process of being updated. Once visible, any listeners
   // specified using addOnSpatialEnvironmentChangedListener will be notified.
}

進階用法

對於需要更精細控管環境的進階用途,您可以加入 SpatialCapabilities 檢查,並實作 addOnSpatialEnvironmentChangedListener,以便判斷何時要設定空間環境偏好設定。

為應用程式的空間環境設定 PassthroughOpacityPreference

應用程式沉浸式虛擬背景的其中一個元件是穿透式表面。在這種情況下,顯示的背景是裝置外向攝影機的即時影像。

setPassthroughOpacityPreference 用於設定應用程式的偏好值透視不透明度。此方法只會設定偏好設定,不會立即造成變更,除非有 SpatialCapabilities.SPATIAL_CAPABILITY_PASSTHROUGH_CONTROL 功能。裝置進入可變更穿透式遮罩透明度的狀態,且可使用 SpatialCapabilities.SPATIAL_CAPABILITY_PASSTHROUGH_CONTROL 功能時,系統會自動套用應用程式偏好的穿透式遮罩透明度。

透過式不透明度偏好設定的值範圍從 0.0f (零不透明度,透過式表面不可見) 到 1.0f (完全不透明度,透過式表面會隱藏空間環境)。setPassthroughOpacityPreference 參數為可為空值的浮點值。將值設為空值表示應用程式沒有透過式不透明度偏好設定,並會將透過式控制項傳回至系統。

基本用法

這個程式碼片段會設定透過式不透明度偏好設定。系統會記住這項偏好設定,並在應用程式能夠設定穿透不透明度時套用。

// Assume that session is a Session that has been previously created

val preferenceResult = session.spatialEnvironment.setPassthroughOpacityPreference(1.0f)

if (preferenceResult ==  SpatialEnvironment.SetPassthroughOpacityPreferenceChangeApplied()) {
  // The passthrough opacity request succeeded and should be visible now, and any listeners specified using addOnPassthroughOpacityChangedListener
  // will be notified
} else if (preferenceResult == SpatialEnvironment.SetPassthroughOpacityPreferenceChangePending()) {
  // 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
}

進階用法

針對需要更精細控管穿透式透明度的進階用途,您可以加入 SpatialCapabilities 檢查,並實作 addOnPassthroughOpacityChangedListener,以便決定何時要設定穿透式透明度偏好設定。

素材資源最佳化

建立素材資源以設定使用者的 SpatialEnvironment 時,請務必確保素材資源能達到高品質解析度,同時維持合理的檔案大小。請務必確保 glb 使用 mipmap 和 ktx2 紋理。您也應留意 glb 檔案中的多邊形數量,因為多邊形數量過多可能會導致不必要的耗電量。大多數 SpatialEnvironment 例項的檔案大小,主要來自用於 Skybox 的圖片。為確保圖片經過最佳化處理,請透過最佳化工具 (例如 ktx) 執行素材資源。

判斷目前的穿透不透明度

val currentPassthroughOpacity =  session.spatialEnvironment.getCurrentPassthroughOpacity()

另請參閱