アプリで 3D モデルをカスタマイズする

対応する XR デバイス
このガイダンスは、次のようなタイプの XR デバイス向けのエクスペリエンスを構築する際に役立ちます。
[
XR Headsets
]
有線 XR グラス

3D モデルをカスタマイズする前に、まずアプリに追加する必要があります。 3D モデルをアプリに追加したら、3D モデルの外観と動きをカスタマイズして、視覚的および インタラクティブなエクスペリエンスを強化できます。

たとえば、埋め込まれた glTF アニメーションを再生して制御したり、モデルを構成するノードにアクセスして移動したり、カスタム テクスチャを読み込んでマテリアル プロパティを定義して内部メッシュをオーバーライドしたりできます。これらの機能を使用すると、実行時にオブジェクトの外観と動作を動的に変更できます。

Android XR の 3D オブジェクト

Jetpack XR SDK は、Khronos Group の glTF 2.0 オープン スタンダードを 3D モデルでサポートし、glTF 2.0 標準(サポートされている 拡張機能 を含む)で指定された 物理ベース レンダリング(PBR) 手法を使用して これらのオブジェクトをレンダリングします。glTF(Graphics Library Transmission Format)は、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 では、KhronosPbrMaterial クラスと KhronosUnlitMaterial クラスを使用して、これらのマテリアルを作成して操作します。名前が示すように、 KhronosUnlitMaterials は照明がなく、シーンの照明の影響を受けません。 KhronosPbrMaterial を使用すると、光沢の色、オブジェクトの金属感や粗さ、発光するかどうかなど、幅広いプロパティをカスタマイズできます。

サポートされている各プロパティと Android XR でカスタマイズ可能な パラメータについて詳しくは、リファレンス ドキュメントをご覧ください。これらのプロパティについて詳しくは、Khronos 用語集をご覧ください。

図 1.3D モデルの基本色を変更する例。

3D モデルのマテリアル プロパティをカスタマイズするには、まず 新しいマテリアルを KhronosPbrMaterial を使用して作成します。実現しようとしている視覚的な外観に合わせて 適切な AlphaMode を設定する必要があります。

次に、変更するプロパティを定義します。この例では、 setBaseColorFactor を使用してメッシュの基本色を紫に変更します。このメソッドには Vector4 が必要です。x, y, z コンポーネントと w コンポーネントは、それぞれ RGBA(赤、緑、青、アルファ)の値に対応しています。

// 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 を使用すると、PNG ファイルなどの画像データをアプリの /assets/ フォルダから非同期で読み込むことができます。

テクスチャを読み込むときに、テクスチャのレンダリング方法を制御するTextureSamplerを指定できます。サンプラーは、フィルタリング プロパティ(テクスチャが元のサイズより小さく表示される場合や大きく表示される場合)とラッピング モード(標準の [0, 1] 範囲外の座標を処理する場合)を定義します。TextureKhronosPbrMaterial に割り当てて、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 node の特定のノードの既存のマテリアルをオーバーライドします。これを行うには、 setMaterialOverride を呼び出します。

node?.setMaterialOverride(
    material = material
)

新しく作成したマテリアルを削除するには、clearMaterialOverrideを 以前にオーバーライドしたノードで呼び出します。これにより、3D モデルがデフォルトの状態に戻ります。

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

3D モデルをアニメーション化する

3D モデルにはアニメーションを埋め込むことができます。内部的には、アニメーションは サンプラーを使用して動きのタイミングと値を定義し、 チャンネルを使用してそれらの動きを個々のノードと メッシュに接続します。Jetpack XR SDK では、 KHR_animation_pointer glTF 拡張機能で作成されたスケルトン アニメーションとマテリアル アニメーションが サポートされています。

アニメーションは、SceneCore の GltfAnimationGltfModelEntity を使用してのみ制御できます。このエンティティを Compose for XR レイアウトに追加するには、 SpatialGltfModel ではなく SceneCoreEntity を使用する必要があります。

GltfModelEntityanimations のリストから、特定のトラックの名前を指定します。 GltfAnimationStartOptions を使用して、アニメーションの再生を制御します。必要に応じて、速度、シーク時間、アニメーションをループさせるかどうかを指定できます。

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


glTF と glTF のロゴは、 Khronos Group Inc. の商標です。