在程序界学习任何新语言时都离不开hello world。在学习3d的过程中自然也不例外。只不过它的hello world 是一只兔子。下面就让我们看看之前说的几个框架分别如何实现加载一个兔子模型。
首先,自然是受众最广的three.js :
1. 创建canvas画布:
2. 加载所需要的js,其中three.js为主体js,其他的都为插件用到什么加载什么即可。这里因为我用的是vue,所以大体代码如下:
window.THREE = THREE
import * as THREE from 'three';
require('three/examples/js/loaders/OBJLoader')
require('three/examples/js/controls/OrbitControls')
这里你一定会好奇为什么有一个window.THREE = THREE 。 这是因为three.js对vue之类的框架现在支持还不是很好,如果不写全局变量,会导致找不到THREE导致报错。
3. 创建场景,相机,灯光,设置操作加载模型。
render: function () {
this.renderer = new THREE.WebGLRenderer({antialias: true});
this.renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(this.renderer.domElement);
},
cameraF: function () {
this.scene = new THREE.Scene();
this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
this.camera.position.set(0, 0, 50);
this.camera.lookAt(0, 0, 0);
this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
// 如果使用animate方法时,将此函数删除
//controls.addEventListener( 'change', render );
// 使动画循环使用时阻尼或自转 意思是否有惯性
this.controls.enableDamping = true;
//动态阻尼系数 就是鼠标拖拽旋转灵敏度
//controls.dampingFactor = 0.25;
//是否可以缩放
this.controls.enableZoom = true;
//是否自动旋转
this.controls.autoRotate = true;
//设置相机距离原点的最远距离
this.controls.minDistance = 100;
//设置相机距离原点的最远距离
this.controls.maxDistance = 600;
//是否开启右键拖拽
this.controls.enablePan = true;
this.controls.update();
},
initLight: function () {
this.scene.add(new THREE.AmbientLight(0x404040));
var light = new THREE.DirectionalLight(0xffffff);
light.position.set(1, 1, 1);
this.scene.add(light);
},
cav: function () {
/* var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({color: 0x00ff00});
var cube = new THREE.Mesh(geometry, material);
this.scene.add(cube);
this.camera.position.z = 10;*/
//var _this = this
// 加载 glTF 格式的模型
let loader = new THREE.OBJLoader();
/!*实例化加载器*!/
/*const dracoLoader = new THREE.DRACOLoader();
THREE.DRACOLoader.setDecoderPath('D:\\project\\vue-three1\\src\\assets\\draco');
loader.setDRACOLoader(dracoLoader);
// Optional: Pre-fetch Draco WASM/JS module, to save time while parsing.
THREE.DRACOLoader.getDecoderModule();*/
var _this = this
loader.load('http://192.168.0.109:8000/static/bunny_norm.obj', function (obj) {
console.log(obj);
//obj.scene.position.y = 5;
/*obj.scene.traverse(function (child) {
if (child.isMesh) {
//console.log(child)
child.scale.set(0.0001, 0.0001, 0.0001)
child.material.emissive = child.material.color;
child.material.emissiveMap = child.material.map;
}
})*/
_this.scene.add(obj);
_this.renderer.render(_this.scene, _this.camera);
//document.getElementById('loading').style.display = 'none';
}, function (xhr) {
console.log((xhr.loaded / xhr.total * 100) + '% loaded');
}, function (error) {
console.log('load error!' + error);
})
_this.renderer.render(_this.scene, _this.camera);
}
,
contr: function () {
this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
// 如果使用animate方法时,将此函数删除
//controls.addEventListener( 'change', render );
// 使动画循环使用时阻尼或自转 意思是否有惯性
this.controls.enableDamping = false;
//动态阻尼系数 就是鼠标拖拽旋转灵敏度
//controls.dampingFactor = 0.25;
//是否可以缩放
this.controls.enableZoom = true;
//是否自动旋转
this.controls.autoRotate = false;
//设置相机距离原点的最远距离
this.controls.minDistance = 200;
//设置相机距离原点的最远距离
this.controls.maxDistance = 60000;
//是否开启右键拖拽
this.controls.enablePan = true;
},
anm: function () {
requestAnimationFrame(this.anm);
this.controls.update();
this.renderer.render(this.scene, this.camera);
}
通过以上代码,基本就可以加载一个obj模型,并进行一些简单的观察操作。
2. babylon.js 我们这在后面会主要用到,这里就不详细分解了:
1. 创建canvas
2. 加载js
import * as BABYLON from 'babylonjs';
import 'babylonjs-loaders';
3.创建场景,相机,灯光,加载模型
test: function () {
// Get the canvas DOM element
//获得画布
var canvas = document.getElementById('renderCanvas')
// Load the 3D engine 加载
var engine = new BABYLON.Engine(canvas, true, {preserveDrawingBuffer: true, stencil: true})
// This creates a basic Babylon Scene object (non-mesh) 设置场景
var scene = new BABYLON.Scene(engine);
//創建相机
var camera = new BABYLON.ArcRotateCamera('camera1', 10, 0.8, 50, new BABYLON.Vector3(0, 0, 0), scene);
// This targets the camera to scene origin
camera.setTarget(BABYLON.Vector3.Zero());
// This attaches the camera to the canvas
camera.attachControl(canvas, true);
camera.useFramingBehavior = true;
var light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
BABYLON.SceneLoader.LoadAssetContainerAsync("http://192.168.0.109:8000/static/", "niaolong.obj", scene).then(function (container) {
//container.createRootMesh().scaling = new BABYLON.Vector3(0.003, 0.003, 0.003);
container.addAllToScene();
});
// Register a render loop to repeatedly render the scene
//加载刷新
engine.runRenderLoop(function () {
scene.render();
});
// Watch for browser/canvas resize events
window.addEventListener("resize", function () {
engine.resize();
});
}
3. xeogl 这个框架由于是为特定领域开发,用的人不多。但在特定领域它用起来还是很方便的。xeogl由于只为特定领域而生,所以它本身缺少很多其他框架拥有的功能。在使用上和其他框架也有一定区别。
1. 加载js
2. 创建相机,加载模型。
var model = new xeogl.OBJModel({
id: "gearbox",
src: "http://192.168.0.109:8000/static/niaolong,obj",
position: [-100, -100, -100],
rotation: [0, 45, 0],
scale: [0.01, 0.01, 0.01]
});
var scene = xeogl.getDefaultScene();
var camera = scene.camera;
camera.eye = [30,30, -30];
new xeogl.CameraControl();
至此,3个框架的基本使用也就完了。
总结,在使用上three,babylon的思想基本相近。都是需要创建画布,相机,场景,灯光,加载器等东西。相对操作性更大。而xeogl只需要关注加载的模型,和相机即可。所以在使用上xeogl的使用更加简单。