admin管理员组文章数量:1551525
threejs
现代浏览器都支持 WebGL,这样我们就不必使用 Flash、Java 等插件就能在浏览器中创建三维图形。虽然 WebGL 提供的接口非常丰富和强大,但使用起来过于繁琐和复杂。
Three.js 的出现完美地解决了这个矛盾。它提供一个很简单的关于 WebGL 特性的 JavaScript API,使得用户不需要详细地学习 WebGL,就能轻松创作出好看的三维图形样例。
更多学习案例尽在我的github
1、基本介绍
1.1 Three.js 的功能特点
- 创建简单和复杂的三维几何图形。
- 在三维场景下创建动画和移动物体。
- 为物体添加纹理和材质。
- 使用各种光源来装饰场景。
- 通过三维模型软件加载物体。
- 为三维场景添加高级的后期处理效果。
- 使用自定义的着色器。
- 创建点云(粒子系统)
1.2 桌面浏览器兼容性
基本上所有的现代浏览器都支持 Three.js。
- Firefox:4.0 版本后开始支持
- Chrome:9.0 版本后开始支持
- Safari:5.1 版本后开始支持
- Opera:12.00 版本后开始支持
- IE:IE11 起才开始支持(唯一一个很长时间都不支持 WebGL 的浏览器)
如果想在低版本的 IE 浏览器(IE10 或者更低版本)上运行 Three.js,可以安装 iewebgl 插件。
1.3 移动设备兼容性
Three.js 还可以在移动设备上运行,不同设备对于 Three.js 的支持情况如下:
- Android:Android 原生的浏览器是不支持 WebGL 的。如果想在 Android 上运行 WebGL,需要安装最新的移动版本的 Chrome、Firefox 或者 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看这里就行了 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/xitong/1725800309a1043482.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论