部门内的分享内容;threejs部分在前端组内分享过一次,涉及到一些代码方面的东西,这次分享做了简化;
本篇文章把两次分享的内容整合起来;
一、基本原理
现在大家在网页中看到的3D效果,很多都是用 WebGL 开发的;
1、WebGL概念
一种 JavaScript API(接口/标准/规则/规范),用于在不使用插件(浏览器内置)的情况下在任何兼容的网页浏览器中呈现交互式2D和3D图形。WebGL绘制的内容,最终在html的canvas标签中呈现出来的;
任何兼容:WebGL标准出来后,各浏览器厂商是否按该标准实现了功能;老版浏览器肯定是没有实现,新版浏览器可能实现了一部分功能,这样就出现了兼容问题;
- WebGL 基于 OpenGL ES,可以理解为 Opengl ES 的 Web(浏览器)实现,功能有所删减;
- OpenGL ES:OpenGL 针对手机、pad等便携设备的嵌入式实现;
- OpenGL:用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程接口;
- OpenGL SC:其设计为面向航空电子、工业、军事、医疗以及车载应用等安全关键市场;
OpenGL、OpenGL ES、WebGL的关系如下:
开发人员写程序实现3D效果的过程中,涉及下面3方面的概念:
- 标准:OPENGL, Khronos Group维护,官方组织;
- 具体实现:显卡驱动,硬件厂商开发,实现具体的 OpenGL API功能;GLSL支持,语言独立;
- 语言绑定:java和C绑定底层驱动,iOS提供C绑定,Android提供Java和C绑定;
2、WebGL组成
- 标准:WebGL,OPENgl ES的子集;
- 具体实现:绑定是在浏览器端,最终调用的是显卡驱动中的openGL(ES) ,PC上调用OpenGL,移动端调用OpenGL ES;
- 语言绑定:javascript绑定(绑定GLSL),浏览器处理;
浏览器端组成:JavaScript代码和GLSL代码;
- JavaScript代码是运行在浏览器中的代码;
- GLSL代码是运行在GPU中的代码,浏览器解析不了,只能当做字符串传给GPU;
JavaScript代码和GLSL代码关系示例
- GLSL代码:有一个颜色,根据颜色绘制一个像素点;
- JavaScript代码:设置GLSL代码中的颜色为红色;
3、硬件加速
定义:通过把计算量非常大的工作分配给专门的硬件来处理以减轻CPU工作量的技术;
3D硬件加速:显卡渲染,借助OpenGL,减轻CPU工作量;
处理图形时,GPU为什么比CPU快:
CPU:对计算机的所有硬件资源(如存储器、输入输出单元) 进行控制调配、执行通用运算的核心硬件单元(处理指令、执行操作、控制时间、处理数据);
GPU:简单命令和简单运算;是基于大吞吐量设计:Cache比较小、控制单元简单,但GPU的核数很多,适合于并行高吞吐量运算;
CPU是特级厨师,会做各种类型的菜;GPU是学徒,只会拌个凉菜、炒个西红柿鸡蛋、土豆丝啥的;特级厨师炒菜的质量和效率要比学徒高;一个大型餐馆里有2个特级厨师,20个学徒;绘制图形的时候,相当于一下来了很多桌客人,都只点了土豆丝、拌凉菜这种简单的菜,这时候学徒的优势就体现出来了;
二、Threejs
封装了GLSL代码,开发时只需要操作JS代码;
1、基本概念
场景(Scene): Threejs创建的空间,用来放置物体、灯光、摄像机,可以类比现实中的三维空间;
相机(Camera): Threejs中创建的场景,通过相机才能看到;透过相机,可以看到场景的一部分,相机可以类比现实中的摄像机镜头;
渲染器(Renderer):通过相机看到的一部分场景,需要经过渲染器的渲染,才能展示出来;渲染器可以类比现实中摄像机的图像处理器;
画布(Canvas):渲染器处理完成后,需要有一个容器用来展示图像,这个容器就是画布;可以类比现实中摄像机显示图像的的屏幕;
2、场景中物体
网格、点、线、面、骨架、骨骼等;以网格为例,简单介绍一些相关的概念;
2.1、网格/几何物体(Mesh)
基于以三角形为多边形网格的物体,构建时需要指定物体的几何形状和材质;
2.2、几何形状(Geometry)
Threejs中内置了很多几何体,立方体、圆形体、圆锥体等;
2.3、材质(Material)
材质描述了对象的外观,Threejs内置了很多材质;
2.4、纹理 ( Texture )
纹理可以简单理解为物体上的花纹,但是它没法直接应用到物体上;使用时,必须先应用在材质上,通过材质设置到物体上;图片也可以作为纹理使用;
3、场景中的光(Light)
照亮物体以及产生阴影的光源,WebGL中并没有光源相关的专门接口/类,需要手动计算,Threejs对常用的几种光源做了封装;
Threejs内置了几种光源,比如:
- 环境光:均匀照亮场景中的所有物体,不能用来投射阴影,因为它没有方向;
- 平行光:沿着特定方向发射的光,用来模拟地球上的太阳光,可以投射阴影;
- 点光源:从一个点向各个方向发射的光源,可以用来模拟灯泡发出的光,可以投射阴影;
- 聚光灯:从一个方向上的一个点发出,沿着一个圆锥体,它离光越远,它的尺寸就越大,可以投射阴影;举例:带灯罩的台灯;
4、3D模型
Threejs中定义了很多的3D资源加载器,支持格式非常多,有GLTF、3MF、AMF、obj、mtl、stl、mmd、PMD、PMX、VMD、VPD、BVH、DDS等等
官方推荐的是glTF格式;
glTF,图形语言交换格式,它是一种3D内容的格式标准,由Khronos Group管理;glTF的目标是3D领域的JPEG、MP3;
载入3D模型可参考这里
加载器文档在”示例”-“加载器”中,文档里也不全,全部的可以在examples中找到,基本涵盖了所有3D资源格式;
5、示例 examples 中的一些操作方法/组件
Threejs 的文档中,并不是所有的内容都列在了”手册”和”参考”中,还有一些是在”示例”中体现的;
github源码中的examples 要比 在线examples 中的例子多一些,可以下载源码本地跑一下,查看全部的实例;
控制器 Controls
一些封装好的摄像机控件,使用这些控件,可以根据需求控制场景中的摄像机;比如:
- FirstPersonControls:第一视角控制器,类似第一视角射击游戏中的摄像机;
- FlyControls:飞行控制器,飞行模拟控制器;
- OrbitControls:轨道控制器,可以使得相机围绕目标进行轨道运动;
这些控制器,在文档中,只有OrbitControls,其他的可以在examples中找到;
6、Threejs 的应用
- 全景图;
- 3D模型展示:展示细节、换肤;
- 前端效果:比较炫酷的动画;
- 数据可视化:数据展示,更形象,但不如用其他专门的可视化库,d3之类的;
- 游戏:不多,Unity3D;