3D-Modelle in Ihrer App anpassen

XR‑Geräte, für die der Leitfaden gilt
Dieser Leitfaden hilft Ihnen dabei, Erlebnisse für die folgenden Arten von XR-Geräten zu entwickeln.
XR-Headsets
XR-Brille mit Kabel

Bevor Sie ein 3D-Modell anpassen können, müssen Sie es zuerst in Ihre App einfügen. Nachdem Sie ein 3D-Modell in Ihre App eingefügt haben, können Sie die visuellen und interaktiven Elemente verbessern, indem Sie das Aussehen und die Bewegungen des 3D-Modells anpassen.

Sie können beispielsweise eingebettete glTF-Animationen abspielen und steuern, auf Knoten zugreifen und sie verschieben, aus denen Ihr Modell besteht, oder sogar benutzerdefinierte Texturen laden und Materialeigenschaften definieren, um interne Meshes zu überschreiben. Mit diesen Funktionen können Sie das Aussehen und Verhalten eines Objekts zur Laufzeit dynamisch ändern.

3D-Objekte in Android XR

Das Jetpack XR-SDK unterstützt den offenen Standard glTF 2.0 der Khronos Group für 3D‑Modelle und rendert diese Objekte mit physikalisch basierten Rendering-Techniken (PBR), die im glTF 2.0-Standard (zusammen mit unterstützten Erweiterungen) angegeben sind. glTF (Graphics Library Transmission Format) ist ein Standarddateiformat für die Übertragung und das Laden von 3D-Szenen und ‑Modellen. Ein glTF-Modell besteht aus einer hierarchischen Struktur interner Komponenten.

Hier sind die wichtigsten Komponenten:

  • Knoten: Sie definieren die Struktur und Hierarchie des Modells. Jeder Knoten kann seine eigene Position, Drehung und Skalierung haben.
  • Meshes: Die strukturelle 3D-Geometrie, die die Form eines 3D-Objekts bildet.
  • Materialien: Diese definieren das visuelle Erscheinungsbild der Meshes, z. B. ihre Farbe, Rauheit oder wie sie auf die Beleuchtung reagieren.
  • Texturen: Ein Bild-Asset, z. B. eine PNG-Datei, das Sie auf die Oberfläche eines 3D-Modells anwenden können, um benutzerdefinierte Muster, Farben, Details oder andere visuelle Effekte zu erstellen.
  • Animationen: Das sind vordefinierte Sequenzen oder Animations-Tracks, die Änderungen an einzelnen Knoten und Meshes enthalten, um den Eindruck von Bewegung im Zeitverlauf zu erzeugen.

In Jetpack Compose XR rendern Sie diese Dateien mit SpatialGltfModel und verfolgen den Lade- und Animationsstatus mit einem SpatialGltfModelState. Weitere Informationen finden Sie unter 3D-Modelle in Ihre App einfügen.

3D-Modelle animieren

3D-Modelle können eingebettete Animationen enthalten. Intern werden für Animationen Samplers verwendet, um das Timing und die Werte einer Bewegung zu definieren, und Channels, um diese Bewegungen mit einzelnen Knoten und Meshes zu verbinden. Skelett- und Materialanimationen, die mit der KHR_animation_pointer glTF-Erweiterung erstellt wurden, werden im Jetpack XR SDK unterstützt.

Wenn Sie mit Compose for XR eine Animation abspielen möchten, geben Sie den Namen des jeweiligen Tracks aus der Liste der animations an. Verwende animation.start(), um mit dem Spielen zu beginnen. Optional können Sie mit SpatialGltfModelAnimation die Geschwindigkeit, die Suchzeit und die Frage angeben, ob die Animation wiederholt werden soll:

val animation = modelState.animations.find { it.name == "Walk" }

animation?.animationState?.let { state ->
    LaunchedEffect(state) {
        Log.i("SpatialGltfModelAnimationSample", "Animation State: $state")
    }
}

DisposableEffect(animation) {
    animation?.loop()
    onDispose {
        animation?.stop()
    }
}

Knoten bearbeiten: Posen und Drehung

Wenn Sie bestimmte Teile eines Modells bearbeiten und seine Eigenschaften wie Drehung oder Pose ändern möchten, müssen Sie die interne nodes des glTF-Modells mit SpatialGltfModelState abfragen.

// 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" }

Nachdem Sie den richtigen Knoten gefunden haben, können Sie seine localPose festlegen, um seine 3D-Position und ‑Drehung relativ zum übergeordneten GltfModelNode zu ändern, oder modelPose verwenden, um die Position relativ zum GltfModelEntity-Stamm festzulegen. Ebenso können Sie mit „localScale“/„modelScale“ die Skalierung des Modells relativ zum übergeordneten Element oder Stamm ändern.

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

Materialeigenschaften Ihres 3D-Modells anpassen

Sie können Materialattribute zur Laufzeit anpassen, um das Erscheinungsbild eines Objekts dynamisch basierend auf Nutzereingaben oder dem aktuellen Status der App zu ändern.

In Jetpack XR werden die Klassen KhronosPbrMaterial und KhronosUnlitMaterial verwendet, um diese Materialien zu erstellen und zu bearbeiten. Wie der Name schon sagt, sind KhronosUnlitMaterials unbeleuchtet und werden nicht von der Szenenbeleuchtung beeinflusst. Mit KhronosPbrMaterial können Sie eine größere Auswahl an Eigenschaften anpassen, z. B. die Farbe des Glanzes, wie metallisch oder rau ein Objekt ist und ob es Licht aussendet.

Weitere Informationen zu den einzelnen unterstützten Eigenschaften und den anpassbaren Parametern in Android XR finden Sie in unserer Referenzdokumentation. Weitere Informationen zu diesen Attributen finden Sie im Khronos-Glossar.

Abbildung 1. Beispiel für das Ändern der Grundfarben eines 3D-Modells.

Wenn Sie die Materialeigenschaften Ihres 3D-Modells anpassen möchten, erstellen Sie zuerst das neue Material mit KhronosPbrMaterial. Sie müssen die entsprechende AlphaMode für das gewünschte Erscheinungsbild festlegen:

Definieren Sie als Nächstes die Eigenschaften, die Sie ändern möchten. In diesem Beispiel wird setBaseColorFactor verwendet, um die Grundfarbe des Mesh in Lila zu ändern. Für diese Methode ist ein Vector4 erforderlich, wobei die Komponenten x, y, z und w den RGBA-Werten (Rot, Grün, Blau und Alpha) entsprechen:

// 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
            )
        )
    }

Benutzerdefinierte Texturen für Ihr 3D-Modell laden

Eine Texture ist ein Bild-Asset, das Sie auf die Oberfläche eines 3D-Modells anwenden können, um Farbe, Details oder andere Oberflächeninformationen bereitzustellen. Mit der Jetpack XR Texture API können Sie Bilddaten wie PNG-Dateien asynchron aus dem Ordner /assets/ Ihrer App laden.

Beim Laden einer Textur können Sie einen TextureSampler angeben, der bestimmt, wie die Textur gerendert wird. Der Sampler definiert Filterungseigenschaften (für den Fall, dass die Textur kleiner oder größer als ihre Originalgröße angezeigt wird) und Wrapping-Modi (für die Verarbeitung von Koordinaten außerhalb des Standardbereichs [0, 1]). Ein Texture muss einem KhronosPbrMaterial zugewiesen werden, damit es einen visuellen Effekt auf ein 3D-Modell hat.

Abbildung 2: Beispiel für das Ändern der Textur eines 3D-Modells.

Wenn Sie eine benutzerdefinierte Textur laden möchten, müssen Sie die Bilddatei zuerst im Ordner /assets/ speichern. Als Best Practice sollten Sie in diesem Ordner auch ein textures-Unterverzeichnis erstellen.

Nachdem Sie die Datei im entsprechenden Verzeichnis gespeichert haben, erstellen Sie die Textur mit der Texture API. Hier können Sie bei Bedarf auch ein optionales TextureSampler anwenden.

In diesem Beispiel wird eine Okklusionstextur angewendet und die Okklusionsstärke festgelegt:

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
    )
}

Materialien und Texturen auf 3D-Objekte anwenden

Wenn Sie das neue Material oder die neue Textur anwenden möchten, überschreiben Sie das vorhandene Material für einen bestimmten Knoten in Ihrem glTF-Knoten. Rufen Sie dazu setMaterialOverride auf:

node?.setMaterialOverride(
    material = material
)

Rufen Sie clearMaterialOverride für den zuvor überschriebenen Knoten auf, um die neu erstellten Materialien zu entfernen. Dadurch wird das 3D-Modell auf den Standardzustand zurückgesetzt:

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


glTF und das glTF-Logo sind Marken der Khronos Group Inc.