webGL 学习手记 | webGL 教程 (二)
上一篇的文章 《webGL 学习手记 | webGL 教程 (一)》 说到如何获取webGL的上下文 , 这是webGL的第一步,就好比上画家拿到了绘画的纸。接下来,在拿到webGL的上下文之后,我们就可以愉快的和webGL玩耍了。
- DEMO预览
- http://zmofei.github.io/yes-webgl/demo/drawpoint.html
- DEMO源码
- https://github.com/zmofei/yes-webgl/blob/master/demo/drawpoint.html
渲染流程
图片说明,本来自己画了一张漂漂亮亮的图,结果改版的时候貌似弄丢了,翻遍了全网都没有找到,那些偷文章的也不好好偷,图片都没有帮我缓存,只能网上找一张了,虽然心中一万头羊驼奔过,但是还是感谢图片的作者。
简单描述一下,绘制webGL你需要Program,Shader两样东西。
1. 通过 createProgram() 创建了 program 对象
2. 通过 createShader() 创建 sharder 对象,
并通过 shaderSource() 绑定原始的 sharder 程序,这个后续有介绍,
绑定完成之后执行 complieShader() 完成 sharder 对象的创建
3. 通过 attachShader 将 shader 绑定到 project 上
4. 链接、使用、绘制
着色器(shader)
代码中我们看到了如下两段着色器
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'void main() {\n' +
' gl_Position = a_Position;\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';
webGL,主要通过 vertex shader (顶点着色器),fragment shader (片元着色器)来进行渲染。
这里我们看到,着色器中的代码都是JavaScript中的string类型的 GLSL(openGL shader language)语言。
GLSL类似于 C 语言,和JavaScript相比起来,要尤其注意变量类型,如果你声明了一个 float 然后传给了一个 int(比如10)就会出错,正确的应该是10.0,这点对于JSer来说还是有点不一样的。
通常情况下,我们会去声明一些变量:
attribute vec4 a_Position;
声明变量通常由上以下格式组成
存储限定符
(attribute) 类型
(vec4) 变量名
(a_Position)
然后声明“入口函数”:
void main(){
//code
}
代码再执行的时候会去执行main函数中的代码,这点和C类语言很像。
vertex shader 顶点着色器
顾名思义,顶点着色器主要负责定义图形的顶点坐标,大小等位置相关的信息。
如上代码 VSHADER_SOURCE
片段所示,我们定义了一个存储限定符号 attribute
,类型为 vec4
(4个长度的矢量)的变量 a_Position
。
在main
函数中,我们将位置信息赋给gl_Position
,将顶点大小赋值给gl_PointSize
.
fragment shader 片元着色器
片元着色器主要是定义颜色等属性。
这里我们简单的通过 gl_FragColor
告诉着色器点的颜色为 vec4(1.0, 0.0, 0.0, 1.0)
渲染开始
前面我们定义了两个最重要的着色器,接下来就是简单的赋值,渲染了,更多的是流程。
首先我们需要创建一个GL的项目
var program = webgl.createProgram(); //这个program将会在后续绑定顶点、片元时候用到。
创建shader对象并绑定到(1)中的
program
上这里我们以定点着色器为例来说明,片元着色器的过程和定点着色器一致。
2.1 创建 shader 对象
var VShader = webgl.createShader(webgl.VERTEX_SHADER); //createShader方法 //webgl.VERTEX_SHADER告诉webgl绑定的是顶点着色器 //同理片元着色器应该是webgl.FRAGMENT_SHADER
2.2 绑定 shader 脚本
webgl.shaderSource(VShader, VSHADER_SOURCE); //shaderSource方法 //VShader是上一步创建的shader对象 //VSHADER_SOURCE 是我们之前准备的脚本
2.3 完成 sharder 对象的脚本绑定
webgl.compileShader(VShader); //compileShader 完成脚本的绑定
2.4 将 sharder 对象绑定到 program 上
webgl.attachShader(program, VShader); //program 是我们第一步创建的对象 //VShader 是我们2.1时候创建的sharder对象
连接 program 和 webgl
webgl.linkProgram(program);
使用 program
webgl.useProgram(program);
绘制
webgl.clearColor(0.0, 0.0, 0.0, 1.0); webgl.clear(webgl.COLOR_BUFFER_BIT); //上面两步是为了清除画布,并且将画布重置成我们需要的颜色。 webgl.drawArrays(webgl.POINTS, 0, 1); //drawArrays方法有多重绘制方法,这里我们需要的是点所以使用了webgl.POINTS
上述步骤第一眼看起来很麻烦,总结一下:
创建program
-> 创建shader
-> 绑定shader到program
-> 绘制
PS:还是解释一下,drawArrays
方法吧,drawArrays第一个参数决定了如何“连接”这些点,偷来一张图,大家看了自然会明白。(BTW:网上找的图,不知道是哪家的,如果作者看到了,麻烦通知我加一下链接)
* 请注意点的顺序
至于第二个、第三个参数就很好理解了,分别是,起始点(从0开始),和点的个数,比如一个三角形可以写成0,3
##总结
好了,至此我们已经完成了一个DEMO的开发,WebGL前期学习成本还是比较高的,前面的基础知识搞定之后,后面的学习将会很快。后续有新的进展会及时和大家沟通的。