来源:未知 时间:2017-04-24 13:54 作者:xxadmin 阅读:次
[导读] 引言 本文主要是讲解Three.js的相关概念,帮助读者对Three.js以及相关知识形成比较完整的理解。 近年来web得到了快速的发展。随着HTML5的普及,网页的表现能力越来越强大。网页上已经...
引言 本文主要是讲解Three.js的相关概念,帮助读者对Three.js以及相关知识形成比较完整的理解。 近年来web得到了快速的发展。随着HTML5的普及,网页的表现能力越来越强大。网页上已经可以做出很多复杂的动画,精美的效果。 OpenGL,WebGL到Three.js OpenGL大概许多人都有所耳闻,它是最常用的跨平台图形库。 简单点的说法:WebGL可以看成是浏览器给我们提供的接口,在javascript中可以直接用这些API进行3D图形的绘制;而Three.js就是在这些接口上又帮我们封装得更好用一些。 WebGL与Three.js对比 既然有了WebGL,我们为什么还需要Three.js? Three.js的学习问题 Three.js的入门是相对简单的,但是当我们真的去学的时候,会发现一个很尴尬的问题:相关的学习资料很少。 这里推荐一些相对较好的教程: Three.js开发指南(第一版中文版) Learning Three.js- Second Edition 当然,实际的学习过程中这些资料肯定是不太够的,遇到问题还是要自己去查资料。不过这里要提醒一下,Three.js的更新是相当频繁的,现在是r80版本,自2010年4月发布r1以来,这已经是第72个版本了(中间有的版本号跳过了)。因此,在网上找到的资料有些可能是不适合当前版本的,需要注意甄别(前面推荐的资料也都或多或少存在这样的问题)。 Three.js中的一些概念 要在屏幕上展示3D图形,思路大体上都是这样的: 构建一个三维空间 下面来具体看一看Three中的这些概念。 Scene 场景是所有物体的容器,也对应着我们创建的三维世界。 Camera 坐标系 Camera是三维世界中的观察者,为了观察这个世界,首先我们要描述空间中的位置。 Three中使用采用常见的右手坐标系定位。 三维投影 Three中的相机有两种,分别是正投影相机THREE.OrthographicCamera和透视投影相机THREE.PerspectiveCamera。 正交投影与透视投影的区别如上图所示,左图是正交投影,物体发出的光平行地投射到屏幕上,远近的方块都是一样大的;右图是透视投影,近大远小,符合我们平时看东西的感觉。 正交投影相机 注:图中的”视点”对应着Three中的Camera。 可以近似地认为,视景体里的物体平行投影到近平面上,然后近平面上的图像被渲染到屏幕上。 透视投影相机 透视投影相机的视景体是个四棱台,它的构造函数是这样的:PerspectiveCamera( fov, aspect, near, far ) Objects 有了相机,总要看点什么吧?在场景中添加一些物体吧。 Mesh 我们都知道,计算机的世界里,一条弧线是由有限个点构成的有限条线段连接得到的。线段很多时,看起来就是一条平滑的弧线了。
这是那只著名的斯坦福兔子。它在3D图形中的地位与数字图像处理领域中著名的lena是类似的。 在Three中,Mesh的构造函数是这样的:Mesh( geometry, material ) Geometry Geometry,形状,相当直观。Geometry通过存储模型用到的点集和点间关系(哪些点构成一个三角形)来达到描述物体形状的目的。 Material Material,材质,这就没有形状那么直观了。 Points 讲完了Mesh,我们来看看另一种Object——Points。 Light 神说:要有光! Renderer 在场景中建立了各种物体,也有了光,还有观察物体的相机,是时候把看到的东西渲染到屏幕上了。这就是Render做的事情了。 让画面动起来 现在,一个静态的画面已经可以得到了,怎么才能让它动起来? function render() { renderer.render(scene, camera); } 只需要改成这样: function render() { requestAnimationFrame(render); object.position.x += 1; renderer.render(scene, camera); } object就可以动起来了! 举个栗子 下面我们用一个简单的例子来梳理一下这个过程。 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>立方体</title> <script src="http://sqimg.qq.com/qq_product_operations/mma/javanli_test/lib/three.min.js"></script> <style type="text/css"> html, body { margin: 0; padding: 0; } #three_canvas { position: absolute; width: 100%; height: 100%; } </style> </head> <body> <canvas id="three_canvas"></canvas> </body> </html> 下面来做Javascript的部分 function initRenderer() { width = document.getElementById('three_canvas').clientWidth; height = document.getElementById('three_canvas').clientHeight; renderer = new THREE.WebGLRenderer({ //将Canvas绑定到renderer canvas: document.getElementById('three_canvas') }); renderer.setSize(width, height);//将渲染的大小设为与Canvas相同 renderer.setClearColor(0xFFFFFF, 1.0);//设置默认颜色与透明度 } 初始化场景: function initScene() { scene = new THREE.Scene(); } 初始化相机: function initCamera() { //简单的正交投影相机,正对着视口的中心,视口大小与Canvas大小相同。 camera = new THREE.OrthographicCamera(width / -2, width / 2, height / 2, height / -2, 1, 1000); //设置相机的位置 camera.position.x = 0; camera.position.y = 0; camera.position.z = 200; //设置相机的上方向 camera.up.x = 0; camera.up.y = 1; camera.up.z = 0; //设置相机聚焦的位置(其实就是确定一个方向) camera.lookAt({ x: 0, y: 0, z: 0 }); } 要唯一确定一个相机的位置与方向,position、up、lookAt三个属性是缺一不可的。 下面添加一个立方体到场景中: function initObject() { //创建一个边长为100的立方体 var geometry = new THREE.CubeGeometry(100, 100, 100); object = new THREE.Mesh(geometry, new THREE.MeshNormalMaterial()); scene.add(object); } 注意我们使用了法向材质MeshNormalMaterial,这样立方体每个面的颜色与这个面对着的方向是相关的,更便于观察/调试。 在这个简单的demo里我不打算添加光影效果,而法向材质对光也是没有反应的。 function render() { requestAnimationFrame(render); object.rotation.x += 0.05; object.rotation.y += 0.05; renderer.render(scene, camera); } 每次重绘都让这个立方体转动一点点。 function threeStart() { initRenderer(); initCamera(); initScene(); initObject(); render(); } window.onload = threeStart(); 完整的demo是这个样子的: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>立方体</title> <script src="http://sqimg.qq.com/qq_product_operations/mma/javanli_test/lib/three.min.js"></script> <style type="text/css"> html, body { margin: 0; padding: 0; } #three_canvas { position: absolute; width: 100%; height: 100%; } </style> </head> <body> <canvas id="three_canvas"></canvas> <script> var renderer, camera, scene, light, object; var width, height; function initRenderer() { width = document.getElementById('three_canvas').clientWidth; height = document.getElementById('three_canvas').clientHeight; renderer = new THREE.WebGLRenderer({ canvas: document.getElementById('three_canvas') }); renderer.setSize(width, height); renderer.setClearColor(0xFFFFFF, 1.0); } function initCamera() { camera = new THREE.OrthographicCamera(width / -2, width / 2, height / 2, height / -2, 1, 1000); camera.position.x = 0; camera.position.y = 0; camera.position.z = 200; camera.up.x = 0; camera.up.y = 1; camera.up.z = 0; camera.lookAt({ x: 0, y: 0, z: 0 }); } function initScene() { scene = new THREE.Scene(); } function initObject() { var geometry = new THREE.CubeGeometry(100, 100, 100); object = new THREE.Mesh(geometry, new THREE.MeshNormalMaterial()); scene.add(object); } function render() { requestAnimationFrame(render); object.rotation.x += 0.05; object.rotation.y += 0.05; renderer.render(scene, camera); } function threeStart() { initRenderer(); initCamera(); initScene(); initObject(); render(); } window.onload = threeStart(); </script> </body> </html> 保存为html后打开,在屏幕中央会显示这样一个转动的立方体 小结 对Three.js的介绍就到这里了,本文对Three中的重要组件基本上都有提到。其实想要总结的东西还有很多,但写在这一篇里可能会显得很累赘,这篇文章的初衷是想要读者读后对Three.js有一个直观的大体上的理解,并不打算牵涉太多细节。 以上就是本文的全部内容,希望对大家的学习有所帮助。 |
自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习
京ICP备14009008号-1@版权所有www.zixuephp.com
网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com