Personalizzare i modelli 3D nell'app

Dispositivi XR applicabili
Queste indicazioni ti aiutano a creare esperienze per questi tipi di dispositivi XR.
Visori XR
Occhiali XR con cavo

Prima di personalizzare un modello 3D, devi prima aggiungerlo all'app. Dopo aver aggiunto un modello 3D all'app, puoi migliorare l'esperienza visiva e interattiva personalizzando l'aspetto e il movimento del modello 3D.

Ad esempio, puoi riprodurre e controllare le animazioni glTF incorporate, accedere e spostare i nodi che compongono il modello o persino caricare texture personalizzate e definire le proprietà dei materiali per sostituire le mesh interne. Queste funzionalità ti consentono di modificare dinamicamente l'aspetto e il comportamento di un oggetto in fase di runtime.

Oggetti 3D in Android XR

Jetpack XR SDK supporta lo standard aperto glTF 2.0 di Khronos Group per i modelli 3D ed esegue il rendering di questi oggetti con tecniche di rendering basato sulla fisica (PBR) specificate nello standard glTF 2.0 (insieme alle estensioni supportate). Un file glTF (Graphics Library Transmission Format) è un formato di file standard per la trasmissione e il caricamento di scene e modelli 3D. Un modello glTF è composto da una struttura gerarchica di componenti interni.

Ecco i componenti chiave da comprendere:

  • Nodi: definiscono la struttura e la gerarchia del modello. Ogni nodo può avere la propria posizione, rotazione e scala.
  • Mesh: la geometria 3D strutturale che forma la forma di un oggetto 3D.
  • Materiali: definiscono l'aspetto visivo delle mesh, ad esempio il colore, la rugosità o la reazione all' illuminazione.
  • Texture: una risorsa immagine, ad esempio un file PNG, che puoi applicare alla superficie di un modello 3D per creare pattern, colori, dettagli o altri effetti visivi personalizzati.

In Jetpack Compose per XR, esegui il rendering di questi file utilizzando SpatialGltfModel e monitora lo stato di caricamento utilizzando SpatialGltfModelState. Per ulteriori informazioni, vedi Aggiungere modelli 3D all'app.

Manipolare i nodi: pose e rotazione

Per manipolare parti specifiche di un modello e modificarne le proprietà, come la rotazione o la posa, devi eseguire una query sui nodes interni del modello glTF utilizzando SpatialGltfModelState.

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

Dopo aver trovato il nodo corretto, puoi impostare il relativo localPose per modificarne la posizione e la rotazione 3D rispetto al relativo GltfModelNode padre immediato oppure utilizzare modelPose per impostare la posizione rispetto alla radice GltfModelEntity. Allo stesso modo, puoi utilizzare localScale/modelScale per modificare la scala del modello rispetto al relativo padre o alla radice.

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

Personalizzare le proprietà dei materiali del modello 3D

Puoi modificare gli attributi dei materiali in fase di runtime per cambiare dinamicamente l'aspetto di un oggetto in base all'input dell'utente o allo stato attuale dell'app.

In Jetpack XR, le KhronosPbrMaterial e KhronosUnlitMaterial classi vengono utilizzate per creare e manipolare questi materiali. Come suggerisce il nome, KhronosUnlitMaterials non sono illuminati e non sono influenzati dall'illuminazione della scena. KhronosPbrMaterial ti consente di personalizzare una gamma più ampia di proprietà, come il colore della lucentezza, la metallicità o la rugosità di un oggetto e se emette luce.

Per ulteriori informazioni su ogni proprietà supportata e sui parametri personalizzabili in Android XR, consulta la documentazione di riferimento. Per comprendere meglio queste proprietà, consulta il glossario di Khronos.

Figura 1. Esempio di modifica dei colori di base di un modello 3D.

Per personalizzare le proprietà dei materiali del modello 3D, devi prima creare il nuovo materiale utilizzando KhronosPbrMaterial. Dovrai impostare l'oggetto appropriato AlphaMode per l'aspetto visivo che stai cercando di ottenere:

Poi, definisci le proprietà che vuoi modificare. Questo esempio utilizza setBaseColorFactor per modificare il colore di base della mesh in viola. Questo metodo richiede un Vector4, in cui i componenti x, y, z e w corrispondono rispettivamente ai valori RGBA (rosso, verde, blu e alfa):

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

Caricare texture personalizzate per il modello 3D

Una Texture è una risorsa immagine che puoi applicare alla superficie di un modello 3D per fornire colore, dettagli o altre informazioni sulla superficie. L'API Texture di Jetpack XR ti consente di caricare in modo asincrono i dati delle immagini, ad esempio i file PNG, dalla cartella /assets/ dell'app.

Quando carichi una texture, puoi specificare un TextureSampler, che controlla il rendering della texture. Il campionatore definisce le proprietà di filtro (per quando la texture appare più piccola o più grande delle dimensioni originali) e le modalità di wrapping (per la gestione delle coordinate al di fuori dell'intervallo standard [0, 1] ). A Texture must be assigned to a KhronosPbrMaterial to have a visual effect on a 3D model.

Figura 2. Esempio di modifica della texture di un modello 3D.

Per caricare una texture personalizzata, devi prima salvare il file immagine nella cartella /assets/. Come best practice, potresti anche creare una sottodirectory textures in questa cartella.

Dopo aver salvato il file nella directory appropriata, crea la texture con l'API Texture. Qui puoi anche applicare un TextureSampler facoltativo, se necessario.

Questo esempio applica una texture di occlusione e imposta la forza di occlusione:

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

Applicare materiali e texture agli oggetti 3D

Per applicare il nuovo materiale o la nuova texture, sostituisci il materiale esistente per un nodo specifico sul nodo glTF node. Per farlo, chiama setMaterialOverride:

node?.setMaterialOverride(
    material = material
)

Per rimuovere i materiali appena creati, chiama clearMaterialOverride sul nodo sostituito in precedenza . In questo modo, il modello 3D torna allo stato predefinito:

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

Animare i modelli 3D

I modelli 3D possono avere animazioni incorporate. Internamente, le animazioni utilizzano campionatori per definire i tempi e i valori di un movimento e canali per collegare questi movimenti a singoli nodi e mesh. Le animazioni scheletriche e le animazioni dei materiali create con l' KHR_animation_pointer estensione glTF sono supportate in Jetpack XR SDK.

Le animazioni possono essere controllate solo utilizzando GltfAnimation di SceneCore con un GltfModelEntity. Per aggiungere questa entità a un layout Compose per XR, devi utilizzare un SceneCoreEntity anziché un SpatialGltfModel.

Specifica il nome della traccia specifica da l'elenco di animations in GltfModelEntity. Utilizza GltfAnimationStartOptions per controllare la riproduzione dell'animazione. Se vuoi, puoi specificare la velocità, il tempo di ricerca e se l'animazione deve essere ripetuta:

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


glTF e il logo glTF sono marchi di Khronos Group Inc.