03. OpenUSD 기반 씬
Isaac Sim 씬은 처음부터 끝까지 OpenUSD다. 메시·머티리얼·라이트뿐 아니라 UsdPhysics(질량·관절), SemanticLabel(클래스 라벨), UsdLux(라이트), UsdShade(MDL/PBR)까지 모두 USD 스키마로 정의된다. 그래서 한 .usd 파일이 "학습 데이터 + 시뮬레이션 설정 + 머티리얼"을 다 담는다.
이 기능의 강점
- 레이어링 — base/physics/lighting을 분리된 sublayer로 두고 합성
- 레퍼런스/인스턴싱 — 한 프로토타입을
PointInstancer로 수만 개 복제해도 메모리·로딩 비용 일정 - VariantSet — 하나의 USD에 "Gripper=Default/AltFinger", "Mesh=Basic/Quality" 같은 옵션을 미리 정의
- Houdini · Maya · Blender · Cosmos · Replicator 모두 같은 USD를 읽고 쓴다
구현 방법
인스턴싱: UsdGeom.PointInstancer에 CreatePrototypesRel로 프로토타입 등록, positions/protoIndices 배열 채움. 변환은 인스턴서 prim 레벨 Xformable.AddRotateZOp 등으로 그룹 단위 적용.
최소 데모
검증 결과
5×5 격자에 동일 큐브 인스턴싱, 인스턴서 회전 20도 일괄 적용이 결과 PNG에 보임.
핵심 코드 발췌
from pxr import UsdGeom, Vt, Gf
proto = UsdGeom.Cube.Define(stage, "/World/Prototypes/Cube")
inst = UsdGeom.PointInstancer.Define(stage, "/World/Instancer")
inst.CreatePrototypesRel().SetTargets([proto.GetPath()])
pos, idx = [], []
for i in range(5):
for j in range(5):
pos.append(Gf.Vec3f((i-2)*1.2, (j-2)*1.2, 0.3))
idx.append(0)
inst.CreatePositionsAttr().Set(Vt.Vec3fArray(pos))
inst.CreateProtoIndicesAttr().Set(Vt.IntArray(idx))
UsdGeom.Xformable(inst).AddRotateZOp().Set(20.0)
코드 다운로드 (zip)
실무 예제 — Franka USD의 VariantSet (Gripper × Mesh) 시연
NVIDIA Franka USD는 Gripper (Default / AlternateFinger), Mesh (Basic / Quality) 등의 VariantSet을 가지고 있다. Python API prim.GetVariantSet(name).SetVariantSelection(value) 한 줄로 동일 USD를 다른 형상으로 렌더할 수 있다.
스크립트가 동일한 franka.usd를 3개 다른 variant 조합으로 reference한 결과 — 같은 base mesh + variant override 만으로 형상 변형이 가능. 실무에선 sim-to-real 격차를 줄이는 도구 풀의 일부.
실무 데모 코드
from isaacsim.core.utils.stage import add_reference_to_stage
from isaacsim.storage.native import get_assets_root_path
franka_url = get_assets_root_path() + \
"/Isaac/Robots/FrankaRobotics/FrankaPanda/franka.usd"
robot = add_reference_to_stage(usd_path=franka_url, prim_path="/World/Franka")
robot.GetVariantSet("Gripper").SetVariantSelection("AlternateFinger")
robot.GetVariantSet("Mesh").SetVariantSelection("Quality")
실무 데모 코드 zip