注:文章译自http://wgld.org/,原作者杉本雅広(doxas),文章中如果有我的额外说明,我会加上[lufy:],另外,鄙人webgl研究还不够深入,一些专业词语,如果翻译有误,欢迎大家指正。
是用来在OpenGL中着色编程的语言,GLSL使用C语言为基础,并且有自己独立的语法。WebGL的难点之一,就是这个GLSL,不理解GLSL的话,就无法进行渲染。所以,学习WebGL不但要学习WebGL的基本知识,还需要了解GLSL,有点抓狂了吧。
但是,如果只做一些基本的东西的话,也不太难。等习惯了之后,能够自己编写着色器的话会有很大的好处。这一点要慢慢来,不能太着急。
GLSL的知识不用从零开始彻底理解,只需要先了解一下最基本的东西就行。细节部分,留到后面再讲,先把基本的部分彻底理解。
*下面开始,我用最容易理解的方式来介绍,所以会简化很多东西。
首先,WebGL里有顶点着色器和片段着色器两种着色器。无论哪一种都可以使用GLSL来编写。顶点着色器和片段着色器是相互依赖的,缺一不可,并且首先被调用的是顶点着色器。
可以把顶点相关的所有情报都传给顶点着色器。比如,顶点的位置,顶点法线,纹理坐标,顶点颜色等等,跟顶点相关的所有情报都可以传给顶点着色器。在这里,你可以自由决定传入着色器的内容,这种灵活性就是可编辑渲染管线的好处。但是,虽然说传入着色器的内容是自由决定的,但是顶点的位置情报是必须的,因为如果不知道顶点的位置的话,是没有办法绘制模型的。
顶点着色器就跟它的字面上的意思一样,接受顶点相关的情报,最后决定如何处理这些顶点。而片段着色器则决定了画面上用什么颜色来输出。片段着色器的英文是fragment,其实就是断片,碎片的意思。而画面上的像素则是画面上的最小的断片,所以片段着色器操作的是颜色。
再简单一点说明的话,顶点着色器就是处理顶点相关的信息,片段着色器就是处理画面上的颜色信息。
好了,已经理解了着色器是干什么的了吧,下面接着来看一下GLSL的编写方法。
首先,不管是顶点着色器还是片段着色器,都必须定义一个main函数,函数里记录你要做的处理。而且,顶点着色器的话,必须要把顶点信息传给一个叫做gl_Position的变量。比如下面是一个非常简单的顶点着色器的例子。
attribute vec3 position; void main(void) { gl_Position = position; }这里出现了一个奇怪的单词吧,最上面一行里的attribute是个什么东东呢?
再稍微说明一下,attribute修饰符是用来接收不同顶点传来的不同信息。如果存在很多个顶点的话,这些顶点的位置是不同的吧。用来接收这些不同顶点的不同信息的机制,用attribute修饰符来定义变量。
刚才说了,顶点着色器是处理顶点相关的信息,但是不要忘了,顶点相关的处理就是坐标变换。模型变幻,视图变换,投影变换这三个变换也是顶点着色器的工作之一。
基本上,用顶点着色器来做什么是比较自由的,但是在WebGL程序中,首先生成模型,视图,投影的各个矩阵,然后进行合并,最后将得到的坐标变换的矩阵传给顶点着色器,这是一般的做法。
那么,考虑一下,这个坐标变换的矩阵怎么样传给顶点着色器比较好呢?
使用之前的attribute吗,但是attribute是传递不同顶点的不同情报的。而坐标变换矩阵对于所有顶点来说都是相同的,使用attribute修饰符就有点奇怪了。
这个时候使用的修饰符是uniform。使用uniform修饰符的话,可以传递对于所有顶点一致的处理的情报。基于这一点,来修改一下刚才的代码吧。*只是一个示例。
attribute vec3 position; uniform mat4 mvpMatrix; void main(void) { gl_Position = mvpMatrix * position; }这里出现的mvpMatrix,是模型,视图,投影的各个变换矩阵结合后的矩阵。从WebGL一侧将这个坐标变换矩阵传给通过用uniform修饰符定义的变量。
刚才给出的代码例子中,修饰符后面还跟着vec3和mat4等,这是变量的类型。这里只是代表一下,简单接触一下。
vec*表示的是向量,*的部分是一个2~4的数字,vec2就代表一个2维的响亮。
mat*表示的是方阵,和向量一样,可以指定的范围也是2~4,如果是mat3的话,就表示一个3x3的方阵。
另外,int是整型,float是浮点型,bool是布尔型,这些都跟C语言中是一个意思。vec*和mat*中的元素,都是浮点型。
虽然写的有点长了,但是再稍微加点东西。attribute和uniform这两个修饰符已经理解了吧。
GLSL里面还有一个特别重要的修饰符,就是varying修饰符。这个varying修饰符,是顶点着色器和片段着色器之间的桥梁。
举个例子,要把绘制的模型变成半透明,要怎么做呢?
方法虽然有很多,但是一般的做法是,向顶点里添加颜色的情报信息,然后通过操作颜色的透明度的变化来使模型半透明或者完全透明。这时候,如果想操作顶点里的颜色信息和画面上的颜色信息的话,就需要向片段着色器里传入一些必要的信息。
可是要怎么传递这些信息呢?这时候就用到varying了。根据前面给的代码例子,再稍微修改一下,这一次不光有顶点着色器,片段着色器也一起写进去。
首先,顶点着色器部分。
attribute vec4 position; attribute vec4 color; uniform mat4 mvpMatrix; varying vec4 vColor void main(void) { vColor = color; gl_Position = mvpMatrix * position; }接着,片段着色器接收通过varying修饰符所定义的变量vColor。
varying vec4 vColor; void main(void) { gl_FragColor = vColor; }就是这样,要从顶点着色器将数据传到片段着色器,需要使用varying修饰符所定义的变量。另外,和顶点着色器中必需要把数据传给gl_Position类似,片段着色器要把数据传给gl_FragColor。
与顶点着色器不同的是,片段着色器的gl_FragColor不是必须要赋值的。但是一般都会输出一种什么颜色,所以gl_FragColor就变成必要的了。
简单的把这次的内容总结一下。
顶点着色器和片段着色器,都可以通过GLSL来书写,基本上它们算是一个组合。着色器的内部,必须要定义一个main函数,在这个函数里面添加自己的处理。而且,要从WebGL一侧向着色器传递数据的时候,需要用到一些特殊的修饰符所定义的变量。
要向着色器传递各个顶点的不同的信息的时候,使用attribute修饰符声明变量,要向着色器传递对所有顶点来说都一样的信息的时候,使用uniform修饰符声明变量。
另外,从顶点着色器向片段着色器传递数据的时候,使用varying修饰符声明变量。
顶点着色器中内置的变量gl_Position必须赋值,而片段着色器的内置变量gl_FragColor虽然不是必须赋值的,但是一般情况下都会赋值。
关于GLSL,正式的内容的话是很深的,这次的内容是算是介绍了一些表层的最基本的部分。和这些相关的内容,以后会逐渐接触到,到时候再慢慢的说明。首先,把这次的内容彻底理解一下吧。
下次,介绍顶点缓存相关的内容。
转载请注明:转自lufy_legend的博客http://blog.csdn.net/lufy_legend
[WebGL入门]八,着色器的说明和基础,布布扣,bubuko.com
原文:http://blog.csdn.net/lufy_legend/article/details/38342919