在應用程式中自訂 3D 模型

適用的 XR 裝置
這份指南可協助您為這類 XR 裝置打造體驗。
XR 頭戴式裝置
有線 XR 眼鏡

自訂 3D 模型前,請先將模型新增至應用程式。將 3D 模型新增至應用程式後,即可自訂 3D 模型的外觀和動作,提升視覺和互動體驗。

舉例來說,您可以播放及控制內嵌的 glTF 動畫、存取及移動組成模型的節點,甚至載入自訂紋理並定義材質屬性,以覆寫內部網格。這些功能可讓您在執行階段動態變更物件的外觀和行為。

Android XR 中的 3D 物體

Jetpack XR SDK 支援 Khronos Group 的 glTF 2.0 開放式標準,可處理 3D 模型,並使用 glTF 2.0 標準中指定的以物理為基礎的算繪 (PBR) 技術算繪這些物件 (以及支援的擴充功能)。glTF (圖形媒體庫傳輸格式) 是傳輸及載入 3D 場景和模型的標準檔案格式。glTF 模型是由內部元件的階層式結構組成。

以下是需要瞭解的關鍵元件:

  • 節點:定義模型的結構和階層。每個節點都可以有自己的位置、旋轉和縮放比例。
  • 網格:構成 3D 物件形狀的結構性 3D 幾何圖形。
  • 材質:這些材質定義網格的視覺外觀,例如顏色、粗糙度,或對光線的反應。
  • 紋理:圖片素材資源 (例如 PNG 檔案),可套用至 3D 模型表面,建立自訂圖案、顏色、細節或其他視覺效果。

在 Jetpack Compose for XR 中,您可以使用 SpatialGltfModel 算繪這些檔案,並使用 SpatialGltfModelState 追蹤載入狀態。詳情請參閱「在應用程式中加入 3D 模型」。

操控節點:姿勢和旋轉

如要操控模型的特定部分,並變更旋轉或姿勢等屬性,您需要使用 SpatialGltfModelState 查詢 glTF 模型的內部 nodes

// Retrieve the list of nodes (individual components/meshes) defined within the glTF model.
val entityNodes = modelState.nodes

// Find a specific node by name to apply modifications, such as material overrides.
val node = entityNodes.find { it.name == "node_name" }

找到正確的節點後,您可以設定該節點的 localPose,變更其相對於直接父項 GltfModelNode 的 3D 位置和旋轉角度,或使用 modelPose 設定相對於 GltfModelEntity 根目錄的位置。同樣地,您可以使用 localScale/modelScale 變更模型相對於父項或根項的比例。

LaunchedEffect(node, degrees) {
    val rotation = Quaternion.fromEulerAngles(degrees, 0f, degrees)
    node?.let {
        it.localPose = Pose(it.localPose.translation, rotation)
    }
}

自訂 3D 模型的材質屬性

您可以在執行階段調整材質屬性,根據使用者輸入內容或應用程式的目前狀態,動態變更物件的外觀。

在 Jetpack XR 中,KhronosPbrMaterialKhronosUnlitMaterial 類別用於建立及操控這些材質。顧名思義,KhronosUnlitMaterials 不會發光,也不會受到場景照明影響。KhronosPbrMaterial 可自訂更多屬性,例如光澤顏色、物體金屬感或粗糙程度,以及是否發光。

如要進一步瞭解各項支援的屬性,以及 Android XR 中可自訂的參數,請參閱參考文件。如要進一步瞭解這些屬性,請參閱 Khronos 詞彙表

圖 1. 變更 3D 模型底色的範例。

如要自訂 3D 模型的材質屬性,請先使用 KhronosPbrMaterial 建立新材質。您需要設定適當的 AlphaMode,才能達到所需視覺效果:

接著定義要修改的屬性。這個範例使用 setBaseColorFactor 將網格的基本顏色變更為紫色。這個方法需要 Vector4,其中 x, y, zw 元件分別對應至 RGBA (紅、綠、藍和 Alpha) 值:

// Maintain a reference to the custom material to avoid re-creating it on every recomposition.
var pbrMaterial by remember { mutableStateOf<KhronosPbrMaterial?>(null) }

// Create and apply the custom material once the session is ready and the target node is available.
LaunchedEffect(node) {
    val material = KhronosPbrMaterial.create(
        session = xrSession,
        alphaMode = AlphaMode.OPAQUE
    ).also {
        pbrMaterial = it
        // Apply a base color factor (RGBA) to change the color of the model.
        it.setBaseColorFactor(
            Vector4(
                x = 0.5f,
                y = 0.0f,
                z = 0.5f,
                w = 1.0f
            )
        )
    }

為 3D 模型載入自訂紋理

Texture 是可套用至 3D 模型表面的圖片素材資源,用來提供顏色、細節或其他表面資訊。Jetpack XR Texture API 可讓您從應用程式的 /assets/ 資料夾非同步載入圖片資料,例如 PNG 檔案。

載入紋理時,您可以指定 TextureSampler,藉此控管紋理的算繪方式。取樣器會定義篩選屬性 (紋理顯示大小大於或小於原始大小時) 和包裝模式 (用於處理標準 [0, 1] 範圍外的座標)。Texture 必須指派給 KhronosPbrMaterial,才能對 3D 模型產生視覺效果。

圖 2. 變更 3D 模型紋理的範例。

如要載入自訂紋理,請先將圖片檔儲存到 /assets/ 資料夾。最佳做法是在該資料夾中建立子目錄。textures

將檔案儲存到適當的目錄後,請使用 Texture API 建立紋理。如有需要,您也可以在這裡套用選用的 TextureSampler

這個範例會套用遮蔽紋理,並設定遮蔽強度:

LaunchedEffect(node) {
    val material = KhronosPbrMaterial.create(
        session = xrSession,
        alphaMode = AlphaMode.OPAQUE
    ).also {
        pbrMaterial = it

        // Load a texture
        val texture = Texture.create(
            session = xrSession,
            path = Path("textures/texture_name.png")
        )

        // Set the texture and configure occlusion to define how the material surface handles ambient lighting.
        it.setOcclusionTexture(
            texture = texture,
            strength = 1.0f
        )
    }
    node?.setMaterialOverride(
        material = material
    )
}

為 3D 物件套用材質和紋理

如要套用新材質或紋理,請覆寫 glTF 節點上特定節點的現有材質。請呼叫 setMaterialOverride

node?.setMaterialOverride(
    material = material
)

如要移除新建立的素材資源,請在先前覆寫的節點上呼叫 clearMaterialOverride。這會將 3D 模型還原為預設狀態:

if (removeMaterial) {
    node?.clearMaterialOverride()
}

為 3D 模型製作動畫

3D 模型可以內嵌動畫。在內部,動畫會使用取樣器定義動作的時間和值,並使用通道將這些動作連結至個別節點和網格。Jetpack XR SDK 支援使用 KHR_animation_pointer glTF 擴充功能建立的骨架動畫和材質動畫。

動畫只能使用 SceneCore 的 GltfAnimation 搭配 GltfModelEntity 控制。如要將這個實體新增至 Compose for XR 版面配置,您必須使用 SceneCoreEntity,而不是 SpatialGltfModel

GltfModelEntityanimations 清單中指定特定曲目的名稱。使用 GltfAnimationStartOptions 控制動畫播放。您可以選擇指定速度、搜尋時間,以及動畫是否應循環播放:

val animation = gltfEntity.getAnimations().find { it.name == "Walk" }
animation?.start(GltfAnimationStartOptions(shouldLoop = true))


glTF 和 glTF 標誌是 Khronos Group Inc. 的商標。