Pixar USD 教程:变换操作、时间采样动画与图层偏移详解
OpenUSD Universal Scene Description 项目地址: https://gitcode.com/gh_mirrors/us/USD
概述
本教程将带领读者深入了解Pixar USD(通用场景描述)系统中的核心概念:空间变换(Transformations)、时间采样动画(Time-sampled Animation)以及图层偏移(Layer Offsets)。我们将通过构建一个旋转陀螺的示例场景,逐步演示这些技术的实际应用。
基础准备
静态几何体
教程从静态几何体开始,使用了一个在Houdini中建模的陀螺几何体。这个模型被导出为USD格式文件,包含以下特点:
- 采用旋转曲线建模技术创建
- 每个面都分配了顶点颜色属性
- 使用+Z轴作为"上"方向(USD支持自定义上方向轴)
坐标系选择
在计算机图形学中,选择坐标系的上方向轴是重要决策:
- 常见选择:+Y或+Z轴
- USD作为管道交换格式,支持两种配置方式:
- 站点级默认设置
- 每个文件显式声明
- 本教程统一使用+Z轴向上,并在每个文件中明确声明
动画实现
时间范围设置
首先需要建立动画的时间范围:
def MakeInitialStage(path):
stage = Usd.Stage.CreateNew(path)
UsdGeom.SetStageUpAxis(stage, UsdGeom.Tokens.z)
stage.SetStartTimeCode(1) # 开始帧
stage.SetEndTimeCode(192) # 结束帧
return stage
- 采用电影行业标准的24fps帧率
- 动画总时长192帧(8秒)
- 设置时间码范围确保正确插值计算
引用静态几何体
通过USD的引用机制将静态模型引入场景:
def AddReferenceToGeometry(stage, path):
geom = UsdGeom.Xform.Define(stage, path)
geom.GetPrim().GetReferences().AddReference('./top.geom.usd')
return geom
关键点:
- 使用
prepend
操作确保引用优先级 - 创建Xform基元作为容器
- 引用操作保持场景结构清晰
添加旋转动画
实现陀螺自转效果:
def AddSpin(top):
spin = top.AddRotateZOp(opSuffix='spin')
spin.Set(time=1, value=0) # 起始帧角度
spin.Set(time=192, value=1440) # 结束帧角度(4圈)
技术细节:
- 使用
UsdGeomXformable
模式表示变换 - 属性命名规范:
xformOp:rotateZ:spin
- 必须设置
xformOpOrder
定义操作顺序 - USD使用线性插值计算中间帧
变换操作进阶
多重变换组合
真实陀螺会因重力倾斜,添加X轴旋转:
def AddTilt(top):
tilt = top.AddRotateXOp(opSuffix='tilt')
tilt.Set(value=12) # 固定倾斜角度
变换顺序的重要性:
- 先倾斜后旋转:
["xformOp:rotateX:tilt", "xformOp:rotateZ:spin"]
- 陀螺沿倾斜轴旋转
- 先旋转后倾斜:
["xformOp:rotateZ:spin", "xformOp:rotateX:tilt"]
- 完全不同的运动效果
完整物理效果模拟
添加进动和位移效果:
def AddOffset(top):
top.AddTranslateOp(opSuffix='offset').Set(value=(0, 0.1, 0))
def AddPrecession(top):
precess = top.AddRotateZOp(opSuffix='precess')
precess.Set(time=1, value=0)
precess.Set(time=192, value=360) # 一周进动
最终变换顺序:
- 进动旋转
- 位置偏移
- 倾斜角度
- 自转运动
图层偏移技术
基本概念
图层偏移允许对引用动画进行时间重映射:
# 无偏移引用
ref.AddReference(assetPath=anim_layer_path)
# 带96帧偏移
ref.AddReference(assetPath=anim_layer_path,
layerOffset=Sdf.LayerOffset(offset=96))
# 0.25倍速播放
ref.AddReference(assetPath=anim_layer_path,
layerOffset=Sdf.LayerOffset(scale=0.25))
时间计算公式: stageTime = layerTime * scale + offset
实际应用注意事项
-
时间采样行为:
- USD不进行采样外推值
- 超出范围时保持最近采样值
-
变换层级设计:
- 使用父Xform节点管理位置
- 避免直接修改引用内容的变换顺序
-
默认基元设置:
- 设置defaultPrim可简化引用路径
总结与最佳实践
通过本教程,我们学习了:
- USD变换系统的工作原理
- 时间采样动画的实现方式
- 复杂变换顺序的设计思路
- 图层偏移的实用技巧
生产环境建议:
- 资产通常不应包含根变换动画
- 简单重定时使用图层偏移
- 复杂动画循环考虑值剪辑(Value Clips)
- 始终明确设置变换操作顺序
这些技术构成了USD强大动画系统的基础,理解它们对于构建复杂的动画场景至关重要。
OpenUSD Universal Scene Description 项目地址: https://gitcode.com/gh_mirrors/us/USD
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考