我正在参加csdn《新程序员》有奖征文 活动链接.


前言

n年前在北森,我还是个意气风发的少年,舔着脸的对森哥说我以后的志向要做前端人工智能、前端机器学习、前端3d、Ar、Vr。森哥笑笑说,那你何必要将这些标签关联在前端上呢,语言只是工具,用它擅长的做自己合适的不是更好吗。
当年不懂,现在早已物是人非。唏嘘感概之中,提笔记录下自己成长的点滴吧

一、Three.js是什么

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网页游戏等等。

2.Three.js与WebGL的关系

Three.js是一款webGL框架,Three.js在WebGL的api接口基础上,又进行的一层封装。相当于js和JQuery的关系,众所周知学习webgl需要图形学知识,而webgl需要通过js和glsl两种语言。如果我们不通过threejs使用webgl势必逃不过底层知识:你必须全面了解着色器语法和自己编写顶点着色片元着色;而有了Three.js就可以大大减少了3d开发所需的专业知识储备。

3.Three.js的优缺点

优点

  • Three.js掩盖了3D渲染的细节:Three.js将WebGL原生API的细节抽象化,将3D场景拆解为网格、材质和光源(即它内- 置了图形编程常用的一些对象种类)。
  • 面向对象:开发者可以使用上层的JavaScript对象,而不是仅仅调用JavaScript函数。
  • 功能非常丰富:Three.js除了封装了WebGL原始API之外,Three.js还包含了许多实用的内置对象,并内置了常用着色器。
  • 速度很快:Three.js采用了3D图形最佳实践来保证在不失可用性的前提下,保持极高的性能。
  • 支持交互:WebGL本身并不提供拾取(picking)功能(即是否知道鼠标正处于某个物体上)。而Three.js则固化了拾取支持,这就使得你可以轻松为你的应用添加交互功能。
  • 包含数学库:Three.js拥有一个强大易用的数学库,你可以在其中进行矩阵、投影和矢量运算。
  • 内置文件格式支持:你可以使用流行的3D建模软件导出fbx格式或其他格式的文件,然后使用Three.js加载
  • 支持HTML5 canvas:Three.js不但支持WebGL,而且还支持使用Canvas2D、Css3D和SVG进行渲染。

缺点:

  • 官网文档非常粗糙,对于新手极度不友好。
  • 国内的相关资源匮乏。Three.js资料以英文为主,并且大版本之间代码变更导致很多demo运行不起来。
  • Three.js 对于游戏开发功能需要进行二次开发。
  • 对于商业落地仍成本很大

二、Three.js与Babylon.js对比

Three.js与Babylon.js为目前国内webgl3d开发易用的两大主流开源框架,此处不对于非开源框架对比(个人学习成本有点高,开源我都学不完,T T)

  1. Three.js是纯渲染引擎,容易作为学习WebGL、3D图形、3D数学应用的平台,也可以做中小型的重表现的Web项目而Babylon.js专注于游戏方面,在更大的项目中会需要联网通信功能的封装、声音普通控制甚至高级频谱控制、输入设备信息的处理等诸多渲染以外的功能。这时候,就比较适合使用Babylon.js或者国内的一些针对游戏和多媒体应用开发的引擎或者说框架,例如LayaAir以及Egret3D等
  2. Babylon.js提供了对碰撞检测、场景重力、面向游戏的照相机,Three.js本身不自带,需要依靠引入插件实现。
  3. 对于WebGL的封装,双方做的各有千秋,Three.js浅一些,好处是易于扩展,易于向更底层学习;Babylon.js深一些,好处是易用扩展难度大一些。

三、我通过Three实现的功能\效果

基于一些智慧城市,智慧楼宇,智慧园区等项目或demo,逐步的实现了一些功能和效果。有的是借鉴的,有的是仿写抄的。反正我吸收了就是我自己的了(狗头保命,后续会注明出处)
1.360度Vr全景视频
在这里插入图片描述
2.Ar看房

在这里插入图片描述
3.楼层分层展示特效
在这里插入图片描述
4.线框模型(模型线框包边,单独线框模型,三角面线框模型等等)在这里插入图片描述
5.场景特效(烟雾场景、雪花场景、雷电场景、下雨场景、乌云场景、动态星空等等等等)
在这里插入图片描述

四、源码目录分析

首先看源码目录,了解以下的概念和知识
在这里插入图片描述
1.场景(Scene):是物体、光源等元素的容器。
2.相机(Camera):场景中的相机,代替人眼去观察,场景中只能添加一个,一般常用的是透视相机(PerspectiveCamera)
3.物体对象(Mesh):包括二维物体(点、线、面)、三维物体,模型等等
4.光源(Light):场景中的光照,如果不添加光照场景将会是一片漆黑,包括全局光、平行光、点光源等
5.渲染器(Renderer):场景的渲染方式,如webGL\canvas2D\Css3D。
6.控制器(Control): 可通过键盘、鼠标控制相机的移动
7.纹理属性(Texture):可以理解物体表面的贴图
8.材质(Materials):材质则决定了物体的性质,如反射度,光滑度,金属感,塑料感或者玻璃的模仿。
9.几何体(Geometry):创建形状,如立方体,平面,球体,正面体等等。
10.模型加载(loaders):引入外部模型,如fbx模型,.obj模型+mtl贴图,json模型等
11.动画(animation)
12.音频(audio)
13.核心模块(core)
14.数学方法(math)包含了一些常用的数学方法.

五、实战坑点讲解

1.3d模型导入问题

1.模型格式不支持的问题

模型格式在页面不支持,大多都是环境没有设置MIME,包括一些OBJ和MTL引用的TIFF文件作为贴图。

文件扩展名:.fbx
MIME类型:application/octet-stream

文件扩展名:.obj 
MIME类型:application/octet-stream

文件扩展名:.mtl 
MIME类型:application/octet-stream

文件扩展名:.dds 
MIME类型:image/vnd.ms-dds

文件扩展名:.json 
MIME类型:application/json

文件扩展名:.tiff
MIME类型:image/tiff

2.模型找不到,模型翻转。

  • 1.模型导入屏幕一片漆黑,百分之80的概率是由于没有设置光源
  • 2.设置光源,找不到模型。loader引入路径要为绝对路径
  • 3.12步骤都没问题,打印模型位置,是否在摄像机镜头外
  • 4.123步骤都没问题,模型缩放比例是否合适
  • 5 如果调整环境光后还是黑色或其他的纯色,那么将模型的材质里的emssive设置为material.color,如果材质里有纹理,再把emissiveMap设置为material.map。
  • 6.找到了模型,模型是翻转的,这是由于three使用的右手坐标系,模型导出时调整坐标系指向。

3.模型过大,首屏加载慢

  • 1.导出外部模型的格式与实现的目的相关,如果带有骨骼动画,可选择让建模师导出fbx模型,如果是静态需要细节的,可导出.obj模型+mtl贴图,如果要求不高,可转换成json格式或glTF格式大大减少模型大小
  • 2.不要让建模师带渲染,输出白模即可。如果需要科技风,可转换成线框模型,进一步减少体积。
  • 3.减少模型三角面,对动画模型的帧数、面、顶点进行删减。

4.模型动画播放问题。

  • 1.导出模型时选择好动画的帧数,如果没选择,导出的json文件会有空帧。并且文件也会相对增大
  • 2 模型导入后动画不会自动播放,需要打印模型帧,调用play方法,再加入render中定时器循环播放

2.深度冲突(Z-Fighting)

深度冲突(Z-Fighting)现象:在转动模型时,模型的重叠部位不停的闪烁。
原因:场景中的两个模型在同一个像素生成的渲染结果对应到一个相同的深度值时,渲染器就不知道该使用哪个模型的渲染结果
方法:

  • 1.logarithmicDepthBuffer 对数深度缓冲区let renderer = new THREE.WebGLRenderer({ logarithmicDepthBuffer: true });
    4、设置摄像机的合理near和far值
  • 2.给模型网格等加到场景的东西加上renderOrderthis.mesh.renderOrder = this.addOrder() || 0;

this.renderOrder = 100;
addOrder() {
this.renderOrder += 10;
return this.renderOrder;
}

  • 3 设置多边形偏移polygonOffsetFactor=0, polygonOffsetUnits=1.0
  • 4.设置摄像机的合理near和far值

3.在页面中选中模型,操作模型

具体可参考vue-3d-model的pick方法,以及examples的实例。

总结

后续会逐渐讲解具体实现的过程,同时感谢csdn博主暮志未晚Webgl、
hpugisers等,给我当时的学习带来了鼓励和帮助。正是由于博主们开源精神以及无私奉献,才让整个环境越来越好!!!

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐