Avant de personnaliser un modèle 3D, vous devez d'abord l'ajouter à votre application. Une fois que vous avez ajouté un modèle 3D à votre application, vous pouvez améliorer l'expérience visuelle et interactive en personnalisant l'apparence et les mouvements du modèle 3D.
Par exemple, vous pouvez lire et contrôler des animations glTF intégrées, accéder aux nœuds qui composent votre modèle et les déplacer, ou même charger des textures personnalisées et définir des propriétés de matériau pour remplacer les maillages internes. Ces fonctionnalités vous permettent de modifier dynamiquement l'apparence et le comportement d'un objet au moment de l'exécution.
Objets 3D dans Android XR
Le SDK Jetpack XR est compatible avec la norme ouverte glTF 2.0 du Khronos Group pour les modèles 3D et effectue le rendu de ces objets à l'aide de techniques de rendu basées sur la physique (PBR) spécifiées dans la norme glTF 2.0 (ainsi que les extensions compatibles). Un glTF (Graphics Library Transmission Format) est un format de fichier standard pour la transmission et le chargement de scènes et de modèles 3D. Un modèle glTF est composé d'une structure hiérarchique de composants internes.
Voici les principaux composants à comprendre :
- Nœuds : ils définissent la structure et la hiérarchie du modèle. Chaque nœud peut avoir sa propre position, sa propre rotation et sa propre échelle.
- Maillages : géométrie 3D structurelle qui forme la forme d'un objet 3D.
- Matériaux : ils définissent l'apparence visuelle des maillages, comme leur couleur, leur rugosité ou leur réaction à l' éclairage.
- Textures : composant Image, tel qu'un fichier PNG, que vous pouvez appliquer à la surface d'un modèle 3D pour créer des motifs, des couleurs, des détails ou d'autres effets visuels personnalisés.
Dans Jetpack Compose pour XR, vous effectuez le rendu de ces fichiers à l'aide de SpatialGltfModel
et suivez leur état de chargement à l'aide de SpatialGltfModelState.
Pour en savoir plus, consultez Ajouter des modèles 3D à votre application.
Manipuler des nœuds : poses et rotation
Pour manipuler des parties spécifiques d'un modèle et modifier ses propriétés telles que la rotation ou la pose, vous devez interroger les nodes internes du modèle glTF à l'aide de 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" }
Une fois que vous avez trouvé le nœud approprié, vous pouvez définir son localPose pour modifier sa position et sa rotation 3D
par rapport à son parent immédiat GltfModelNode ou
utiliser modelPose pour définir la position par rapport à la
GltfModelEntity racine. De même, vous pouvez utiliser localScale/modelScale pour modifier l'échelle du modèle par rapport à son parent ou à sa racine.
LaunchedEffect(node, degrees) { val rotation = Quaternion.fromEulerAngles(degrees, 0f, degrees) node?.let { it.localPose = Pose(it.localPose.translation, rotation) } }
Personnaliser les propriétés de matériau de votre modèle 3D
Vous pouvez ajuster les attributs de matériau au moment de l'exécution pour modifier dynamiquement l'apparence d'un objet en fonction de la saisie de l'utilisateur ou de l'état actuel de l'application.
Dans Jetpack XR, les KhronosPbrMaterial et KhronosUnlitMaterial
classes sont utilisées pour créer et manipuler ces matériaux. Comme leur nom l'indique,
KhronosUnlitMaterials ne sont pas éclairés et ne sont pas affectés par l'éclairage de la scène.
KhronosPbrMaterial vous permet de personnaliser un plus large éventail de propriétés, telles que la couleur de brillance, le caractère métallique ou rugueux d'un objet, et s'il émet de la lumière.
Pour en savoir plus sur chaque propriété compatible et les paramètres personnalisables dans Android XR, consultez notre documentation de référence. Pour mieux comprendre ces propriétés, consultez le glossaire Khronos.
Pour personnaliser les propriétés de matériau de votre modèle 3D, vous devez d'abord créer le
nouveau matériau à l'aide de KhronosPbrMaterial. Vous devez définir le
approprié AlphaMode pour l'apparence visuelle que vous essayez d'obtenir
:
Définissez ensuite les propriétés que vous souhaitez modifier. Cet exemple utilise
setBaseColorFactor pour remplacer la couleur de base du maillage par du violet. Cette méthode nécessite un Vector4, où les composants x, y, z et w correspondent respectivement aux valeurs RGBA (rouge, vert, bleu et 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 ) ) }
Charger des textures personnalisées pour votre modèle 3D
Une Texture est un composant Image que vous pouvez appliquer à la surface d'un modèle 3D pour fournir des informations sur la couleur, les détails ou d'autres informations de surface. L'API Jetpack XR Texture vous permet de charger des données d'image, telles que des fichiers PNG, à partir du dossier /assets/ de votre application de manière asynchrone.
Lorsque vous chargez une texture, vous pouvez spécifier un TextureSampler, qui contrôle
la façon dont la texture est rendue. L'échantillonneur définit les propriétés de filtrage (lorsque la texture apparaît plus petite ou plus grande que sa taille d'origine) et les modes d'habillage (pour gérer les coordonnées en dehors de la plage [0, 1] standard). Un Texture doit
être attribué à un KhronosPbrMaterial pour avoir un effet visuel sur un modèle 3D.
Pour charger une texture personnalisée, vous devez d'abord enregistrer le fichier image dans votre dossier /assets/. Il est recommandé de créer également un sous-répertoire textures dans ce dossier.
Une fois le fichier enregistré dans le répertoire approprié, créez la texture
avec l'API Texture. C'est également là que vous appliquerez un TextureSampler facultatif si nécessaire.
Cet exemple applique une texture d'occlusion et définit la force d'occlusion :
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 ) }
Appliquer des matériaux et des textures à vos objets 3D
Pour appliquer le nouveau matériau ou la nouvelle texture, remplacez le matériau existant pour un
nœud spécifique de votre glTF nœud. Pour ce faire, appelez
setMaterialOverride :
node?.setMaterialOverride( material = material )
Pour supprimer les matériaux que vous venez de créer, appelez clearMaterialOverride sur le
nœud précédemment remplacé. Votre modèle 3D revient alors à son état par défaut :
if (removeMaterial) { node?.clearMaterialOverride() }
Animer des modèles 3D
Les modèles 3D peuvent contenir des animations intégrées. En interne, les animations utilisent
des échantillonneurs pour définir la durée et les valeurs d'un mouvement, et
des canaux pour connecter ces mouvements à des nœuds et
des maillages individuels. Les animations squelettiques et les animations de matériau créées avec l'
KHR_animation_pointer extension glTF sont
compatibles avec le SDK Jetpack XR.
Les animations ne peuvent être contrôlées qu'à l'aide de GltfAnimation de SceneCore avec
un GltfModelEntity. Pour ajouter cette entité à une mise en page Compose pour XR,
vous devez utiliser un SceneCoreEntity au lieu d'un SpatialGltfModel.
Spécifiez le nom de la piste spécifique dans
la liste des animations de votre GltfModelEntity. Utilisez
GltfAnimationStartOptions pour contrôler la lecture de l'animation. Vous pouvez éventuellement spécifier la vitesse, le temps de recherche et si l'animation doit être répétée :
val animation = gltfEntity.getAnimations().find { it.name == "Walk" } animation?.start(GltfAnimationStartOptions(shouldLoop = true))
glTF et le logo glTF sont des marques de the Khronos Group Inc.