admin管理员组

文章数量:1551525

threejs

现代浏览器都支持 WebGL,这样我们就不必使用 FlashJava 等插件就能在浏览器中创建三维图形。虽然 WebGL 提供的接口非常丰富和强大,但使用起来过于繁琐和复杂。
Three.js 的出现完美地解决了这个矛盾。它提供一个很简单的关于 WebGL 特性的 JavaScript API,使得用户不需要详细地学习 WebGL,就能轻松创作出好看的三维图形样例。

更多学习案例尽在我的github


 

1、基本介绍

1.1 Three.js 的功能特点

  • 创建简单和复杂的三维几何图形。
  • 在三维场景下创建动画和移动物体。
  • 为物体添加纹理和材质。
  • 使用各种光源来装饰场景。
  • 通过三维模型软件加载物体。
  • 为三维场景添加高级的后期处理效果。
  • 使用自定义的着色器。
  • 创建点云(粒子系统)

1.2 桌面浏览器兼容性

基本上所有的现代浏览器都支持 Three.js

  • Firefox4.0 版本后开始支持
  • Chrome9.0 版本后开始支持
  • Safari5.1 版本后开始支持
  • Opera12.00 版本后开始支持
  • IEIE11 起才开始支持(唯一一个很长时间都不支持 WebGL 的浏览器)


如果想在低版本的 IE 浏览器(IE10 或者更低版本)上运行 Three.js,可以安装 iewebgl 插件。

1.3 移动设备兼容性

Three.js 还可以在移动设备上运行,不同设备对于 Three.js 的支持情况如下:

  • AndroidAndroid 原生的浏览器是不支持 WebGL 的。如果想在 Android 上运行 WebGL,需要安装最新的移动版本的 ChromeFirefox 或者 Opera
  • iOS:从 iOS8 起就开始支持
  • Windows mobile:从 8.1 版本后开始支持

2、概念

2.1 Three.js 制作 3D 的五要素

  • 渲染器(render)
    我们可以把渲染器想想成为一个画布,我们需要在这个画布上去画出我们需要展示的东西。
  • 场景(scene)
    相当于一个空间,我们需要将展示的东西放在这个空间里,然后再在画布上绘制出来。
  • 照相机(camera)
    相当于眼睛,我们想要看到物体,就需要眼睛去看。
  • 光源(light)
    物体需要光照才能看见,不然就是漆黑一片(但是在某些情况下展示物体不需要光源)。
  • 物体(object)
    我们想要表现的内容,会有形状和材质属性。

2.2 顶点概念、几何体结构

在ThreeJs中有个物体元素的基类,通过设置顶点的个数来呈现不同的几何体,一个顶点一般是三个参数即xyz的坐标点,如果设置两个参数,则z轴默认为0 。

ThreeJs中所有的模型都是通过顶点来构成的。比如:线模型(两个顶点),网格模型的基本单位三角形(三个顶点)

同时顶点可以有颜色值,还有顶点法向量(光照影响)

几何体的本质:

立方体网格模型Mesh是由立方体几何体geometry和材质material两部分构成,立方体几何体BoxGeometry本质上就是一系列的顶点构成,只是Threejs的APIBoxGeometry把顶点的生成细节封装了,用户可以直接使用

var geometry = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
var material = new THREE.MeshLambertMaterial({
  color: 0x0000ff
}); //材质对象Material
var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh

几何体对象:

几何体对象

区别

场景

Geometry

顶点数据用一个对象表示

适用于一般案例场景

BufferGeometry

顶点数据使用类型化数组集中表示

适用于实际应用场景,使用 BufferGeometry 可以有效减少向 GPU 传输上述数据所需的开销

几何体结构:

几何体对象

属性

旋转、缩放、平移

Geometry

vertices(位置),colors(颜色),face3(每个三角面属性)

改变几何体的顶点位置数据

BufferGeometry

attributes(属性,包括position,color,normal... ),index (索引,便于重复使用顶点)

改变几何体的顶点位置数据

2.3 材质对象

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

本质: 顶点着色器、片元着色器代码、unifomrs数据

分类:点材质、线材质、网格材质、精灵材质、自定义着色器材质

常用网格材质:

  • 网格基础材质(MeshBasicMaterial) 该材质不受光照的影响,不需要光源即可显示出来,设置颜色后,各个面都是同一个颜色。
  • 网格法向材质(MeshNormalMaterial) 该材质不受光照的影响,不需要光源即可显示出来,并且每个方向的面的颜色都不同,同但一个方向的面颜色是相同的,该材质一般用于调试。
  • 网格朗博材质(MeshLambertMaterial)  该材质会受到光照的影响,没有光源时不会显示出来,用于创建表面暗淡,不光亮的物体。
  • 网格 Phong 材质(MeshPhongMaterial)  该材质会受到光照的影响,没有光源时不会显示出来,用于创建光亮的物体。

 以网格 Phong 材质为例创建材质

var material = new THREE.MeshPhongMaterial({
      color: "yellow" //设置颜色为yellow
});
 
//创建物体
var cube = new THREE.Mesh(geometry, material);

2.4 模型对象

类型

特性

渲染方式

点模型

几何体的每个顶点,可以设置大小

每个顶点对应位置都会渲染出来一个方形的点区域

线模型

两个顶点构成一线条,可以设置大小,变换位置

从第一个点开始到最后一个点,依次连成线

网格模型

三个顶点构成一个三角面,可以设置大小,变换位置

顶点每三个顶点为一组可以确定一个三角形,顶点可以重复使用

2.5 光源对象

模拟生活中的光源效果

环境光:没有特定的方向,只有颜色。不会产生阴影,可以理解为全局的背景色。

点光源:由一个点散发的光,类似于蜡烛,可以设置阴影。

      

平行光:从一个方向平行照射的光,类似于阳光,可以设置阴影。

      

2.6 几何体对象、三维建模

基类Geometry:BoxGeometry、CylinderGeometry、SphereGeometry ...

几何体有提供的基类对象:

  •  3D:长方体、正方体、正多面体
  •  2D:圆平面,正平面、环平面

2D转3D的几种方案:

      ExtrudeGeometry 拉伸: 

     ExtrudeGeometry 扫描: 

常见几何体:

类型

Geometry

BufferGeometry

长方体

BoxGeometry

BoxBufferGeometry

圆柱体

CylinderGeometry

CylinderBufferGeometry

球体

SphereGeometry

SphereBufferGeometry

圆锥

SphereGeometry

SphereBufferGeometry

正四面体

TetrahedronGeometry

TetrahedronBufferGeometry

正八面体

OctahedronGeometry

OctahedronBufferGeometry

正十二面体

OctahedronGeometry

OctahedronBufferGeometry

正二十面体

DodecahedronGeometry

DodecahedronBufferGeometry

圆平面

CircleGeometry

CircleBufferGeometry

矩形平面

PlaneGeometry

PlaneBufferGeometry

2.7 纹理贴图

贴图是通过将图像应用到对象的一个或多个面,来为3D对象添加细节的一种方法。

这使我们能够添加表面细节,而无需将这些细节建模到我们的3D对象中,从而大大精简3D模型的多边形边数,提高模型渲染性能

应用场景:

  • 全景贴图,比如:3D地球贴图,天空盒子贴图
  • 添加文字,视频 比如:在大楼上加横幅,地板上加文字之类的,通过canvas绘制好图,通过uv映射原理贴到几何体上面。
  • 3D美术贴图,流程:3D美术创建好模型和纹理贴图--->程序员解析3D美术导出的资源-→纹理映射到几何体上面(一般美术导出的模型都会解析好,程序员只用解析显示就好了)

UV映射原理:

      

2.8 相机对象(投影方式)

相机拍照本质就是投影计算的过程,相机分为两种相机,正投影相机OrthographicCamera和透视投影相机PerspectiveCamera。

目前的实际项目中,一般使用的就是 PerspectiveCamera,其他相机很少用。

相机对象

特性

应用场景

正投影相机

物体不受物体与相机的距离影响,改变相机位置,物体大小不会变化

小的场景,比如一些物品展示

透视投影相机

物体随着距离的变化显示的大小会变化,类似于人的眼睛

大的场景,比如游戏,地图,数据展示之类的

相机是继承基类Object3D,所以相机有position属性来设置位置。然后通过.lookAt()来设置相机对着哪里(看向哪里)。

2.9 精灵模型、粒子系统

精灵模型对象Sprite

  • 效果:无论相机如何变化,始终平行于桌面的矩形区域,等价于一个PlaneGeometry创建的矩形网格模型,正面永远朝着屏幕
  • 模型对比:不包含几何体geometry参数
  • 应用:大数据可视化,通过大量的精灵对象近似模拟下雨,下雪等特效。
  • 粒子系统:足够多精灵对象构成一个粒子系统
  • 缩放:和网格模型受正投影、透视投影相机的影响一样

2.10 模型文件导出&导入

可导出模型:几何体、网格模型、材质、光源、相机...

导出方法:toJSON()

导出一个json的过程:threejs对象-->从threejs对象提取数据-->执行toJSON方法得到一个对象-->将JSON对象转为字符串→HTML5的文件保存模块

几种可导入模型类型:

  • JSON文件,和上面的json导出模型对应。
  • stl文件 ,3d美术导出文件,适用于几何体、材质、贴图
  • obj文件,3d美术导出文件,适用于几何体、材质、贴图
  • FBX并解析骨骼动画,3d美术导出文件,主要适用于骨骼动画这块。

2.11 后期处理

 THREEJS 中的后期处理通道(ShaderPass)以及特效合成器(effectComposer)

后期处理通道(Pass),每个通道都是一个ShaderPass,也就是一个Shader,熟悉 GLSL 的 learner 都可以自定义ShaderPass,每个通道就类似于美图秀秀的滤镜的功能,能给你的画面一些特效,比如发光、褐色、清新之类的。

而特效合成器(effectComposer)就会把叠加在这个画面上的所有通道(一个画面可以叠加多个通道,类似于一个图片用多个滤镜)的结果计算并渲染出来,所以特效合成器也算是一个render

案例:让场景模型点击发光。

主要后期处理代码:

thisposer = new EffectComposer(this.renderer)
var renderPass = new RenderPass(this.scene, this.camera)
thisposer.addPass(renderPass)
this.outlinePass = new OutlinePass(
    new THREE.Vector2(window.innerWidth, window.innerHeight),
    this.scene,
    this.camera
)
this.outlinePass.edgeStrength = 5 //包围线浓度
this.outlinePass.edgeGlow = 0.5 //边缘线范围
this.outlinePass.edgeThickness = 2 //边缘线浓度
this.outlinePass.pulsePeriod = 2 //包围线闪烁频率
this.outlinePass.visibleEdgeColor.set('#ffffff') //包围线颜色
this.outlinePass.hiddenEdgeColor.set('#190a05') //被遮挡的边界线颜色
thisposer.addPass(this.outlinePass)

处理前效果:

处理后效果:

2.12 性能优化

  • 绘制的时候,利用几何体buffer缓存对象来绘制。
  • threejs的对象并不会被自动释放,需要调用特定的api,写一套废置对象的代码,无用的对象直接废置掉,节省Gpu开支。
  • 尽量重用Material和Geometry
  • 使用web worker web worker 是运行在后台的 JavaScript,它独立于其他脚本,不会影响页面的性能,通过webworker先把计算做好,再渲染。
  • 分时加载,类似于react的fiber加载方式。

本文标签: 就行了ThreeJs