更多详情可跳转 glTF 官方网站
glTF(GL Transmission Format)是 khronos 发布的一种能高效传输和加载 3D 场景的规范,是 3D 领域中的 "JPEG" 格式,其功能涵盖了 FBX、OBJ 等传统模型格式,基本支持 3D 场景中的所有特性,其插件机制也使用户可以灵活地自定义实现想要的功能。
glTF 的导出产物一般分为两种:
以上两种产物在 Galacean 中都已支持,如何选择产物的导出类型可以按照项目实际情况决定。
glTF2.0 是目前 Galacean 推荐的首选 3D 场景传输格式,Galacean 对 glTF2.0 的核心功能和插件都做了很好的支持:
glTF 拥有非常多的特性,官网提供了大量的示例进行参考,Galacean 也提供了一份复刻版本进行快速浏览,可以通过以下 glTF List 切换不同的 glTF 模型。
Galacean 目前支持以下 glTF 插件,若 glTF 文件中包含相应插件,则会自动加载相应功能:
插件 | 功能 |
---|---|
KHR_draco_mesh_compression | 支持 Draco 压缩模型,节省显存 |
KHR_texture_basisu | 支持 KTX2 纹理压缩,节省显存 |
KHR_lights_punctual | 支持多光源组合,会解析成引擎的光源,详见光照教程 |
KHR_materials_pbrSpecularGlossiness | 支持 PBR 高光-光泽度工作流 |
KHR_materials_unlit | 支持 Unlit 材质 |
KHR_materials_variants | 允许渲染器存在多个材质,然后通过 setMaterial 接口进行材质切换 |
KHR_mesh_quantization | 支持顶点数据压缩,节省显存,如顶点数据一般都是浮点数,此插件可以保存为整型 |
KHR_texture_transform | 支持纹理的缩放位移变换,可以参考 TilingOffset 案例 |
KHR_materials_clearcoat | 支持材质的透明清漆度拓展,可以参考 Clearcoat 案例 |
KHR_materials_ior | 支持材质的折射率设置 |
KHR_materials_anisotropy | 支持材质的各向异性设置,可以参考 各向异性 案例 |
GALACEAN_materials_remap | 支持编辑器材质映射 |
如果官方内置的插件不能满足您的需求,我们还提供了拓展插件的方法。
举个例子,如果 Unity 导出了以下 glTF 插件,希望能根据材质拓展 Unity_Material_Plugin
生成新的自定义材质,然后根据灯光插件 Unity_Light_Plugin
表示想在某个节点上面加一个灯光:
{
...
materials:[{
extensions:{
Unity_Material_Plugin:{
color: [1,1,1],
...
}
}
}],
nodes:[{
extensions:{
Unity_Light_Plugin:{
type:"point",
...
}
}
}]
}
按照上面的例子,我们注册一个材质插件,第二个参数 GLTFExtensionMode.CreateAndParse
表示这个插件是用来创建实例和解析的:
@registerGLTFExtension("Unity_Material_Plugin", GLTFExtensionMode.CreateAndParse)
class UnityMaterialPluginParser extends GLTFExtensionParser {
createAndParse(context: GLTFParserContext, schema: {color,...other}}): Promise<Material> {
const { engine } = context.glTFResource;
const yourCustomMaterial = new Material(engine,customShader);
...
return yourCustomMaterial;
}
}
按照上面的例子,我们注册一个灯光插件,第二个参数 GLTFExtensionMode.AdditiveParse
表示这个插件是在原来实例的基础上进行一些增量解析的,比如在这个实体上添加一个光源:
@registerGLTFExtension("Unity_Light_Plugin", GLTFExtensionMode.AdditiveParse)
class UnityLightPlugin extends GLTFExtensionParser {
additiveParse(context: GLTFParserContext, entity: Entity, extensionSchema: {type,...other}): void {
entity.addComponent(type==="point"?PointLight:DirectLight);
...
}
}
如果上面的方法还不能满足您的需求,还可以完全自定义解析管线,用来重写解析的逻辑:
@registerGLTFParser(GLTFParserType.Material)
class CustomMaterialParser extends GLTFParser{
parse(context: GLTFParserContext, index: number): Promise<Material> {
const materialInfo = context.glTF.materials[index];
...
return materialPromise;
}
}
engine.resourceManager
.load<GLTFResource>({
type: AssetType.GLTF,
url: "https://gw.alipayobjects.com/os/bmw-prod/150e44f6-7810-4c45-8029-3575d36aff30.gltf"
})
.then((gltf) => {
const entity = rootEntity.createChild();
entity.addChild(gltf.defaultSceneRoot);
})