其实可以先看看官方案例
你想要的东西 官方里面都有,就看你找不找得到了。。。。
话不多说
我们先看看这个例子吧
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - FBX loader</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #000;
color: #fff;
margin: 0px;
overflow: hidden;
}
#info {
color: #fff;
position: absolute;
top: 10px;
width: 100%;
text-align: center;
z-index: 100;
display:block;
}
#info a {
color: #046;
font-weight: bold;
}
</style>
</head>
<body>
<div id="info">
<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - FBXLoader<br />
Character and animation from <a href="https://www.mixamo.com/" target="_blank" rel="noopener">Mixamo</a>
</div>
<script src="../build/three.js"></script>
<script src="js/libs/inflate.min.js"></script>
<script src="js/loaders/FBXLoader.js"></script>
<script src="js/controls/OrbitControls.js"></script>
<script src="js/Detector.js"></script>
<script src="js/libs/stats.min.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container, stats, controls;
var camera, scene, renderer, light;
var clock = new THREE.Clock();
var mixers = [];
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.set( 100, 200, 300 );
controls = new THREE.OrbitControls( camera );
controls.target.set( 0, 100, 0 );
controls.update();
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xa0a0a0 );
scene.fog = new THREE.Fog( 0xa0a0a0, 200, 1000 );
light = new THREE.HemisphereLight( 0xffffff, 0x444444 );
light.position.set( 0, 200, 0 );
scene.add( light );
light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 0, 200, 100 );
light.castShadow = true;
light.shadow.camera.top = 180;
light.shadow.camera.bottom = -100;
light.shadow.camera.left = -120;
light.shadow.camera.right = 120;
scene.add( light );
// scene.add( new THREE.CameraHelper( light.shadow.camera ) );
// ground
var mesh = new THREE.Mesh( new THREE.PlaneGeometry( 2000, 2000 ), new THREE.MeshPhongMaterial( { color: 0x999999, depthWrite: false } ) );
mesh.rotation.x = - Math.PI / 2;
mesh.receiveShadow = true;
scene.add( mesh );
var grid = new THREE.GridHelper( 2000, 20, 0x000000, 0x000000 );
grid.material.opacity = 0.2;
grid.material.transparent = true;
scene.add( grid );
// model
var loader = new THREE.FBXLoader();
loader.load( 'models/fbx/Samba Dancing.fbx', function ( object ) {
object.mixer = new THREE.AnimationMixer( object );
mixers.push( object.mixer );
var action = object.mixer.clipAction( object.animations[ 0 ] );
action.play();
object.traverse( function ( child ) {
if ( child.isMesh ) {
child.castShadow = true;
child.receiveShadow = true;
}
} );
scene.add( object );
} );
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;
container.appendChild( renderer.domElement );
window.addEventListener( 'resize', onWindowResize, false );
// stats
stats = new Stats();
container.appendChild( stats.dom );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
//
function animate() {
requestAnimationFrame( animate );
if ( mixers.length > 0 ) {
for ( var i = 0; i < mixers.length; i ++ ) {
mixers[ i ].update( clock.getDelta() );
}
}
renderer.render( scene, camera );
stats.update();
}
</script>
</body>
</html>
首先我们找到这个例子,然后对其解析,化为自己的知识
我们看到引入的js库有以上几类
首当其先的为three.js
然后是inflate.min.js,我也不知道这是干撒的,但是当我百度这个找到了后,怀着崇敬的心情以及准备自我翻译作用的时候,我看到了汉字+五十音的时候,心中崩腾过了emmm。2只羊驼。只好勉强看汉字,应该是压缩用的吧。。。知道的麻烦给个准信。。。
接着是FBXLoader.js库,看名字就知道是fbx文件的加载库
所以,我们这个时候应该看看源码。
恩,一来就看到要求fbx格式以及一串的支持。
看正文
( function () {
//构造函数
THREE.FBXLoader = function ( manager ) {
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
};
Object.assign( THREE.FBXLoader.prototype, {
//加载函数
load: function ( url, onLoad, onProgress, onError ) {
var self = this;
var resourceDirectory = THREE.LoaderUtils.extractUrlBase( url );
var loader = new THREE.FileLoader( this.manager );
loader.setResponseType( 'arraybuffer' );
loader.load( url, function ( buffer ) {
try {
//解析
var scene = self.parse( buffer, resourceDirectory );
onLoad( scene );
} catch ( error ) {
window.setTimeout( function () {
if ( onError ) onError( error );
self.manager.itemError( url );
}, 0 );
}
}, onProgress, onError );
},
parse: function ( FBXBuffer, resourceDirectory ) {
var FBXTree;
//判断类型
if ( isFbxFormatBinary( FBXBuffer ) ) {
FBXTree = new BinaryParser().parse( FBXBuffer );
} else {
var FBXText = convertArrayBufferToString( FBXBuffer );
if ( ! isFbxFormatASCII( FBXText ) ) {
throw new Error( 'THREE.FBXLoader: Unknown format.' );
}
if ( getFbxVersion( FBXText ) < 7000 ) {
throw new Error( 'THREE.FBXLoader: FBX version not supported, FileVersion: ' + getFbxVersion( FBXText ) );
}
FBXTree = new TextParser().parse( FBXText );
}
// console.log( FBXTree );
//一连串的emmmmm,解析以及构建(你猜)
var connections = parseConnections( FBXTree );
var images = parseImages( FBXTree );
var textures = parseTextures( FBXTree, new THREE.TextureLoader( this.manager ).setPath( resourceDirectory ), images, connections );
var materials = parseMaterials( FBXTree, textures, connections );
var skeletons = parseDeformers( FBXTree, connections );
var geometryMap = parseGeometries( FBXTree, connections, skeletons );
var sceneGraph = parseScene( FBXTree, connections, skeletons, geometryMap, materials );
return sceneGraph;
}
} );
上面最后的一串方法都在库后面放着的,有兴趣的可以看看。
然后是OrbitControls.js 接收的camera参数
这就是它的介绍,至于源码有兴趣的看看吧。
剩下的库有兴趣自己看看源码吧,找不到,去three.js官网下载压缩包,撒都有。
然后我们开始了解如何构造的
上图emmm,不用说了
这句我想知道什么意思,查了一下原来是检查兼容性。一句话就解决了。。给个赞!
container = document.createElement( 'div' );
document.body.appendChild( container );
//相机
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.set( 100, 200, 300 );
//控制器 相应鼠标左键右键点击
controls = new THREE.OrbitControls( camera );
controls.target.set( 0, 100, 0 );
controls.update();
//舞台(场景)
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xa0a0a0 );
scene.fog = new THREE.Fog( 0xa0a0a0, 200, 1000 );
//灯光
light = new THREE.HemisphereLight( 0xffffff, 0x444444 );
light.position.set( 0, 200, 0 );
scene.add( light );
light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 0, 200, 100 );
light.castShadow = true;
light.shadow.camera.top = 180;
light.shadow.camera.bottom = -100;
light.shadow.camera.left = -120;
light.shadow.camera.right = 120;
scene.add( light );
// ground
var mesh = new THREE.Mesh( new THREE.PlaneGeometry( 2000, 2000 ), new THREE.MeshPhongMaterial( { color: 0x999999, depthWrite: false } ) );
mesh.rotation.x = - Math.PI / 2;
mesh.receiveShadow = true;
scene.add( mesh );
var grid = new THREE.GridHelper( 2000, 20, 0x000000, 0x000000 );
grid.material.opacity = 0.2;
grid.material.transparent = true;
scene.add( grid );
明显的构建广场。最后就是加载model
// model
//得到加载器
var loader = new THREE.FBXLoader();
//开始加载,并且异步加载,别问我,我也不知道,方法体里参数是
//(url,onLoad,onProgress,onError)
//所以对应咯
loader.load( '../fbx/aa.FBX', function ( object ) {
//动画
object.mixer = new THREE.AnimationMixer( object );
mixers.push( object.mixer );
var action = object.mixer.clipAction( object.animations[ 0 ] );
action.play();
//那个,纹理maybe,理解错了 请指出
object.traverse( function ( child ) {
if ( child.isMesh ) {
child.castShadow = true;
child.receiveShadow = true;
}
} );
scene.add( object );
} );
好了,看不看得懂,不要紧,要懂得基本操作就好了,是在不行,自己去例子里面现学现卖。当然懂了最好
最后我们实际运行一下。
ok,一切完美。
对了这些代码需要在服务器上执行,没有服务器?你的ide没有自带么?(webstorm)
最后,给个“毒”福利。
希望你们在看例子的时候
https://threejs.org/examples/#webgl_loader_fbx
能听这首歌 Its love -张碧晨
很带感!!!