Three.js的使用及绘制基础3D图形详解


Posted in Javascript onApril 27, 2017

一、 前言

Three.js 是一款 webGL(3D绘图标准,在此不赘述)引擎,可以运行于所有支持 webGL 的浏览器。Three.js 封装了 webGL 底层的 API ,为我们提供了高级的开发接口,可以使用简单的代码去实现 3D 渲染。(官网:https://threejs.org/)

二、 为什么要选择Three.js?

Three.js 作为原生 web3D 引擎,对插件式 web3D 引擎的优势不言而喻:不需要安装插件、在移动端支持好。

Three.js 与其他原生 web3D 引擎对比:

  • Babylon.js:一个强大的 3D 游戏引擎,由 Microsoft 的员工 David Cathue 主导开发。和 Three.js 相比,three.js 更倾向于动画,而 Babylon.js 则更适合游戏开发。
  • PhiloGL:增加了额外的功能帮助你可以使用本地的 WebGL ,这个 WebGL 的接口不是百分之百的被封装好了的,这使得 PhiloGL 上手难度较高。
  • SceneJS:一个开源的 JavaScript 3D 引擎,特别适合需要高精度细节的模型需求,比如工程学和医学上常用的高精度模型。
  • CopperLicht:一个“商业级别的 WebGL 3D 引擎和编辑器”,你可以免费使用,但是要想获得未压缩的完整版带支持文档的源码和其他服务,则需要购买授权。

相对这些 web3D 引擎,Three.js 的还有以下几点优势:

  • 开发和维护比较活跃;
  • 文档齐全,案例丰富,易于学习;
  • 设计灵活、方便拓展以及增加新的特性;

我们可以根据自己的需要去选择web3D引擎。

三、 开始Three.js

1、 引导

在开始我们的第一个 3D 程序之前,我们需要了解 Three.js 的一些基础,以下是 Three.js 制作 3D 的五要素:

1、渲染器(render)

我们可以把渲染器想想成为一个画布,我们需要在这个画布上去画出我们需要展示的东西。

2、场景(scene)

相当于一个空间,我们需要将展示的东西放在这个空间里,然后再在画布上绘制出来。

3、照相机(camera)

相当于眼睛,我们想要看到物体,就需要眼睛去看。

4、光源(light)

物体需要光照才能看见,不然就是漆黑一片(但是在某些情况下展示物体不需要光源)。

5、物体(object)

我们想要表现的内容,会有形状和材质属性。

了解了五要素之后,就可以开始写我们的代码了。

2、 创建渲染器

首先,我们创建一个渲染器。创建渲染器有两种方式:

a. 在 html 上写出 canvas 元素

<canvas id="mainCanvas" width="600px" height="450px" ></canvas>
然后创建渲染器时绑定此元素
var renderer = new THREE.WebGLRenderer({
 canvas: document.getElementById('mainCanvas')
});
renderer.setClearColor(“#000”); // 设置渲染器背景为黑色

b. html 上不创建 canvas 元素,而是使用普通的元素作为容器

<div id="mainCanvas" style="width:600px;height:450px;" ></div>
然后创建渲染器,放入容器中
var canvasContainer = document.getElementById('mainCanvas');
var width = canvasContainer.clientWidth; //获取画布的宽
var height = canvasContainer.clientHeight; //获取画布的高
var renderer = new THREE.WebGLRenderer({
 antialias: true //抗锯齿开
});
renderer.setSize(width, height); //设置渲染器的宽和高
renderer.setClearColor(0x000000); //设置渲染器的背景颜色为黑色
var canvas = renderer.domElement; //获取渲染器的画布元素
canvasContainer.appendChild(canvas); //将画布写入html元素中

这样,我们的渲染器就创建成功了。创建渲染器时,还可以设置多个属性,比如抗锯齿、透明度等等,详见 three.js 官方文档。

3、 创建场景

渲染器创建之后,我们再创建场景,准备将我们需要绘制的东西放入场景。

var scene = new THREE.Scene();

4、 创建照相机

照相机常用的有两种,一种叫正投影相机:

THREE.OrthographicCamera( left, right, top, bottom, near, far );

下图为该照相机的视野:

Three.js的使用及绘制基础3D图形详解

一种叫做透视照相机:

THREE.PerspectiveCamera( fov, aspect, near, far ) ;

下图为该照相机的视野:

Three.js的使用及绘制基础3D图形详解

下图为两个照相机展示效果的对比:

Three.js的使用及绘制基础3D图形详解

**左边为正投照相机,远近大小都一样;右边为透视照相机,远小近大,更接近于人眼观察物体的感觉。**

在此以正投照相举例:

var camera = new THREE.OrthographicCamera(-6, 6, 4.5, -4.5, 0, 50); //创建照相机
camera.position.set(35, 15, 25); //设置照相机的位置
camera.lookAt(new THREE.Vector3(0, 0, 0)); //设置照相机面向(0,0,0)坐标观察

照相机默认坐标为(0,0,0);

默认面向为沿z轴向里观察;

5、 创建光源

常用光源有:

1、平行光(DirectionalLight),效果类似太阳光

DirectionalLight ( color, intensity )

color — 光源颜色的RBG数值。

intensity — 光强的数值。

2、点光源(PointLight),效果类似灯泡

PointLight ( color, intensity, distance, decay )

color — 光源颜色的RBG数值。

intensity — 光强的数值。

distance -- 光强为0处到光源的距离,0表示无穷大。

decay -- 沿着光照距离的衰退量。

3、聚光光源(SpotLight),效果类似聚光灯

SpotLight ( color, intensity, distance, angle, penumbra, decay )

color — 光源颜色的RBG数值。

intensity — 光强的数值。

distance -- 光强为0处到光源的距离,0表示无穷大。

angle -- 光线散射角度,最大为Math.PI/2。

penumbra -- 聚光锥的半影衰减百分比。在0和1之间的值。默认为0。

decay -- 沿着光照距离的衰退量。

在此以点光源举例:

var light = new THREE.PointLight(0xffffff, 1, 100); //创建光源
light.position.set(12, 15, 10); //设置光源的位置
scene.add(light); //在场景中添加光源

6、 创建物体

制作物体的方法是 Mesh:

new THREE.Mesh(Geometry, Material);

Geometry 为物体的形状,Material 为物体的材质;

1、形状(Geometry)

three.js 给出了很多方法去生成固定的形状,比如长方体(BoxGeometry)、球体(SphereGeometry)、圆形(CircleGeometry)等等。还有根据坐标去生成具体形状的方法,可以借助第三方建模软件建模之后引入,转换为坐标后再生成,就可以做比较复杂的形状了,比如人脸、汽车等等。

在此以长方体为例生成形状:

//设置正方体宽度,高度,深度分别为5,5,5
var geometry = new THREE.BoxGeometry (5, 5, 5);

2、材质(Material)

材质就像是物体的皮肤,决定物体外表的样子,例如物体的颜色,看起来是否光滑,是否有贴图等等。

常用材质有:

·网格基础材质(MeshBasicMaterial)

该材质不受光照的影响,不需要光源即可显示出来,设置颜色后,各个面都是同一个颜色。

·网格法向材质(MeshNormalMaterial)

该材质不受光照的影响,不需要光源即可显示出来,并且每个方向的面的颜色都不同,同但一个方向的面颜色是相同的,

该材质一般用于调试。

·网格朗博材质(MeshLambertMaterial)

该材质会受到光照的影响,没有光源时不会显示出来,用于创建表面暗淡,不光亮的物体。

·网格 Phong 材质(MeshPhongMaterial)

该材质会受到光照的影响,没有光源时不会显示出来,用于创建光亮的物体。

在此以网格 Phong 材质为例创建材质:

var material = new THREE.MeshPhongMaterial({
  color: "yellow" //设置颜色为yellow
});

创建形状和材质之后,就可以创建该物体了:

//创建物体
var cube = new THREE.Mesh(geometry, material);

7、 渲染画布

通过以上步骤,我们已经有了渲染器(renderer)、场景(scene)、照相机(camera)、光源(light)和物体(cube),此时我们需要将光源和物体加入场景中:

scene.add(light);
scene.add(cube);

然后再使用渲染器将场景和照相机渲染出来:

renderer.render(scene, camera);

效果如下图:

Three.js的使用及绘制基础3D图形详解

四、 结束语

在以上内容中,只写到了 Three.js 中提供的基础功能,还有很多高级的功能需要大家去探索。希望大家看完这篇文章后能对 Three.js 有一个初步的了解,并能够使用 Three.js 绘制出基础的 3D 图形。

大家可以去 Three.js 官网的 examples 中看看,这里面都是一些很优秀和典型的 examples,并且还有代码可以下载,大家可以去研究探索一番。

在此附上几个精彩的例子供大家欣赏:

Three.js的使用及绘制基础3D图形详解

Three.js的使用及绘制基础3D图形详解

Three.js的使用及绘制基础3D图形详解

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
JavaScript 常用函数
Dec 30 Javascript
最简单的js图片切换效果实现代码
Sep 24 Javascript
ASP.NET jQuery 实例6 (实现CheckBoxList成员全选或全取消)
Jan 13 Javascript
js数组去重的常用方法总结
Jan 24 Javascript
JavaScript使表单中的内容显示在屏幕上的方法
Jun 29 Javascript
JS选取DOM元素的简单方法
Jul 08 Javascript
Bootstrap和Angularjs配合自制弹框的实例代码
Aug 24 Javascript
Javascript快速实现浏览器系统通知
Aug 26 Javascript
完美解决linux下node.js全局模块找不到的情况
May 16 Javascript
layer弹出的iframe层在执行完毕后关闭当前弹出层的方法
Aug 17 Javascript
VUE 全局变量的几种实现方式
Aug 22 Javascript
vue项目中的支付功能实现(微信支付和支付宝支付)
Feb 18 Vue.js
jquery ui sortable拖拽后保存位置
Apr 27 #jQuery
ES5 ES6中Array对象去除重复项的方法总结
Apr 27 #Javascript
JavaScript实现隐藏省略文字效果的方法
Apr 27 #Javascript
Vue自定义图片懒加载指令v-lazyload详解
Dec 31 #Javascript
JavaScript实现反转字符串的方法详解
Apr 27 #Javascript
jquery 禁止鼠标右键并监听右键事件
Apr 27 #jQuery
jQuery EasyUI tree增加搜索功能的实现方法
Apr 27 #jQuery
You might like
php xml-rpc远程调用
2008/12/19 PHP
php中$_REQUEST、$_POST、$_GET的区别和联系小结
2011/11/23 PHP
WordPress中制作导航菜单的PHP核心方法讲解
2015/12/11 PHP
Zend Framework教程之模型Model用法简单实例
2016/03/04 PHP
利用PHP判断文件是否为图片的方法总结
2017/01/06 PHP
用php+ajax新建流程(请假、进货、出货等)
2017/06/11 PHP
Laravel多域名下字段验证的方法
2019/04/04 PHP
硬盘浏览程序,保存成网页格式便可使用
2006/12/03 Javascript
取得窗口大小 兼容所有浏览器的js代码
2011/08/09 Javascript
js 在定义的时候立即执行的函数表达式(function)写法
2013/01/16 Javascript
JavaScript String.replace函数参数实例说明
2013/06/06 Javascript
jquery中通过父级查找进行定位示例
2013/06/28 Javascript
在JavaScript中正确引用bind方法的应用
2015/05/11 Javascript
Javascript验证方法大全
2015/09/21 Javascript
jqGrid 学习笔记整理——进阶篇(一 )
2016/04/17 Javascript
微信小程序实现图片预加载组件
2017/01/18 Javascript
Node之简单的前后端交互(实例讲解)
2017/11/14 Javascript
详解vue中点击空白处隐藏div的实现(用指令实现)
2018/04/19 Javascript
jQuery中元素选择器(element)简单用法示例
2018/05/14 jQuery
手把手教你vue-cli单页到多页应用的方法
2018/05/31 Javascript
Vue中常用rules校验规则(实例代码)
2019/11/14 Javascript
Windows系统下安装Python的SSH模块教程
2015/02/05 Python
在Python程序中操作MySQL的基本方法
2015/07/29 Python
详解使用Python处理文件目录的相关方法
2015/10/16 Python
Java分治归并排序算法实例详解
2017/12/12 Python
Python使用paramiko连接远程服务器执行Shell命令的实现
2021/03/04 Python
Roxy美国官网:澳大利亚冲浪、滑雪健身品牌
2016/07/30 全球购物
补充协议书范本
2014/04/23 职场文书
建筑投标担保书
2014/05/20 职场文书
大学优秀班集体申报材料
2014/05/23 职场文书
个人四风问题对照检查材料思想汇报
2014/10/06 职场文书
2014年人力资源部工作总结
2014/11/19 职场文书
销售2014年度工作总结
2014/12/08 职场文书
2016入党积极分子心得体会
2016/01/06 职场文书
pytorch实现手写数字图片识别
2021/05/20 Python
变长双向rnn的正确使用姿势教学
2021/05/31 Python