• 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;

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

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

  • 相关阅读:
    接口与实现分离
    C++的explicit关键字
    C++的类型转换
    使用catch做单元测试简介
    C++可调用对象与函数表
    在sublime中使用cppcheck
    你需要的代码静态检查
    构造析构与拷贝赋值那些事
    c++的关联容器入门(map and set)
    【致敬程序猿】
  • 原文地址:https://www.cnblogs.com/alanalan/p/2990910.html
Copyright © 2020-2023  润新知