javascript|three.js案例解析之代码实现morph动画

你好,我先给你截图效果。
变形前:
javascript|three.js案例解析之代码实现morph动画
文章图片

变形后:
javascript|three.js案例解析之代码实现morph动画
文章图片

你可以先了解一下这个变形动画的参数:

  • spherify,圆化度
  • twist,弯曲度
本案例用到的three.js知识点 Scene 场景是你放置物体、灯光和摄像机甚至定向音频对象(PositionalAudio)的地方。
场景的background和environment属性
背景和环境,你觉得它们有什么区别? 背景是单独给场景设置清空背景的。 环境属性则是统一给每个场景中的物体设置环境贴图。
MeshPhoneMaterial
const material = new THREE.MeshPhongMaterial( { color: 0xff0000, flatShading: true } );

该材质使用非物理的Blinn-Phong模型
来计算反射率。 该材质的属性:
  • map,纹理贴图
  • emissiveMap, 放射贴图
  • envMap,环境贴图
  • lightMap,光照贴图。
  • flatShading,定义材质是否使用平面着色进行渲染
  • specular,材质的高光颜色
开启平面着色的效果:
javascript|three.js案例解析之代码实现morph动画
文章图片

不开启平面着色的效果
javascript|three.js案例解析之代码实现morph动画
文章图片

Blinn-Phong模型
一种物体表面光反射模型,用于影响最终片元着色器中的gl_FragColor变量的值。
下面一张经典的图片解释了该模型:
javascript|three.js案例解析之代码实现morph动画
文章图片

这下你就清楚了specular属性是用来做什么的。
不过在实际的使用过程中,默认值的感官是最好的。
specular: 0x666666时的效果一言难尽。 javascript|three.js案例解析之代码实现morph动画
文章图片

创建morph几何体的关键代码
function createGeometry() { const geometry = new THREE.BoxGeometry( 2, 2, 2, 32, 32, 32 ); geometry.morphAttributes.position = []; const positionAttribute = geometry.attributes.position; const spherePositions = []; const twistPositions = []; const direction = new THREE.Vector3( 1, 0, 0 ); const vertex = new THREE.Vector3(); for ( let i = 0; i < positionAttribute.count; i ++ ) {const x = positionAttribute.getX( i ); const y = positionAttribute.getY( i ); const z = positionAttribute.getZ( i ); spherePositions.push(x * Math.sqrt( 1 - ( y * y / 2 ) - ( z * z / 2 ) + ( y * y * z * z / 3 ) ), y * Math.sqrt( 1 - ( z * z / 2 ) - ( x * x / 2 ) + ( z * z * x * x / 3 ) ), z * Math.sqrt( 1 - ( x * x / 2 ) - ( y * y / 2 ) + ( x * x * y * y / 3 ) )); vertex.set( x * 2, y, z ); vertex.applyAxisAngle( direction, Math.PI * x / 2 ).toArray( twistPositions, twistPositions.length ); }geometry.morphAttributes.position[ 0 ] = new THREE.Float32BufferAttribute( spherePositions, 3 ); geometry.morphAttributes.position[ 1 ] = new THREE.Float32BufferAttribute( twistPositions, 3 ); return geometry; }

  • 首先,拿到几何体的顶点属性,geometry.attributes.position
  • 然后,创建两个数组,spherePositions和twistPositions,分别控制圆化度和弯曲度。
  • 遍历每一个顶点坐标,分别获取顶点向量的x,y,z值。
  • 圆化度通过一个公式计算出各个顶点的位置
  • 最后赋值给geometry.morphAttributes.position[0]的元素值。
这个公式有看懂的小伙伴吗?
【javascript|three.js案例解析之代码实现morph动画】欢迎在评论区解答。

    推荐阅读