Antes de personalizar um modelo 3D, você precisa primeiro adicioná-lo ao app. Depois de adicionar um modelo 3D ao app, você pode melhorar a experiência visual e interativa personalizando a aparência e o movimento do modelo 3D.
Por exemplo, você pode reproduzir e controlar animações glTF incorporadas, acessar e mover nós que compõem o modelo ou até mesmo carregar texturas personalizadas e definir propriedades de material para substituir malhas internas. Esses recursos permitem alterar dinamicamente a aparência e o comportamento de um objeto durante a execução.
Objetos 3D no Android XR
O SDK do Jetpack XR oferece suporte ao padrão aberto glTF 2.0 do Khronos Group para modelos 3D e renderiza esses objetos com técnicas de renderização baseada em física (PBR) especificadas no padrão glTF 2.0 (junto com extensões compatíveis). Um glTF (Graphics Library Transmission Format) é um formato de arquivo padrão para transmitir e carregar cenas e modelos 3D. Um modelo glTF é composto por uma estrutura hierárquica de componentes internos.
Confira os principais componentes:
- Nós: definem a estrutura e a hierarquia do modelo. Cada nó pode ter sua própria posição, rotação e escala.
- Malhas: a geometria estrutural 3D que forma a forma de um objeto 3D.
- Materiais: definem a aparência visual das malhas, como cor, rugosidade ou como elas reagem à iluminação.
- Texturas: um recurso de imagem, como um arquivo PNG, que pode ser aplicado à superfície de um modelo 3D para criar padrões, cores, detalhes ou outros efeitos visuais personalizados.
No Jetpack Compose para XR, esses arquivos são renderizados usando SpatialGltfModel
e o status de carregamento é rastreado usando um SpatialGltfModelState.
Para mais informações, consulte Adicionar modelos 3D ao app.
Manipular nós: poses e rotação
Para manipular partes específicas de um modelo e mudar as propriedades dele, como rotação ou pose, é necessário consultar os nodes internos do modelo glTF usando 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" }
Depois de encontrar o nó correto, defina o localPose dele para mudar a posição e a rotação 3D
em relação ao pai imediato GltfModelNode ou
use modelPose para definir a posição em relação à
GltfModelEntity raiz. Da mesma forma, é possível usar localScale/modelScale para mudar a escala do modelo em relação ao pai ou à raiz.
LaunchedEffect(node, degrees) { val rotation = Quaternion.fromEulerAngles(degrees, 0f, degrees) node?.let { it.localPose = Pose(it.localPose.translation, rotation) } }
Personalizar as propriedades de material do modelo 3D
É possível ajustar os atributos de material durante a execução para mudar a aparência de um objeto de forma dinâmica com base na entrada do usuário ou no estado atual do app.
No Jetpack XR, as classes KhronosPbrMaterial e KhronosUnlitMaterial
são usadas para criar e manipular esses materiais. Como o nome sugere,
KhronosUnlitMaterials não são iluminados e não são afetados pela iluminação da cena.
KhronosPbrMaterial permite personalizar uma variedade maior de propriedades, como cor de brilho, quão metálico ou áspero um objeto é e se ele emite luz.
Para mais informações sobre cada propriedade compatível e os parâmetros personalizáveis no Android XR, consulte nossa documentação de referência. Para entender melhor estas propriedades, consulte o glossário do Khronos.
Para personalizar as propriedades de material do modelo 3D, primeiro crie o
novo material usando KhronosPbrMaterial. É necessário definir o
adequado AlphaMode para a aparência visual que você está tentando
alcançar:
Em seguida, defina as propriedades que você quer modificar. Este exemplo usa
setBaseColorFactor para mudar a cor de base da malha para roxo. Esse método exige um Vector4, em que os componentes x, y, z e w correspondem aos valores RGBA (vermelho, verde, azul e 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 ) ) }
Carregar texturas personalizadas para o modelo 3D
Um Texture é um recurso de imagem que pode ser aplicado à superfície de um modelo 3D
para fornecer cor, detalhes ou outras informações de superfície. A API Texture do Jetpack XR permite carregar dados de imagem, como arquivos PNG, da pasta /assets/ do app de forma assíncrona.
Ao carregar uma textura, é possível especificar um TextureSampler, que controla
como a textura é renderizada. O sampler define propriedades de filtragem (para quando a textura aparece menor ou maior que o tamanho original) e modos de encapsulamento (para processar coordenadas fora do intervalo padrão [0, 1]). Um Texture precisa
ser atribuído a um KhronosPbrMaterial para ter um efeito visual em um modelo 3D.
Para carregar uma textura personalizada, primeiro salve o arquivo de imagem na pasta /assets/. Como prática recomendada, crie também um subdiretório textures nessa pasta.
Depois de salvar o arquivo no diretório apropriado, crie a textura
com a Texture API. É aqui que você também aplicaria um TextureSampler opcional, se necessário.
Este exemplo aplica uma textura de oclusão e define a intensidade da oclusão:
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 ) }
Aplicar materiais e texturas a objetos 3D
Para aplicar o novo material ou textura, substitua o material existente por um nó específico no nó glTF. Para fazer isso, chame
setMaterialOverride:
node?.setMaterialOverride( material = material )
Para remover os materiais recém-criados, chame clearMaterialOverride no
nó substituído anteriormente. Isso retorna o modelo 3D ao estado padrão:
if (removeMaterial) { node?.clearMaterialOverride() }
Animar modelos 3D
Os modelos 3D podem ter animações incorporadas. Internamente, as animações usam
samplers para definir o tempo e os valores de um movimento e
canais para conectar esses movimentos a nós e
malhas individuais. Animações esqueléticas e animações de material criadas com a
KHR_animation_pointer extensão glTF são
compatíveis com o SDK do Jetpack XR.
As animações só podem ser controladas usando GltfAnimation do SceneCore com
uma GltfModelEntity. Para adicionar essa entidade a um layout do Compose para XR,
use SceneCoreEntity em vez de SpatialGltfModel.
Especifique o nome da faixa específica de
a lista de animations em sua GltfModelEntity. Use
GltfAnimationStartOptions para controlar a reprodução da animação. Se quiser, especifique a velocidade, o tempo de busca e se a animação precisa ser repetida:
val animation = gltfEntity.getAnimations().find { it.name == "Walk" } animation?.start(GltfAnimationStartOptions(shouldLoop = true))
glTF e o logotipo glTF são marcas registradas da Khronos Group Inc.