제10부 시뮬레이션·디지털트윈·피지컬 AI
10.3 OpenUSD I — Stage·Prim·Layer
10.3.1 이 장에서 배우는 것 / 선수 지식
9.11~10.2에서 Isaac Sim·Omniverse의 모든 것 — 씬·협업(Nucleus)·렌더(RTX)·연결(커넥터) — 이 USD 위에 선다고 반복했다. "USD가 접착제"라고만 하고 미뤘던 그 USD 자체의 데이터 모델을 이제 판다. OpenUSD(Universal Scene Description) 는 픽사가 만든 3D 씬을 기술하고 구성하는 오픈 표준이고, 그 핵심 자료구조가 Stage(합성된 씬)·Prim(객체 노드)·Layer(저장·합성 단위) 다. 이 셋을 이해하면 "왜 Omniverse·로봇 시뮬·디지털트윈이 USD 위에 서는가"가 데이터 모델 차원에서 보인다. 컴포지션의 깊은 메커니즘(참조·변형·상속 등)은 10.4.
핵심 통찰: USD는 "파일 포맷"이 아니라 "비파괴적 합성(non-destructive composition)을 위한 씬 데이터베이스"다. USD의 실질적 힘은 메시·라이트를 담는 것이 아니라, 여러 레이어(layer)의 "의견(opinion)"을 비파괴적으로 겹쳐 하나의 씬(Stage)으로 합성하는 데 있다. 베이스 씬은 건드리지 않고 더 강한 레이어에서 덮어쓰기(override)만 한다 — 그래서 여럿이 같은 씬을 동시에 편집해도(Nucleus 협업 10.2) 서로의 작업을 안 깨고, 도메인 랜덤화(9.14)가 베이스를 보존한 채 변형을 오버레이하고, 디지털트윈이 설계 위에 운영 데이터를 겹친다. Stage는 결과(합성된 씬), Layer는 재료(의견의 묶음), Prim은 그 안의 객체. 이 분리가 USD가 협업·시뮬·트윈의 토대가 된 이유다.
배우는 것:
- OpenUSD란 — 씬을 기술·구성하는 오픈 표준(픽사·AOUSD), 왜 Omniverse·로봇이 그 위에.
- Stage — 레이어들을 합성한 결과인 씬그래프(작업·질의·편집 대상).
- Prim — 씬의 노드(경로·타입(스키마)·계층) — 메시·라이트·Xform·로봇.
- 속성 — Attribute(타입 있는 값·타임샘플=애니메이션)·Relationship(다른 프림 가리킴).
- Layer — 저장·합성의 단위, 오피니언·비파괴 오버라이드·
.usda/.usdc. 협업(10.2)·랜덤화(9.14)의 근거.
선수 지식: 10.1·10.2(Omniverse·Nucleus — USD가 그 토대)·9.11(USD 씬·아티큘레이션)·9.14(도메인 랜덤화 — 레이어 오버라이드). 컴포지션 아크(참조·페이로드·변형·상속·특수화·서브레이어 — LIVRPS)의 심화는 10.4, 합성데이터는 10.5, 디지털트윈은 10.8. 씬그래프·계층 구조 개념은 가정(BK-02).
정직: USD는 픽사 발 오픈소스·오픈 표준(AOUSD — NVIDIA·픽사·어도비·애플·오토데스크 등) 으로, NVIDIA 전유물이 아니다(여러 도구가 USD 지원, 10.2). API(
pxr.Usd·UsdGeom등)는 비교적 안정적이나 버전·스키마 확장은 의존이 있다. 이 장은 "USD 데이터 모델의 구조·원리(Stage/Prim/Layer·비파괴 합성)"를 가르치고, 구체 스키마·API·확장은 "그 버전 USD 문서로 확인". 코드(.usda·pxr)는 개념 골격이되 USD API는 실제와 가깝게 둔다. 컴포지션의 강도 규칙(LIVRPS) 등 깊은 부분은 10.4로 미룬다.
10.3.2 OpenUSD란 — 씬을 기술·구성하는 오픈 표준
OpenUSD는 단순한 3D 파일 포맷(FBX·OBJ 같은)이 아니라 씬을 기술(describe)하고 구성(compose)하는 시스템이다.
USD가 다른 포맷과 다른 점:
전통 포맷(FBX·OBJ·glTF): "씬 하나를 한 파일에 일괄 직렬화"
· 하나의 묶음, 편집은 파괴적(원본 수정), 협업·재사용·오버라이드 어려움
USD: "여러 레이어의 의견을 비파괴적으로 합성해 씬을 만든다"
· 씬 = 레이어들의 합성 결과(Stage)
· 베이스는 그대로, 더 강한 레이어에서 덮어쓰기(override)
· 참조(reference)로 자산 재사용, 변형(variant)으로 옵션(10.4)
· 대규모·협업·비파괴·상호운용
왜 픽사가 만들었나: 영화 한 씬에 수백 아티스트·수만 자산이
동시에·비파괴적으로·재사용하며 작업해야 → 합성 시스템이 필요
- 합성(composition) 시스템: USD의 본질은 여러 출처(레이어)의 씬 기술을 규칙대로 합쳐 하나의 씬을 만드는 것. 이것이 "기술 + 구성"이고, 단순 포맷과의 결정적 차이(심화 10.4).
- 비파괴(non-destructive): 자산·베이스 씬을 수정하지 않고 다른 레이어에서 변경을 오버레이한다 — 영화에서 라이팅 팀이 모델 팀의 자산을 안 건드리고 조명만 바꾸듯. 협업·재사용·실험의 핵심.
- 왜 Omniverse·로봇이 USD 위에(10.1·10.2): ① 협업(Nucleus) — 여럿이 비파괴적으로 동시 편집 ② 상호운용 — 도구 간 공통 언어(커넥터 10.2) ③ 재사용·스케일 — 자산 참조·대규모 씬 ④ 시뮬·트윈 — 같은 씬을 설계·시뮬·운영이 공유. 이 모두가 USD의 합성 모델 덕.
- 오픈 표준(정직): USD는 픽사 발 오픈소스이고 AOUSD(Alliance for OpenUSD) 로 표준화(NVIDIA·픽사·어도비·애플·오토데스크 등) — NVIDIA 고유가 아니라 업계 공통. Omniverse는 USD를 잘 구현·확장한 플랫폼일 뿐(10.2).
핵심: USD는 파일 포맷이 아니라 씬을 기술·합성하는 시스템이다 — 여러 레이어의 의견을 비파괴적으로 합성해 씬을 만든다(베이스 보존·오버라이드·재사용). 픽사가 대규모 협업 영화 제작을 위해 만들었고, 그 합성 모델이 Omniverse·로봇 시뮬·트윈(10.1·10.2·10.8)의 토대. 오픈 표준(AOUSD) — NVIDIA 전유물 아님.
10.3.3 Stage — 합성된 씬
Stage(스테이지) 는 USD에서 작업하는 씬 — 여러 레이어를 합성한 결과인 씬그래프다.
Stage는 '최종 합성된 뷰'로 우리가 질의·편집·렌더하는 대상이다. 같은 레이어를 합성하면 같은 Stage(재현)이고, Stage를 통해 Prim을 순회·읽기·쓰기한다(쓰면 특정 레이어에 기록).
- Stage = 결과, Layer = 재료: Stage는 직접 저장되는 것이 아니라, 레이어들을 합성한 런타임 뷰다. 레이어(파일)를 열어 합성하면 Stage가 생긴다 —
Usd.Stage.Open("root.usda"). - 씬그래프: Stage는 Prim의 계층 트리(씬그래프)다 —
/World/Robot/Arm같은 경로로 객체를 가리킨다. 순회·질의·편집은 Stage를 통해. - 편집은 어느 레이어에?: Stage에 변경을 쓰면 현재 편집 대상 레이어(edit target) 에 기록된다 — 기본은 루트 레이어, 바꾸면 다른 레이어에. 이것이 "베이스는 두고 오버라이드 레이어에 쓰기"의 메커니즘(10.3.6).
- 합성 = 재현 가능: 같은 레이어 세트 → 같은 Stage. 그래서 Nucleus(10.2)가 레이어를 공유하면 모두가 같은 합성 결과를 본다.
- Isaac Sim의 Stage(9.11): 9.11의
omni.usd.get_context().get_stage()가 이 Stage — 로봇·환경·센서 프림이 사는 씬그래프. 시뮬·렌더가 이 Stage를 본다.
핵심: Stage는 여러 레이어를 합성한 결과인 씬그래프 — 우리가 질의·편집·렌더하는 대상이다. Layer가 재료, Stage가 결과. 편집은 edit target 레이어에 기록되어(베이스 보존), 같은 레이어 세트는 같은 Stage(재현·협업 10.2). Isaac Sim·렌더가 보는 것이 이 Stage(9.11).
10.3.4 Prim — 씬의 노드
Prim(프림, primitive) 은 Stage 씬그래프의 기본 노드 — 메시·라이트·카메라·Xform·로봇이 전부 Prim이다.
Prim의 구성:
경로(path) : 씬그래프 위치 = 네임스페이스 (/World/Robot/Arm/Hand)
타입(type) : 스키마(schema) — 무엇인가 (Xform·Mesh·Camera·DistantLight·...)
계층(children): 자식 Prim들 (트리)
속성(properties): Attribute·Relationship (10.3.5)
메타데이터 : kind·active·instanceable 등
def Xform "World" ← Prim: 타입 Xform, 이름 World
{
def Mesh "Cube" { ... } ← 자식 Prim: 타입 Mesh
def DistantLight "Sun" {} ← 자식 Prim: 타입 DistantLight
}
- 경로 = 네임스페이스: Prim은
/World/Robot/Arm같은 경로로 식별된다 — 파일시스템 경로처럼 계층적. 다른 프림 참조·관계가 이 경로로. - 타입 = 스키마(schema): Prim의 타입은 스키마로 정해진다 —
Xform(변환 그룹)·Mesh(지오메트리)·Camera·DistantLight·PhysicsScene등. 스키마가 그 프림이 가질 속성·의미를 정의한다(예: Mesh는 points·normals, Camera는 focalLength).- typed schema(프림의 정체: Mesh·Xform) vs applied schema(추가 기능: PhysicsRigidBodyAPI·CollisionAPI 등을 적용함 — 물리 9.11). 로봇·물리·렌더 기능이 스키마로 확장된다.
- 계층(네임스페이스): Prim은 자식을 가져 트리를 이룬다 — 로봇은 링크·조인트 프림의 트리(아티큘레이션 9.11). Xform 프림은 자식의 변환을 묶는다.
def·over·class:def(define, 새 프림 정의)·over(override, 기존 프림에 의견만 오버레이하기 — 비파괴 10.3.6)·class(상속용 추상).over가 오버라이드의 문법.- API(pxr):
stage.GetPrimAtPath("/World/Cube")·UsdGeom.Mesh.Define(stage, path)·prim.GetTypeName(). 스키마별 클래스(UsdGeom.Mesh·UsdLux.DistantLight)로 타입 안전하게.
핵심: Prim은 씬그래프의 노드 — 경로(네임스페이스)·타입(스키마)·계층·속성을 가진다. 메시·라이트·카메라·로봇이 전부 Prim이고, 스키마가 그 정체(typed: Mesh·Xform)와 추가 기능(applied: 물리 API 9.11)을 정의한다.
def(정의)·over(오버라이드)·class(추상)로 선언. 경로로 서로를 참조.
10.3.5 속성 — Attribute·Relationship·타임샘플
Prim이 무엇을 담나 — 속성(property)은 두 종류다: 값을 담는 Attribute와 다른 프림을 가리키는 Relationship.
Prim의 속성(property) 두 종류:
① Attribute(속성값) — 타입 있는 이름붙은 값
예: point3f[] points, float radius, color3f displayColor,
double3 xformOp:translate, float intensity
· 타입(float·int·token·array·…), 단일값 또는 배열
· 타임샘플(time sample) → 애니메이션(시간별 값)
② Relationship(관계) — 다른 Prim(들)을 가리킴(경로)
예: material:binding → /World/Materials/Metal (머티리얼 바인딩)
물리 조인트의 body0/body1 → 링크 프림들
def Mesh "Cube" {
point3f[] points = [...] ← Attribute
color3f[] primvars:displayColor = [(0.8,0.2,0.2)] ← Attribute
double3 xformOp:translate = (0,0,1) ← Attribute(변환)
uniform token[] xformOpOrder = ["xformOp:translate"]
rel material:binding = </World/Mat> ← Relationship
}
- Attribute = 타입 있는 값: 지오메트리(points·normals)·변환(xformOp:translate/rotate/scale)·외형(displayColor·intensity)·물리(mass·velocity) 등 그 프림의 데이터. 스키마가 어떤 속성이 있는지 정의. 단일값 또는 배열.
- 타임샘플 = 애니메이션: Attribute는 시간별 값(time sample) 을 가질 수 있다 —
translate를 프레임마다 다르게 → 애니메이션. 로봇 관절 궤적·카메라 무빙·시뮬 기록이 타임샘플(9.12 rosbag 정신의 USD판). 시간 없는 default 값도 있다. - Relationship = 프림 가리키기: 값이 아니라 다른 프림(경로)을 가리킨다 — 머티리얼 바인딩(
material:binding), 물리 조인트가 잇는 두 바디, 그룹 멤버십 등. 씬의 연결 구조. - xformOp(변환): USD에서 변환은
xformOp:translate/rotate/scale속성 +xformOpOrder(적용 순서)로 표현 — 유연하지만 순서가 중요(함정).UsdGeom.XformCommonAPI로 간편하게. - primvars: 프림에 붙는 추가 데이터(displayColor·UV 등) — 렌더·셰이딩에 쓰임.
- API:
prim.GetAttribute("radius").Get()/Set(2.0)·attr.Set(value, time)(타임샘플)·UsdShade로 머티리얼 바인딩.
견해: Prim의 속성은 Attribute(타입 있는 값 — 지오메트리·변환·외형·물리) 와 Relationship(다른 프림 가리킴 — 머티리얼·조인트) 둘이다. Attribute는 타임샘플로 애니메이션(로봇 궤적·시뮬 기록). 변환은
xformOp+ 순서로 표현(순서 주의). 스키마(10.3.4)가 어떤 속성이 유효한지 정의 — Mesh엔 points, Camera엔 focalLength. 이 속성들이 씬의 실제 데이터.
10.3.6 Layer — 저장·합성의 단위
Layer(레이어) 는 USD의 저장·합성 단위 — 프림·속성의 "의견(opinion)"을 담은 파일(또는 익명 버퍼)이고, 비파괴 합성의 핵심이다.
base는 안 건드린다 — override 레이어만 추가/제거하면 변경을 on/off한다(비파괴).
- 레이어 = 의견의 묶음: 각 레이어는 프림·속성에 대한 의견(opinion) 을 담는다 — "Cube의 색은 파랑", "translate는 (0,0,1)". 여러 레이어의 의견을 강도 순서로 합성해 Stage를 만든다(강도 규칙 LIVRPS는 10.4).
- 비파괴 오버라이드(핵심): 강한 레이어(예: 위에 오버레이한 override.usda)의 의견이 약한 레이어(base.usda)를 덮어쓴다 — 단, base 파일은 안 바뀐다. override 레이어를 빼면 원래대로.
over문법으로 "이 프림에 의견만 오버레이하기". - 왜 이것이 결정적인가(10.2·9.14·10.8):
- 협업(Nucleus 10.2): 라이팅 팀은 lighting.usda에, 모델 팀은 model.usda에 의견을 써 서로 안 깨고 합성. 동시 편집이 비파괴라 가능.
- 도메인 랜덤화(9.14): 베이스 씬 위에 랜덤화 레이어로 마찰·색·위치 변형을 오버레이하고, 빼면 원복 — 베이스 보존.
- 디지털트윈(10.8): 설계 레이어 위에 운영·센서 레이어를 겹침.
- 변형(variant 10.4): 한 자산의 여러 버전을 레이어로.
- 루트·서브레이어·LayerStack: 루트 레이어가 서브레이어(sublayer) 로 다른 레이어를 포함 → LayerStack. (참조·페이로드 등 다른 합성 아크는 10.4.)
.usdavs.usdcvs.usd:.usda(ASCII — 사람이 읽고 디버깅),.usdc(crate — 바이너리·빠름·대용량),.usd(둘 중 하나). 개발·디버깅은.usda, 프로덕션·대용량은.usdc.
핵심: Layer는 의견(opinion)의 묶음이고, 강한 레이어가 약한 레이어를 비파괴적으로 덮어쓴다(base 보존, override 레이어 추가/제거로 on/off). 이 비파괴 합성이 협업(Nucleus 10.2)·도메인 랜덤화(9.14)·디지털트윈(10.8)·변형(10.4) 의 근거 — "USD가 토대인 이유"의 핵심.
.usda(디버깅)/.usdc(프로덕션). 강도 규칙·참조는 10.4.
10.3.7 워크스루 — USD 읽고·쓰고·오버라이드
USD 데이터 모델을 "텍스트로 읽고, Python으로 쓰고, 레이어로 오버라이드" 흐름으로 익힌다.
# base.usda — 사람이 읽는 USD(.usda ASCII)
#usda 1.0
(
defaultPrim = "World"
upAxis = "Z"
metersPerUnit = 1.0
)
def Xform "World"
{
def Mesh "Cube"
{
float3[] extent = [(-1,-1,-1), (1,1,1)]
point3f[] points = [ (-1,-1,-1), (1,-1,-1), ... ] # 지오메트리
color3f[] primvars:displayColor = [(0.8, 0.2, 0.2)] # 빨강
double3 xformOp:translate = (0, 0, 1) # 변환
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def DistantLight "Sun" { float inputs:intensity = 1000 }
}
# Python(pxr)으로 읽고 쓰기 — USD API는 비교적 안정적
from pxr import Usd, UsdGeom, UsdLux, Sdf, Gf
# 1) 새 스테이지·프림 만들기
stage = Usd.Stage.CreateNew("base.usda")
UsdGeom.SetStageUpAxis(stage, UsdGeom.Tokens.z)
world = UsdGeom.Xform.Define(stage, "/World") # Xform 프림
cube = UsdGeom.Cube.Define(stage, "/World/Cube") # Cube 프림(스키마)
cube.GetPrim().GetAttribute("size").Set(2.0) # Attribute 설정
UsdGeom.XformCommonAPI(cube).SetTranslate(Gf.Vec3d(0, 0, 1))
sun = UsdLux.DistantLight.Define(stage, "/World/Sun")
sun.GetIntensityAttr().Set(1000)
stage.SetDefaultPrim(world.GetPrim())
stage.GetRootLayer().Save() # base.usda에 저장
# 2) 읽기·순회
stage2 = Usd.Stage.Open("base.usda")
for prim in stage2.Traverse(): # 씬그래프 순회
print(prim.GetPath(), prim.GetTypeName()) # /World Xform, /World/Cube Cube ...
# 3) 비파괴 오버라이드 — 별도 레이어에서 색만 바꿈(base는 그대로, 10.3.6)
# 핵심: override를 '루트'로 두고 base를 '서브레이어'로 추가해야 override가 base를 이긴다.
# (레이어 스택에서 루트의 직접 의견 > 서브레이어 → base 위에 단순 append하면 안 이김)
over_layer = Sdf.Layer.CreateNew("override.usda") # 강한 레이어(루트가 됨)
over_layer.subLayerPaths.append("base.usda") # base를 더 약한 서브레이어로 추가함
stage = Usd.Stage.Open(over_layer) # override.usda 루트 → base보다 강함
stage.SetEditTarget(over_layer) # 편집 대상 = override 레이어
cube = stage.GetPrimAtPath("/World/Cube")
cube.GetAttribute("primvars:displayColor").Set([(0, 0, 0.8)]) # 파랑으로 override(루트가 base 이김)
over_layer.Save()
# → base.usda는 빨강 그대로, override.usda(루트)만 파랑 의견. 빼면 원복(비파괴)
체크포인트:
· .usda를 텍스트로 열어 Prim(def)·속성·변환을 읽을 수 있나(디버깅)
· Traverse로 씬그래프 순회·타입 확인
· edit target을 override 레이어로 두면 base 보존하며 덮어쓰기(10.3.6)
· 같은 레이어 세트 → 같은 Stage(재현·협업 10.2)
.usda로 디버깅: USD가 이상할 때.usda(텍스트)로 열어 프림·속성·합성을 눈으로 — 가장 강력한 디버깅(바이너리.usdc는usdcat으로 텍스트 변환). 변환 순서(xformOpOrder)·머티리얼 바인딩·스키마를 확인.- edit target이 핵심: 어느 레이어에 쓸지(
SetEditTarget)가 "베이스 보존 오버라이드"의 메커니즘 — Isaac Sim·도메인 랜덤화(9.14)·세션 변경이 이걸로 베이스를 안 깬다. - usdview·usdcat 도구:
usdview(씬 시각·검사)·usdcat(텍스트 출력)·usdchecker(검증) 등 USD CLI 도구로 검사·디버깅.
견해: USD 실습의 핵심은 ①
.usda를 텍스트로 읽고 쓰기(프림·속성·변환 — 디버깅) ② Traverse로 씬그래프 순회 ③ edit target을 override 레이어로 두어 베이스 보존 비파괴 오버라이드(10.3.6). USD가 이상하면.usda(또는usdcat)로 열어 합성 결과를 눈으로. 이 데이터 모델 위에서 Isaac Sim(9.11)·협업(10.2)·랜덤화(9.14)가 실행된다.
10.3.8 중간 점검 (체크포인트)
- [ ] USD가 파일 포맷이 아니라 비파괴 합성 씬 시스템이고, 왜 Omniverse·로봇·트윈이 그 위에 서는지 안다.
- [ ] Stage = 레이어 합성 결과(씬그래프), 우리가 질의·편집·렌더하는 대상임을 안다.
- [ ] Prim = 경로·타입(스키마)·계층·속성을 가진 노드이고, typed/applied 스키마(물리 API 9.11)를 안다.
- [ ] 속성이 Attribute(타입 값·타임샘플=애니메이션)·Relationship(프림 가리킴) 둘임을 안다.
- [ ] Layer = 의견 묶음, 강한 레이어가 약한 레이어를 비파괴 오버라이드(base 보존)함과 그 협업·랜덤화·트윈 의의를 안다.
- [ ]
.usda(디버깅)/.usdc(프로덕션), edit target으로 베이스 보존 오버라이드, usdview/usdcat을 안다.
증상→의심: 변경이 베이스를 덮어씀(원복 불가) → edit target이 베이스 레이어 → override 레이어로(10.3.6). 프림이 안 보임/타입 이상 → 스키마·경로·active·합성 순서 → .usda/usdview 검사. 변환이 이상 → xformOp 순서(xformOpOrder)·단위(metersPerUnit)·upAxis → 확인. 머티리얼이 안 붙음 → Relationship(material:binding) 경로 → usdview. USD가 깨짐/안 열림 → usdchecker·.usda 텍스트 검사. 협업서 충돌 → 같은 레이어 동시 쓰기 → 레이어 분리(10.2). 대용량 느림 → .usda 대신 .usdc·페이로드(10.4).
10.3.9 트레이드오프·대안
| 결정 | 트레이드오프 |
|---|---|
| USD(합성) vs 단일 파일 포맷(FBX·glTF) | 비파괴·협업·재사용·스케일 vs 단순·즉시·널리 지원 |
.usda(ASCII) vs .usdc(crate) | 사람이 읽음·디버깅·diff vs 빠름·작음·대용량 |
| 오버라이드 레이어 vs 직접 편집 | 비파괴·재사용·실험 vs 단순(파괴적) |
| typed schema vs 일반 프림 | 의미·도구 지원 vs 유연 |
| 참조/페이로드(10.4) vs 인라인 | 재사용·지연로드·스케일 vs 단순(다음 장) |
견해: 여러 도구·팀이 비파괴적으로 협업하고 자산을 재사용하며 대규모 씬을 다루려면 USD가 강하다 — Omniverse·시뮬·트윈의 토대(10.1·10.2·10.8)인 이유. 단 단일 자산 교환·단순 뷰어엔 FBX·glTF가 더 간단·널리 지원될 수 있고, USD는 합성·레이어 개념의 학습 곡선이 있다. 개발·디버깅엔
.usda(텍스트), 프로덕션·대용량엔.usdc. 변경은 오버라이드 레이어로 비파괴(베이스 보존) — 협업·랜덤화(9.14)·트윈의 핵심. 합성의 강도·재사용 메커니즘(참조·변형)은 10.4에서.
비엔비디아 정직: USD는 픽사 발 오픈 표준(AOUSD) 으로 NVIDIA 전유물이 아니며, 대안·관련 포맷도 있다 — glTF(웹·경량 전송 표준)·FBX(DCC 교환, 폐쇄적)·Alembic(베이크된 지오메트리·VFX)·MaterialX(머티리얼, USD와 상호보완). USD의 강점은 합성(비파괴 레이어·참조·변형)·대규모 협업·스키마 확장성이라 씬 조립·협업·파이프라인에 강하고, glTF는 최종 전송·웹, Alembic은 베이크 캐시에 강하다. NVIDIA(Omniverse)는 USD를 잘 구현·확장·실시간 협업(10.2) 한 것이지 USD를 소유하지 않는다 — 다른 도구도 USD를 쓴다(10.2 상호운용). 스키마·API·버전은 그 시점 확인.
10.3.10 흔한 함정
- USD를 단순 파일 포맷으로 취급. 합성·레이어를 모르면 협업·오버라이드·재사용을 못 씀 → 합성 시스템으로 이해(10.3.2·10.3.6).
- 베이스 레이어에 직접 편집. edit target이 베이스면 원본 파괴·원복 불가 → 오버라이드 레이어로(10.3.6).
- xformOp 순서·단위 무시. translate/rotate/scale 순서(xformOpOrder)·metersPerUnit·upAxis가 틀리면 물체가 잘못된 위치/크기 →
.usda확인. .usdc만 보고 디버깅 포기. 바이너리라 안 읽힘 →usdcat으로 텍스트·usdview로 시각.- 스키마 무시한 프림. 타입 없이 속성만 넣으면 도구·렌더가 해석 못 함 → 적절한 스키마(Mesh·Xform·물리 API 9.11).
- Relationship 경로 오타. material:binding·조인트 타깃 경로가 틀리면 안 붙음 → usdview로 관계 확인.
- 타임샘플 vs default 혼동. 애니메이션(타임샘플)과 정적(default) 값 혼용 → 의도대로 설정.
- 대용량을
.usda로. 텍스트라 느리고 큼 → 프로덕션은.usdc·페이로드(10.4). - 합성 강도 가정. 어느 레이어가 이기는지(LIVRPS)를 모르고 추측 → 10.4에서 정확히.
- USD를 NVIDIA 전유물로 오해. 오픈 표준(AOUSD) → 다른 도구도 사용(10.2 상호운용).
10.3.11 연습문제
연습 1 (4계층). USD의 Stage·Prim·Property·Layer의 관계를 설명하고, "Stage는 결과, Layer는 재료"라는 말의 의미와 그것이 왜 USD가 단순 파일 포맷과 다른 핵심인지 답하라.
정답
네 계층의 관계: Layer(레이어) = 저장·합성의 단위(파일 또는 익명 버퍼)로, 프림·속성에 대한 의견(opinion) 을 담는다("Cube의 색은 파랑"). Stage(스테이지) = 하나 이상의 레이어를 합성한 결과인 씬그래프 — 우리가 질의·편집·렌더하는 대상. Prim(프림) = Stage 씬그래프의 노드(메시·라이트·로봇)로 경로·타입(스키마)·계층을 가진다. Property(속성) = Prim이 담는 데이터 — Attribute(타입 값)·Relationship(프림 가리킴). 즉 Layer(들) → 합성 → Stage(Prim 트리, 각 Prim에 Property). "Stage는 결과, Layer는 재료": Stage는 직접 저장되는 단일 파일이 아니라, 레이어들을 합성한 런타임 뷰다. 레이어(base.usda + override.usda)를 열어 강도 순서로 합치면 Stage가 생긴다. 같은 레이어 세트 → 같은 Stage(재현). 편집은 edit target 레이어에 기록(베이스 보존). 왜 단순 포맷과 다른 핵심인가: FBX·glTF는 "씬 하나를 한 파일에 일괄 직렬화" — 하나의 묶음이라 편집이 파괴적(원본 수정)이고 협업·재사용·오버라이드가 어렵다. USD는 씬을 여러 레이어의 의견으로 분해하고 합성한다 → ① 비파괴 — 베이스를 안 건드리고 강한 레이어에서 덮어쓰기(원복 가능) ② 협업 — 여럿이 다른 레이어에 동시 작성(서로 안 깸, Nucleus 10.2) ③ 재사용 — 참조로 자산 공유(10.4) ④ 스케일 — 대규모 씬을 레이어·지연로드로. "Stage=결과, Layer=재료"의 분리가 이 모든 것을 가능케 한다 — 결과(Stage)를 고정 저장하는 대신 재료(Layer)를 조합하니, 재료를 더하고 빼고 겹쳐 비파괴적으로 변형·협업·재사용. 이것이 USD가 "포맷이 아니라 합성 시스템"인 이유이자 Omniverse·시뮬·트윈(10.1·10.2·10.8)의 토대.
연습 2 (스키마). Prim의 타입(스키마)이 무엇이고 왜 중요한지 설명하고, typed schema와 applied schema의 차이를 로봇 시뮬(9.11) 예로 답하라.
정답
스키마란: Prim의 타입은 스키마(schema) 로 정해진다 — 스키마는 그 프림이 무엇인지와 어떤 속성·의미를 갖는지 정의한다. 예: Mesh 스키마는 points·normals·faceVertexIndices를, Camera는 focalLength·clippingRange를, DistantLight는 intensity를 정의. 왜 중요한가: ① 의미 부여 — "이 프림은 메시/카메라/라이트"라는 정체를 줘 도구·렌더가 올바로 해석. ② 속성 규약 — 어떤 속성이 유효한지 정의해 일관성(임의의 속성을 넣는 것이 아니라 스키마가 정한 것). ③ 도구 지원 — 스키마를 아는 도구가 적절히 처리(렌더러가 Mesh를 그리고 Camera로 뷰). ④ 확장성 — 새 도메인(물리·로봇)을 스키마로 추가. typed vs applied schema: typed schema = 프림의 정체(무엇인가) — Mesh·Xform·Camera·DistantLight. 프림 하나당 하나의 타입(def Mesh "Cube"). applied schema = 프림에 추가 기능(API)을 적용함 — 기존 타입을 바꾸지 않고 능력을 더함. 로봇 시뮬(9.11) 예: 로봇 링크는 typed schema Mesh(또는 Xform 아래 Mesh)로 지오메트리를 갖고, 거기에 applied schema PhysicsRigidBodyAPI(강체 — 질량·속도)·PhysicsCollisionAPI(충돌 모양)를 적용해 물리 객체로 만든다. 로봇 전체는 PhysicsArticulationRootAPI를 적용한 프림 아래 링크·조인트(PhysicsJoint 타입 + 드라이브 API). 즉 "무엇인가"는 typed(Mesh·Xform), "어떤 능력을 추가하나"는 applied(물리·충돌·머티리얼 API). URDF→USD 임포트(9.11)가 이 스키마들을 붙여 PhysX가 시뮬할 아티큘레이션을 만든다. 핵심: 스키마가 프림의 정체·속성·기능을 정의하고, applied schema로 물리·렌더 능력을 비파괴적으로 확장 → USD가 로봇·물리·다양한 도메인을 담는 확장 가능 데이터 모델이 된다. 스키마 없이 속성만 넣으면 도구가 해석 못 함(함정).
연습 3 (Attribute vs Relationship·타임샘플). Attribute와 Relationship의 차이를 예로 설명하고, 타임샘플이 무엇이며 로봇·시뮬에서 어떻게 쓰이는지 답하라.
정답
Attribute vs Relationship: Attribute(속성값) = 타입 있는 이름붙은 값 — 그 프림의 데이터를 직접 담는다. 예: point3f[] points(지오메트리), double3 xformOp:translate(변환), color3f displayColor(색), float intensity(밝기), float mass(질량). 타입(float·int·token·array…)이 있고 단일값 또는 배열. Relationship(관계) = 값이 아니라 다른 Prim(들)을 가리킴(경로). 예: material:binding → /World/Materials/Metal(이 메시에 이 머티리얼을 바인딩), 물리 조인트의 body0/body1 → 링크 프림들(이 조인트가 잇는 두 바디), 그룹 멤버십. 즉 Attribute는 "이 프림의 데이터", Relationship은 "이 프림과 다른 프림의 연결". 씬의 데이터는 Attribute, 씬의 연결 구조는 Relationship. 타임샘플(time sample): Attribute는 시간별 값을 가질 수 있다 — translate를 프레임 0에 (0,0,0), 프레임 30에 (1,0,0)…으로 저장하면 애니메이션. 시간 없는 default 값과 구분된다(attr.Set(v) = default, attr.Set(v, time) = 타임샘플). 로봇·시뮬 활용: ① 로봇 관절 궤적 — cuMotion(9.10)이나 RL(9.13)이 만든 관절각 시퀀스를 조인트 각도 Attribute의 타임샘플로 → 로봇 동작 재생. ② 시뮬 기록·재생 — 시뮬 한 에피소드의 모든 프림 변환을 타임샘플로 기록하면 결정적 재생·리뷰(9.12 rosbag·8.14 재시뮬의 USD판). ③ 카메라 무빙·애니메이션 — 카메라 자세 타임샘플. ④ 센서 데이터 시간열. ⑤ 물리 시뮬 베이크 — PhysX 결과를 타임샘플로 구워 재생(물리 재계산 없이). 즉 타임샘플이 USD에 시간 차원을 줘 애니메이션·기록·재생을 표현 — 로봇 동작·시뮬 결과를 담는 그릇. Relationship은 머티리얼·물리 조인트 연결에. 핵심: Attribute(값·타임샘플 애니메이션)·Relationship(프림 연결)이 프림의 데이터와 구조를 이루고, 타임샘플이 시간 의존 데이터(궤적·기록)를 담는다. usdview로 타임샘플·관계를 검사.
연습 4 (비파괴 오버라이드). Layer의 비파괴 오버라이드가 어떻게 동작하는지 설명하고, 이것이 왜 Nucleus 협업(10.2)·도메인 랜덤화(9.14)·디지털트윈(10.8)의 핵심 메커니즘인지 답하라.
정답
동작: 각 레이어는 프림·속성에 대한 의견(opinion) 을 담는다. USD는 여러 레이어를 강도 순서로 합성해 Stage를 만드는데(강도 규칙 LIVRPS는 10.4), 강한 레이어의 의견이 약한 레이어를 이긴다. 예: base.usda(약)가 "Cube 색=빨강, translate=(0,0,1)"을, override.usda(강, 위에 오버레이됨)가 over "Cube" { 색=파랑 }을 담으면, 합성 결과는 색=파랑(override 이김)·translate=(0,0,1)(base 유지, override가 의견 없음). 결정적: base.usda 파일은 바뀌지 않는다 — override 레이어에만 새 의견을 썼다. override 레이어를 빼면 원래(빨강)로. over 문법이 "이 프림에 의견만 오버레이하기"(새로 정의 def가 아니라). edit target(10.3.7)을 override 레이어로 두면 변경이 거기 기록. 왜 세 곳의 핵심인가: ① Nucleus 협업(10.2) — 라이팅 팀은 lighting.usda에, 모델 팀은 model.usda에, 애니 팀은 anim.usda에 각자 의견을 쓴다. 비파괴라 한 팀이 다른 팀 자산을 안 깨고 동시 작성, 합성으로 모두 반영. 단일 파일이면 동시 편집 시 충돌·덮어쓰기. 비파괴 레이어가 실시간 협업을 가능케. ② 도메인 랜덤화(9.14) — 베이스 씬 위에 랜덤화 레이어로 마찰·색·위치·조명 변형을 오버레이한다. 매 에피소드 다른 변형을 override로, 빼면 베이스 원복 — 베이스를 보존하며 수천 변형(9.13 병렬 환경마다). 베이스 파괴 없이 무한 변형. ③ 디지털트윈(10.8) — 설계 레이어(CAD) 위에 운영 레이어(실시간 센서·상태)·what-if 레이어(가상 변경)를 겹친다. 설계는 그대로, 운영 데이터·시나리오를 비파괴로 오버레이해 실물과 동기·실험. 또 변형(variant 10.4) — 한 자산의 여러 버전을 레이어로. 공통 원리: "베이스를 보존하며 변경을 오버레이하고 제거한다"가 협업(여럿이 안 깸)·실험(랜덤화·what-if)·동기(설계+운영)의 토대. 파괴적 편집(단일 파일)이면 이 모두가 불가능 — 누군가의 변경이 원본·남의 작업을 덮어씀. USD의 비파괴 레이어 합성이 Omniverse·시뮬·트윈이 USD 위에 서는 가장 깊은 이유. 정직: 강도 규칙(어느 레이어가 이기나)은 10.4에서 정확히.
연습 5 (디버깅·포맷). USD 씬이 이상할 때(물체가 안 보이거나 잘못된 위치) 어떻게 디버깅하는지 단계로 설명하고, .usda/.usdc/.usd의 차이와 언제 무엇을 쓰는지 답하라.
정답
디버깅 단계: ① .usda(텍스트)로 열어 읽기 — USD의 가장 강력한 디버깅. 바이너리 .usdc면 usdcat scene.usdc 로 텍스트 변환해 본다. 프림(def)·속성·변환·관계를 눈으로. ② 물체가 안 보임 → 프림이 존재하나(경로·오타)·active인가(비활성 프림)·합성에서 다른 레이어가 지웠나(강한 레이어 override)·visibility 속성·스키마 타입이 맞나 → usdview로 씬그래프·합성 검사. ③ 잘못된 위치/크기 → xformOp 순서(xformOpOrder — translate/rotate/scale 적용 순서)·단위(metersPerUnit — m vs cm)·upAxis(Y vs Z) 불일치 → .usda에서 변환·스테이지 메타 확인. 흔한 원인. ④ 머티리얼 안 붙음 → material:binding Relationship 경로 오타·대상 프림 부재 → usdview 관계 검사. ⑤ 합성이 이상(어느 레이어가 이기나) → LayerStack·강도(10.4)·edit target 확인 → usdview의 레이어 스택 뷰. ⑥ 검증 — usdchecker로 USD 유효성·일관성 검사. 도구: usdview(씬 시각·계층·속성·합성 검사 — GUI), usdcat(텍스트 출력), usdchecker(검증), .usda 텍스트 에디터. 포맷 차이: .usda = ASCII(사람이 읽는 텍스트) — 디버깅·diff·버전관리·학습에 좋음, 느리고 큼. .usdc = crate(바이너리) — 빠름·작음·대용량, 사람이 못 읽음(usdcat 필요). .usd = 둘 중 하나(확장자만, 내부는 ASCII 또는 binary) — 유연. 언제 무엇: 개발·디버깅·작은 씬·텍스트 diff가 필요하면 .usda; 프로덕션·대용량·성능·배포는 .usdc; 둘을 섞을 수 있게 .usd. 협업(10.2)에선 작은 오버라이드 레이어는 .usda(읽기·diff), 대용량 지오메트리는 .usdc(성능). 핵심: USD 디버깅의 출발은 .usda(또는 usdcat)로 합성 결과를 텍스트로 보는 것 + usdview로 시각·합성·관계 검사. 변환 문제(순서·단위·축)가 "잘못된 위치"의 단골. 정직: 도구·API는 버전 의존이나 usdview/usdcat/usdchecker는 표준.
10.3.12 요약 · 다음 장
- USD = 비파괴 합성 씬 시스템(파일 포맷 아님): 여러 레이어의 의견을 합성해 씬을 만든다(베이스 보존·오버라이드·재사용). 픽사 발 오픈 표준(AOUSD) — Omniverse·로봇·트윈(10.1·10.2·10.8)의 토대, NVIDIA 전유물 아님.
- Stage: 레이어 합성 결과인 씬그래프 — 질의·편집·렌더 대상. Layer가 재료, Stage가 결과. 같은 레이어 → 같은 Stage(재현·협업).
- Prim: 경로·타입(스키마)·계층·속성의 노드. typed schema(Mesh·Xform — 정체)·applied schema(물리 API 9.11 — 추가 기능).
def/over/class. - 속성: Attribute(타입 값·타임샘플=애니메이션/기록)·Relationship(프림 가리킴 — 머티리얼·조인트). 변환은 xformOp + 순서.
- Layer: 의견 묶음, 강한 레이어가 약한 레이어를 비파괴 오버라이드(base 보존). 이것이 협업(10.2)·도메인 랜덤화(9.14)·디지털트윈(10.8) 의 핵심 메커니즘.
.usda(디버깅)/.usdc(프로덕션), edit target, usdview/usdcat. 합성 강도·참조는 10.4.
다음 장: 10.4 OpenUSD II — 컴포지션 아크. Stage·Prim·Layer(데이터 모델)를 봤으니, 이제 USD의 합성 메커니즘 으로 깊이 들어간다 — 자산을 재사용하는 참조(reference)·페이로드(payload), 옵션을 담는 변형(variant), 상속·특수화·서브레이어, 그리고 이들의 강도 규칙(LIVRPS). "어느 레이어·아크가 이기는가"를 정확히, 실습으로. 데이터 모델에서 합성의 작동 원리로.