TGideas

分享

Web3d模型拼装类活动技术点整理

经验·团队博客

2019-10-24

开灯
最近看到不少3d模型拼装的活动专题,这里整理一下这类需求涉及到的技术点,以及技术场景的拓展。

最近接触不少3d模型拼装的活动专题,这里整理一下这类需求涉及到的技术点,以及技术场景的拓展。

首先模型拼装活动大致上就是指这种类型:

通过调整3d模型的部件,组装成新模型的玩法。

这样的专题涉及到的技术点有:

  • web3d模型加载
  • web3d模型单体节点对象属性控制
  • web3d模型部件材质控制
  • web3d模型骨骼蒙皮控制

由于目前我基本是使用3dsmax和threejs进行处理,所以下面都以3dsmax导出以及threejs导入为例进行介绍。


 web3d模型加载

在threejs中,导入模型的方式有很多

但threejs代码写法大同小异:

引入对应的loader的js文件,然后加载(略去threejs的场景基础搭建)

<script src="GLTFLoader.js"></script>
new THREE.GLTFLoader().load( 'model.gltf', function ( gltf ) { })
<script src="FBXLoader.js"></script>
new THREE.FBXLoader().load( 'model.fbx', function ( object ) { })

关于web模型载入,最推荐的是gltf格式。

关于gltf格式更多介绍可以看这个https://www.khronos.org/gltf/

在3dsmax安装babylon插件https://doc.babylonjs.com/resources/3dsmax,安装后导航条会出现Babylon


 web3d模型单体节点对象属性控制

threejs加载3d模型后,模型内部结构如图

比较常用的模型节点有 group,object3d,mesh

通过遍历模型的children数组或者使用.traverse函数,则可以获取各个子节点。

这些节点都有position,rotation,scale,对这些属性进行操作,执行

object.position.set(x, y, z);
object.rotation.set(x, y, z);
object.scale.set(x, y, z);

则可以对指定部件位移旋转缩放。

group节点

group节点相当于一个空节点,用来集合其他的节点,比如4个轮子的模型mesh放在同一个group里,这样移动group则能同时操作4个轮子。

object3d节点

object3d节点是threejs里的基础节点的,使用的时候和group有点像,但它往往由同一个“部件”组成,比如“手臂和手指”,“车头和车窗”,而这些子节点拆分的原因大部分是因为它们使用的贴图的材质是不同的,子节点是mesh节点。

mesh节点

mesh节点是一个包含geometry几何体和Material材质的节点,通常我们可以通过替换mesh节点来改变当前模型的显示,也可以改变mesh的材质和贴图改变画面的呈现。模型间相互嵌套通过.add即可挂载。

group.add(object3d)
group.add(mesh)

还有个bone节点,可以理解为特殊的object3节点

通过修改节点visible属性,可以显示或隐藏模型

mesh.visible = false;

web3d模型部件材质控制

当获取模型的mesh节点后,我们可以通过改变material的贴图路径,直接进行贴图替换

mesh.material.map.image.setAttribute('src', url);
mesh.material.map.needsUpdate = true;

material里往往有各种贴图,如:

alphaMap:透明贴图

metalnessMap:金属质感贴图

roughnessMap:粗糙度贴图

envMap:反射贴图

……

不过这些贴图我们一般需要在模型编辑器内提前贴好,而在代码中改变的,大多数时候只是修改主贴图map。

(左边只有主map贴图效果,右边增加金属,反射,高光贴图效果)


web3d模型骨骼蒙皮控制

当模型带有骨骼动画时,模型中会有bone节点

bone节点是特殊的object3d对象,其对应了SkinnedMesh

关于模型的骨骼与蒙皮的效果可以看下这个官方示例:

https://threejs.org/docs/index.html#api/en/objects/SkinnedMesh

从图中可以开到,通过修改bone节点的position,rotation,scale属性,可以让模型产生“变形”的效果。


 小结一下,web端模型组装类的活动,基础技术点就是

载入模型,调整模型节点的属性,从而实现模型重新拼接变形的效果

那么这些技术点可以应用在什么场景呢?


组装车

一般看到上面总结的那些技术点,很容易就联想到,可以通过切换不同的节点,替换不同的贴图,实现载具拼装的玩法。

 

遗传玩法

因为这些技术点的核心是对模型进行“拆解拼装”,所以往往联想到的都是一些“机械类”的拼接,实际上,这种玩法对应一些“活的生物”也是适用的。

通过修改玩法规则,甚至可以产生完全不同的感觉。

如缘分猫专题(echo制作):

玩家A与玩家B持有不同的猫部件,而当两者结合后,就进行模型的拆解重组:

猫A的耳朵 + 猫B的眼镜 + 自然随机部件 = 新的猫C

 

捏脸玩法

而在模型拼装的类型中,骨骼蒙皮的调整是更为复杂的一个部分。如果在一个模型上同时绑定多个骨骼,并建立好对应的蒙皮关系,则可以实现捏脸效果。

如完美世界web捏脸专题(kimi制作):

捏脸的状态中,通过调整骨骼的参数让脸部呈现不同的样貌。

 

换脸玩法

这个专题的核心技术点在于2d照片转3d头像,但是在表现力层面依然使用的是基础的模型拼接方法来将生成好的3d头像拼装到模型上。

 

AR换装

实际上因为模型的属性的调整是比较基础的功能,因此,如果引入一些行的技术点,则能创造出更多有趣的玩法,比如,结合ARkit/ARcore的环境追踪功能,我们能实现“通过移动手机,来给现实空间中的虚拟角色换装”的效果。

上面的图可能看起来对部分同学来说不好理解,实际上因为ARkit的功能,上图的游泳圈就是玩家当前手机所在的位置,而猫是固定在空间中的一个位置,玩家通过移动手机,将游泳圈放到猫身上。

 

除了上面那些,实际上还有很多可以用得上的玩法,比如常见的集齐2d拼图活动->集齐3d部件活动,测一测两人是否匹配活动->组合3d模型,来比对匹配度……等等。

这些3d拼装类活动,目前在数据表现上都比正常活动高出不少,玩家保持了很高的互动参与率。

 

模型拼接的方法较为简单,实际上web3d的难点在于模型的调试

 

附加一个模型载入后,threejs内模型各属性定义:

metadata:
模型里信息概要
       sourceFile:源文件,比如model.obj,obj.max。
       generatedBy: 转换的插件名称
       formatVersion: 版本
       vertices: 顶点数
       normals: 与顶点对应的法线向量
       colors: 与顶点对应的颜色值
       uvs: uv映射
       triangles: 三角形
       materials: 材质
 
materials:
模型的材质,一个模型可同时包含多个材质,材质信息是一个模型里很重要并且略繁杂的信息,这里列一下比较常见的材质的属性:
 
       DbgIndex: 材质索引
       DbgName: 材质名称
       colorDiffuse:漫射颜色
       colorSpecular: 镜面颜色
       opacity:透明度
       colorDiffuse:镜面系数
       mapDiffuse: 漫射贴图
       vertexColors:顶点颜色
 
vertices:
顶点数据,这个数据是一个一维数组,每3个值组成一个点的位置,[x1,y1,z1,x2,y2,z2,x3...]
 
normals:
顶点法线向量,配合顶点颜色,用来计算不同角度光照时的漫反射光的显示,同样是xyz循环的一维数组
 
colors:
顶点颜色,rgb循环的一维数组,与normals配合可以实现多种顶点颜色分布,这个涉及到着色器。
 
uvs:
uv映射,就是模型与贴图的对应关系,uvs并不是一维数组。
 
faces:
这个是threejs内的类型,存储了顶点vertices的索引,详情可参考https://threejs.org/docs/index.html#api/core/Face3 
 
bones:
骨骼,是一个包含每段骨骼数据的数组
 
    parent:骨骼的父节点(实际作用类似于骨骼节点索引)
    name:骨骼名称
    pos:骨骼位置(xyz)
    scl:骨骼缩放(xyz)
    rotq:骨骼旋转(四元)
 
skinIndices:
蒙皮索引
 
skinWeights:
蒙皮权重,蒙皮的概念如下图
 
animations:
通过时间控制每组骨骼状态。一般情况下,一个模型对应一组骨骼动画,但有些模型里,可能会同时存在多组骨骼动画
 
    name:动画名称
    fps:帧频
    hierarchy:骨骼层级,包含各个骨骼的信息的数组
    length:总时长
          parent:骨骼父节点
          keys:动画帧,每一帧都有当前骨骼的信息
                pos:骨骼位置(xyz)
                scl:骨骼缩放(xyz)
                rotq:骨骼旋转(四元)
                time:当前帧的时间(取决于导出时的帧频)
 
 

现阶段的3d建模软件并没有很好的支持web3d格式,同时web端也没有一个稳定用来处理3d模型的“可视化编辑引擎”,感觉未来web端也许会围绕不同的核心再分割出更多的工种,比如web端的3d开发,web端的3d美术,web端的技术美术等等……

web前端真的是个很大的范围啊……

 
最近正在制作小游戏《精灵之息》,欢迎来玩(与本文无关):
 
 
 
 

 

-
求经验 -

COPYRIGHT © 2019. ALL RIGHTS RESERVED.

点击“ . . . ”进行分享