Dostosowywanie modeli 3D w aplikacji

Obsługiwane urządzenia XR
Te wskazówki pomogą Ci tworzyć aplikacje na te typy urządzeń XR.
Gogle XR
Przewodowe okulary XR

Zanim dostosujesz model 3D, musisz go dodać do aplikacji. Gdy to zrobisz, możesz ulepszyć wrażenia wizualne i interaktywne, dostosowując wygląd i ruch modelu 3D.

Możesz na przykład odtwarzać i sterować osadzonymi animacjami glTF, uzyskiwać dostęp do węzłów tworzących model i przesuwać je, a nawet wczytywać niestandardowe tekstury i definiować właściwości materiałów, aby zastępować wewnętrzne siatki. Te możliwości pozwalają dynamicznie zmieniać wygląd i zachowanie obiektu w czasie działania aplikacji.

Obiekty 3D w Androidzie XR

Jetpack XR SDK obsługuje otwarty standard glTF 2.0 opracowany przez Khronos Group dla modeli 3D i renderuje te obiekty za pomocą technik renderowania opartych na fizyce (PBR) określonych w standardzie glTF 2.0 (wraz z obsługiwanymi rozszerzeniami). glTF (Graphics Library Transmission Format) to standardowy format plików do przesyłania i wczytywania scen i modeli 3D. Model glTF składa się z hierarchicznej struktury komponentów wewnętrznych.

Oto najważniejsze komponenty, które warto poznać:

  • Węzły: definiują strukturę i hierarchię modelu. Każdy węzeł może mieć własne położenie, obrót i skalę.
  • Siatki: strukturalna geometria 3D, która tworzy kształt obiektu 3D.
  • Materiały: definiują wygląd siatek, np. ich kolor, szorstkość lub sposób reagowania na oświetlenie.
  • Tekstury: zasób graficzny, np. plik PNG, który można zastosować na powierzchni modelu 3D, aby utworzyć niestandardowe wzory, kolor, szczegóły lub inne efekty wizualne.

W Jetpack Compose for XR renderujesz te pliki za pomocą SpatialGltfModel i śledzisz stan ich wczytywania za pomocą SpatialGltfModelState. Więcej informacji znajdziesz w artykule Dodawanie modeli 3D do aplikacji.

Manipulowanie węzłami: pozy i obrót

Aby manipulować określonymi częściami modelu i zmieniać jego właściwości, takie jak obrót czy pozy, musisz wysłać zapytanie do wewnętrznych nodes modelu glTF za pomocą 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" }

Gdy znajdziesz odpowiedni węzeł, możesz ustawić jego localPose, aby zmienić jego położenie i obrót 3D względem bezpośredniego elementu nadrzędnego GltfModelNode lub użyć modelPose, aby ustawić położenie względem elementu głównego GltfModelEntity. Podobnie możesz użyć localScale/modelScale, aby zmienić skalę modelu względem jego elementu nadrzędnego lub elementu głównego.

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

Dostosowywanie właściwości materiału modelu 3D

Możesz dostosowywać atrybuty materiału w czasie działania aplikacji, aby dynamicznie zmieniać wygląd obiektu na podstawie danych wejściowych użytkownika lub bieżącego stanu aplikacji.

W Jetpack XR do tworzenia tych materiałów i manipulowania nimi używane są klasy KhronosPbrMaterial i KhronosUnlitMaterial. Jak sama nazwa wskazuje, KhronosUnlitMaterials są nieoświetlone i nie mają na nie wpływu oświetlenie sceny. KhronosPbrMaterial umożliwia dostosowanie szerszego zakresu właściwości, takich jak kolor połysku, stopień metaliczności lub szorstkości obiektu oraz to, czy emituje on światło.

Więcej informacji o każdej obsługiwanej właściwości i parametrach, które można dostosować w Androidzie XR, znajdziesz w naszej dokumentacji referencyjnej. Aby lepiej zrozumieć te właściwości, zapoznaj się ze słownikiem Khronos.

Rysunek 1. Przykład zmiany kolorów podstawowych w modelu 3D.

Aby dostosować właściwości materiału modelu 3D, najpierw utwórz nowy materiał za pomocą KhronosPbrMaterial. Musisz ustawić odpowiedni AlphaMode, aby uzyskać pożądany wygląd:

Następnie zdefiniuj właściwości, które chcesz zmodyfikować. W tym przykładzie używamy setBaseColorFactor, aby zmienić kolor podstawowy siatki na fioletowy. Ta metoda wymaga Vector4, gdzie komponenty x, y, z i w odpowiadają odpowiednio wartościom RGBA (czerwony, zielony, niebieski i 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
            )
        )
    }

Wczytywanie niestandardowych tekstur modelu 3D

Texture to komponent z obrazem, który można zastosować na powierzchni Modelu 3D, aby nadać mu kolor, szczegóły lub inne informacje o powierzchni. Jetpack XR Texture API umożliwia asynchroniczne wczytywanie danych obrazu, np. plików PNG, z folderu /assets/ aplikacji.

Podczas wczytywania tekstury możesz określić TextureSampler, który kontroluje sposób renderowania tekstury. Sampler definiuje właściwości filtrowania (gdy tekstura wydaje się mniejsza lub większa niż jej oryginalny rozmiar) oraz tryby zawijania (do obsługi współrzędnych poza standardowym zakresem [0, 1] ). Aby Texture miało efekt wizualny na modelu 3D , musi być przypisane do KhronosPbrMaterial.

Rysunek 2. Przykład zmiany tekstury w modelu 3D.

Aby wczytać niestandardową teksturę, najpierw musisz zapisać plik obrazu w folderze /assets/. Zalecamy też utworzenie w tym folderze podkatalogu textures.

Gdy zapiszesz plik w odpowiednim katalogu, utwórz teksturę za pomocą Texture API. W razie potrzeby możesz też zastosować opcjonalny TextureSampler.

Ten przykład stosuje teksturę okluzji okluzji i ustawia jej intensywność:

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

Stosowanie materiałów i tekstur do obiektów 3D

Aby zastosować nowy materiał lub teksturę, zastąp dotychczasowy materiał określonego węzła w węźle glTF. Aby to zrobić, wywołaj setMaterialOverride:

node?.setMaterialOverride(
    material = material
)

Aby usunąć nowo utworzone materiały, wywołaj clearMaterialOverride w węźle, który został wcześniej zastąpiony . Spowoduje to przywrócenie domyślnego stanu modelu 3D:

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

Animowanie modeli 3D

Modele 3D mogą mieć osadzone animacje. Wewnętrznie animacje używają samplerów do definiowania czasu i wartości ruchu oraz kanałów do łączenia tych ruchów z poszczególnymi węzłami i siatkami. Jetpack XR SDK obsługuje animacje szkieletowe i animacje materiałów utworzone za pomocą KHR_animation_pointer rozszerzenia glTF są obsługiwane.

Animacje można sterować tylko za pomocą GltfAnimation z GltfModelEntity w SceneCore. Aby dodać ten element do układu Compose for XR, musisz użyć SceneCoreEntity zamiast SpatialGltfModel.

Określ nazwę konkretnej ścieżki z listy animations w GltfModelEntity. Użyj GltfAnimationStartOptions, aby sterować odtwarzaniem animacji. Opcjonalnie możesz określić szybkość, czas wyszukiwania i to, czy animacja ma być odtwarzana w pętli:

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


glTF i logo glTF są znakami towarowymi firmy Khronos Group Inc.