UnityGLTF 材质创建与赋值流程
本文档详细介绍了 UnityGLTF 中 GLTFSceneImporter 的 LoadSceneAsync 方法执行后,游戏对象材质的创建与赋值流程。
流程概览
详细流程
1. LoadSceneAsync 方法入口
LoadSceneAsync 方法是 GLTF 场景导入的入口点,它负责加载 GLTF 文件并初始化场景导入过程。此方法会调用 _LoadScene 方法来处理实际的场景加载逻辑。
2. 场景加载与节点构建
_LoadScene 方法会调用 ConstructScene 方法来构建场景,ConstructScene 方法会遍历场景中的所有节点,并为每个节点调用 ConstructNode 方法。
3. 节点构建与材质创建
ConstructNode 方法负责创建游戏对象和组件,当节点包含网格数据时,会创建 MeshRenderer 或 SkinnedMeshRenderer 组件,并从 _assetCache.MaterialCache 中获取材质数组,然后赋值给渲染器的 sharedMaterials 属性。
4. 材质创建流程
ConstructMaterial 方法是材质创建的核心,它根据 GLTF 材质定义创建 Unity 材质:
4.1 确定材质类型
根据 GLTF 材质定义中的扩展信息,确定材质类型:
- PBR 金属粗糙度材质 (KHR_materials_pbrSpecularGlossiness)
- 高光光泽材质
- 未光照材质
4.2 创建材质映射器
根据材质类型创建相应的材质映射器:
PBRGraphMap:用于 PBR 材质SpecularGraphMap:用于高光材质UnlitGraphMap:用于未光照材质
4.3 处理基础材质属性
设置材质的基础属性,如:
- Alpha 模式
- 双面渲染
- 混合模式
4.4 处理 PBR 材质属性
对于 PBR 材质,设置以下属性:
- 基础颜色因子
- 基础颜色纹理
- 金属度因子
- 粗糙度因子
- 金属度粗糙度纹理
4.5 处理材质扩展
处理各种材质扩展,如:
- KHR_materials_sheen(光泽)
- KHR_materials_anisotropy(各向异性)
- KHR_materials_transmission(传输)
- KHR_materials_volume(体积)
- KHR_materials_iridescence(虹彩)
- KHR_materials_specular(高光)
- KHR_materials_clearcoat(清漆)
5. 纹理加载流程
ConstructTexture 方法负责加载纹理资源:
5.1 获取纹理源
从 GLTF 纹理定义中获取纹理源(图像)ID。
5.2 构建图像
ConstructImage 方法会根据图像数据来源(URI 或缓冲区视图)加载图像数据。
5.3 构建 Unity 纹理
ConstructUnityTexture 方法会根据图像的 MIME 类型创建相应的 Unity 纹理:
- JPEG/PNG:使用
Texture2D.LoadImage加载 - KTX2:使用 KTX 插件加载(如果可用)
5.4 设置纹理属性
设置纹理的过滤模式和包装模式:
- 过滤模式:点采样、双线性、三线性
- 包装模式:重复、镜像、钳制到边缘
6. 材质属性设置
材质属性设置包括:
6.1 纹理属性
为各种纹理属性设置纹理、纹理坐标和纹理变换:
- 基础颜色纹理
- 金属度粗糙度纹理
- 法线纹理
- 自发光纹理
- 遮挡纹理
6.2 纹理变换
处理纹理变换,包括:
- 缩放
- 偏移
- 旋转
6.3 材质关键字
根据使用的材质特性启用相应的 Shader 关键字:
_SHEEN:光泽_ANISOTROPY:各向异性_TRANSMISSION:传输_VOLUME:体积_IRIDESCENCE:虹彩_SPECULAR:高光_CLEARCOAT:清漆
7. 材质缓存与赋值
创建的材质会被缓存到 _assetCache.MaterialCache 中,然后在 ConstructNode 方法中被赋值给渲染器:
// 获取材质数组
var materials = new Material[primitive.MaterialsIndices.Length];
for (int i = 0; i < primitive.MaterialsIndices.Length; i++)
{materials[i] = _assetCache.MaterialCache[primitive.MaterialsIndices[i]].UnityMaterial;
}// 赋值给渲染器
if (meshRenderer != null)
{meshRenderer.sharedMaterials = materials;
}
else if (skinnedMeshRenderer != null)
{skinnedMeshRenderer.sharedMaterials = materials;
}
总结
UnityGLTF 的材质创建与赋值流程是一个复杂但有序的过程,它从 GLTF 文件加载开始,经过场景构建、节点创建、材质创建、纹理加载、属性设置等多个步骤,最终将创建的材质赋值给相应的渲染器组件。这个过程支持多种材质类型和扩展,能够满足各种复杂的材质需求。
通过理解这个流程,开发者可以更好地定制和扩展 UnityGLTF 的材质处理功能,以满足特定的项目需求。
