Three.js学习笔记 – “我和小伙伴都惊呆了”的特效和Three.js初探

原文出处:http://www.cnblogs.com/xufeiyang/articles/3181369.html

什么是Three.js

three.js是JavaScript编写的WebGL第三方库。提供了非常多的3D显示功能。Three.js 是一款运行在浏览器中的 3D 引擎,你可以用它创建各种三维场景,包括了摄影机、光影、材质等各种对象。你可以在它的主页上看到许多精采的演示。不过,这款引擎目前还处在比较不成熟的开发阶段,其不够丰富的 API 以及匮乏的文档增加了初学者的学习难度(尤其是文档的匮乏)three.js的代码托管在github上面。

上面摘自百度百科。依我来看就是一个在HTML5画布(canvas)上显示的3D引擎。如果你之前折腾过本地3D引擎,比如Steam,寒霜,那上手这个就非常简单了。

学习这个引擎难处有几点:第一,正如上面所说,没有比较系统的文档,只有一些大神写的Demo,对于一些js基础不好或者英语不好的童鞋来说简直不能历届;第二,一般人对游戏引擎里面的纹理、光源、材质等词不甚理解。第三,不晓得怎么去调试。

在开始正式介绍之前,可以先看看Demo,了解一下这个引擎能做什么。

官方网站上的例子:http://threejs.org/

GitHub上的例子:http://stemkoski.github.io/Three.js/

其中几个比较有特色的列一下(提提你们的胃口~)(都不要使用IE或基于IE的浏览器打开!推荐使用Chrome):

最基本的Hello World:http://stemkoski.github.io/Three.js/HelloWorld.html

调用你的摄像头http://stemkoski.github.io/Three.js/Webcam-Texture.html

体感操作(你没有看错!):http://stemkoski.github.io/Three.js/Webcam-Motion-Detection-Texture.html

支持你的游戏手柄(XBox等):http://stemkoski.github.io/Three.js/Mesh-Movement-Gamepad.html

3D建模和方向键控制移动方向:http://stemkoski.github.io/Three.js/Model-Animation-Control.html

SkyBox和3个气泡渲染(可见Three.js的渲染真心不赖):http://stemkoski.github.io/Three.js/Metabubbles.html

3D红蓝偏光的名车展(打开前自备偏光镜):http://threejs.org/examples/webgl_materials_cars_anaglyph.html

帅爆了的元素周期表:http://threejs.org/examples/css3d_periodictable.html

跑车游戏:http://hexgl.bkcore.com/

有没有和小伙伴们都惊呆了?——至少我是的。没有使用Flash,没有大量的图片拼接,绝大多数的特效靠代码实现,包括文章配图那款SS跑车,AMAZING!

Three.js环境的准备

正文现在开始。

我整个例子有不少地方参考的是http://www.hiwebgl.com/?p=1058。向这样的译者表示绝对的敬意!(话说原文是日文的,我这个看英语文档无压力的无论如何也受不鸟日文啊……)

Three.js从GitHub库中获取:https://github.com/mrdoob/three.js/,下载请点击在页面右边的“Download ZIP”按钮。比较齐活的例子在:https://github.com/stemkoski/stemkoski.github.com可以下载。

Three.js至少需要build目录下的three,js,three.min.js是前者的压缩版。docs下的index.html是器官方文档(我还没细致看过,质量怎么样没法说)。example目录下都是例子,值得一提的是,这些例子必须要挂到服务器里面预览,本地打开会有问题,IIS或者Tomcat或者Apache都可以(以后会说到为什么)。

运行第一个Three.js

第一个例子也用来确定一下Three.js是否能正常运行。在WebRoot下建一个js文件夹,把three,js拷贝进去(three.min.js也行)。

在WebRoot下建一个index.html,内容如下:

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4. <meta charset="UTF-8">  
  5. <title>Three.js チュートリアル1</title>  
  6. <script src="Three.js"></script>  
  7. <style type="text/css">  
  8. div#canvas-frame {  
  9.     border: none;  
  10.     cursor: pointer;  
  11.     width: 600px;  
  12.     height: 600px;  
  13.     background-color: #EEEEEE;  
  14. }  
  15. </style>  
  16. <script>  
  17.     var renderer;  
  18.     function initThree() {  
  19.         width = document.getElementById('canvas-frame').clientWidth;  
  20.         height = document.getElementById('canvas-frame').clientHeight;  
  21.         renderer = new THREE.WebGLRenderer({  
  22.             antialias : true  
  23.         });  
  24.         renderer.setSize(width, height);  
  25.         document.getElementById('canvas-frame')  
  26.                 .appendChild(renderer.domElement);  
  27.         <span style="color:#FF0000;">renderer.setClearColor(0xFFFFFF, 1.0);</span>  
  28.     }  
  29.   
  30.     var camera;  
  31.     function initCamera() {  
  32.         camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);  
  33.         camera.position.x = 100;  
  34.         camera.position.y = 20;  
  35.         camera.position.z = 50;  
  36.         camera.up.x = 0;  
  37.         camera.up.y = 0;  
  38.         camera.up.z = 1;  
  39.         camera.lookAt({  
  40.             x : 0,  
  41.             y : 0,  
  42.             z : 0  
  43.         });  
  44.     }  
  45.     var scene;  
  46.     function initScene() {  
  47.         scene = new THREE.Scene();  
  48.     }  
  49.     var light;  
  50.     function initLight() {  
  51.         light = new THREE.DirectionalLight(0xFF0000, 1.0, 0);  
  52.         light.position.set(100, 100, 200);  
  53.         scene.add(light);  
  54.     }  
  55.     var cube;  
  56.     function initObject() {  
  57.         cube = new THREE.Mesh(new THREE.CubeGeometry(50, 50, 50), //形状の設定  
  58.         new THREE.MeshLambertMaterial({  
  59.             color : 0xff0000  
  60.         }) //材質の設定  
  61.         );  
  62.         scene.add(cube);  
  63.         cube.position.set(0, 0, 0);  
  64.     }  
  65.     function threeStart() {  
  66.         initThree();  
  67.         initCamera();  
  68.         initScene();  
  69.         initLight();  
  70.         initObject();  
  71.         renderer.clear();  
  72.         renderer.render(scene, camera);  
  73.     }  
  74. </script>  
  75. </head>  
  76.   
  77. <body onload="threeStart();">  
  78.     <div id="canvas-frame"></div>  
  79. </body>  
  80. </html>  

执行的结构应该是这样,Three.js也比较大,网的质量可能不好,看不到效果的多刷几次:http://tonythegod.eu5.org/three.js/1/demo1.html


自二个例子:一个可控制的长方体

最后的效果(没看到效果多刷几次):http://tonythegod.eu5.org/three.js/1/demo2.html


我没有给李兴华打广告……只是这本书在我写Demo时就在我手边,然后就当了模特了~

贴出主要的代码,附上一些主要的注释:

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <!doctype html>  
  2. <html lang="en">  
  3. <head>  
  4. <title>Template (Three.js)</title>  
  5. <meta charset="utf-8">  
  6. <meta name="viewport"  
  7.     content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">  
  8. <link rel=stylesheet href="css/base.css" /> <!-- 这个样式表主要写了body的背景为#F5F5F5,就是整个网页的背景颜色 -->  
  9. </head>  
  10.   
  11. <body>  
  12.     <script src="../js/Three.js"></script> <!-- 这个是Three.js引擎的js -->  
  13.     <script src="../js/Detector.js"></script>  
  14.     <script src="../js/Stats.js"></script>  
  15.     <script src="../js/OrbitControls.js"></script>  
  16.     <script src="../js/THREEx.KeyboardState.js"></script>  
  17.     <script src="../js/THREEx.FullScreen.js"></script>  
  18.     <script src="../js/THREEx.WindowResize.js"></script>  
  19.     <script src="../js/Texture.js"></script> <!-- 一些js工具类,现在不深究 -->  
  20.   
  21.     <div id="ThreeJS"  
  22.         style="z-index: 1; position: absolute; left: 0px; top: 0px"></div> <!--这个div就是整个画布 -->  
  23.     <script>  
  24.         //      
  25.         // MAIN //  
  26.         //  
  27.         // standard global variables  
  28.         var container, scene, camera, renderer, controls, stats; <!-- 几个变量代表的含义:容器、场景、摄像机(视角)、渲染器、控制装置 -->  
  29.         var keyboard = new THREEx.KeyboardState();  
  30.         var clock = new THREE.Clock();  
  31.   
  32.         // custom global variables  
  33.         var cube;  
  34.   
  35.         // initialization  
  36.         init();  
  37.   
  38.         // animation loop / game loop  
  39.         animate();  
  40.   
  41.         ///  
  42.         // FUNCTIONS //  
  43.         ///  
  44.   
  45.         function init() { <!-- 初始化 -->  
  46.             ///  
  47.             // SCENE //  
  48.             ///  
  49.             scene = new THREE.Scene(); <!-- 定义场景 -->  
  50.   
  51.               
  52.             // CAMERA //  
  53.               
  54.   
  55.             // set the view size in pixels (custom or according to window size)  
  56.             // var SCREEN_WIDTH = 400SCREEN_HEIGHT = 300;  
  57.             var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;  
  58.             // camera attributes  
  59.             var VIEW_ANGLE = 45ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;  
  60.             // set up camera  
  61.             camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR); <!-- 定义视角 -->  
  62.             // add the camera to the scene  
  63.             scene.add(camera);  
  64.             // the camera defaults to position (0,0,0)  
  65.             // so pull it back (z = 400) and up (y = 100) and set the angle towards the scene origin  
  66.             camera.position.set(-400, 150, 200); <!--视角的位置 -->  
  67.             camera.lookAt(scene.position);  
  68.   
  69.             //  
  70.             // RENDERER //  
  71.             //  
  72.   
  73.             // create and start the renderer; choose antialias setting.  
  74.             if (Detector.webgl)  
  75.                 renderer = new THREE.WebGLRenderer({  
  76.                     antialias : true  
  77.                 });  
  78.             else  
  79.                 renderer = new THREE.CanvasRenderer();  
  80.   
  81.             renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);  
  82.   
  83.             // attach div element to variable to contain the renderer  
  84.             container = document.getElementById('ThreeJS');  
  85.             // alternatively: to create the div at runtime, use:  
  86.             // container = document.createElement( 'div' );  
  87.             // document.body.appendChild( container );  
  88.   
  89.             // attach renderer to the container div  
  90.             container.appendChild(renderer.domElement);  
  91.   
  92.               
  93.             // EVENTS //  
  94.               
  95.   
  96.             // automatically resize renderer  
  97.             THREEx.WindowResize(renderer, camera);  
  98.             // toggle full-screen on given key press  
  99.             THREEx.FullScreen.bindKey({  
  100.                 charCode : 'm'.charCodeAt(0)  
  101.             });  
  102.   
  103.             //  
  104.             // CONTROLS //  
  105.             //  
  106.   
  107.             // move mouse and: left   click to rotate,   
  108.             //                 middle click to zoom,   
  109.             //                 right  click to pan  
  110.             controls = new THREE.OrbitControls(camera, renderer.domElement); <!-- 设置控制,这里只有鼠标操作 -->  
  111.   
  112.             ///  
  113.             // STATS //  
  114.             ///  
  115.   
  116.             // displays current and past frames per second attained by scene  
  117.             stats = new Stats();  
  118.             stats.domElement.style.position = 'absolute';  
  119.             stats.domElement.style.bottom = '0px';  
  120.             stats.domElement.style.zIndex = 100;  
  121.             container.appendChild(stats.domElement);  
  122.   
  123.             ///  
  124.             // LIGHT //  
  125.             ///  
  126.   
  127.             // create a light  
  128.             var light = new THREE.PointLight(0xffffff); <!-- 设置光源 -->  
  129.             light.position.set(0, 250, 0);  
  130.             scene.add(light);  
  131.   
  132.             // CUBE  
  133.             var cubeGeometry = new THREE.CubeGeometry(260, 35, 185, 1, 1, 1); <!-- 定义一个立方体,就是那本书的模型 -->  
  134.   
  135.             var cubeMaterialArray = [];  
  136.             cubeMaterialArray.push(new THREE.MeshBasicMaterial({  
  137.                 map : new THREE.ImageUtils.loadTexture('img/side-up.png') <!-- 给每一面上贴图,下同 -->  
  138.             }));  
  139.             cubeMaterialArray.push(new THREE.MeshBasicMaterial({  
  140.                 map : new THREE.ImageUtils.loadTexture('img/side-up.png')  
  141.             }));  
  142.             cubeMaterialArray.push(new THREE.MeshBasicMaterial({  
  143.                 map : new THREE.ImageUtils.loadTexture('img/up.png')  
  144.             }));  
  145.             cubeMaterialArray.push(new THREE.MeshBasicMaterial({  
  146.                 map : new THREE.ImageUtils.loadTexture('img/down.png')  
  147.             }));  
  148.             cubeMaterialArray.push(new THREE.MeshBasicMaterial({  
  149.                 map : new THREE.ImageUtils.loadTexture('img/side-right.png')  
  150.             }));  
  151.             cubeMaterialArray.push(new THREE.MeshBasicMaterial({  
  152.                 map : new THREE.ImageUtils.loadTexture('img/side-left.png')  
  153.             }));  
  154.             var cubeMaterials = new THREE.MeshFaceMaterial(cubeMaterialArray);  
  155.   
  156.             cube = new THREE.Mesh(cubeGeometry, cubeMaterials);  
  157.             cube.position.set(0, 0, 0); <!-- 立方体放置的位置 -->  
  158.             scene.add(cube);  
  159.   
  160.         }  
  161.   
  162.         function animate() {  
  163.             requestAnimationFrame(animate);  
  164.             render();  
  165.             update();  
  166.         }  
  167.   
  168.         function update() {  
  169.             // delta = change in time since last call (in seconds)  
  170.             var delta = clock.getDelta();  
  171.   
  172.             controls.update();  
  173.             stats.update();  
  174.         }  
  175.   
  176.         function render() {  
  177.             renderer.render(scene, camera);  
  178.         }  
  179.     </script>  
  180.   
  181. </body>  
  182. </html>  

其实学习Three.js大多是这样,因为缺少相应的文档,看大牛们写的注释是最快上手的办法。

这次就先到这儿,下次再说怎么一点点在画布上作画。

ps:可能用的three.js版本不一致,红色代码处与原文不一致

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值