效果:
代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Morph-Bird</title>
<style>body{background:#eeeeee;margin:0;padding:0;overflow:hidden;}</style>
<script src="js/three.min.js"></script>
<!--<script src="js/stats.min.js"></script>
<script src="js/Detector.js"></script>-->
</head>
<body>
<script>
var morphs = [];
var clock = new THREE.Clock(); //创建一个时针/秒表
var width = window.innerWidth;
var height = window.innerHeight;
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 40, width/2 / height, 1, 10000 );
camera.position.y = 300;
camera.target = new THREE.Vector3( 0, 150, 0 );
//scene.add(camera);
var loader = new THREE.JSONLoader();
loader.load("models/animated/flamingo.js", function(geometry){
morphColorsToFaceColors( geometry );
geometry.computeMorphNormals(); //计算面的每一个法线(这样才能得到正确的关照效果)
var material = new THREE.MeshLambertMaterial( { color: 0xffffff, morphTargets: true, morphNormals: true, vertexColors: THREE.FaceColors, shading: THREE.FlatShading } );
/*MorphAnimMesh类是Mesh的扩展类,封装了对mesh.morphTargetInfluences的处理*/
var morphAnimMesh = new THREE.MorphAnimMesh( geometry, material ); //动画网格模型(本质和Mesh一样,都表示一个可以显示的对象,所不同的是他包含几个动画帧,可以通过播放帧来看到动画)
//morphAnimMesh.playAnimation();
morphAnimMesh.duration = 1500; //持续时间(单位ms)
morphAnimMesh.scale.set( 1.5, 3.0, 1.5 ); //设置模型比例(放大了一些)
morphAnimMesh.position.y = 150; //设置位置(在y轴上)
scene.add( morphAnimMesh );
morphs.push( morphAnimMesh );
});
/*将geometry.morpColors中存储的颜色复制到geometry.faces信息中,因为绘制的时候会用到faces中的颜色*/
function morphColorsToFaceColors( geometry ) {
if ( geometry.morphColors && geometry.morphColors.length ) {
var colorMap = geometry.morphColors[ 0 ];
for ( var i = 0; i < colorMap.colors.length; i ++ ) {
geometry.faces[ i ].color = colorMap.colors[ i ];
geometry.faces[ i ].color.offsetHSL( 0, 0.3, 0 ); //模型的饱和度提高0.3
}
}
}
var upLight = new THREE.DirectionalLight(0xffffff, 1.3);
upLight.position.set(1, 1, 1);
scene.add(upLight);
var downLight = new THREE.DirectionalLight(0xffffff, 0.1);
//downLight.position.set(0.25, -1, 0);
downLight.position.set(-1, -1, -1);
scene.add(downLight);
var renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize(width, height);
renderer.setClearColor(0xeeeeee, 1.0);
renderer.sortObjects = false;
renderer.autoClear = false;
renderer.gammaInput = true;
renderer.gammaOutput = true;
document.body.appendChild(renderer.domElement);
var theta = 0;
var delta = null;
var radius = 600;
function render() {
theta += 0.1; //每帧0.1度(如果1秒钟60帧,那么1秒钟就是6度)
/*相机绕y轴以半径为600的圆旋转*/
camera.position.x = radius * Math.sin( THREE.Math.degToRad( theta ) );
camera.position.z = radius * Math.cos( THREE.Math.degToRad( theta ) );
camera.lookAt( camera.target ); //相机聚焦于相机的焦点(一般为(0,0,0))
delta = clock.getDelta(); //得到距离上一次调用render()过去的时间(单位秒)
for ( var i = 0; i < morphs.length; i ++ ) {
morph = morphs[ i ];
//console.log(i); //永远是0
morph.updateAnimation( 1000 * delta ); //更新动画的每一帧,并在其中渲染动画
}
renderer.clear(); //清空渲染器
renderer.setViewport( 0, 0, width, height ); //设置视口(等于窗口的位置和大小)
renderer.render( scene, camera );
requestAnimationFrame(render);
}
render();
</script>
</body>
</html>
附注:笔者当前使用的three.js版本是r69