three.js蒙皮网格初探

237

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

网格

表示基于以三角形为polygon mesh(多边形网格)的物体的类。 计算机一个复杂的模型,比如人物,老虎,总是由简单的基本图元组成,比如三角形。 将三角形边界勾勒出来,看起来就像网格一样。

chrome-capture-2022-4-7.gif

构成模型的图元越多,模型越逼真【接近真实世界】。

蒙皮网格

具有Skeleton(骨架)和bones(骨骼)的网格,可用于给几何体上的顶点添加动画。 蒙皮网格的动画有两种:

骨骼动画

模拟有骨动物的骨骼运动。

morph动画

面部细微表情的变化,肌肉的波动

所谓蒙皮网格,其本质是将额外的骨骼数据与网格数据的动画联动,骨骼产生运动带动网格产生运动。

SkinnedMesh

SkinnedMesh can only be used with WebGL 2. With WebGL 1 OES_texture_float and vertex textures support is required. 蒙皮网格仅能在webgl2版本环境下使用。 three.js使用蒙皮网格的代码示例:

const geometry = new THREE.CylinderGeometry( 5, 5, 5, 5, 15, 5, 30 ); 
const position = geometry.attributes.position; 
const vertex = new THREE.Vector3();
const skinIndices = []; 
const skinWeights = []; 
for ( let i = 0; i < position.count; i ++ ) 
{ vertex.fromBufferAttribute( position, i ); 
const y = ( vertex.y + sizing.halfHeight ); 
const skinIndex = Math.floor( y / sizing.segmentHeight );
const skinWeight = ( y % sizing.segmentHeight ) / sizing.segmentHeight; skinIndices.push( skinIndex, skinIndex + 1, 0, 0 ); skinWeights.push( 1 - skinWeight, skinWeight, 0, 0 ); } geometry.setAttribute( 'skinIndex', new THREE.Uint16BufferAttribute( skinIndices, 4 ) ); geometry.setAttribute( 'skinWeight', new THREE.Float32BufferAttribute( skinWeights, 4 ) ); 
const mesh = new THREE.SkinnedMesh( geometry, material ); 
const skeleton = new THREE.Skeleton( bones ); 
const rootBone = skeleton.bones[ 0 ]; 
mesh.add( rootBone ); 
skeleton.bones[ 1 ].rotation.x = 0.2;
  • 创建蒙皮索引和蒙皮权重
  • 蒙皮索引用于与网格数据关联,权重则代表了网格受蒙皮影响的比重。
  • 利用一些算法计算蒙皮索引和蒙皮权重。
  • 创建蒙皮网格和骨架
  • 将骨架与几何体绑定起来。

这里创建蒙皮索引和蒙皮的算法是关键。