OpenUSD 体积数据指南:Field3DAsset Schema 与 Field3D (.f3d) 体积资产的完整使用手册
2026/9/17 20:38:50 网站建设 项目流程

OpenUSD 体积数据指南:Field3DAsset Schema 与 Field3D (.f3d) 体积资产的完整使用手册

【免费下载链接】OpenUSDUniversal Scene Description项目地址: https://gitcode.com/GitHub_Trending/ope/OpenUSD

Field3DAsset 是 OpenUSD(Universal Scene Description)中 usdVol 域提供的具体 schema(具体类型),用于在 USD 场景中以 Field3D(.f3d)文件为数据源描述体积字段(Volume Field)。本文将以 Field3DAsset 官方 schema 文档 为核心骨架,结合 usdVol schema 定义、C++ 实现与测试代码,完整讲解 Field3DAsset 的定位、字段属性、USD 数据编写示例及在体积渲染管线中的用法,帮助读者在 OpenUSD 中正确组织基于 Field3D 资产的体积数据。

Field3DAsset 是什么

Field3DAsset 是一种 "Field representing a Field3D volume field"(表示 Field3D 体积字段的字段 prim)。它属于 usdVol 域的 VolumeFieldAsset 一族 schema,代表由外部文件定义的体积字段:体积数据本身存放在磁盘上的 Field3D(.f3d)格式文件中,而 USD 场景内的 Field3DAsset prim 负责以资产路径(asset path)的形式引用该文件,并提供描述字段语义的元数据。

从 schema 定义看,schema.usda 中声明:

class Field3DAsset "Field3DAsset" ( doc = """Field3D field primitive. The FieldAsset filePath attribute must specify a file in the Field3D format on disk.""" inherits = </FieldAsset> )

在 schema 继承体系中的位置

Field3DAsset 处于一条清晰的继承链上,其祖先类分别是:

Schema类型作用
VolumeFieldBase抽象所有体积字段 prim 的基类,继承自Xformable
FieldBase抽象(已弃用)旧版基类,未来版本将移除,应改用VolumeFieldBase
VolumeFieldAsset抽象由外部文件定义的体积字段的公共基类,声明filePathfieldNamefieldIndexfieldDataTypevectorDataRoleHint
FieldAsset抽象(已弃用)旧版中间层,继承自VolumeFieldAsset
Field3DAsset具体类型可直接实例化的 Field3D 字段 prim

其中FieldBaseFieldAsset在 schema.usda 中被标记为 deprecated("This schema will be removed in a future release"),当前实际使用的继承路径为VolumeFieldBase → VolumeFieldAsset。因此,Field3DAsset 最终拥有VolumeFieldAsset声明的全部属性,再加上自身声明的fieldPurpose与收窄取值范围的fieldDataType

在 C++ 中,对应类为UsdVolField3DAsset(field3DAsset.h),继承自UsdVolFieldAsset,其schemaKindUsdSchemaKind::ConcreteTyped,即可以直接用UsdVolField3DAsset::Define(stage, path)在舞台上定义;而 Python 绑定位于 wrapField3DAsset.cpp,可通过UsdVol.Field3DAsset直接访问。

最小可用示例:引用单个密度场

原文档给出了一个最典型的 Field3DAsset 用例——引用 .f3d 文件中的单个密度场:

def Field3DAsset "densityField3D" { token fieldDataType = "float" token fieldName = "density" token fieldPurpose = "cluster_0" asset filePath.timeSamples = { 1: @/f3ddata/Volumes_Cumulus01_Puff01M.1.f3d@, } }

这段代码演示了 Field3DAsset 的四个核心要素:

  • filePath:指向磁盘上的 Field3D(.f3d)文件,且此处以时间采样(timeSamples)形式给出,表示该字段是随时间变化的动画数据;
  • fieldName.f3d文件内部具体字段(Field)的名字,这里是"density"
  • fieldPurpose:字段用途或分组的标识,消费 Field3D 文件的客户端应将其视为 Field3D 字段的name(与fieldName的区别见下文);
  • fieldDataType:字段数据类型,这里是"float"

注意:原文档明确指出,filePath属性必须指向磁盘上 Field3D(.f3d)格式的文件,这是 Field3DAsset 与 OpenVDBAsset(.vdb)等其它 VolumeFieldAsset 子类最大的区别。

属性详解(Properties)

Field3DAsset 的属性分为"自身声明"与"继承自祖先"两部分,下面逐一说明。

自身属性:fieldPurpose

USD 类型token(可选属性)

fieldPurpose用于指明单个字段的用途或分组。消费 Field3D 文件的客户端应将此 token 视为 Field3D 字段的名称(name)。它出现在 schema.usda 的 Field3DAsset 类声明中,是 Field3DAsset 区别于其它 VolumeFieldAsset 子类的专属属性。

典型用途是区分一个 .f3d 文件中的多个字段用途,例如示例中的cluster_0表示该字段属于某个聚类分组。由于它是可选属性,未编写时消费者可按 Field3D 文件中的默认字段信息处理。

继承自 VolumeFieldAsset 的属性

fieldDataType

USD 类型token

字段的数据类型,例如"float"。设置该属性可以让消费者无需打开资产文件即可获知字段类型信息。其允许的 token 集合在 Field3DAsset 中收窄为:

标量类型向量类型
halffloatdoublehalf3float3double3

这一限定列表定义于 schema.usda,与 field3DAsset.h 中注释的 "Allowed Values" 一致,反映了 Field3D 格式实际支持的数据类型选择。相比之下,OpenVDBAsset 的fieldDataType允许集合大得多(含intuintboolmaskstringmatrix3d等),这体现了不同体积格式的能力差异。

VolumeFieldAsset基类中,fieldDataType被描述为"A missing value is considered an error"(缺失值视为错误),因此为 Field3DAsset 编写fieldDataType是推荐做法。

fieldIndex

USD 类型int(可选属性)

一个资产文件中可能包含多个同名字段,fieldIndex用于在多个同名字段之间消歧。例如一个 OpenVDB 文件中可能有两个名为 "density" 的 Grid,此时fieldIndex为 0 表示引用第一个 "density" Grid。Field3D 文件同样适用这一约定。

fieldName

USD 类型token

表示 VolumeFieldAsset 资产文件内部某个字段的名称。一个资产文件可以包含多个字段,该属性精确指定引用其中的哪一个。例如 OpenVDB 文件中可能有 "density"、"temperature" 等多个命名 Grid,fieldName指定其中之一。

与 Volume 上 field 关系的命名区别:Volume prim 还通过field:命名空间前缀的关系(relationship)为字段提供"名称",但这个名称与资产数据无关,是 Volume 为渲染管线组织字段而使用的。字段关系名与fieldName的区别详见 usdVol userDoc 总览 的 "Understanding fieldName and the Field's Relationship Name" 一节(源码位于 overview.md)。例如:Volume 的 shader 需要 "velocity" 输入,但 .f3d 文件里的字段名叫 "vel",此时可在 Volume 中写rel field:velocity = </.../fieldPrim>,而 Field 内的fieldName仍为 "vel"。

filePath

USD 类型asset

指向磁盘文件的资产路径属性。对于 Field3DAsset,其指向的文件类型必须是 Field3D(.f3d)文件;对于 OpenVDBAsset 则必须是 OpenVDB(.vdb)文件。该属性的 C++ 类型为SdfAssetPath(见 volumeFieldAsset.h)。

两个关键约束:

  1. 可随时间动画:大多数体积资产格式只代表体积的单个时间采样(single timeSample),因此filePath可以(也通常需要)通过 timeSamples 逐帧指定不同文件,实现体积动画;
  2. 不支持模式替换:当前版本的filePath不支持$F之类的帧号模式替换,必须逐帧显式编写时间采样。

动画写法示例(以 OpenVDBAsset 为例,Field3DAsset 同理,来自 overview.md):

def Volume "wisp" { float3[] extent = [(-57, -91, -44), (57, 31, -23)] rel field:density = </wisp/density> def OpenVDBAsset "density" { asset filePath.timeSamples = { 101: @./wisp_01.101.vdb@, 102: @./wisp_01.102.vdb@, 103: @./wisp_01.103.vdb@, 104: @./wisp_01.104.vdb@, } token fieldName = "density" } }
vectorDataRoleHint

USD 类型tokenFallback 值None(可选属性)

用于指明向量值字段的角色(role),例如"Color"。它决定字段在渲染器中以何种数据类型暴露,以及向量值是否需要被变换。允许的 token 为:

None, Point, Normal, Vector, Color

该列表在 schema.usda 中通过allowedTokens声明。对向量型 Field3D 字段(half3/float3/double3),设置正确的 role hint 可让渲染器做出正确解释,例如把字段数据当作法线(Normal)还是颜色(Color)。

继承自 Xformable 的属性

xformOpOrder

USD 类型token[]

继承自Xformable,控制字段 prim 的变换操作顺序。字段 prim 的 local-to-world 变换会将提取出的网格(grid)定位到世界空间,详见下文"变换与组织"。

继承自 Imageable 的属性

proxyPrim

USD 类型rel(关系)

指向代理 prim 的关系,用于指示可替代本 prim 进行渲染的轻量代理。

purpose

USD 类型tokenFallback 值default

prim 的渲染用途(如defaultrenderproxyguide),控制该 prim 是否参与渲染、以何种质量渲染。

visibility

USD 类型tokenFallback 值inherited

可见性控制,取值inheritedinvisible等,决定字段是否参与绘制。

在 Volume 中使用 Field3DAsset

Field3DAsset 通常不单独出现,而是作为 Volume prim 的字段被引用。usdVol 的 Volume schema(schema.usda)规定:Volume 由任意数量的 FieldBase 派生 prim 组成,每个字段通过命名空间前缀为field的关系绑定:

def Volume "Volume" ( prepend apiSchemas = ["MaterialBindingAPI"] ) { custom rel field:density = </Volume/densityField3D> uniform token purpose = "render" double3 xformOp:scale = (1, 1, 1) double3 xformOp:translate = (0, -3, 0) token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"] rel material:binding = </Materials/VolumeMaterial> def Field3DAsset "densityField3D" { token fieldDataType = "float" token fieldName = "density" token fieldPurpose = "cluster_0" asset filePath = @/f3ddata/Volumes_Cumulus01_Puff01M.1.f3d@ } }

要点:

  • 关系名即渲染器绑定名field:density中的 "density" 被渲染器用来把该字段与体积 shader 上的同名输入参数关联;
  • 字段 prim 名称无关紧要:Volume 引用字段靠关系而非字段 prim 的名字,因此单个字段 prim 可被多个 Volume 复用、或作为不同 shader 参数使用;
  • 推荐组织方式:除非需要多 Volume 共享,否则建议将字段 prim 置于 Volume 命名空间之下(如上面的</Volume/densityField3D>),便于场景组织与随 Volume 一起变换。字段 prim 提取出的网格由字段 prim 的 local-to-world 变换(外加外部资产编码内含的变换)定位到世界空间。

Volume 同样继承自 GPrim/Imageable,可绑定材质并通过 primvars 将数据接入 USD Material/Shader 管线;若无材质绑定,Hydra 会使用回退体积材质。

测试用例佐证

在 testenv/testUsdVolVolume.py 中,Field3DAsset 以 Python API 方式被实际创建与验证:

f1 = UsdVol.Field3DAsset.Define(stage, '/base/volume/f3dField') ... refVol.CreateFieldRelationship('diffuse', '/volModel/volume/f3dField')

该测试依次验证了:在 Volume 下定义 Field3DAsset prim、通过CreateFieldRelationship建立field:命名空间关系、以及场景引用的解析。这为"Field3DAsset + Volume field 关系"的用法提供了直接的实现证据。

常见问题与最佳实践

  1. 文件格式必须匹配filePath必须指向 .f3d 文件。若指向其它格式(如 .vdb),应改用对应的 OpenVDBAsset 等 schema,而不是 Field3DAsset。
  2. 动画数据务必逐帧写 timeSamples:由于不支持$F等模式替换,逐帧资产序列需要显式列出每个时间采样,如文档示例所示。
  3. fieldName与关系名是两个概念fieldName是资产文件内部字段的名字;Volume 上的field:xxx关系名服务于渲染管线的 shader 参数绑定。二者可以不同。
  4. 同名字段用fieldIndex消歧:当 .f3d 文件中存在多个同名 Field 时,用整数索引指定目标。
  5. fieldDataType尽量填写:它让消费者无需读取文件即可获知数据类型;在VolumeFieldAsset基类语义中缺失值视为错误。Field3DAsset 的取值限于half/float/double/half3/float3/double3
  6. 向量字段配合vectorDataRoleHint:对向量型字段设置Point/Normal/Vector/Color角色,可帮助渲染器决定数据类型与是否做向量变换。

延伸阅读

  • Schema 权威定义:usdVol/schema.usda
  • C++ 类实现:field3DAsset.h、volumeFieldAsset.h
  • Python 绑定:wrapField3DAsset.cpp
  • 体积与字段总览:usdVol userDoc overview
  • 测试用例:testUsdVolVolume.py
  • 姊妹 schema:OpenVDBAsset 文档

若要了解 Volume 的整体机制、字段关系的完整语义以及粒子场(ParticleField)等进阶主题,可继续阅读 usdVol 用户指南总览 与 usdVol 域相关文档。

【免费下载链接】OpenUSDUniversal Scene Description项目地址: https://gitcode.com/GitHub_Trending/ope/OpenUSD

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询