前端 3D 开发

部门内的分享内容;threejs部分在前端组内分享过一次,涉及到一些代码方面的东西,这次分享做了简化;

本篇文章把两次分享的内容整合起来;

一、基本原理

现在大家在网页中看到的3D效果,很多都是用 WebGL 开发的;

1、WebGL概念

一种 JavaScript API(接口/标准/规则/规范),用于在不使用插件(浏览器内置)的情况下在任何兼容的网页浏览器中呈现交互式2D3D图形。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;
如果这篇文章对你有用,可以点击下面的按钮告诉我

0

发表回复