如同你看见的,它使用了getShader函数来获取两样东西,一个是“片元着色器”(Fragment Shader),另一个是“顶点着色器”(Vertex Shader),然后把它们俩同时附加到了一个叫做“program”的WebGL对象里。Program是系统中原生于WebGL里的二进制码,你可以把它看作是一种在显卡中运行指定指令的方法。和你想的一样,你可以把若干着色器组合捆绑到一个program中,每个着色器都可以看做一段program中的代码。特别是每个program可以储存一个片元着色器和一个顶点着色器。
100 101 shaderProgram.shaderProgramgl.
函数设置好program并捆绑好着色器之后,就会引用一个“属性”(attribute),也就是program对象的新字段vertexPositionAttribute。在这里我们再一次用到了Javascript的优点,那就是可以给任何对象增加任何字段。默认情况下program对象并没有vertexPositionAttribute这个字段,但是有了它我们就可以方面的把两个值放到一起,所以我们就给他赋予了“属性”这个新字段。
那vertexPositionAttribute又是用来做什么的呢?你也许会记得,我们在drawScene函数中用到过他。如果你回头去看那段从相应数组对象中设置三角形的顶点位置的代码,你会发现我们在处理数组对象的时候用到了这个属性。你一会就会明白它的含义,现在让我们看下gl.enableVertexAttribArray,我们使用它来告诉WebGL我们会用一个数组来为属性赋值。
103 104 105 shaderProgram.shaderProgramshaderProgram.shaderProgram
initShaders最后做的事情是从program中取得另外两个值,也就是两个叫做uniform的变量的地址。一会我们还会用到它们;现在你只需要记住和属性类似,为了方便,这两个值也是储存在program对象中。
现在我们来看看getShader函数:
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 shaderScript shaderScript k kk.str k shaderScript.shader shaderScript.shader gl.gl. gl.gl. return shader; }
这又是一个看起来复杂但实际上非常简单的函数。我们这里所作的一切就是从我们的HTML页面中寻找一个id能够对应传递进去的参数的元素,取出它的内容,建立一个片元着色器或一个顶点着色器(之后的课程中我们会讲到它们俩的区别),然后传递到WebGL端编译成可以在显卡中运行的形式。代码会再来处理发生的错误。就是这样!当然,我们也可以在Javascript中把着色器定义为字符串并且不与从HTML中提取出来的字符串混在一起,但是显然我们代码中的方式更加简单易读,因为他们在网页中被定义为脚本,一如他们本来的身份就是Javascript脚本!
我们看看着色器的代码:
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 script> aVertexPosition; uPMatrix; uPMatrix aVertexPositionscript>
首先你要记住的是,这段代码不是用Javascript写成的!尽管看起来语法很像,但事实上这段代码属于一种特殊的着色器语言——叫做GLSL——很像C的一种语言(当然也就像Javascript了)。首先在第一段代码中,片元着色器实际上没有做任何事情,我们只是按照约定俗成惯的例加上这段代码,告诉显卡我们需要精确到浮点值的数字运算,然后指定绘制物体的时候要用白色(下一课我们还会详细讲述物体的颜色的)。相对来说第二个着色器更有趣一些。这是一个顶点着色器,你也许会记得它的作用是让显卡对顶点做任何想要做的事。与它相关的两个uniform变量,叫做uMVMatrix和uPMatrix。uniform变量非常有用,因为你可以在着色器之外访问它们,甚至在它们的容器program之外!回忆一下,在initShaders函数中我们提取出了它们的地址,在下面的代码里我们把它们赋值给模型视图矩阵和投影矩阵。你或许可以把着色器的program想象成一个对象(面对对象的观念),把uniform变量想象成字段。
由于在把属性和数组对象联系到一起的时候,我们在drawScene函数中使用了vertexPositionAttribute,所以现在可以为每个顶点调用着色器,并且把顶点作为aVertecPosition传递给着色器代码。在着色器的二进制码的主程序中,顶点位置与模型视图矩阵和投影矩阵相乘,然后把最终顶点位置作为结果输出。
总结一下,webGLStart函数调用了initShaders,后者使用了getShader来从网页文件的脚本中载入片元着色器和顶点着色器,所以他们可以被编译并传送给WebGL,然后提供给稍后进行的3D场景渲染时使用。
最后,还剩最后一个没有提到的函数,那就是setMatrixUniforms。如果上面的讲解你都明白了,那你会容易理解它的含义的。
111 112 113 114 gl.pMatrix.gl.mvMatrix.
使用我们在initShaders中得到的储存模型视图矩阵和投影矩阵的uniform变量,我们把变量值从Javascript风格的矩阵推送到WebGL当中去。
好了!第一课到此结束!可真长啊!希望你能理解这些基础知识,为我们以后创作更多更有趣的东西(颜色、移动、三维模型)做好准备!
Posted in WebGL教程, 推荐 and tagged oak3d, webgl, webgl中文教程, webgl教程. Bookmark the permalink.
← MocoSpace旗下HTML5游戏基金增至200万美元
用WebGL进行局部水体环境渲染 →
1 trackback WebGL中文教程翻译工程启动!HiWebGL | HiWebGL 2011 年 8 月 20 日 下午 11:51 37 comments
支持!!!
支持啊,不错
有个地方有问题,是等腰三角形,不是等边三角形~
已经修改了,感谢指正!
想问下用的是什么编辑器呢
你可以使用你喜欢的任意文本编辑器来编辑html文件,我们用的是notepad++
请问下画圆又要怎么画呢?
只能用多边形逼近
很棒啊,你这里翻译的比较通俗简单,把原著进行了整理,也增加上了一些注释。很棒~来支持你一下,微博也关注你了,加油!
作为一个初学者来说还是有难度的。很希望下载下来的源代码也能带上注释。
刚看完lesson0和里面的一些demo很激动马上就看lesson1,的确有点难度啊,楼主辛苦了,支持
支持一下 非常好啊 值得学习
兄弟多谢了