一、背景
2016年准备从欧特克离职的前后,有段时间比较迷恋WebGL相关的内容,特别是ThreeJS这个框架。看了Javascript和ThreeJS的教程后尝试着写了一下,比较顺利,通过ThreeJS官网上的示例拼凑出一个能工作的三维展示页面,居然比预想的要容易上手很多。
后来又看了下nodeJS,感觉好像也有能力可以学一学,磕磕绊绊,通过复制黏贴、拼凑代码、来回调试自己写了一些,最后在开发同事的帮忙下把threedpad.com这个网站部署到了阿里云ECS上。
二、想法与思路
2.1 初始想法
2015年,在欧特克支持Homestyler项目的时候,团队内做过一个家具展示的小项目Configurator,但是非常遗憾由于各种原因最终没有做起来。
Autodesk Homestyler Configurator
这个项目的想法比较简单,用一句话概括:线上家具选配与360°展示。
利用Homestyler产品已有模型内容和模型渲染能力,能够渲染出照片级别真实渲染图,加上后台模型资产管理系统后,能够成为一个相对完整的产品。替代摄影棚实拍,利用三维渲染技术满足家具厂商线上家具展示、配置、并即时预览的需求,这个需求是现实存在的并且可行的,而且能降低时间和钱成本,宜家当时已经开始这么做了。
就前端的展示来说,具有以下主要能力:
- 切换材质。举例:在网页上预览一款沙发,需要能够切换同一款沙发的不同材质,在真皮、布艺之间进行切换。
- 切换模型。举例:在网页上预览一款沙发,需要能够切换同一款沙发的不同造型,在单人、双人、三人沙发之间进行切换
- 360°全角度的预览。举例:在网页上预览一款沙发,不是固定一个角度,可以360°旋转展示查看。
当时采用的方案使用图片展示,允许用户拖动360°旋转预览,效果如下图。
鼠标点击拖动时旋转效果
在做Configurator的过程发现有以下问题:
- 摄像机的俯仰角度是固定不可变的。意味着:无法查看产品模型的底部或顶部。
- 总是会有像定格动画那种跳帧的感觉,就算360°每1°放一张图片也会有。
- 最严重的问题是:产品模型选配项非常多的情况下,用到的图片就特别多。
- 比如上图这个椅子的展示,有2个坐垫的布艺材质,有2个框架的木头材质。360度转一圈最少36张图,分别渲染坐垫的2个布艺材质和框架的2个木头材质就是36*(2+2)的图片数量,然后再分别组装,最终图片数量是36*(2*2),看上去还能接受。
- 但如配置数量特别多,如下图中的座椅:有2个靠背材质、4个坐垫材质、2个支撑架材质、3个椅腿材质,分别渲染后输出图片数量是36*(2+4+2+3),然后再分别组装,最终图片数量是36*(2*4*2*3)。也就是说4种配置互相搭配,会有48种配置方式,每种配置方式有36张图片,这就非常多了。
- 如果是橱柜、办公柜这种需要允许用户对每一格柜子进行不同的配置,那就是根本不可能完成的任务。
Autodesk Homestyler Configurator
2.2 迭代思路
使用WebGL的方式可以很好的解决这个问题。2016年的ThreeJS自带PBR材质MeshStandardMaterial已经能够调整出不错的效果,而且SketchFab上面也见到过用户上传的家具模型,展示效果还是可以接受的,所以值得用ThreeJS试一试。
相比2.1章节中的思路,使用ThreeJS有以下优势:
- 图片资源不会指数增长,提供展示对象配置的各种贴图、模型即可,在WebGL画布中可以任意加载并进行组合。
- 在WebGL的三维场景中可以任意角度旋转、缩放。
- 不需要大量的渲染时间,使用带有法线的高质量贴图就能获得不错的效果。
以上图中的黄色椅子举例(链接):
坐垫提供黄色和蓝色两种材质切换,除颜色贴图外,分别给了一张凹凸贴图(见下图)。
框架提供了深色木纹和浅色木纹两种材质切换,除颜色贴图外,分别给了一张凹凸贴图(见下图)。
为增加真实效果,分别给靠垫、坐垫、框架添加了一张AO贴图,展UV需要注意,threejs中只使用一套UV,这套UV要适用于材质贴图也要适用与AO贴图,切换材质配置时,AO贴图是同一张,不替换的(见下图)。
模型分部分加载,为了在WebGL环境中进行模型的切换,所以靠垫、坐垫、框架分别是一个单独的模型(见下图)。
基本思路大概就是这样,请看下一章示例。
三、示例
3.1 配置切换
每个示例中:
- 可以通过右上角GUI控件切换模型的材质和造型配置。
- 可以通过左下角控制按钮控制旋转、全屏等操作。
3.2 示例链接
3.2.1 桌椅



点击图片在新窗口中查看Demo3.2.2 沙发



点击图片在新窗口中查看Demo3.2.3 产品

点击图片在新窗口中查看Demo3.2.4 橱窗展示

点击图片在新窗口中查看Demo四、小结
项目过程中实际还是发现了很多问题:
- 代码能力很弱。只能通过学习示例然后拼凑,所以有些很乱。
- 贴图分辨率问题。线上版本导出使用1024分辨率的贴图,WebGL画布中zoomin后贴图分辨率还是不够的。
- 模型尺寸过大导致加载速度慢。用ThreeJS加载的都是.obj模型,尺寸非常大,等项目做完后发现有个WebGL专用的格式,叫Gltf,无论导出.gltf还是.glb面片模型数据的尺寸要比.obj小得多得多。
- 模型内容制作工作流过于复杂。都在3dsMax中调整好后然后把三维面片、贴图分别载入WebGL画布中,然后再用ThreeJS的MeshStandardMaterial材质在WebGL画布中线上调试效果。等项目做完后才知道Gltf是可以支持PBR材质一起打包的,并且ThreeJS也支持载入。
- 显示效果
- 三维展示效果没有达到预期。
- 内容制作过程中显示效果与实物家具的显示效果差异没法控制。
- 性能功耗问题。没有优化,在手机端打开时,手机的耗电非常厉害。