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

你好,我先给你截图效果。

变形前:

three.js案例解析之代码实现morph动画_第1张图片

变形后:

three.js案例解析之代码实现morph动画_第2张图片

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

  • 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,材质的高光颜色

开启平面着色的效果:

three.js案例解析之代码实现morph动画_第3张图片

不开启平面着色的效果

three.js案例解析之代码实现morph动画_第4张图片

Blinn-Phong模型

一种物体表面光反射模型,用于影响最终片元着色器中的gl_FragColor变量的值。

下面一张经典的图片解释了该模型:

three.js案例解析之代码实现morph动画_第5张图片

这下你就清楚了specular属性是用来做什么的。

不过在实际的使用过程中,默认值的感官是最好的。

specular: 0x666666时的效果一言难尽。 three.js案例解析之代码实现morph动画_第6张图片

创建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,3d,贴图)