Personaliza modelos 3D en tu app

Dispositivos de realidad extendida correspondientes
Esta guía te ayuda a crear experiencias para estos tipos de dispositivos de realidad extendida.
Visores de realidad extendida
Lentes de realidad extendida con cable

Antes de personalizar un modelo 3D, primero debes agregarlo a tu app. Después de agregar un modelo 3D a tu app, puedes mejorar la experiencia visual e interactiva personalizando la apariencia y el movimiento del modelo 3D.

Por ejemplo, puedes reproducir y controlar animaciones glTF integradas, acceder a los nodos que componen tu modelo y moverlos, o incluso cargar texturas personalizadas y definir propiedades de materiales para anular las mallas internas. Estas capacidades te permiten alterar de forma dinámica la apariencia y el comportamiento de un objeto en el tiempo de ejecución.

Objetos 3D en Android XR

El SDK de Jetpack XR admite el estándar abierto glTF 2.0 de Khronos Group para modelos 3D y renderiza estos objetos con técnicas de renderización basada en la física (PBR) especificadas en el estándar glTF 2.0 (junto con las extensiones compatibles). Un glTF (Graphics Library Transmission Format) es un formato de archivo estándar para transmitir y cargar escenas y modelos 3D. Un modelo glTF se compone de una estructura jerárquica de componentes internos.

Estos son los componentes clave que debes comprender:

  • Nodos: Definen la estructura y la jerarquía del modelo. Cada nodo puede tener su propia posición, rotación y escala.
  • Mallas: La geometría estructural en 3D que forma la figura de un objeto 3D.
  • Materiales: Estos definen la apariencia visual de las mallas, como su color, rugosidad o cómo reaccionan a la iluminación.
  • Texturas: Son recursos de imagen, como un archivo PNG, que puedes aplicar a la superficie de un modelo 3D para crear patrones, colores, detalles u otros efectos visuales personalizados.

En Jetpack Compose para XR, renderizas estos archivos con SpatialGltfModel y haces un seguimiento de su estado de carga con un SpatialGltfModelState. Para obtener más información, consulta Cómo agregar modelos 3D a tu app.

Manipula nodos: poses y rotación

Para manipular partes específicas de un modelo y cambiar sus propiedades, como la rotación o la pose, deberás consultar el nodes interno del modelo glTF con 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" }

Después de encontrar el nodo correcto, puedes establecer su localPose para cambiar su posición y rotación en 3D en relación con su elemento superior inmediato GltfModelNode o usar modelPose para establecer la posición en relación con la raíz GltfModelEntity. De manera similar, puedes usar localScale/modelScale para cambiar la escala del modelo en relación con su elemento principal o raíz.

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

Personaliza las propiedades del material de tu modelo en 3D

Puedes ajustar los atributos del material durante el tiempo de ejecución para cambiar la apariencia de un objeto de forma dinámica según la entrada del usuario o el estado actual de la app.

En Jetpack XR, las clases KhronosPbrMaterial y KhronosUnlitMaterial se usan para crear y manipular estos materiales. Como su nombre lo indica, los KhronosUnlitMaterials no tienen iluminación y no se ven afectados por la iluminación de la escena. KhronosPbrMaterial te permite personalizar una mayor variedad de propiedades, como el color del brillo, qué tan metálico o áspero es un objeto y si emite luz.

Para obtener más información sobre cada propiedad admitida y los parámetros personalizables en Android XR, consulta nuestra documentación de referencia. Para comprender mejor estas propiedades, consulta el glosario de Khronos.

Figura 1: Ejemplo de cómo cambiar los colores base en un modelo 3D.

Para personalizar las propiedades del material de tu modelo 3D, primero crearás el nuevo material con KhronosPbrMaterial. Deberás establecer el AlphaMode adecuado para el aspecto visual que deseas lograr:

A continuación, define las propiedades que deseas modificar. En este ejemplo, se usa setBaseColorFactor para cambiar el color base de la malla a púrpura. Este método requiere un Vector4, en el que los componentes x, y, z y w corresponden a los valores RGBA (rojo, verde, azul y alfa) respectivamente:

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

Cómo cargar texturas personalizadas para tu modelo 3D

Una Texture es un recurso de imagen que puedes aplicar a la superficie de un modelo 3D para proporcionar color, detalles o cualquier otra información de la superficie. La API de Jetpack XR Texture te permite cargar datos de imágenes, como archivos PNG, desde la carpeta /assets/ de tu app de forma asíncrona.

Cuando cargas una textura, puedes especificar un TextureSampler, que controla cómo se renderiza la textura. El muestreador define las propiedades de filtrado (para cuando la textura aparece más pequeña o más grande que su tamaño original) y los modos de ajuste (para controlar las coordenadas fuera del rango estándar de [0, 1]). Se debe asignar un Texture a un KhronosPbrMaterial para que tenga un efecto visual en un modelo 3D.

Figura 2: Ejemplo de cómo cambiar la textura de un modelo 3D.

Para cargar una textura personalizada, primero deberás guardar el archivo de imagen en tu carpeta /assets/. Como práctica recomendada, también puedes crear un subdirectorio textures en esa carpeta.

Después de guardar el archivo en el directorio correspondiente, crea la textura con la API de Texture. Aquí también puedes aplicar un TextureSampler opcional si es necesario.

En este ejemplo, se aplica una textura de oclusión y se establece la intensidad de la oclusión:

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

Aplica materiales y texturas a tus objetos 3D

Para aplicar el nuevo material o textura, anula el material existente para un nodo específico en tu archivo glTF. Para ello, llama a setMaterialOverride:

node?.setMaterialOverride(
    material = material
)

Para quitar los materiales recién creados, llama a clearMaterialOverride en el nodo anulado anteriormente. Esto restablecerá el modelo 3D a su estado predeterminado:

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

Anima modelos 3D

Los modelos 3D pueden tener animaciones incorporadas. Internamente, las animaciones usan muestreadores para definir el tiempo y los valores de un movimiento, y canales para conectar esos movimientos a nodos y mallas individuales. Las animaciones esqueléticas y las animaciones de materiales creadas con la KHR_animation_pointer extensión de glTF se admiten en el SDK de Jetpack XR.

Las animaciones solo se pueden controlar con el GltfAnimation de SceneCore con un GltfModelEntity. Para agregar esta entidad a un diseño de Compose para XR, deberás usar un SceneCoreEntity en lugar de un SpatialGltfModel.

Especifica el nombre del segmento específico de la lista de animations en tu GltfModelEntity. Usa GltfAnimationStartOptions para controlar la reproducción de la animación. De manera opcional, puedes especificar la velocidad, el tiempo de búsqueda y si la animación debe repetirse:

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


glTF y el logotipo de glTF son marcas comerciales de Khronos Group Inc.