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 相关文章推荐
很全的显示阴历(农历)日期的js代码
Jan 01 Javascript
基于Jquery的实现回车键Enter切换焦点
Sep 14 Javascript
关于backbone url请求中参数带有中文存入数据库是乱码的快速解决办法
Jun 13 Javascript
jQuery extend()详解及简单实例
May 06 jQuery
JS实现身份证输入框的输入效果
Aug 21 Javascript
C#实现将一个字符转换为整数
Dec 12 Javascript
动态Axios的配置步骤详解
Jan 12 Javascript
javascript获取图片的top N主色值方法详解
Jan 26 Javascript
基于Bootstrap下拉框插件bootstrap-select使用方法详解
Aug 07 Javascript
vue 点击按钮实现动态挂载子组件的方法
Sep 07 Javascript
JavaScript显式数据类型转换详解
Mar 18 Javascript
vue实现路由懒加载及组件懒加载的方式
Jun 11 Javascript
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
Protoss热键控制
2020/03/14 星际争霸
PHP文件打开、关闭、写入的判断与执行代码
2011/05/24 PHP
PHP分页详细讲解(有实例)
2013/10/30 PHP
php删除数组中重复元素的方法
2015/12/22 PHP
Jquery 基础学习笔记
2009/05/29 Javascript
原生Js与jquery的多组处理, 仅展开一个区块的折叠效果
2011/01/09 Javascript
formStorage 基于jquery的一个插件(存储表单中元素的状态到本地)
2012/01/20 Javascript
js动态移动滚动条至底部示例代码
2014/04/24 Javascript
Node.js编程中客户端Session的使用详解
2015/06/23 Javascript
JS实现新浪微博效果带遮罩层的弹出框代码
2015/10/12 Javascript
基于JavaScript实现简单的随机抽奖小程序
2016/01/05 Javascript
用JavaScript获取页面文档内容的实现代码
2016/06/10 Javascript
浅谈AngularJS中ng-class的使用方法
2016/11/11 Javascript
JS实现的适合做faq或menu滑动效果示例
2016/11/17 Javascript
基于Bootstrap漂亮简洁的CSS3价格表(附源码下载)
2017/02/28 Javascript
Vue.js 的移动端组件库mint-ui实现无限滚动加载更多的方法
2017/12/23 Javascript
vue2.0模拟锚点的实例
2018/03/14 Javascript
webpack4 处理CSS的方法示例
2018/09/03 Javascript
使用 Vue cli 3.0 构建自定义组件库的方法
2019/04/30 Javascript
vue history 模式打包部署在域名的二级目录的配置指南
2019/07/02 Javascript
浅谈Vue为什么不能检测数组变动
2019/10/14 Javascript
在vue中实现禁止屏幕滚动,禁止屏幕滑动
2020/07/22 Javascript
Python实现替换文件中指定内容的方法
2018/03/19 Python
python3安装speech语音模块的方法
2018/12/24 Python
Python2 Selenium元素定位的实现(8种)
2019/02/25 Python
为什么你还不懂得怎么使用Python协程
2019/05/13 Python
python 判断三个数字中的最大值实例代码
2019/07/24 Python
python 连续不等式语法糖实例
2020/04/15 Python
CSS3 中的@keyframes介绍
2014/09/02 HTML / CSS
小学生竞选班干部演讲稿
2014/04/24 职场文书
三八妇女节演讲稿
2014/05/27 职场文书
幼儿园教师的自我评价范文
2014/09/17 职场文书
会计试用期自我评价怎么写
2014/09/18 职场文书
在酒桌上的敬酒词
2015/08/12 职场文书
2016元旦晚会主持人开场白和结束语
2015/12/03 职场文书
golang判断key是否在map中的代码
2021/04/24 Golang