来源:未知 时间: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