基于Three.js的虚拟漫游服装店的构建

2024-04-12 03:16耿秋晚张海波
纺织科技进展 2024年3期
关键词:碰撞检测服装店漫游

耿秋晚,张海波

(北京服装学院信息中心,北京 100029)

目前服装品牌利用智能科技打破营销同质化成为了当下的趋势,许多服装品牌对虚拟现实营销进行了尝试[1]。虚拟现实开发技术在线上零售中可以再现购物中心、货架、产品等,通过虚拟服装店环境的搭建,可以为顾客营造良好的视觉氛围。通过数字服装延伸的虚拟陈列,可以拓宽线上展示形式、表达品牌理念,抢占消费者市场[2]。通过在服装店中漫游功能的实现,可以增加趣味性,吸引消费者并引发其购买行为,最终达到推动服装营销和增加营收的目的。

早期虚拟现实在线上主要通过VRML、Java3D 等技术实现,但这些实现技术均存在需要安装应用插件的共性问题[3],WebGL 技术解决了这个问题,它可以在所有兼容WebGL的浏览器中流畅地展示三维场景和模型[4]。Three.js是一个用于辅助WebGL 开发的框架和第三方库,它简化了Web GL 原生API中的底层细节,对3D 图形编程中常用的对象以简单和直观的方式进行了封装。Three.js功能强大,在开发过程中采用了很多图形引擎中的高级技巧,可以极大地提高性能[5-6],有效降低开发难度和复杂度。基于Three.js实现在Web端无插件构建虚拟服装店及漫游功能,对其中的关键技术进行介绍,如前期模型的数字化、基本场景的构建、碰撞检测、人物漫游等。

1 虚拟服装店的数字化

1.1 虚拟服装数字化

1.1.1 服装缝合模拟

服装是由衣片相互缝合而成,虚拟服装的生成也一样需要在衣片之间设置一对一缝线[7]。三维服装软件Style3D 是一个国产3D 数字化设计和建模工具。在Style3D 中导入虚拟模特,将版片在2D 窗口进行显示并对其摆放位置进行调整;然后在3D 窗口将版片合理放置在模特安排点上,对需要缝合的边使用缝合工具进行虚拟缝合;经过“模拟”,服装版片和缝纫线就会在模特身上模拟形成三维服装。服装的缝合模拟流程,如图1所示。

图1 服装虚拟缝合模拟流程

1.1.2 服装悬挂模拟

对上衣、连衣裙这2类服装进行悬挂的操作流程比较简单。在Style3D 中完成虚拟试穿之后,只需要将场景中的人体模特删除;然后添加衣架并将衣架移动到服装内部合适的位置,使衣架与服装的肩缝处于同一水平,再进行模拟即可;模拟完成之后对服装进行局部调整,直至达到理想的悬挂效果,如图2所示。

图2 上衣悬挂模拟过程

裤装、半身裙这2类使用裤架进行悬挂的服装模拟的操作流程相对比较复杂。使用上衣类型的衣架在进行模拟时,服装会在重力的模拟作用下落在衣架上,但是如果使用裤架以衣架模拟的方法直接进行模拟,服装会在重力的作用下直接掉落在地上。以裤装为例,介绍使用裤架进行悬挂模拟的流程,见表1。

表1 裤装悬挂模拟流程

1.2 虚拟陈列展示数字化

1.2.1 服装虚拟陈列展示方式

服装陈列是一种视觉表现手法和宣传手段,正挂陈列、侧挂陈列、叠装陈列和人模陈列是常见的4种陈列方式[8]。为使用户在漫游逛店时可以看到服装的全貌,充分展示服装细节,采取正挂陈列、侧挂陈列和人模陈列3种方式相结合,丰富陈列形式,增加视觉变化。在Style3D 中将悬挂模拟的服装生成正挂陈列装置和侧挂陈列装置,穿着模拟的服装生成人模陈列装置。服装虚拟陈列展示的3种方式如图3所示。

图3 服装虚拟陈列展示方式

1.2.2 虚拟零售空间布局

好的零售空间布局能够对店铺的整体外观进行展示,为用户提供最佳体验,实现用户的购买行为最大化。零售商开发了几种常见的布局方式,比如简单网格布局、回环布局、岛式布局、展会布局等[9]。采用如图4所示的展会布局方式,像展会一样把商品像艺术品那样布置。在店铺的边界处摆放商品,中间区域保持空旷,以便用户四处走动。由于商品前没有任何遮挡物,这种布局使可视区域最大化[9]。在Blender中对服装店进行建模,并将从Style3D 中导出的服装陈列装置导入Blender,按照此布局进行摆放。由于模型要在线上进行展示,为兼顾展示效果和速度,在Blender中对模型进行轻量化处理并导出。

图4 展会布局方式

2 Three.js场景构建

2.1 基本场景构建

Three.js基本场景的构建需要3 个基本的元素,即场景、相机和渲染器。场景是一个容器,主要用于保存、跟踪所要渲染的物体和使用的光源[10],任何物体都必须添加到场景中才有可能被绘制。相机决定在场景中能够看到什么,选择透视投影相机,它遵循近大远小的透视规律,更贴近人对现实生活的感知[11]。渲染器会基于相机和场景提供的信息,调用底层图形API执行场景绘制工作。

当场景或相机发生变化时,渲染器需要重新执行渲染方法对渲染图像进行更新,即渲染循环。渲染循环通过.request AnimationFrame()方法来实现,它以渲染函数作为参数,请求再次执行渲染函数渲染下一帧,在理想的情况下渲染帧率可以达到60 FPS。

2.2 加载三维模型

加载的服装店三维模型是通过Blender导出的gltf格式的压缩模型,必须经过DRACOLoader解压缩转换后才能使用[12](DRACOLoader,用加载出Draco库压缩的几何体的加载器)。解压缩时首先要在解析器中设置draco文件路径,使用gltf加载器GLTFLoader,用load()方法解析gltfJSON 文件,载入外部资源并通过回调函数返回结果[5],设置gltf加载器的draco解码器;用加载器加载模型,并将其添加到Three.js场景中。

3 碰撞检测

3.1 八叉树碰撞检测原理

碰撞检测的目的是避免出现人物在场景中漫游时,与其他模型发生穿透的问题,并提高虚拟场景的真实性。采用八叉树碰撞检测,它属于空间剖分的碰撞检测。八叉树是一种空间数据结构[13],它基于树型结构能够同时在多个尺度上进行空间细分,将一个围绕整个空间的包围体划分成8个更小的立方体空间,检测小立方体空间中是否存在碰撞点,如果没有检测到碰撞就不再对这个立方体进行划分;如果检测到碰撞点就对这个立方体进行再划分;这样一直划分下去,通过这种方法可以对碰撞点进行快速聚焦,检测到空间中物体碰撞发生的位置。

3.2 碰撞检测实现

3.2.1 创建人物碰撞体和场景碰撞组

创建漫游人物的碰撞体,在代码中创建一个胶囊体对象对人物进行模拟,通过胶囊体参数的设置可以模拟出人物的身高和宽度,如图5所示。创建碰撞组对象THREE.Group(),加载服装店模型后通过.add()方法将需要与漫游人物进行碰撞检测的物体添加进来,然后将碰撞组添加到场景中。

图5 胶囊碰撞体

在Three.js中创建八叉树空间对象,通过.from Graph Node()方法把碰撞组中所有的网格节点添加到八叉树空间对象中,进行八叉树的划分,确保所有网格对象被分配到合适的节点中。在进行碰撞检测时,可以避免对整个场景中的所有网格进行遍历,从而有效降低碰撞检测过程中的计算量,提高性能。

3.2.2 碰撞检测

碰撞函数是判断人物与物体发生的碰撞计算。在处理碰撞时涉及3个不同阶段,分别是碰撞检测、碰撞测定和碰撞响应[13]。

(1)碰撞检测。

碰撞检测即判断碰撞有没有发生。碰撞检测是碰撞处理的第一阶段,如果没发生碰撞,就不需执行之后的阶段。将人物的胶囊碰撞体作为参数,通过调用八叉树自带的.capsuleIntersect()方法,将胶囊碰撞体实例添加到八叉树空间中进行碰撞检测。

(2)碰撞测定。

碰撞测定即做出碰撞具体在什么地方出现。检测会返回一个结果result,若result的值为false则没有发生碰撞,若发生碰撞会返回一个碰撞的法向量和深度值。

(3)碰撞响应。

碰撞响应即做出碰撞产生的效果。场景中的碰撞检测,最基本的就是人物站在地面上不穿透地面。当检测到人物与地面发生碰撞时,对当前人物是否在地面上这个状态值由false变为true,为避免发生地面穿模现象,重力加速度应该停止,并将人物垂直方向的速度变为0。由于发生碰撞人物会陷进地面一定的深度,还需要对人物的高度位置进行还原处理,避免发生地面穿模现象。将碰撞的法向量与深度相乘得到需要进行调整的距离向量,将它作为参数传入胶囊碰撞体对象的.translate()方法中,即可还原人物位置。

4 人物漫游

4.1 漫游人物的创建和加载

漫游人物模型应是本身带有变形动画数据的模型。为了方便在Style3D 中直接导出obj格式的模特作为人物模型,在Mixamo网站选择人物待机状态、走路状态、跑步状态等动作将其赋予给人物;下载角色绑定使用与Blender 兼容的FBX 二进制格式;选择With Out Skin选项下载模型,这个选项下载的模型只有骨骼没有蒙皮,因此文件会很小。通过Mixamo生成的角色,如图6所示。在Blender中将多个动作动画合成在一个模型上,如图7所示,将模型导出为gltf格式,用于在Three.js代码中进行加载。加载时要通过GLTFLoader生成加载器对象,并通过.load方法加载路径中的人物模型到场景中。

图6 Mixamo网站制作动作

图7 Blender中合成动作

4.2 第三人称效果

第三人称是用户以旁观者的视角观察场景中的漫游人物与环境。这种视角通常处于用户所控制的漫游人物的上方,所以第三人称也被称为“上帝视角”[14]。这种上帝视角往往通过相机来实现,通过相机绑定人物,跟随人物的移动或旋转来调整位置或角度并始终观察场景。

4.2.1 相机绑定跟随人物

在将人物与相机进行绑定时,为人物添加一个空的子物体,让相机作为这个空对象的子物体,它们之间为父子绑定关系,如图8所示。这样设置,不但可以实现相机对人物的跟随,而且当相机跟随空对象一起旋转时也不会影响人物。通过相机的位置参数设置相机与人物的位置关系,让相机跟随在人物后面并设置合适的高度,通过相机的.look At()方法传入人物的位置让相机看向人物。

图8 绑定关系

4.2.2 相机自由视角控制

相机自由视角控制是指让相机跟随鼠标移动而变化,实现用户操纵鼠标以第三人称视角在场景中进行环视及俯视查看。在代码中实现时,对鼠标事件进行监听,根据鼠标在屏幕中的移动,左右旋转人物或上下旋转空对象。鼠标事件MouseEvent.movement X 提供当前和上一个mousemove事件之间鼠标在水平方向上的移动值,根据鼠标移动的方向进行计算。鼠标移动的距离越大,旋转角度就越大。鼠标垂直移动实现俯仰查看时,需要设定一个旋转临界角度值,当超出这个角度时就固定在这个角度,避免出现旋转到地面下或者上下翻转的情况。最终实现的第三人称效果如图9所示。

图9 第三人称视角

4.3 人物移动控制

通过键盘按键控制人物前后左右移动,键盘行为与其对应功能见表2。

表2 键盘绑定

根据键盘状态更新人物移动的速度,根据按下的时间累加状态,在更新函数中对控制人物移动的函数进行调用,实现人物的移动。设计按下“W”键时实现人物的前进,因此需对人物的前进方向向量进行设置,获取人物前进的方向,计算人物速度时需给人物的速度加上当前前进的方向通过.multiplyScalar()方法与时间相乘,就可以实现按键的时间长短控制人物移动的速度(按得越久速度越快)。设计按下“S”键时实现人物后退,因此需在设置速度时加一个负号。

当按键抬起后,人物应该由移动变为停止。添加阻尼的参数设置,在键盘状态为未按下的条件下,给速度添加一个反方向的力,通过.addScaled Vector()方法将本身的速度与反方向相乘,将得到的乘积加到速度向量上,实现人物移动逐渐停止的效果。

已知人物向上的方向与前进的方向,而侧方方向垂直于这2个方向形成的平面,因此可以运用向量叉积运算求出人物左右的方向,如图10所示。向上方向为(x1,y1,z1),前进方向为(x2,y2,z2),叉积运算求得侧方方向公式,如式(1)所示。代码实现时,正前方方向向量通过.cross()方法传入正上方方向,进行叉积运算得到侧方方向向量。人物移动的原理与前后移动一样,当按下“A”“D”键时,可以实现人物的左右移动。

图10 叉积运算求侧方向示意图

4.4 人物动画切换

在不添加动画的情况下,人物只能以静止僵硬的姿态在场景中移动,因此需要为人物添加动画,并根据不同的状态对动画进行切换,让人物在场景中完成走或跑的动画。

4.4.1 动作处理

为加载后的漫游人物模型创建一个动作混合器对象,然后对模型自带的动画数据进行for循环处理,根据模型中名为animations的成员对象的长度进行循环,animations的长度即模型包含动作的数量,通过animations[i].name可获取每一个动作的名称,通过mixer.clip Action方法可裁剪对应的动作[10]。这样就可以将动作名称和动画一一对应。

为人物设置一个初始的激活动作,加载漫游人物后让人物在没有移动时播放静止状态下的“待机”动画。要让程序正常播放动画,还需要在渲染函数中以mixer.update(delta)的形式告诉混合器本次渲染和上次渲染的时间差,调用update函数对每一帧动作进行更新。混合器将根据时间差来判断模型的顶点从上一个关键帧向下一个变形目标移动的距离[10]。

4.4.2 动作切换

为实现动作流畅切换,首先将上一个动作通过fadeOut方法慢慢淡出。动作切换时以.reset().set Effective TimeScale(1).set EffectiveWeight(1).fadeIn(0.3).play()链式调用的方式将动作进行重置并设置时间影响因子、权重影响因子、动作渐入等,调用play方法执行播放动画。THREE.Animation Mixer提供了可监听的事件,调用混合器的addEvent Listener函数指定事件监听函数,当一个动画彻底播放完成时,监听函数会收到“finished”事件通告。监听到动画结束后,执行将动作再次恢复到默认的人物静止休闲状态。当人物在运动状态下,会有一个水平的速度(x或z),这时需要根据人物的运动速度大小判断人物的动作(走或跑)。判断流程如图11所示。最终实现人物前进的动画效果如图12所示。

图11 动画切换判断流程

图12 人物前进动画

5 结束语

讨论了基于Three.js构建虚拟漫游服装店的关键技术和流程,实践表明:经过数字化处理的服装店三维模型可以在Web端实现可视化显示及场景漫游。分析了服装店场景中服装数字化不同的模拟方式,基于虚拟陈列展示和零售空间布局的理论对服装店场景中的陈列展示进行数字化;介绍了Three.js中场景构建的流程,结果页面中实现以良好的预览效果对服装店进行显示;基于八叉树原理的碰撞检测可以避免穿透现象,实现人物在场景中的漫游和交互,用户可以方便地在网页中进行虚拟漫游逛店。基于现有成果,可进一步开展对服装三维交互等功能的研究,提供更加丰富的用户购物体验。

猜你喜欢
碰撞检测服装店漫游
全新预测碰撞检测系统
基于BIM的铁路信号室外设备布置与碰撞检测方法
热闹的服装店
霹雳漫游堂
Unity3D中碰撞检测问题的研究
服装店
NASA漫游记
热闹的街道
BIM技术下的某办公楼项目管线碰撞检测
森林服装店