从零构建你的第一个USD厨房:代码驱动场景创作实战
如果你刚接触3D内容开发,面对“通用场景描述”这个听起来有些宏大的概念,可能会感到无从下手。别担心,这篇文章就是为你准备的。我们将绕过那些抽象的理论,直接动手,用代码搭建一个具体的厨房场景。通过这个实战过程,你将直观地理解USD如何组织复杂的3D世界,并掌握用Python脚本生成、预览和调试.usda文件的核心技能。无论你是想为游戏引擎准备资产,还是为数字孪生项目构建基础,这套方法都能让你快速上手。
1. 环境搭建与第一个.usda文件
在开始编写复杂的厨房场景之前,我们需要一个能跑起来的开发环境。USD本身是一个跨平台的框架,但为了简化,我们这里以macOS或Linux环境为例进行说明。最快捷的方式是使用Python的pip安装usd-core包,它包含了USD的核心Python API和必要的命令行工具。
# 安装usd-core,这将安装USD的Python绑定和基础工具
pip install usd-core
安装完成后,验证一下关键工具是否可用。打开终端,输入usdview --version和usdcat --help,如果能看到版本信息和帮助文档,说明环境就绪。usdview是我们的3D场景查看器,usdcat则是查看和转换USD文件格式的命令行利器。
现在,让我们抛开任何图形界面,纯粹用代码来创建第一个USD“世界”。打开你喜欢的代码编辑器,创建一个名为hello_kitchen.py的Python脚本。
#!/usr/bin/env python3
# hello_kitchen.py - 创建第一个包含简单几何体的USD场景
from pxr import Usd, UsdGeom, Gf
import os
# 1. 创建一个新的USD舞台(Stage),这是所有场景内容的容器
stage = Usd.Stage.CreateNew('hello_kitchen.usda')
# 2. 在舞台的根路径下定义一个Xform(变换)基元(Prim),我们可以把它想象成场景中的一个空节点或文件夹
world_xform = UsdGeom.Xform.Define(stage, '/World')
# 为这个节点设置一个友好的显示名称
world_xform.GetPrim().SetMetadata('displayName', 'Kitchen World')
# 3. 在/World下创建一个球体,代表一个简单的苹果或灯泡
sphere_prim = UsdGeom.Sphere.Define(stage, '/World/SimpleSphere')
sphere_prim.CreateRadiusAttr().Set(0.5) # 设置半径为0.5个单位
# 移动这个球体,避免它待在原点
sphere_xform = UsdGeom.Xformable(sphere_prim.GetPrim())
translate_op = sphere_xform.AddTranslateOp()
translate_op.Set(Gf.Vec3d(2.0, 1.0, 0.0))
# 4. 再创建一个立方体,代表一个简单的桌子或箱子
cube_prim = UsdGeom.Cube.Define(stage, '/World/SimpleCube')
cube_prim.CreateSizeAttr().Set(1.2)
cube_xform = UsdGeom.Xformable(cube_prim.GetPrim())
cube_translate = cube_xform.AddTranslateOp()
cube_translate.Set(Gf.Vec3d(-1.5, 0.6, 0.0))
# 5. 将舞台内容保存到磁盘
stage.GetRootLayer().Save()
print(f"场景文件已保存至: {os.path.abspath('hello_kitchen.usda')}")
运行这个脚本:python hello_kitchen.py。你会发现在当前目录生成了一个hello_kitchen.usda文件。用文本编辑器打开它,你会看到类似下面的内容:
#usda 1.0
(
doc = """Generated from scratch"""
)
def Xform "World" (
displayName = "Kitchen World"
)
{
def Sphere "SimpleSphere"
{
double radius = 0.5
double3 xformOp:translate = (2, 1, 0)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cube "SimpleCube"
{
double size = 1.2
double3 xformOp:translate = (-1.5, 0.6, 0)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
}
这就是USD的文本格式(.usda),人类可读,结构清晰。def关键字定义了一个“基元”(Prim),它是USD场景树中的基本节点。Xform、Sphere、Cube是这些基元的类型,定义了它们的语义和行为。属性(如radius、size、xformOp:translate)则存储了具体的数值数据。
提示:在USD中,
Xform是一个极其重要的基元类型。你可以把它理解为3D软件中的“空物体”或“组”,它本身没有几何形状,但可以包含子物体并对它们施加变换(移动、旋转、缩放)。它是组织场景层级结构的基础。
现在,用usdview命令在3D视窗中查看你的成果:usdview hello_kitchen.usda。你应该能看到一个球体和一个立方体悬浮在空间中。尝试在usdview中点击左侧的场景树(Prim树),选中物体,右侧的属性面板会显示我们刚才用代码设置的属性。恭喜,你已经完成了从代码到可视化的完整流程!
2. 理解USD场景图与厨房层级构建
理解了如何创建单个物体后,我们来构建一个更有组织性的场景。一个典型的厨房不是物体的简单堆砌,而是有逻辑的层级结构。USD的核心优势就在于它能通过“场景图”清晰地表达这种层级和引用关系。
想象一下一个简化的厨房场景图:
- 厨房 (Kitchen_Room)
- 北墙区域 (NorthWall_Group)
- 橱柜 (Cabinet_01)
- 水槽 (Sink_01)
- 中央岛台区域 (Island_Group)
- 岛台本体 (IslandBase)
- 水龙头 (Faucet_01)
- 餐桌区域 (DiningTable_Group)
- 餐桌 (Table)
- 椅子_01 (Chair_01)
- 椅子_02 (Chair_02)
- 北墙区域 (NorthWall_Group)
在USD中,我们通过嵌套的Prim(基元)来实现这种结构。每个Xform都可以作为一个“组”节点,其下可以包含其他Xform或具体的几何体。让我们用代码构建这个骨架。
#!/usr/bin/env

&spm=1001.2101.3001.5002&articleId=152252103&d=1&t=3&u=bd9ca20611564b64981309cf17ec92d1)
219

被折叠的 条评论
为什么被折叠?



