一个 Collada 文件本质上是一个 XML 文档,它使用一组特定的标签和属性来描述三维模型数据,例如几何网格、材质、光照、动画以及场景层级。理解它的结构对于解析、导入或导出 DAE 模型非常有帮助。Collada 不是直接存储渲染指令,而是把资源定义与场景使用分离开来,数据以模块化的库形式组织,并通过 id 引用完成装配。

整体骨架与命名空间
一个有效的 Collada 文件以 XML 声明开头,根元素是 <COLLADA>,它通过 xmlns 属性声明命名空间,通常指向 COLLADA 规范的官方 URI。version 属性标明规范版本,常见为 1.4.1 或 1.5.0。根元素内部主要由资产信息 <asset> 和若干资源库组成,例如 <library_geometries>、<library_visual_scenes>、<library_materials> 等。
这种把资源定义与场景使用分离的设计是 Collada 的核心思想。库中定义的对象并不直接出现在最终渲染画面里,只有被 <scene> 或者 <node> 实例化之后才会形成一个可见的场景。下面是一个最小可用的 DAE 文件骨架,它只声明了命名空间和资产信息,但没有任何几何数据。
<?xml version="1.0" encoding="utf-8"?>
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
<asset>
<contributor>
<author>ExampleAuthor</author>
</contributor>
<created>2023-01-01T00:00:00Z</created>
<modified>2023-01-01T00:00:00Z</modified>
<unit name="meter" meter="1"/>
<up_axis>Y_UP</up_axis>
</asset>
<scene>
<instance_visual_scene url="#DefaultScene"/>
</scene>
</COLLADA>
上面的骨架里 <asset> 用于记录作者、创建时间、单位和坐标轴朝向等信息,这些信息对模型的正确解释非常关键。例如 <up_axis> 若写成 Z_UP,则导入工具需要做轴翻转,否则模型会躺倒或方向错误。不同工具生成的 DAE 文件在 asset 部分可能存在差异,但根元素和 xmlns 声明一般是固定的。
几何数据与网格定义
模型的实际形状存储在 <library_geometries> 中。每个 <geometry> 拥有唯一 id,内部通常包含一个或多个 <mesh> 元素。网格由顶点位置、法线、纹理坐标等数组构成,这些数组通过 <source> 和 <float_array> 定义,并通过 <technique_common> 下的 <accessor> 说明数据排列方式。
例如一个三角形的三个顶点位置可能这样表示:
<library_geometries>
<geometry id="triangle-lib" name="triangle">
<mesh>
<source id="triangle-lib-positions">
<float_array id="triangle-lib-positions-array" count="9">
0 0 0 1 0 0 0 1 0
</float_array>
<technique_common>
<accessor source="#triangle-lib-positions-array" count="3" stride="3">
<param name="X" type="float"/>
<param name="Y" type="float"/>
<param name="Z" type="float"/>
</accessor>
</technique_common>
</source>
<vertices id="triangle-lib-vertices">
<input semantic="POSITION" source="#triangle-lib-positions"/>
</vertices>
<triangles count="1">
<input semantic="VERTEX" source="#triangle-lib-vertices" offset="0"/>
<p>0 1 2</p>
</triangles>
</mesh>
</geometry>
</library_geometries>
这里的 <float_array> 包含 9 个浮点数,代表 3 个顶点的 xyz 坐标。<accessor> 的 stride 属性等于 3,表示每个顶点读取 3 个数值。<vertices> 把 POSITION 语义与位置 source 绑定,而 <triangles> 则通过 <p> 中的索引列表描述三角形图元。索引 0、1、2 分别对应顶点数组的前三个点。
真实模型往往还包含法线和 UV 坐标,这时可以在 <triangles> 中增加多个 input 节点,并通过 offset 区分不同数据流的索引。例如 offset 0 对应顶点索引,offset 1 对应法线索引,offset 2 对应纹理坐标索引。每个三角形的数据就会按三个一组交叉写入 <p> 中。解析时需要根据 offset 和 stride 规则还原出每个顶点的完整属性,这是 Collada 几何部分最容易出错的地方之一。
场景图与实例化
光有几何数据还不足以成为可渲染的场景。Collada 通过 <library_visual_scenes> 组织节点层级,节点使用 <node> 表示,可以在内部用 <matrix> 指定局部变换,也可以嵌套子节点形成父子关系。最终需要把几何对象实例化到节点上,用 <instance_geometry> 引用对应的几何体 id。
<library_visual_scenes>
<visual_scene id="DefaultScene">
<node id="TriangleNode" name="triangle">
<matrix>
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
</matrix>
<instance_geometry url="#triangle-lib">
<bind_material>
<technique_common>
<instance_material symbol="Material0" target="#material0"/>
</technique_common>
</bind_material>
</instance_geometry>
</node>
</visual_scene>
</library_visual_scenes>
这里的 <instance_geometry> 通过 url 属性引用之前定义的几何体,链接采用 XML 片段标识符形式,如 #triangle-lib。矩阵 16 个数值默认按行主序存储,表示单位变换。节点可以添加平移、旋转、缩放等动画通道,但基本的静态摆放使用 matrix 就足够了。
需要特别注意的是,Collada 中的 URL 引用是场景组织的关键。除了 geometry,材质、效果、动画等资源也都使用 #id 形式进行引用。如果某个引用指向的 id 不存在,解析器通常会报错或忽略该节点。同时,节点层级可以嵌套,子节点的变换会叠加父节点的变换,形成最终的模型矩阵,因此导入时需要从根节点开始递归计算世界变换。
材质与效果
要让模型有颜色和光照反应,需要定义材质和效果。效果库 <library_effects> 描述着色器参数或固定渲染管线的光照模型,材质库 <library_materials> 则把效果绑定到某一种材质实例。
<library_effects>
<effect id="effect0">
<profile_COMMON>
<technique sid="common">
<lambert>
<diffuse>
<color>1 0 0 1</color>
</diffuse>
</lambert>
</technique>
</profile_COMMON>
</effect>
</library_effects>
<library_materials>
<material id="material0" name="red">
<instance_effect url="#effect0"/>
</material>
</library_materials>
在 <profile_COMMON> 中可以使用 Lambert 或 Blinn 光照模型,通过 <diffuse>、<ambient> 等元素设置反射颜色。这里使用 Lambert 模型并设置漫反射为红色。材质定义完成后,场景节点在实例化几何体时通过 <bind_material> 引用材质 id,从而把材质应用到网格上。
如果模型包含纹理贴图,效果中会引用 <library_images> 中的图片资源,并在 sampler2D 和 surface 节点中定义采样方式。现代渲染引擎导入 Collada 时,通常会从 profile_COMMON 中提取漫反射颜色和纹理路径,再转换为引擎自身的材质格式。解析这一部分需要同时处理材质绑定、纹理坐标通道以及多个纹理单元之间的关系。
总体而言,Collada 的 XML 格式清楚地把资产定义为可复用的模块,再通过实例化和引用构建出完整场景。掌握几何 source、场景 node 和材质 effect 三层结构之后,就可以较为顺利地读取、修改或生成 DAE 模型文件了。