上次我们介绍了如何在<canvas>中使用WebGL,以及几个基础的WebGL函数;实现了背景色的重置;为了扩展方便,我们把上次的代码做了些改动,将绘制图形的js独立成文件,这样我们只关注与这个js文件的编写;以后除非HTML文件发生变化,我们就跳过它,直接讨论JavaScript代码。
1 <!doctype html>
2 <html>
3 <head>
4 <meta charset="UTF-8">
5 <meta name="Generator" content="EditPlus®">
6 <meta name="Author" content="Mirror">
7 <meta name="Keywords" content="">
8 <meta name="Description" content="">
9 <title>Hello Point</title>
10 <!--《WebGL编程指南》的作者为读者编写的WebGL辅助函数-->
11 <script src="lib/webgl-utils.js"></script>
12 <script src="lib/webgl-debug.js"></script>
13 <script src="lib/cuon-utils.js"></script>
14 <!--JavaScript文件,在<canvas>中绘制图形-->
15 <script src="lib/hello-point.js"></script>
16 </head>
17 <body onload="main()">
18 <!--定义<canvas>标签,通过width属性和height属性规定它是一片400×400的绘制区域-->
19 <canvas id="myCanvas" width="400" height="400">
20 <!--当浏览器不支持时,会直接忽略<canvas>标签,而直接显示下面这一行提示-->
21 Please use the browser supporting "canvas".
22 </canvas>
23 </body>
24 </html>
接下来,我们在此基础上,绘制一个位于原点(0.0,0.0,0.0)处的10个像素大的红色的点。因为使用的是三维图形上下文,所以指定这个点时需要使用三维坐标。坐标系统后面介绍,这里只需要理解为原点位于<canvas>中心位置。效果如如下:
实际上,我们使用矩形而不是圆来绘制一个点,因为绘制矩形比绘制圆更快;就像在前一次中我们以RGBA的形式指定了背景色一样,这里也需要同样的处理;在前面,我们使用2d上下文来绘制了一个矩形;先指定了绘图颜色,然后进行绘制。你可能认为WebGL也差不多,不幸的是,没那么简单。WebGL依赖于一种新的称为着色器的绘图机制。着色器提供了灵活且强大的绘制二维或三维图形的方法,所有WebGL必须使用它。正因为强大,所以更复杂。
要使用WebGL绘图,必须使用着色器,哪怕是一个点(矩形);着色器程序是以字符串的形式“嵌入”在JavaScript文件中,并且在程序开始运行前就已经设置好了。WebGL需要使用两种着色器:顶点着色器、片源着色器;下面分别介绍:
顶点着色器:顶点着色器是用来描述顶点特性(如位置、颜色等)的程序。顶点是指二维或三维空间中的一个点,比如二维或三维图形的端点或交点。
片元着色器:进行逐片元处理过程(如光源)的程序。片元是一个WebGL术语,你可以将其理解为像素(图像的单元)。
在后续,我们会详细的学习着色器。简单的说,在三维场景中,仅仅用线条和颜色把图形画出来是远远不够的。你必须考虑如光线照上去后,或者观察者的视角发生变化时,对场景会有什么影响。着色器可以高度灵活的完成这些工作;提供各种渲染效果。这也就是现在制作的三维场景如此逼真的原因。
上图显示了WebGL系统的执行流程;左侧为浏览器,首先执行JavaScript程序,调用了WebGL的相关方法,然后顶点着色器和片元着色器就会执行,顶点着色器指定绘制图形的位置和尺寸;片元着色器则指定绘制图形的颜色;然后在颜色缓冲区内进行绘制,这时就清空了绘图区,最后,颜色缓冲区中的内容就自动在浏览器的<canvas>标签上显示出来。
回到我们今天的目标来,下面显示了hello-point.js的代码。
1 //顶点着色器程序 2 var VSHADER_SOURCE = 3 "void main() { \n" + 4 //设置坐标 5 "gl_Position = vec4(0.0, 0.0, 0.0, 1.0); \n" + 6 //设置尺寸 7 "gl_PointSize = 10.0; \n" + 8 "} \n"; 9 10 //片元着色器 11 var FSHADER_SOURCE = 12 "void main() {\n" + 13 //设置颜色 14 "gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" + 15 "}\n"; 16 17 function main() { 18 //获取<canvas>标签。 19 var canvas = document.getElementById("myCanvas"); 20 //获取WebGL绘图上下文。 21 var gl = getWebGLContext(canvas); 22 //如果浏览器不支持WebGL则提示错误。 23 if (!gl) { 24 console.log("Failed to get the rendering context for WebGL."); 25 return; 26 } 27 28 //初始化着色器 29 if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) { 30 console.log("Faile to initialize shaders."); 31 return; 32 } 33 34 //设置<canvas>的背景色 35 gl.clearColor(0.0, 0.0, 0.0, 1.0); 36 37 //清空<canvas> 38 gl.clear(gl.COLOR_BUFFER_BIT); 39 40 //绘制一个点 41 gl.drawArrays(gl.POINTS, 0, 1); 42 43 }