着色器流程
上一章里我们用WebGL绘制了一个10像素的红色正方形。 在绘制过程中我们使用到一个新的概念,着色器。对着色器的概念我们也做了解释。
在三维场景中,仅仅用线条和颜色把图形画出来是远远不够的,你必须考虑光照射上去之后,或者观察者视角发生了变化, 对场景会有什么影响。 类型我们现实中看待物体一样。着色器可以高度灵活的完成这些工作,提供各种渲染效果。
js读取了着色器的相关信息,然后在WebGL系统中可以调用。

这就是整个流程,菱形部分为说明,矩形为具体流程。
简化之后就是
- 执行加载的js程序
- 顶点着色器,片元着色器
- 颜色缓存区
着色器代码解析
结合刚才的知识,我们再来看下上一章说着色器部分的代码
//顶点着色器程序var VSHADER_SOURCE="" +"void main(){\n" +" gl_Position = vec4(0.0,0.0,0.0,1.0);\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";function main() {//首先获取到canvas的dom对象var canvas = document.getElementById("canvas");//获取到WebGL的上下文var gl = getWebGLContext(canvas);//不支持WebGL的浏览器将打印一个错误,并结束代码运行if (!gl) {console.log("浏览器不支持WebGL");return;}//初始化着色器if(!initShaders(gl,VSHADER_SOURCE,FSHADER_SOURCE)){console.log("初始化着色器失败");return;}//指定一个覆盖(清空)canvas的颜色gl.clearColor(0.0, 0.0, 0.0, 1.0);//执行清空gl.clear(gl.COLOR_BUFFER_BIT);//绘制一个点gl.drawArrays(gl.POINTS,0,1);}
顶点着色器代码位于第2到6行, 片元着色器位于第10到13行,实际上,它们是以js字符串形式编写的着色器语言程序。
这样主程序就可以将它们传给WebGL系统。
在前面说到过,着色器是类似于c的OpenGL ES着色器语言(GLSL ES)来编写。着色器的语言很简单,稍微懂一点c或者js就可以理解。
初始化着色器
在研究着色器内部细节之前我们先看一下main函数的执行流程。
获取canvas元素 => 获取webGL绘图上下文 => 初始化着色器 => 设置canvas背景色 => 清楚canvas => 绘图
第三步初始化着色器, 调用了辅助函数initShaders()对字符串形式的着色器进行了初始化。该辅助函数定义在cuon.util.js中
/*** Create a program object and make current* @param gl GL context* @param vshader a vertex shader program (string)* @param fshader a fragment shader program (string)* @return true, if the program object was created and successfully made current*/function initShaders(gl, vshader, fshader) {var program = createProgram(gl, vshader, fshader);if (!program) {console.log('Failed to create program');return false;}gl.useProgram(program);gl.program = program;return true;}/*** Create the linked program object* @param gl GL context* @param vshader a vertex shader program (string)* @param fshader a fragment shader program (string)* @return created program object, or null if the creation has failed*/function createProgram(gl, vshader, fshader) {// Create shader objectvar vertexShader = loadShader(gl, gl.VERTEX_SHADER, vshader);var fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fshader);if (!vertexShader || !fragmentShader) {return null;}// Create a program objectvar program = gl.createProgram();if (!program) {return null;}// Attach the shader objectsgl.attachShader(program, vertexShader);gl.attachShader(program, fragmentShader);// Link the program objectgl.linkProgram(program);// Check the result of linkingvar linked = gl.getProgramParameter(program, gl.LINK_STATUS);if (!linked) {var error = gl.getProgramInfoLog(program);console.log('Failed to link program: ' + error);gl.deleteProgram(program);gl.deleteShader(fragmentShader);gl.deleteShader(vertexShader);return null;}return program;}/*** Create a shader object* @param gl GL context* @param type the type of the shader object to be created* @param source shader program (string)* @return created shader object, or null if the creation has failed.*/function loadShader(gl, type, source) {// Create shader objectvar shader = gl.createShader(type);if (shader == null) {console.log('unable to create shader');return null;}// Set the shader programgl.shaderSource(shader, source);// Compile the shadergl.compileShader(shader);// Check the result of compilationvar compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);if (!compiled) {var error = gl.getShaderInfoLog(shader);console.log('Failed to compile shader: ' + error);gl.deleteShader(shader);return null;}return shader;}
参数
gl: 指定渲染上线文
vshader: 指定顶点着色器程序代码
fshader: 指定片元着色器程序代码
返回值
true 初始化着色器成功
false 初始化着色器失败
后面我们会研究这个函数的内部细节, 现在只需要知道这个函数初始化了着色器。供我们使用即可。
WebGL系统由两部分组成, 顶点着色器和片元着色器。 这是简化之后的。初始化着色器之前, 顶点着色器和片元着色器都是空白的,我们需要将字符串形式的着色器代码从js传给WebGL系统, 并建立着色器, 这就是initShaders()所做的事情。 注意,着色器是运行在WebGL系统中,而不是js中。
