Three.js学习笔记 – “我和小伙伴都惊呆了”的特效和Three.js初探
什么是Three.js
three.js是JavaScript編寫的WebGL第三方庫(kù)。提供了非常多的3D顯示功能。Three.js 是一款運(yùn)行在瀏覽器中的 3D 引擎,你可以用它創(chuàng)建各種三維場(chǎng)景,包括了攝影機(jī)、光影、材質(zhì)等各種對(duì)象。你可以在它的主頁(yè)上看到許多精采的演示。不過(guò),這款引擎目前還處在比較不成熟的開發(fā)階段,其不夠豐富的 API 以及匱乏的文檔增加了初學(xué)者的學(xué)習(xí)難度(尤其是文檔的匱乏)three.js的代碼托管在github上面。
上面摘自百度百科。依我來(lái)看就是一個(gè)在HTML5畫布(canvas)上顯示的3D引擎。如果你之前折騰過(guò)本地3D引擎,比如Steam,寒霜,那上手這個(gè)就非常簡(jiǎn)單了。
學(xué)習(xí)這個(gè)引擎難處有幾點(diǎn):第一,正如上面所說(shuō),沒有比較系統(tǒng)的文檔,只有一些大神寫的Demo,對(duì)于一些js基礎(chǔ)不好或者英語(yǔ)不好的童鞋來(lái)說(shuō)簡(jiǎn)直不能歷屆;第二,一般人對(duì)游戲引擎里面的紋理、光源、材質(zhì)等詞不甚理解。第三,不曉得怎么去調(diào)試。
在開始正式介紹之前,可以先看看Demo,了解一下這個(gè)引擎能做什么。
官方網(wǎng)站上的例子:http://threejs.org/
GitHub上的例子:http://stemkoski.github.io/Three.js/
其中幾個(gè)比較有特色的列一下(提提你們的胃口~)(都不要使用IE或基于IE的瀏覽器打開!推薦使用Chrome):
最基本的Hello World:http://stemkoski.github.io/Three.js/HelloWorld.html
調(diào)用你的攝像頭:http://stemkoski.github.io/Three.js/Webcam-Texture.html
體感操作(你沒有看錯(cuò)!):http://stemkoski.github.io/Three.js/Webcam-Motion-Detection-Texture.html
支持你的游戲手柄(XBox等):http://stemkoski.github.io/Three.js/Mesh-Movement-Gamepad.html
3D建模和方向鍵控制移動(dòng)方向:http://stemkoski.github.io/Three.js/Model-Animation-Control.html
SkyBox和3個(gè)氣泡渲染(可見Three.js的渲染真心不賴):http://stemkoski.github.io/Three.js/Metabubbles.html
3D紅藍(lán)偏光的名車展(打開前自備偏光鏡):http://threejs.org/examples/webgl_materials_cars_anaglyph.html
帥爆了的元素周期表:http://threejs.org/examples/css3d_periodictable.html
跑車游戲:http://hexgl.bkcore.com/
有沒有和小伙伴們都驚呆了?——至少我是的。沒有使用Flash,沒有大量的圖片拼接,絕大多數(shù)的特效靠代碼實(shí)現(xiàn),包括文章配圖那款SS跑車,AMAZING!
Three.js環(huán)境的準(zhǔn)備
正文現(xiàn)在開始。
我整個(gè)例子有不少地方參考的是http://www.hiwebgl.com/?p=1058。向這樣的譯者表示絕對(duì)的敬意!(話說(shuō)原文是日文的,我這個(gè)看英語(yǔ)文檔無(wú)壓力的無(wú)論如何也受不鳥日文啊……)
Three.js從GitHub庫(kù)中獲取:https://github.com/mrdoob/three.js/,下載請(qǐng)點(diǎn)擊在頁(yè)面右邊的“Download ZIP”按鈕。比較齊活的例子在:https://github.com/stemkoski/stemkoski.github.com可以下載。
Three.js至少需要build目錄下的three,js,three.min.js是前者的壓縮版。docs下的index.html是器官方文檔(我還沒細(xì)致看過(guò),質(zhì)量怎么樣沒法說(shuō))。example目錄下都是例子,值得一提的是,這些例子必須要掛到服務(wù)器里面預(yù)覽,本地打開會(huì)有問(wèn)題,IIS或者Tomcat或者Apache都可以(以后會(huì)說(shuō)到為什么)。
運(yùn)行第一個(gè)Three.js
第一個(gè)例子也用來(lái)確定一下Three.js是否能正常運(yùn)行。在WebRoot下建一個(gè)js文件夾,把three,js拷貝進(jìn)去(three.min.js也行)。
在WebRoot下建一個(gè)index.html,內(nèi)容如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Three.js チュートリアル1</title> <script src="Three.js"></script> <style type="text/css"> div#canvas-frame {border: none;cursor: pointer;width: 600px;height: 600px;background-color: #EEEEEE; } </style> <script>var renderer;function initThree() {width = document.getElementById('canvas-frame').clientWidth;height = document.getElementById('canvas-frame').clientHeight;renderer = new THREE.WebGLRenderer({antialias : true});renderer.setSize(width, height);document.getElementById('canvas-frame').appendChild(renderer.domElement);renderer.setClearColorHex(0xFFFFFF, 1.0);}var camera;function initCamera() {camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);camera.position.x = 100;camera.position.y = 20;camera.position.z = 50;camera.up.x = 0;camera.up.y = 0;camera.up.z = 1;camera.lookAt({x : 0,y : 0,z : 0});}var scene;function initScene() {scene = new THREE.Scene();}var light;function initLight() {light = new THREE.DirectionalLight(0xFF0000, 1.0, 0);light.position.set(100, 100, 200);scene.add(light);}var cube;function initObject() {cube = new THREE.Mesh(new THREE.CubeGeometry(50, 50, 50), //形狀の設(shè)定new THREE.MeshLambertMaterial({color : 0xff0000}) //材質(zhì)の設(shè)定);scene.add(cube);cube.position.set(0, 0, 0);}function threeStart() {initThree();initCamera();initScene();initLight();initObject();renderer.clear();renderer.render(scene, camera);} </script> </head><body οnlοad="threeStart();"><div id="canvas-frame"></div> </body> </html>執(zhí)行的結(jié)構(gòu)應(yīng)該是這樣,Three.js也比較大,網(wǎng)的質(zhì)量可能不好,看不到效果的多刷幾次:http://tonythegod.eu5.org/three.js/1/demo1.html
自二個(gè)例子:一個(gè)可控制的長(zhǎng)方體
最后的效果(沒看到效果多刷幾次):http://tonythegod.eu5.org/three.js/1/demo2.html
我沒有給李興華打廣告……只是這本書在我寫Demo時(shí)就在我手邊,然后就當(dāng)了模特了~
貼出主要的代碼,附上一些主要的注釋:
<!doctype html> <html lang="en"> <head> <title>Template (Three.js)</title> <meta charset="utf-8"> <meta name="viewport"content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> <link rel=stylesheet href="css/base.css" /> <!-- 這個(gè)樣式表主要寫了body的背景為#F5F5F5,就是整個(gè)網(wǎng)頁(yè)的背景顏色 --> </head><body><script src="../js/Three.js"></script> <!-- 這個(gè)是Three.js引擎的js --><script src="../js/Detector.js"></script><script src="../js/Stats.js"></script><script src="../js/OrbitControls.js"></script><script src="../js/THREEx.KeyboardState.js"></script><script src="../js/THREEx.FullScreen.js"></script><script src="../js/THREEx.WindowResize.js"></script><script src="../js/Texture.js"></script> <!-- 一些js工具類,現(xiàn)在不深究 --><div id="ThreeJS"style="z-index: 1; position: absolute; left: 0px; top: 0px"></div> <!--這個(gè)div就是整個(gè)畫布 --><script>// // MAIN ////// standard global variablesvar container, scene, camera, renderer, controls, stats; <!-- 幾個(gè)變量代表的含義:容器、場(chǎng)景、攝像機(jī)(視角)、渲染器、控制裝置 -->var keyboard = new THREEx.KeyboardState();var clock = new THREE.Clock();// custom global variablesvar cube;// initializationinit();// animation loop / game loopanimate();///// FUNCTIONS /////function init() { <!-- 初始化 -->///// SCENE /////scene = new THREE.Scene(); <!-- 定義場(chǎng)景 -->// CAMERA //// set the view size in pixels (custom or according to window size)// var SCREEN_WIDTH = 400, SCREEN_HEIGHT = 300;var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;// camera attributesvar VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;// set up cameracamera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR); <!-- 定義視角 -->// add the camera to the scenescene.add(camera);// the camera defaults to position (0,0,0)// so pull it back (z = 400) and up (y = 100) and set the angle towards the scene origincamera.position.set(-400, 150, 200); <!--視角的位置 -->camera.lookAt(scene.position);//// RENDERER ////// create and start the renderer; choose antialias setting.if (Detector.webgl)renderer = new THREE.WebGLRenderer({antialias : true});elserenderer = new THREE.CanvasRenderer();renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);// attach div element to variable to contain the renderercontainer = document.getElementById('ThreeJS');// alternatively: to create the div at runtime, use:// container = document.createElement( 'div' );// document.body.appendChild( container );// attach renderer to the container divcontainer.appendChild(renderer.domElement);// EVENTS //// automatically resize rendererTHREEx.WindowResize(renderer, camera);// toggle full-screen on given key pressTHREEx.FullScreen.bindKey({charCode : 'm'.charCodeAt(0)});//// CONTROLS ////// move mouse and: left click to rotate, // middle click to zoom, // right click to pancontrols = new THREE.OrbitControls(camera, renderer.domElement); <!-- 設(shè)置控制,這里只有鼠標(biāo)操作 -->///// STATS /////// displays current and past frames per second attained by scenestats = new Stats();stats.domElement.style.position = 'absolute';stats.domElement.style.bottom = '0px';stats.domElement.style.zIndex = 100;container.appendChild(stats.domElement);///// LIGHT /////// create a lightvar light = new THREE.PointLight(0xffffff); <!-- 設(shè)置光源 -->light.position.set(0, 250, 0);scene.add(light);// CUBEvar cubeGeometry = new THREE.CubeGeometry(260, 35, 185, 1, 1, 1); <!-- 定義一個(gè)立方體,就是那本書的模型 -->var cubeMaterialArray = [];cubeMaterialArray.push(new THREE.MeshBasicMaterial({map : new THREE.ImageUtils.loadTexture('img/side-up.png') <!-- 給每一面上貼圖,下同 -->}));cubeMaterialArray.push(new THREE.MeshBasicMaterial({map : new THREE.ImageUtils.loadTexture('img/side-up.png')}));cubeMaterialArray.push(new THREE.MeshBasicMaterial({map : new THREE.ImageUtils.loadTexture('img/up.png')}));cubeMaterialArray.push(new THREE.MeshBasicMaterial({map : new THREE.ImageUtils.loadTexture('img/down.png')}));cubeMaterialArray.push(new THREE.MeshBasicMaterial({map : new THREE.ImageUtils.loadTexture('img/side-right.png')}));cubeMaterialArray.push(new THREE.MeshBasicMaterial({map : new THREE.ImageUtils.loadTexture('img/side-left.png')}));var cubeMaterials = new THREE.MeshFaceMaterial(cubeMaterialArray);cube = new THREE.Mesh(cubeGeometry, cubeMaterials);cube.position.set(0, 0, 0); <!-- 立方體放置的位置 -->scene.add(cube);}function animate() {requestAnimationFrame(animate);render();update();}function update() {// delta = change in time since last call (in seconds)var delta = clock.getDelta();controls.update();stats.update();}function render() {renderer.render(scene, camera);}</script></body> </html>其實(shí)學(xué)習(xí)Three.js大多是這樣,因?yàn)槿鄙傧鄳?yīng)的文檔,看大牛們寫的注釋是最快上手的辦法。
這次就先到這兒,下次再說(shuō)怎么一點(diǎn)點(diǎn)在畫布上作畫。
本文轉(zhuǎn)載自tony的小站:?http://tonythegod.eu5.org/three-js-study-notes-study-on-three-js/ | Tony的工作站
http://www.cnblogs.com/xufeiyang/articles/3181369.html
總結(jié)
以上是生活随笔為你收集整理的Three.js学习笔记 – “我和小伙伴都惊呆了”的特效和Three.js初探的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: css3动画插件
- 下一篇: three.js写的游戏