3D 모델을 맞춤설정하려면 먼저 앱에 추가해야 합니다. 앱에 3D 모델을 추가한 후 3D 모델의 모양과 움직임을 맞춤설정하여 시각적 및 대화형 환경을 개선할 수 있습니다.
예를 들어 삽입된 glTF 애니메이션을 재생하고 제어하거나, 모델을 구성하는 노드에 액세스하고 이동하거나, 맞춤 텍스처를 로드하고 소재 속성을 정의하여 내부 메시를 재정의할 수도 있습니다. 이러한 기능을 사용하면 런타임에 객체의 모양과 동작을 동적으로 변경할 수 있습니다.
Android XR의 3D 객체
Jetpack XR SDK는 3D 모델을 위해 Khronos Group의 glTF 2.0 개방형 표준을 지원하며, glTF 2.0 표준에 지정된 물리 기반 렌더링 (PBR) 기법 (지원되는 확장 프로그램과 함께)으로 이러한 객체를 렌더링합니다. glTF (그래픽 라이브러리 전송 형식)는 3D 장면과 모델을 전송하고 로드하는 표준 파일 형식입니다. glTF 모델은 내부 구성요소의 계층 구조로 구성됩니다.
이해해야 할 주요 구성요소는 다음과 같습니다.
- 노드: 모델의 구조와 계층 구조를 정의합니다. 각 노드는 자체 위치, 회전, 크기를 가질 수 있습니다.
- 메시: 3D 객체의 모양을 형성하는 구조적 3D 지오메트리입니다.
- 재질: 색상, 거칠기, 조명에 대한 반응 등 메시의 시각적 모양을 정의합니다.
- 텍스처: 3D 모델의 노출 영역에 적용하여 맞춤 패턴, 색상, 세부정보 또는 기타 시각적 효과를 만들 수 있는 이미지 애셋(예: PNG 파일)입니다.
- 애니메이션: 시간 경과에 따른 움직임의 모양을 만들기 위해 개별 노드와 메시의 변경사항을 포함하는 사전 정의된 시퀀스 또는 애니메이션 트랙입니다.
XR용 Jetpack Compose에서는 SpatialGltfModel를 사용하여 이러한 파일을 렌더링하고 SpatialGltfModelState를 사용하여 로드 및 애니메이션 상태를 추적합니다.
자세한 내용은 앱에 3D 모델 추가를 참고하세요.
3D 모델 애니메이션
3D 모델에는 애니메이션이 포함될 수 있습니다. 내부적으로 애니메이션은 샘플러를 사용하여 움직임의 타이밍과 값을 정의하고 채널을 사용하여 이러한 움직임을 개별 노드와 메시로 연결합니다. KHR_animation_pointer glTF 확장 프로그램으로 만든 스켈레톤 애니메이션과 Material 애니메이션은 Jetpack XR SDK에서 지원됩니다.
Compose for XR을 사용하여 애니메이션을 재생하려면 animations 목록에서 특정 트랙의 이름을 지정합니다. animation.start()을 사용하여 재생을 시작합니다. 선택적으로 SpatialGltfModelAnimation를 사용하여 속도, 탐색 시간, 애니메이션 반복 여부를 지정할 수 있습니다.
val animation = modelState.animations.find { it.name == "Walk" } animation?.animationState?.let { state -> LaunchedEffect(state) { Log.i("SpatialGltfModelAnimationSample", "Animation State: $state") } } DisposableEffect(animation) { animation?.loop() onDispose { animation?.stop() } }
노드 조작: 포즈 및 회전
모델의 특정 부분을 조작하고 회전이나 포즈와 같은 속성을 변경하려면 SpatialGltfModelState를 사용하여 glTF 모델의 내부 nodes를 쿼리해야 합니다.
// 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" }
올바른 노드를 찾은 후 localPose를 설정하여 직계 상위 GltfModelNode에 대한 3D 위치와 회전을 변경하거나 modelPose를 사용하여 GltfModelEntity 루트에 대한 위치를 설정할 수 있습니다. 마찬가지로 localScale/modelScale을 사용하여 상위 요소 또는 루트를 기준으로 모델의 크기를 변경할 수 있습니다.
LaunchedEffect(node, degrees) { val rotation = Quaternion.fromEulerAngles(degrees, 0f, degrees) node?.let { it.localPose = Pose(it.localPose.translation, rotation) } }
3D 모델의 소재 속성 맞춤설정
런타임 중에 소재 속성을 조정하여 사용자 입력 또는 앱의 현재 상태에 따라 객체의 모양을 동적으로 변경할 수 있습니다.
Jetpack XR에서 KhronosPbrMaterial 및 KhronosUnlitMaterial 클래스는 이러한 소재를 만들고 조작하는 데 사용됩니다. 이름에서 알 수 있듯이 KhronosUnlitMaterials는 조명이 꺼져 있고 장면 조명의 영향을 받지 않습니다.
KhronosPbrMaterial을 사용하면 광택 색상, 객체의 금속성 또는 거칠기, 빛을 내는지 여부 등 다양한 속성을 맞춤설정할 수 있습니다.
지원되는 각 속성과 Android XR의 맞춤설정 가능한 매개변수에 관한 자세한 내용은 참조 문서를 참고하세요. 이러한 속성을 더 잘 이해하려면 Khronos 용어집을 참고하세요.

3D 모델의 소재 속성을 맞춤설정하려면 먼저 KhronosPbrMaterial을 사용하여 새 소재를 만듭니다. 원하는 시각적 효과에 맞게 적절한 AlphaMode를 설정해야 합니다.
다음으로 수정할 속성을 정의합니다. 이 예에서는 setBaseColorFactor를 사용하여 메시의 기본 색상을 보라색으로 변경합니다. 이 메서드에는 Vector4이 필요하며, 여기서 x, y, z 및 w 구성요소는 각각 RGBA (빨강, 녹색, 파랑, 알파) 값에 해당합니다.
// 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 ) ) }
3D 모델의 맞춤 텍스처 로드
Texture는 3D 모델의 표면에 적용하여 색상, 세부정보 또는 기타 표면 정보를 제공할 수 있는 이미지 애셋입니다. Jetpack XR 텍스처 API를 사용하면 앱의 /assets/ 폴더에서 PNG 파일과 같은 이미지 데이터를 비동기적으로 로드할 수 있습니다.
텍스처를 로드할 때 텍스처가 렌더링되는 방식을 제어하는 TextureSampler를 지정할 수 있습니다. 샘플러는 필터링 속성(텍스처가 원래 크기보다 작거나 크게 표시되는 경우)과 래핑 모드(표준 [0, 1] 범위를 벗어난 좌표 처리)를 정의합니다. 3D 모델에 시각적 효과를 적용하려면 Texture를 KhronosPbrMaterial에 할당해야 합니다.
맞춤 텍스처를 로드하려면 먼저 이미지 파일을 /assets/ 폴더에 저장해야 합니다. 권장사항으로 해당 폴더에 textures 하위 디렉터리를 만드는 것이 좋습니다.
적절한 디렉터리에 파일을 저장한 후 Texture API를 사용하여 텍스처를 만듭니다. 필요한 경우 선택사항인 TextureSampler도 여기에 적용합니다.
이 예에서는 폐색 텍스처를 적용하고 폐색 강도를 설정합니다.
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 ) }
3D 객체에 소재 및 텍스처 적용
새 소재나 텍스처를 적용하려면 glTF 노드의 특정 노드에 대한 기존 소재를 재정의하세요. setMaterialOverride을 호출하면 됩니다.
node?.setMaterialOverride( material = material )
새로 생성된 재질을 삭제하려면 이전에 재정의된 노드에서 clearMaterialOverride를 호출합니다. 이렇게 하면 3D 모델이 기본 상태로 돌아갑니다.
if (removeMaterial) { node?.clearMaterialOverride() }
glTF 및 glTF 로고는 Khronos Group Inc.의 상표입니다.