Material 이란? (UV 좌표 매핑하는 예제 포함) - SmartX-Team/Omniverse GitHub Wiki

image

Omniverse에서 Materials 을 이용하여 Object들의 물리적 특성, 표면 특성 및 빛과의 상호 작용을 지정하여 매우 현실적인 표현을 할 수 있다. Materials는 MDL(Material Definition Language)을 사용하여 지원된다. (MDL은 컴퓨터 그래픽에서 재료의 외관을 정의하고 설명하는 데 특화된 쉐이딩 언어이다.)

Omniverse 상에서 사전에 정의된 다양한 Material Template 들을 제공해준다. (UsdPreviewSurface, OmniPBR, OmniGlass, OmniHair 등.)

UsdPreviewSurface: USD 표준 준수하는 단순하고 직관적인 재료 모델. OmniPBR: 유전체 및 비유전체 재료를 위한 물리 기반 재료. OmniPBR_ClearCoat: 추가적인 광택 레이어 포함, 자동차 페인트 등 용도.

image

[Omniverse Material Template 설명]

OmniPBR 주요 속성 예시

  • Albedo: 재료의 기본 색상
  • Reflectivity: 표면 반사 특성
  • AO (Ambient Occlusion): 음영을 통한 깊이와 디테일을 추가
  • Emissive: 자발적으로 빛을 발하는 특성을 설정 여부
  • Opacity: 재료의 투명도를 제어
  • Normal: 표면의 미세한 디테일을 추가
  • UV: 텍스처 매핑을 위한 UV 좌표 설정을 포함

Material 주요 속성 적용 예시 참고자료

https://docs.omniverse.nvidia.com/materials-and-rendering/latest/materials.html

Material 과 Texture 차이

Material은 물체의 전체적인 외관을 정의하는 고수준 속성 모음이며, Texture는 그 속성 중 일부를 시각적으로 표현하는 이미지 데이터이다. (하나의 Material은 여러 Texture를 포함할 수 있다.)

Texture 을 Prim 이나 Mesh 에 적용하기 위해서는 사전에 UV 좌표가 정의되어야한다.

UV 좌표는 각 메쉬(vertex)에 대해 정의된 (U, V) 값으로, 텍스처 이미지에서의 위치를 나타낸다. (U는 수평 축, V는 수직 축을 의미)

3D 모델의 표면을 펼쳐서 2D 평면으로 변환한 UV 맵을 통해, 각 텍스처 픽셀이 모델의 정확한 위치에 대응하는 방식으로 3D 모델의 표면을 2D 텍스처 이미지에 매핑하는 데 사용되는 좌표 체계이다.

Omniverse 에서 생성한 Prim 이나 Mesh 들은 기본적으로 UV 맵도 설정되지만 일부 다른 소프트웨어로 작업한 결과물을 Connector로 Omnivese 로 불러오는 경우에는 UV 맵 좌표 설정이 안될때가 있다.

실제 AutoCAD로 작업한 3D Model 은 UV 좌표가 매핑되어 있지 않아 Texture 설정이 반영되지 않는 문제가 있었다.

아래는 실제 건물 모델에 UV 매핑하는 예제이다.

해당 작업 이후 정상적으로 Texture 설정이 되는걸 확인할 수 있다.

from pxr import Usd, UsdGeom, Gf, Sdf
from omni.usd import get_context

# USD 스테이지 열기
stage = get_context().get_stage()

# 프림 경로 기본 설정
base_path = "/World/show3/Geometry/show3_13/Default_"

# Mesh_1 부터 Mesh_178 까지 처리
for i in range(1, 179):
    prim_path = f"{base_path}{i}/Mesh_{i}"
    prim = stage.GetPrimAtPath(prim_path)
    
    if prim.IsA(UsdGeom.Mesh):
        mesh = UsdGeom.Mesh(prim)
        points_attr = mesh.GetPointsAttr()
        
        if points_attr:
            points = points_attr.Get()
            num_points = len(points)
            
            print(f"Points (vertices) count for {prim_path}: {num_points}")
            
            # UV 좌표 생성 (각 정점에 대해 기본 사각형 UV 좌표 적용)
            uv_coords = []
            for j in range(0, num_points, 4):
                uv_coords.extend([
                    Gf.Vec2f(0, 0),  # Bottom left
                    Gf.Vec2f(1, 0),  # Bottom right
                    Gf.Vec2f(1, 1),  # Top right
                    Gf.Vec2f(0, 1)   # Top left
                ])
            
            # primvars:st 속성 생성
            uv_set = mesh.CreatePrimvar('primvars:st', Sdf.ValueTypeNames.TexCoord2fArray)
            uv_set.Set(uv_coords)
            uv_set.SetInterpolation('faceVarying')
            
            print(f"primvars:st for {prim_path} set with UV coordinates")
        else:
            print(f"No points attribute found for {prim_path}")
    else:
        print(f"Prim at {prim_path} is not a UsdGeom.Mesh")