three.js笔记,加翻译官网getting started

转载自自己的独立博客,

请使用支持webgl的浏览器,猛点这里看效果。

alanslab.cn

three.js是一款轻量级的3d库,能帮我等屌丝轻松的在浏览器上过一把3d瘾。最早被吸引到是因为这个范例(见下图)
+360o - Car Visualizer - Three.js

好吧。。。无话可说了。。。

我昨晚学习的时候参照的教程在这里,当然也改动扩展了不少地方。这里权当作个翻译加解说,能力有限,有错随便揪。

1、基础

原文中假设读者对3d有一定了解。但是很明显由我的实践证明这并不是必须的。。。不过你最起码得知道xyz三个坐标之类的神马的吧。。

这个教程将会带领着你来一起创建:

  1. 一个scene(场景)
  2. 一个renderer(渲染器)
  3. 一个camera(摄像机)
  4. 一或两个object(带material(材质))

2、浏览器支持

原教程建议使用chrome浏览器,我也是chrome控,哈哈。今天注意到ipad版的uc浏览器也支持WebGL,无奈事件模型不一样,没办法在ipad上看自己的成果了。。

3、布置scene

这里简要说一下,canvas渲染方式应用范围相对更加广,但这优势相对于WebGL能够用到硬件加速的能力来说弱爆了。

无论如何,3D的工作对浏览器来说可跟“轻量”一点边都沾不上,单单能在浏览器中运行这一点就已经够碉堡了。所以最好注意你代码中的性能瓶颈,能把它们排除掉的话就更好。

一些准备工作:下载好three.js,下载好jquery
这里的three.js足有70多mb,因为里面包含了很多的范例、文档和一大堆东西。

创建index.html:

  1.  <!doctype html>
  2. <html>
  3.  
  4.     <head>
  5.         <meta charset=“utf-8″ />
  6.         <title>Alan的实验室</title>
  7.  
  8.         <style type=“text/css”>
  9.         body {
  10.             padding: 0;
  11.             margin: 0;
  12.             overflow: hidden;
  13.         }
  14.         </style>
  15.  
  16.    </head>
  17.  
  18.     <body>
  19.         <div id=“container”></div> 
  20.     </body>
  21.  
  22.     <script src=“./js/jquery.min.js></script>
  23.     <script src=“./js/three/three.min.js”></script>
  24.     <script src=“./js/three/fonts/helvetiker_bold.typeface.js”></script>
  25.     <script src=“./js/lalalalademaxiya.js”></script>
  26.  
  27.     <script type=“text/javascript>
  28.         var ua = navigator.userAgent.toLowerCase();
  29.         if(!ua.match(“chrome”)) {
  30.             alert(“本页需要使用支持webgl的浏览器浏览,你可以继续尝试,但建议使用chrome。\r某些浏览器可能需要自行开启webgl支持,自行搜索即可。”);
  31.         }
  32.     </script>
  33.  
  34. </html>

按你的安排修改好js的路径。注意到lalalalademaxiya.js没?还要新建这个文件(实在接受不了的自行修名。。。),后文的js代码都要按顺序放进这里。

布置scene:

  1. // 设置场景尺寸
  2. var WIDTH = 400,
  3.   HEIGHT = 300;
  4.  
  5. // 设置一些摄像机的参数
  6. var VIEW_ANGLE = 45,
  7.   ASPECT = WIDTH / HEIGHT,
  8.   NEAR = 0.1,
  9.   FAR = 10000;
  10.  
  11. // 获取作为容器的DOM元素
  12. // - 假设这次用jquery来处理
  13. var $container = $(‘#container’);
  14.  
  15. // 创建一个WebGL渲染器,摄像机
  16. // 和一个场景
  17. var renderer = new THREE.WebGLRenderer();
  18. var camera =
  19.   new THREE.PerspectiveCamera(
  20.     VIEW_ANGLE,
  21.     ASPECT,
  22.     NEAR,
  23.     FAR);
  24.  
  25. var scene = new THREE.Scene();
  26.  
  27. // 把摄像机加入场景
  28. scene.add(camera);
  29.  
  30. // 摄像机开始时位于坐标(0,0,0)
  31. // 所以把它往后拉
  32. camera.position.= 300;
  33.  
  34. // 开始做渲染器的工作
  35. renderer.setSize(WIDTH, HEIGHT);
  36.  
  37. // 加入供渲染的DOM元素
  38. $container.append(renderer.domElement);

别急着运行,现在什么都没有。

4、制作一个mesh

mesh的翻译是网格,但是这和这个概念实在难以联想到一块,所以继续用原文。没有蒙上材质的mesh看着就像用网格线表现的物体。

现在我们有了场景、摄像机和渲染器,但是我们还没有任何东西可以绘制。这一点上,Three.js其实原生支持几种标准的文件类型,如果你要从其他的3d软件中导出模型,这就帮得上忙了。但是为了简单起见(这只是个入门教程),我们这里就用primitives。Primitives是一些基本的几何体meshes,创建起来很容易:

  1. // 设置球体的一些参数
  2. var radius = 50,
  3.     segments = 16,
  4.     rings = 16;
  5.  
  6. // 创建一个球体,这里用到了
  7. // sphereMaterial这个材质,
  8. // 后面再讲。
  9. var sphere = new THREE.Mesh(
  10.  
  11.   new THREE.SphereGeometry(
  12.     radius,
  13.     segments,
  14.     rings),
  15.  
  16.   sphereMaterial);
  17.  
  18. // 把球体加入到场景中
  19. scene.add(sphere);

 好了,现在浏览你的网页,应该能看到一个网格构成的球体,如果你用浏览器的开发者工具看js代码,还会看到一个(至少)错误,这是因为我们这里用了一个没有定义的变量sphereMaterial,这是球体的材质,下面就讲解,记得把下面这段插入到var sphere = new THREE.Mesh(这行之前。

5、材质

毫无疑问这是Three.js中最有用的部分。(为什么。。。)它提供了不少常用(而且好用)的材质可以应用在你的mesh上:

  1. “Basic” – 就我所知,这只是表示它们不会发光。(Which just means it renders “unlit”, as far as I can tell.)
  2. Lambert
  3. Phong

上面这个列表和这一块内容完全晕头转向,有需要看原文。大意是指Three.js帮了个大忙,减少了很多处理阴影的工作量。

总之,先上代码,把材质应用到球体上(还记得插入到哪吧?这段不是复制到最后)

  1. // 创建给球体用的质材
  2. var sphereMaterial =
  3.   new THREE.MeshLambertMaterial(
  4.     {
  5.       color: 0xCC0000
  6.     });

a这里要说的是在创建材质时你还可以设置很多其他的属性,比如smoothing或environment maps。可以查看文档以了解更多。

6、光源!

你现在如果浏览的话会看到一个红色的圆,即使我们已经应用了lambert材质,但这里没有光的话Three.js就会默认使用最大的全局光(full ambient light),我们只要再创建一个点光源就可以看效果了。

  1. // 创建一个点光源
  2. var pointLight =
  3.   new THREE.PointLight(0xFFFFFF);
  4.  
  5. // 设置它的位置
  6. pointLight.position.= 10;
  7. pointLight.position.= 50;
  8. pointLight.position.= 130;
  9.  
  10. // 加入到场景中
  11. scene.add(pointLight);

7、渲染循环(类似游戏的主循环,求靠谱的翻译法。。。)

所有渲染需要的东西都齐了,动手:

  1. // draw!
  2. renderer.render(scene, camera);

恭喜,到这里Three.js的这部分教程就已经基本完了,还有一些东西,但是似乎是扩展练习之类的,讲解也不如前面那么清楚了,所以先庆祝一下。接下来的我就自己扯了。

现在的情况就像是个静态图片一样。要像那些帅呆了的作品那样动起来,还要做一些工作才行。

实现这个需求,最聪明的办法就是使用requestAnimationFrame,原教程里也提供了一个链接以供读者进一步了解它。

不好意思。。你刚才完成的工作现在又要被我糟蹋了。。。

把刚才加上的最后一句替换成:

  1. // 处理窗体大小改变事件
  2. window.addEventListener( ‘resize’, onWindowResize, false );
  3.  
  4. function onWindowResize() {
  5.  
  6.     var windowHalfX = window.innerWidth / 2;
  7.     var windowHalfY = window.innerHeight / 2;
  8.  
  9.     camera.aspect = window.innerWidth / window.innerHeight;
  10.     camera.updateProjectionMatrix();
  11.  
  12.     renderer.setSize( window.innerWidth, window.innerHeight );
  13.  
  14. }
  15.  
  16. // 动画,这里是重点
  17. function animate() {
  18.  
  19.     requestAnimationFrame( animate );
  20.  
  21.     render()
  22.  
  23. }
  24.  
  25. animate();
  26.  
  27. function render() {
  28.     // 根据鼠标位置改变摄像机位置
  29.     camera.position.+= ( mouseX - camera.position.) * .05;
  30.     camera.position.+= ( - mouseY - camera.position.) * .05;
  31.  
  32.     // 始终看向场景原点
  33.     camera.lookAt( scene.position );
  34.  
  35.     renderer.render( scene, camera );
  36.  
  37. }
  38.  
  39. document.addEventListener(‘click’, function() {
  40.     window.open(“http://blog.alanslab.cn/”);
  41. }, false);
  42.  
  43. document.addEventListener( ‘mousemove’, onDocumentMouseMove, false );
  44.  
  45. function onDocumentMouseMove(event) {
  46.  
  47.     // 从范例中抄来的缓动效果,想到了flash,瞬间感觉好亲切。。
  48.     mouseX = ( event.clientX - windowHalfX ) * 10;
  49.     mouseY = ( event.clientY - windowHalfY ) * 10;
  50.  
  51. }

然后在最前面加入:

  1. var windowHalfX = window.innerWidth / 2;
  2. var windowHalfY = window.innerHeight / 2;
  3.  
  4. var mouseX = 0,    mouseY = 0;

之前的场景尺寸是固定的,为了铺满整个浏览器窗口,还要修改一些语句:

把var WIDTH = 400, HEIGHT = 300;这句修改为
var WIDTH = window.innerWidth, HEIGHT = window.innerHeight;

现在移动鼠标,应该就能看到效果了!

隔夜写文,没经测试,可能会有错。以这里的代码为准,也可以用这个链接下载整站。

原文地址:https://www.cnblogs.com/alanalan/p/2990910.html