一、客户常见的困惑
为什么网上的三维模型那么便宜?买来的三维模型能不能用?
- 网上很多售价非常低廉的三维城市模型,通常用途不是为了三维实时引擎渲染用的,而是作为离线渲染宣传视频用;这些模型的流通渠道并不正规,所以价格便宜;
- 这些建模建模的时候没有考虑实时渲染的场景,通常体积巨大,无法在数字孪生这种实时渲染的场景下使用;
- 如果要强行优化、轻量化此类模型,成本可能比重建还高;因此不建议在网上购买低价三维模型;
为什么其他现成专业三维软件的三维模型不能用?
- 三维模型是一个非常宽泛的概念,数字孪生业务场景涉及的模型往往特指某类实时渲染引擎可以使用的三维模型格式;数字孪生三维引擎能支持的三维模型格式只是一部分;
- 有很专业的行业软件也生成三维模型,比如Revit、ProE等等;此类三维软件往往是用于计算机辅助制造、建筑设计,生成的三维模型体积巨大、构件复杂、数据结构复杂,需要专门的处理才能导出数字孪生三维引擎能使用的格式;
- BIM模型通常是当做三维空间数据源对待,而不是单纯的三维模型;需要有专门是数据工作流程,将BIM模型处理为轻量化三维展示模型和空间关系数据,再进入三维渲染引擎使用;
为什么不能全城手工建模?
- 规范的三维模型是需要建设成本的,全程建模的成本异常高;
- 全程手工建模的模型体量也是异常巨大,渲染引擎一般无法全部渲染;
- 全程实景建模通常采用倾斜摄影这样更加自动化的智能建模手段;
二、三维模型质量评价标准
2.2 如何评价通用三维模型的质量?(专业模型如BIM/CAD除外)
- 1、艺术角度
- 美观度:主管上感受是否美观;
- 设计工作流是否规范
- 是否采用规范的PBR工作流进行制作贴图;如果工作流不规范,那在渲染引擎中模型的呈现和三维建模软件中会有很大的差距;
- 几何体构面、法线、uv等是否规范合理;如何几何数据不规范,在渲染引擎中的光影效果、贴图效果会受到很大影响;
- 2、技术角度
- 面数是否合理:面数越多渲染性能越差,在满足视觉的情况下,模型三角面数越少越好;
- 比例是否正确,上方向是否正确:建议按真实世界比例进行建模,Y+为上方向;
- 必要属性是否完备:
- 几何体ID:模型与点击交互等识别的数据;
- 动画ID:具备动画的模型,用于调用特定的动画片段;
2.3 如何把三维模型的空间数据与业务数据进行融合?
- 三维模型与业务数据需要有统一的坐标参考系,比如都是基于真实的地理坐标参考系,并且是按真实世界的空间大小进行建模;
- 三维渲染引擎需要支持良好的地理坐标参考系,比如对二三维一体真实的地理坐标系支持;
- 三维模型需要有挂载业务数据的能力,比如模型的构件需要有唯一辨识ID,并且有良好的属性描述,才能与业务数据进行融合、互动;这就需要大量应用BIM模型;
三、基于WebGL的数字孪生引擎需要什么模型格式?
3.1 最适用于WebGL引擎的模型格式:gltf
- gltf格式:glTF格式的模型是目前主流推荐的Web 3D模型格式,glTF格式为3D内容的数据格式提供统一的标准、互联网方便传输、浏览器高效渲染;
- gltf实用工具
- gltfViewer查看器,检查模型是否能够被浏览器正常渲染;下载地址: https://github.com/donmccurdy/three-gltf-viewer/releases
- fbx2gltf转换工具,将fbx模型转换为gltf格式;下载地址:https://github.com/facebookincubator/FBX2glTF
- blender建模工具,原生支持gltf模型导出;下载地址:https://www.blender.org/download/
3.2 使用gltf格式模型常见的问题
- 模型本身有问题
- 症状:加载报错或者无法显示
- 排查工具:用gltfViewer查看是否能正常渲染,如果不能,则模型有问题
- 解决办法:用建模软件重新导出
- 模型比例有问题
- 症状:用gltfViewer查看能正常渲染,三维引擎无法显示
- 排查工具:在建模软件里面查看模型比例是否与真实世界一致,3米高的楼建模也需要3米高
- 解决办法:导出模型按真实比例导出,并将视角缩放到合适位置
- 模型位置有问题
- 症状:用gltfViewer查看能正常渲染,三维引擎无法显示
- 排查工具:检查镜头焦点是否和模型放置的地理位置接近
- 解决办法:将模型放置在正确的地理位置,并调整合适的镜头视角
- 模型性能有问题
- 症状:模型体积较大,三维引擎渲染非常卡顿;或者显存不够崩溃;
- 排查工具:打开chrome浏览器,查看帧率比较低,显存占用高;
- 解决办法:1、换用更好的显卡;2、将模型重新处理,减少面数;3、单独处理贴图,缩小分辨率,如2k降为1k,减少显存开销;
3.3 三维模型在数字孪生项目中的建议工作流(基于WebGL引擎)
- 使用blender进行建模;
- 建模比例与真实世界1:1;
- 导出为gltf格式;
- 用gltfviewer验证gltf模型正确之后再导入三维引擎;
3.4 基于blender的建模与三维引擎调用规范
3.4.1 为何推荐blender进行gltf建模?
- blender是原生支持gltf模型最好的三维建模软件;
- blender是开源软件,中小企业无需承担昂贵的三维软件购买费用;
- blender是集建模、雕刻、后期等一站式三维加工软件,能大幅降低项目费用;
3.4.2 建模与动画规范
1、建模规范:blender如何输出必要的属性到gltf模型
- 模型对象:gltf中单个模型对象对应的是blender当中单个mesh对象;
- 组对象:gltf中组对象对应的是blender当中parent对象,通常使用空对象作为parent对象,将多个mesh成组;
- blender建模中模型对象与组对象
- gltf模型中对应的模型对象与组对象
2、动画规范:引擎如何调用gltf中包含的动画片段
- 在GLTF规范中,动画片段有专门的定义:gltf模型中animations的channel的name,就是blender中定义动画的action名字;
- blender中mesh编组动画命名
- gltf模型中对应的动画命名
- 在引擎中就直接可以调用动画,通过blender中定义动画的action名字;
// Play a specific animation in three.js const clip = THREE.AnimationClip.findByName( clips, 'dance' ); const action = mixer.clipAction( clip ); action.play(); //详细文档参见:https://threejs.org/docs/index.html#manual/en/introduction/Animation-system
四、基于DataV.CityPro引擎的三维模型交互实践
这里只讨论常规三维模型的使用,专业三维模型如BIM/倾斜摄影等在后续系列专题中详细讨论;
通常在WebGL引擎中调用GITF模型动画的工作流包括三部分:
- 1、在建模软件中制作动画;
- 2、导出GLTF模型;
- 3、在WebGL引擎中导入GLTF模型并调用动画或操作模型的某些构件;
4.1 DataV.CityPro模型加载器的功能
DataV.CityPro模型加载器针对模型的交互主要有以下功能:
- 模型展开:将模型的单个构件进行移动操作;
- 模型分组展开:将模型的多个构件进行移动操作;
- 材质渐变:覆盖某些构件的材质,如高亮颜色等等;
- 模型动画:调用gltf模型中的动画片段;
- 路径动画:将模型按路径进行移动;
4.2 模型的动画调用
- step 1,在DataV中添加“城市三维构建器”和“Tab列表”两个组件,“Tab列表”用于控制gltf模型动画的状态;
- step 2,“城市三维构建器”中添加“模型加载器”用于加载gltf模型,并设置好模型的地理位置在相机的视野之内;
- step 3,如果不知道模型中包含的动画名,可以用gltfviewer打开查看对应的模型动画名,引擎调用需要;
- step 4,在蓝图中调用gltf模型动画:使用蓝图的数据处理节点,将gltf模型中的动画片段名传递给模型加载器的动画调用方法;
// 调用模型动画需要返回的数据格式 { name: "fly", loopType: "LoopRepeat" } //动画循环参数列表 loopType: LoopRepeat | LoopOnce | LoopPingPong
-
- step 5,查看效果;
此处为语雀视频卡片,点击链接查看:模型动画.mp4
4.3 路径动画:让模型按三维空间的轨迹移动
- step 1,在蓝图中调用路径动画:使用蓝图的数据处理节点,将路径数据传递给模型加载器的路径动画方法:
{ "path": [ [ 121.493636,//经度 31.236628,//纬度 100//海拔高度 ], ...//更多路径位置数据 ], "duration": 20000,//模型移动的动画时间,毫秒制 "loop": true//动画是否循环,布尔值 }
-
- step 2,如何需要同时启动动画,按调用动画方法加入调用动画的蓝图节点;
- step 3,目前组件需要把模型方向在移动的时候旋转一下,可以加入一个调用组件“更新配置”方法的节点,更新组件的Y轴旋转1弧度,方法如下:
{ "position": { "rotationY": 1 } }
- step 2,查看效果;
此处为语雀视频卡片,点击链接查看:路径动画.mp4
4.4 模型分组展开:部件的操纵
模型加载器组件中“模型展开”、“模型分组展开”两个方法的区别是:“模型展开”针对一个对象(mesh对象/成组的对象),“模型分组展开”针对一组对象(mesh对象/成组的对象);
- step 1,建模时对需要操作的构件分别进行命名,分开操作的构件需要是独立的mesh对象;支持成组的对象;
- step 2,开发可以在gltf文本中查找需要操作的构件名称,可以操纵移动成组的对象;
- step 3,在蓝图中调用gltf模型动画:使用蓝图的数据处理节点,将gltf模型中的构件/构件组的ID传递给模型加载器的展开方法;
//成组展开API数据结构 [ { "id": ["shell"],//模型构件名称 "offset": 0.8,//模型构件位移的距离,米制 "axisType": "y",//模型构件位移的方向,xyz三种 "duration": 4000//模型构件位移的动画时间,毫秒制 }, { "id": ["tail"], "offset": -1.5, "axisType": "x", "duration": 100 }, ...//更多模型构件/构件组 ] //如果是调用模型加载器组件的“模型展开”操纵单个构件对象,按以下数据结构: { "id": ["shell"],//模型构件名称 "offset": 0.8,//模型构件位移的距离,米制 "axisType": "y",//模型构件位移的方向,xyz三种 "duration": 4000//模型构件位移的动画时间,毫秒制 }
- step 5,查看效果;
此处为语雀视频卡片,点击链接查看:模型展开.mp4
4.5 材质渐变:将某个特定的模型构件的材质进行更改,达到高亮、隐藏的效果
- step 1,在蓝图中调用gltf模型动画:使用蓝图的数据处理节点,将gltf模型中的构件/构件组的ID传递给模型加载器的"材质渐变"方法;
{ "id": ["shell"],//模型构件名称 "duration": 1000,//模型构件渐变的动画时间,毫秒制 "options": { "color": "#ff0000",//模型构件渐变颜色值 "opacity": 0.7//模型构件渐变颜色透明度 } }
- step 2,查看效果;
此处为语雀视频卡片,点击链接查看:材质渐变.mp4
4.6 模型点击交互:将某个特定的模型构件的ID作为数据传递给其他组件
- 在项目中,有一种非常常见的需求就是点击模型之后,将被点击的模型的构件ID或者构件组的ID传递出来,作为API或者数据库的查询参数,然后再拉取其他业务数据;
- 根据gltf模型的规范,只要将构件或者构件组的“name”字段抛出即可,蓝图节点如下:
- 查看效果:
此处为语雀视频卡片,点击链接查看:模型交互demo.mp4
五、总结
- 三维建模需要找专业的供应商进行制作,需要有标准规范和质量检验;
- 三维模型是一个很宽泛的概念,大部分三维模型是无法直接应用于数字孪生项目的;
- 建模、模型数据加工都需要制定规范,才能支持好数据融合;
- 需要使用合适的数字孪生引擎才能发挥三维模型的效果;