前言
WebGL被设计出来的目的,就是在网页上创建三维的应用和用户体验,它是内嵌在浏览器中的,你不必安装插件和库就可以直接使用它。它允许Javascript在网页上显示和操作三维图形。WebGL程序由HTMLT和JavaScript文件组成。WebGL页面包含三种语言:HTML5,JavaScript,和GLSL ES,而通常GLSLES是以字符创的形式写在JavaScript中的,所以实际上WebGL只需要用到HTML文件和JavaScript文件,其文件结构和传统网页一样;
WebGL程序实际上是网页的一部分,你可以充分利用浏览器的功能,比如放置按钮,弹出对话框,绘制文本,播放声音和视频,与服务器通信等等。WebGL程序允许你自由的使用这些功能。
WebGL技术规范继承自OpenGL标准,WebGL是从OpenGL ES 2.0派生出来的,采用OpenGL ES的电子设备包括智能手机(安卓和iPhone),平板电脑,游戏机等。
WebGL程序的结构
WebGL页面包含三种语言:HTML5,JavaScript,GLSL ES
然而,通常GLSL ES是以字符串的形式在JavaScript中编写的,实际上WebGL程序只需要用的HTML和JavaScript文件,所以WebGL仍然保持与传统网页相同的结构:只用到html和js文件;
WebGL采用HTML5引入的canvas标签,它定义了页面上的绘图区域。如果没有WebGL,Js只能在canvas上绘制二维图形,有了WebGL,就可以在上边绘制三维图形了
Canvas
在HTML5出现之前,如果想在网页上显示图形只能使用img标签,但img只能显示静态的图片,不能实时绘制和渲染。canvas的出现,允许Js动态的绘制图形。canvas提供一些简单的绘制函数,用来绘制点,线,矩形,圆等。
WebGL基本概念
- 着色器:WebGL 依赖于一种称为着色器的绘制机制,要使用WebGL进行绘图就必须使用着色器。着色器提供灵活且强大的绘制二维或三维图形的方法,在代码中,着色器代码(GLSL ES语言)以字符串的形式嵌入到Javascript文件中,在程序真正开始运行前他就已经设置好了。
WebGL需要两种着色器:- 顶点着色器(Vertex shader):用来描述顶点特征的程序,控制点的位置和大小。顶点是指二维或三维空间中的一个点,如二维或三维图形的端点或焦点。顶点着色器程序(字符串代码)必须包含一个main()函数,main()前面的关键字void表示这个函数不会有返回值。另外,不可以为main()指定参数。
- 片元着色器(Fragment shader):进行逐片元处理过程如光照的程序,控制点的颜色。处理片元,使其显示在屏幕上。片元是WebGL中的术语,你可以理解为像素(图像的单元);
顶点着色器的内置变量 类型和变量名 | 描述 |
---|---|
vec4 gl_Position | 表示顶点位置 |
float gl_PointSize | 表示点的尺寸(像素数) |
注意:gl_Position变量必须被赋值,否则着色器就无法正常工作,gl_PointSize不是必须的,如果不赋值,着色器会为其取默认值1.0
片元着色器的内置变量 类型和变量名 | 描述 |
---|---|
vec4 gl_FragColor | 指定片元的颜色(RGBA格式) |
gl_FragColor是片元着色器唯一的内置变量,它控制像素在屏幕上最终的颜色
GLSL ES是强类型编程语言,通过为变量指定类型,系统可以轻易理解变量中存储 的是何种数据,进而优化处理这些数据:
- GLSL ES中的变量类型
- float 浮点数类型
- vec4(v0,v1,v2,v3) 由四个浮点数组成的矢量
- 齐次坐标
由四个分量组成的矢量被称为齐次坐标,齐次坐标使用如下符号描述:(x,y,z,w),其次坐标(x,y,z,w)等价于三维坐标(x/w,y/w,z/w),所以如果齐次坐标的第4个分量是1,你就可以把它当做三维坐标来使用。w的值必须是大于等于0的,如果w趋近于0,那么它所表示的点将趋近无穷远。因为它能够提高处理三维数据的效率,所以在三维图形系统中被大量使用。齐次坐标的存在,使得用矩阵乘法来描述顶点变换成为可能。三维图形系统在计算过程中,通常使用齐次坐标来表示顶点的三维坐标
WebGL基本方法:
- initShaders(gl,vshader,fshader) 在WebGL系统内部建立和初始化着色器;
参数:
gl 渲染上下文;
vshader 顶点着色器的程序代码(字符串);
fshader 片元着色器的程序代码(字符串)
返回值:true 初始化着色器成功; false 初始化着色器失败; - getWebGLContext(element,[,debug]) 获取WenGL绘图上下文;
参数:element 指定的canvas元素; debug为可选参数,默认为false,当它为true时开启调试模式。
返回值:non-null WebFL绘制上下文; null WebGL不可用; - gl.clearColor(red,green,blue,alpha);
参数:red,green,blue,颜色三原色,alpha透明度
返回值:无
颜色分量取值范围在0.0-1.0之间,RGB的值越高,颜色就越亮,第4分量alpha的值越高,颜色越不透明。一旦指定背景色之后,背景色就会贮存在WebGL系统中,在下一次调用gl.clearColor()方法前不会改变。 - gl.clear(buffer) 将指定缓冲区设定为预定的值。
参数:buffer:指定待清空的缓冲区,可选值有gl.COLOR_BUFFER_BIT(颜色缓冲),gl.DEPTH_BUFFER_BIT(深度缓冲),gl.STENCIL_BUFFER_BIT(模板缓冲)。也可使用位操作符“|”(OR)指定多个缓冲区。
返回值:无 - gl.drawArrays(mode,firstIndex,count) 可以用来绘制各种图形
参数:
mode 指定绘制的方式,可选值有gl.POINTS
,gl.LINES
gl.LINE_STRIP
,gl.LINE_LOOP
,gl.TRIANGLES
,gl.TRIANGLE_STRIP
,gl.TRIANGLE_FAN
;
firstIndex 指定从哪个顶点开始绘制(整型数,index);
count 指定需要绘制多少个顶点(整型数)
返回值:无
当程序调用gl.drawArrays()时,顶点着色器将被执行count次,每次处理一个顶点
颜色缓冲区的内容会自动显示在浏览器中
最简单的webgl程序
使用webGL在canvas中绘制一个点
- 大部分的WebGL程序都遵循这样的流程:
=> 获取canvas元素
=> 获取WebGL绘图上下文(getWebGLContext)
=> 初始化着色器(.initShaders)
=> 设置canvas背景色(.clearColor)
=> 清除canvas(.clear)
=> 绘图 - 准备
html文件中引入WebGL提供的工具库:webgl-utils.js,webgl-debug.js,cuon-utils.js,cuon-matrix.js
html:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<canvas id='webgl' width='400' height='400'></canvas>
<p id='nearFar'></p>
<!-- 有用的类库 -->
<script src='../libs/webgl-utils.js'></script>
<script src='../libs/webgl-debug.js'></script>
<script src='../libs/cuon-utils.js'></script>
<script src='../libs/cuon-matrix.js'></script>
<!-- 示例代码 -->
<script src='./js/HelloCanvas.js'></script>
</body>
</html>
HelloCanvas.js:
window.onload = function () {
// 在canvas中绘制一个点
// 顶点着色器程序 (GLSL ES语言)
var VSHADER_SOURCE = `void main() {\n
gl_Position = vec4(0,0,0,1);\n
gl_PointSize = 10.0;\n
}
`
// 片元着色器程序(GLSL ES语言)
var FSHADER_SOURCE = `void main() {\n
gl_FragColor = vec4(1,0,0,1);\n
}\n`
// 以上是以Js字符串形式编写的着色器语言程序,主程序(Js语言编写)可以将他们传给WebGL系统
var canvas = document.getElementById('webgl');// 获取canvas标签
var gl = getWebGLContext(canvas);//获取WebGL上下文 cuon-utils.js中提供的辅助函数,屏蔽获取WebGL上下文时不同浏览器的差异
// 初始化着色器
if (!gl || !initShaders(gl,VSHADER_SOURCE,FSHADER_SOURCE) {
return;
}
gl.clearColor(0,0,1,1);//指定绘图区域(canvas)的背景色,参数值是rgba的值(值范围遵从OpenGL ,为0.0 - 1.0,值越高,颜色越亮,第四分量值越高,越不透明);
gl.clear(gl.COLOR_BUFFER_BIT);//用上一行指定的背景色清空颜色缓冲区(即:用背景色填充,擦除已经绘制的内容)绘图区域
gl.drawArrays(gl.POINTS,0,1); // 绘制点
}
绘制结果
WebGL程序的执行的大致流程:首先运行JavaScript程序,调用WebGL的相关方法,然后顶点着色器和片元着色器就会执行,在颜色缓冲区内进行绘制,这时就清空了绘图区,最后,颜色缓冲区中的内容会自动在浏览器的canvas标签上显示出来
注意:着色器运行在WebGL系统中,而不是JavaScript程序中。WebGL程序包括运行在浏览器中的Js和运行在WebGL系统中的着色器程序这两个部分
WebGL坐标系统
由于WebGL处理的是三维图形,所以它使用三维坐标系统(笛卡尔坐标系),具有x,y,z轴。通常在WebGL中,当你面对计算机屏幕时,X轴是水平的(正方向向右),Y轴是垂直的(正方向向下),Z轴垂直于屏幕(正方向向外)这套坐标系又称为右手坐标系(实际上WebGL本身既不是右手坐标系,又不是左手坐标系,本文以右手坐标系来讲解)
canvas绘制区的坐标系与WebGL坐标系统的原点位置和Y轴正方向不一样,需要将前者映射到后者。
三维场景中,仅仅用线条和颜色把图形画出来是远远不够的,你必须考虑,如光线照上去之后,或观察者的视角发生变化,对场景会有些什么影响。着色器可以高度灵活的完成这些工作,提供各种渲染效果。这也就是当今计算机制作出的三维场景如此逼真和令人震撼的原因