Three.js入门

Three.js入门

2019/11/7 周四


Three.js官网:http://threejs.org/,左边菜单栏第一个documentation可以阅读使用指南和参考手册,在https://www.techbrood.com/threejs/docs/可以阅读汉化版教程。

Three.js是一款开源的主流 3D绘图JS引擎 (名字Three就是3D的含义),原作者为Mr.Doob,项目地址为:https://github.com/mrdoob/three.js/。它可以简化WebGL编程。

一、关于WebGL

1. 什么是WebGL

WebGL(全写Web Graphics Library)是一种3D绘图协议,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一个JavaScript绑定,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和数据视觉化。显然,WebGL技术标准免去了开发网页专用渲染插件的麻烦,可被用于创建具有复杂3D结构的网站页面,甚至可以用来设计3D网页游戏等等。 ------百度百科

简单来说, WebGL就是一种可以在浏览器上显示3D效果的技术,或者说是在浏览器中实现三维效果的一套规范

2. 浏览器为什么能绘制3D世界?

因为浏览器实现了opengl es的规范,这套规范可以直接使用指令操作显卡,使显卡渲染的3D世界直接反应到浏览器中。

3. WebGL与Three.js的关系

使用WebGL原生的API来写3D程序是一件非常痛苦的事情,于是有很多同行花业余时间写了一些WebGL开源框架,其中three.js就是非常优秀的一个,它掩盖了很多麻烦的细节。所以可以说, Three.js是WebGL的一个封装库,它使WebGL的学习更为简单 。WebGL与Three.js的关系,就好比汇编语言与C语言的关系。

二、Three.js三大基本对象

创建WebGL程序本是一种面向过程的编程,但在Three.js中要使用面向对象的方式来构建程序。要渲染物体到网页中,我们需要3个组件,也就是3个基本对象:场景(scene)、相机(camera)和渲染器(renderer)。

1. 场景(scene)

在Threejs中,场景就只有一种,用THREE.Scene来表示,要构件一个场景也很简单,只要new一个对象就可以了:

var scene = new THREE.Scene();

其实在一个网页中可以放不止一个场景,但暂时先不考虑。

2. 相机(camera)

相机决定了场景中哪个角度的景色会显示出来。相机就像人的眼睛一样,人站在不同位置,抬头或者低头都能够看到不同的景色。

在Three.js中有多种相机,最常用的主要是两种:
(1) 透视相机PerspectiveCamera :离视点近的物体大,离视点远的物体小,远到极点即消失成为灭点,这就是人的眼睛观察世界的形式。
(2) 正投影相机OrthographicCamera :远处和近处一样大,投影到物体的大小不受距离的影响,我的个人理解就是上帝视角。

透视相机是最常用的,构建透视相机也是以new对象的方式,它有四个参数

var camera = new THREE.PerspectiveCamera(fov,aspect,near,far);

(1)第一个参数是 视野fov(field of view) ,即在任何给定时刻显示的场景范围,该值以度为单位,比如设置为75,相当于相机到物体最上面的平面(下图中的OAB或OEF)和最下面的平面(下图OCD或OGH)之间的夹角为75度。
在这里插入图片描述
(2)第二个aspect是 相机拍摄平面的长宽比 ,即平面的宽除以高,一般会设置为页面的宽除以高(EF/FG),不然图形可能会变形。

(3)后两个参数near和far,分别是 近剪裁平面(ABCD)和远剪裁平面(EFGH)到相机的距离 ,即图中的OC和OG。要注意near不能设置为负值,且near和far的值不能相同,不然相机就看不到了不是吗。

3. 渲染器(renderer)

渲染器决定了怎么将眼前的场景显示到屏幕上。Three.js中的渲染器也有多种,主要用的是 WebGLRenderer 渲染器

渲染器的定义有几步:
(1)创建渲染器对象

var renderer = new THREE.WebGLRenderer();

(2)设置要渲染应用程序的大小,这里就设置为浏览器窗口的宽度和高度,也可以设置小一点的尺寸

renderer.setSize(window.innerWidth, window.innerHeight);

对于性能密集型应用程序,如果希望保持应用程序的大小,但以较低的分辨率呈现,可以减小宽和高,并通过调用setSize的第三个参数updateStyle来实现,设置它为false,例如:

renderer.setSize(window.innerWidth/2,window.innerHeight/2,false);

如果省略false参数,将使应用程序呈现为一半大小;带上false时,大小不变,将以半分辨率呈现应用程序,但还有一个前提是 canvas画布 具有100%的宽度和高度。

关于canvas元素 :它是HTML5新元素- 画布 ,自带的属性只有两个,分别控制宽度和高度。要注意的是,一定要使用 Canvas 自带的 width 和 height 属性,而不要使用 CSS 来控制,因为 CSS 控制会导致 Canvas 变形。

(3)将renderer元素添加到HTML文档中

document.body.appendChild(renderer.domElement);

三、编写第一个Three.js程序

1. 准备工作

Three.js是本质是JavaScript,首先需要准备开发环境,即一个html页面,并导入Three.js的JavaScript文件

<!DOCTYPE html>
<html>
	<head>
		<meta charset=utf-8>
		<title>My first Three.js app</title>
		<style>
			body { margin: 0; }
			canvas { width: 100%; height: 100% }
		</style>
	</head>
	<body>
		<script src="js/three.js"></script>
		<script>
			// 接下来的Javascript代码写在这里面
		</script>
	</body>
</html>
2. 创建场景、相机和渲染器
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
3. 添加物体到场景中

(1)创建几何模型

var geometry = new THREE.BoxGeometry(1, 1, 1);

这里添加的是BoxGeometry立方体,一个包含立方体的所有点(顶点)和填充(面)的对象。它的构造函数:BoxGeometry(width, height, dept, widthSegments, heightSegments, depthSegments),其中width, height, dept分别是立方体的长宽高,widthSegments, heightSegments, deptSegments是对应长宽高的分段,可以只设置长宽高,不分段。

(2)使用material材料给物体上色

var material = new THREE.MeshBasicMaterial({
            color: 0x00ff00
        });

如果没有材料的话,创建的物体是看不到的。Three.js支持多种材料,这里只使用 网格基础材料(MeshBasicMaterial),所有材料都含有一个属性来设置颜色,这里只提供了颜色值为0x00ff00的绿色。

(3)使用网格Mesh来承载几何模型

var cube = new THREE.Mesh(geometry, material);

Mesh网格是一个对象,它接受一个几何体geometry,并对其应用一种材质material。

(4)将包含物体的网格插入到场景中

scene.add(cube);
camera.position.z = 5; // 移动相机位置

默认情况下,调用scene.add()时,添加的内容将被添加到坐标原点(0,0,0)中。而 相机的默认位置也是在坐标原点 ,这将导致相机和立方体都在彼此内部,就看不到了,为了避免这一点,需要将相机向外移动一点。

4. 渲染场景

这里是创建一个animate loop动画循环,使渲染器在每次刷新屏幕时绘制场景(在典型屏幕上为每秒60次),在每次绘制场景时让物体的位置稍微移动一下,就可以让物体动起来了。

function animate() {
	requestAnimationFrame( animate );
	
	// 设置立方体动画
	cube.rotation.x += 0.01;
	cube.rotation.y += 0.01;
	
	// 通过渲染器,把相机和已经含有物体的场景渲染到屏幕上
	renderer.render( scene, camera ); 
}
animate();

当浏览器空闲时,会不断调用requestAnimationFrame()这个函数,而它里面调用的就是创建的这个animate()动画循环;与setInterval相比,requestAnimationFrame有很多优点,最重要就是当用户导航到另一个浏览器选项卡时,它会暂停,因此不会浪费宝贵的处理能力和电池寿命。

最后,把上面所写的代码在浏览器中打开,就可以看到旋转的绿色立方体了。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值