threejs Web端显示引擎介绍

Posted CADGraphics

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了threejs Web端显示引擎介绍相关的知识,希望对你有一定的参考价值。

今天是个沉重的日子,让我们再一次缅怀“杂交水稻之父”袁隆平院士。袁隆平院士毕生追求让所有人远离饥饿,是我国研究与发展杂交水稻的开创者,也是世界上第一个成功利用水稻杂种优势的科学家,致敬袁隆平院士。

今天我们来介绍一下threejs。在讲threejs之前,我们先了解一下WebGL。WebGL是一套轻量级的javascript的API,可以基于浏览器来显示2D和3D图形。WebGL的上下文通过绑定html的Canvas对象来支持3D显示,Canvas的Item可以和其他的Html元素组合使用,再结合前端框架的灵活性,从而可以实现前端酷炫复杂的UI。
使用WebGL可以让用户能够在浏览器端体验3D硬件加速的效果,这让我想到在WebGL还未普及的时候,如果想在浏览器端浏览三维数据,还得通过一些ActiveX插件。WebGL1.0是对OpenGLES2.0的接口封装,WebGL2.0是对OpenGLES3.0的接口封装。目前主流的还是使用WebGL1.0,各大浏览器对WebGL1.0的支持比较好,threejs是可以同时支持WebGL1.0和WebGL2.0。
回到本文的主题,WebGL和threejs的关系是什么呢。和我们之前介绍的hoops或者VTK等三维引擎类似,threejs也是对WebGL的封装。可以让用户不用去理会WebGL的函数,同样threejs也是通过维护一颗场景树来渲染3D场景。

一、threejs的入门Code。

我们看一下threejs的入门code,用threejs绘制一个简单的立方体。
 const canvas = document.querySelector('#c');  const renderer = new THREE.WebGLRenderer({canvas});  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);  const scene = new THREE.Scene();  const geometry = new THREE.BoxGeometry(111);  const material = new THREE.MeshBasicMaterial({color0x44aa88}); const cube = new THREE.Mesh(geometry, material);  scene.add(cube); renderer.render(scene, camera);
  1. canvas:HtmlElement,用于给3D场景提供Context上下文,嵌入到前端的页面中。

  2. camera:相机对象。

  3. scene:场景树,表示整个3D的场景,场景节点由group和mesh组成,group可以理解为一个集合。

  4. geometry:渲染的几何对象,主要是由三角面片组成。

  5. mesh:scene场景树中的节点,mesh由几何和材质组成。

  6. renderer:threejs中的渲染器,执行整个渲染流程。

threejs的API比较简单,很适合初学者去使用,如果对JavaScript不熟悉,还可以使用TypeScript去编写,并且3D部分的代码可以与前端的代码独立分离。我们来看一下threejs显示的一个比较好看的场景。

二、threejs中的材质对象

threejs中有很多材质,每种材质实现不同的显示效果,一种材质对应一种shader的实现。

1. MeshBasicMaterial

Mesh最基本的材质,看Shader实现可以知道,只显示模型颜色,不进行光照计算。

2. MeshLambertMaterial

threejs中材质显示的最终颜色主要由直接光照和间接光照两部分组成。Lambert没有考虑反射部分,主要由间接diffuse和直接diffuse两部分组成。间接diffuse是对环境光的近似,直接diffuse是计算几何法线与光照方向的点集并乘以光照颜色再乘以材质的diffuse。

3. MeshPhongMaterial

threejs中的phong材质是对Blin-Phong的实现,直接diffuse的计算是取几何法线和光照的中间向量与光照方向的点集并乘以光照颜色和材质的diffuse。同时Phong中也考虑了反射部分,比Lambert更加真实。具体的计算可以参考threejs中的每个材质shader。
4. MeshStandardMaterial
StandardMaterial是threejs对PBR材质的实现,PBR材质是基于真实物理的实现,PBR材质采用很少的参数,通过设置材质的金属度,粗糙度等参数并基于微平面理论来模拟真实的光照计算结果,目前是主流的着色模型。后续我们可以单独讲一次PBR的实现。
5. MeshDepthMaterial

该材质是对当前模型中的深度进行显示,在做图形后处理时,如果想查看当前场景中的深度渲染是否正确,可以采用该材质来对深度进行可视化。

6. ShaderMaterial

该材质是自定义shader的实现,如果需要实现一个自定义的shader效果,可以通过继存该材质并写自己编写shader的code来实现。

三、threejs渲染引擎流程

       threejs虽然是用JavaScript来实现的,但是很适合初学者去学习。如果想要了解一个图形渲染引擎的实现,建议大家去读一下它的源码。我们接下来看看它渲染的一帧到底做了那些工作。threejs的WebGLRenderer对象的render()函数是对场景的一帧渲染。我挑选一些其关键的Code如下:

if ( scene.autoUpdate === true ) scene.updateMatrixWorld();if ( camera.parent === null ) camera.updateMatrixWorld();_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );_frustum.setFromProjectionMatrix( _projScreenMatrix );currentRenderList.init();projectObject( scene, camera, 0, _this.sortObjects );if ( _this.sortObjects === true ) currentRenderList.sort( _opaqueSort, _transparentSort );currentRenderState.setupLights();background.render( currentRenderList, scene );if ( opaqueObjects.length > 0 ) renderObjects( opaqueObjects, scene, camera );if ( transparentObjects.length > 0 ) renderObjects( transparentObjects, scene, camera );

简单分析下:

Line1:更新场景中的节点的世界坐标系的矩阵。

Line2:更新相机的矩阵。

Line3:相机投影矩阵的更新。

Line4:视锥体的构建用于后续的视锥裁剪。

Line5:RenderList对象初始化,把threejs的树状场景结构转换成平铺的List的结构。

Line6:projectObject会构建最终RenderList对象的渲染集合。

Line7:透明和非透明对象分类并排序。

Line8:灯光的初始化。

Line9:背景的渲染,比如天空盒CubeMap的绘制。

Line10:渲染不透明对象。

Line11:渲染半透明及透明对象。

对于每个对象的渲染实现是在RenderObjects的函数中,根据Object的材质类型来采用不同的shader生成shader program来进行渲染。threejs会对program进行缓存,根据object的各种属性构建唯一的key,来匹配最合适的shader program,从而保证使用尽量少的program来提升性能。

四、threejs的后处理

        上面我们介绍的是一帧的渲染,图形的后处理是指的场景并不是通过一帧就渲染结束,而是通过渲染多帧形成多个帧缓存(FrameBuffer),并组合FrameBuffer来形成最终的场景。比如我们常见的SSAO的实现,SSAO是计算当前像素是否被周围的像素的遮挡程度,从而形成明暗的效果,增加场景的真实性。SSAO的计算则是通过多帧组合形成的,渲染第一帧拿到当前场景深度的FrameBuffer,第二帧拿第一帧的深度信息,结合法线等信息进行SSAO遮蔽因子的计算。

        threejs其实并没有提供一个后处理的框架,不过在其example中可以找到EffectComposer对象,该对象可以增加多个Pass,每个Pass可以关联Shader材质,每个Pass可以理解为一帧,下一个Pass可以使用上一个Pass的结果。后处理其实是非常有意思的,逼真的3D场景基本上都是通过后处理形成的,我们看看SSAO的效果吧。

五、总结

threejs是目前github上比较活跃的一款web端显示引擎,如果企业想快速集成前端的3D业务,threejs倒是一个不错的选择。但是对于大场景的显示,threejs还有很多的优化空间。跟threejs类似的还有一款前端3D引擎,Babylon.js,后续我们再介绍一下。 五月太忙了,一直没时间更新,今天抽空发出来,各位的关注是我一直更新下去的动力。再次谢谢大家的关注,如果有不对的地方还希望大家给公众号留言指正,直接给公众号发消息。

   


    

以上是关于threejs Web端显示引擎介绍的主要内容,如果未能解决你的问题,请参考以下文章

ThreeJs/仿vue框架

从ThreeJS史上最简单的Demo说起

vue中使用threejs仿iView官网大波浪特效

如何3d模型在web网页显示展示?用啥技术

threejs加载3d模型踩坑之路--入坑篇

在web端,three.js如何操作3d模型obj对象的子构件