WebGL入门 | 青训营笔记

160 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的的第15天。

今天我们介绍一种3D绘图标准 WebGL

什么是WebGL

WebGL是一种3D绘图标准,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一个JavaScript绑定,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和数据视觉化。显然,WebGL技术标准免去了开发网页专用渲染插件的麻烦,可被用于创建具有复杂3D结构的网站页面,甚至可以用来设计3D网页游戏等等。

WebGL的特性

  1. WebGL是一个开放的标准,任何人都可以使用,不需要支付任何版权费
  2. WebGL利用图形硬件加速图形绘制,这意味着它的速度确实很快(对比使用插件的方式)
  3. WebGL可以在支持它的本地浏览器上运行,不需要任何插件
  4. 由于WebGL是以OpenGL ES 2.0为基础的,因此对于具有OpenGL ES 2.0编程经验的开发人员而言,甚至对于熟悉台式机OpenGL开发的人们而言,它是容易学习的

创建webGL对象

不同浏览器生命WebGL对象方式有所区别,虽然大部分浏览器都支持experimental-webgl,而且以后会变成webgl,所以创建时做一下兼容处理

var canvas = document.getElementById("glcanvas");
gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");

着色器

WebGL依赖一种新的称为着色器(shader)的绘图机制。着色器提供了灵活且强大的绘制二维或三维图形的方法,所有WebGL必须使用它。着色器不仅强大,而且更复杂,仅仅通过一条简单的绘图指令是不能操作它的。

WebGL需要两种着色器

  • 顶点着色器(Vertex shader):顶点着色器是用来描述顶点特性(如位置、颜色等)的程序。顶点(Vertex) 是指二维或三维空间的一个点,比如二维或三维空间线与线之间的交叉点或者端点。
  • 片元着色器(Fragment shader):进行逐片元处理过程(如光照等)的程序。片元(fragment) 是一个WebGL的术语,你可以将其理解成像素。

创建顶点着色器:

var VSHADER_SOURCE =
'void main() {\n' +
' gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n' +
' gl_PointSize = 10.0;\n' +
'}\n';

创建片元着色器:

var FSHADER_SOURCE =
'void main() {\n' +
' gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' +
'}\n';

上述代码部分,VSHADER_SOURCE和FSHADER_SOURCE的一段使用GLSL语言的编码的字符串类型,GLSL是一种C/C++风格的编程语言,执行在GPU上,使其GPU可编程。


attribute vec4 a_Position;
void main() {
    gl_Position = a_Position;
    gl_PointSize = 10.0;
}; 
 
 
void main() {
   //设置填充颜色为不透明的红色
  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
};

基于WebGL封装的框架

  • ThreeJS,目前最流行的开源3D框架,社区活跃,插件丰富
  • ThingJS,  新兴的3D框架,2018年诞生,是针对物联网领域的JavaScript 3D Library
  • Babylon.js, 最专业的的游戏开发框架,提供游戏视角的摄像机和碰撞检测。
  • SceneJS, 是一个开源的JavaScript 3D引擎,适合需要高精度细节的模型需求,比如工程学和医学上常用的高精度模型

实例演示(使用ThreeJS)


// 1. 第一步:获取canvas容器, 并获取宽高
var container = document.getElementById('canvasdiv')
var width = container.clientWidth;
var height = container.clientHeight;
// 2. 第二步:新建一个场景类和摄像机(使用透视投影)
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 90, width/height, 0.1, 1000 );
camera.position.set(0,0,10);
// 3. 第三步: 创建一个渲染器
var renderer = new THREE.WebGLRenderer();
renderer.setSize( width, height );
container.appendChild( renderer.domElement );
// 4. 第四步: 创建一个三维实体--立方体
var geometry = new THREE.BoxGeometry( 2,1,1 );
var material = new THREE.MeshBasicMaterial( { color: 0x645d50 } );
var cube = new THREE.Mesh( geometry, material );
// 5. 第五步: 添加到场景中
scene.add( cube );
renderer.render(scene,camera);

剩下的比如,光照类型、光照的原理(漫反射)、光照的原理(环境反射)、光照效果的对比,以及纹理映射、图片纹理、凹凸纹理、环境贴图等,这里就不再赘述。


如有不对之处,欢迎指出。