在程序界學習任何新語言時都離不開hello world。在學習3d的過程中自然也不例外。只不過它的hello world 是一隻兔子。下面就讓我們看看之前說的幾個框架分別如何實現加載一個兔子模型。
首先,自然是受衆最廣的three.js :
1. 創建canvas畫布:
<canvas id="gltfViewerCanvas"></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
<canvas id="renderCanvas" style="width: 100%;height: 100%;"></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
<script src="js/xeogl.js"></script>
<script src="js/OBJModel.js"></script>
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的使用更加簡單。