在上一节中,我们知道了如何简单的WebGL程序及其相关函数的使用。在这一节中,我们学习如何用简单的着色器画一个点。
我们先来简单说说这里用到的两个着色器。
顶点着色器(Vertex shader)
顶点着色器实际上就是一段小程序,它描述了应用程序传进来的顶点的一些特性,比如位置、颜色、纹理坐标等。其处理过程是逐顶点的,一般会对顶点做一些的相关操作,比如顶点平移、旋转,纹理坐标的变换、顶点光照的计算等等,一般光照的计算会影响显示颜色。具体的知识后续章节详细讲解。
片元着色器(Fragment shader)
片元着色器也可以称作像素着色器,它接收从顶点着色器或其他着色器(几何着色器)传过来的纹理坐标和颜色信息进行处理,接受的是经过光栅化处理后的片元值。它可进行访问纹理、汇总颜色(颜色混合)、雾化等操作,其处理过程是逐片元的,它可以形成各种渲染效果。具体的知识后续章节详细讲解。
我们可以看看这整个的程序流程,如下图:
绘制一个点
我们先来看看这个简单的版本,就只有一个简单的红点。这个红点位于原点的位置(即<canvas>的中心位置),我们用一个小的正方形来代表点。
HelloPoint1.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Draw a Point (1)</title>
</head>
<body onload="main()">
<canvas id="webgl" width="400" height="400">
Please use a browser that supports "canvas"
</canvas>
<script src="lib/webgl-utils.js"></script>
<script src="lib/webgl-debug.js"></script>
<script src="lib/cuon-utils.js"></script>
<script src="HelloPoint1.js"></script>
</body>
</html>
<script src="HelloPoint1.js"></script>
在这行代码中,作用是引用HelloPoint1.js这个文件。其他代码的解释跟上一节的类似,有不清楚的可以看一下上一节的文章:https://blog.csdn.net/swety_gxy/article/details/79905420或者留言哦。
HelloPoint1.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() {
var canvas=document.getElementById('webgl');
if(!canvas){
console.log('Failed to retrieve the <canvas> elemen');
return;
}
var gl=getWebGLContext(canvas);
if(!gl){
console.log('Failed to get the rendering context for WebGL');
return;
}
if(!initShaders(gl,VSHADER_SOURCE,FSHADER_SOURCE)){
console.log('Failed to initialize shaders.');
return;
}
gl.clearColor(0.0,0.0,0.0,1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.POINTS,0,1);
}
在代码中我们可以看到,main()函数的前面多了两个着色器的字符串变量,我们把它们叫做着色器程序,只不过用字符串变量来存储而已。
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';
字符串变量VSHADER_SOURCE的值就是顶点着色器的内容,它们以JavaScript字符串形式编写,这样主程序就可以将他们传入WebGL系统中了。着色器是使用类C的OpenGL ES着色语言(GLSL ES)来写的,后续章节会详细介绍它。为了便于出错分析,每一行代码都用\n结束,读者编写代码时可以不加\n。
function main() {
...
...
...
}
我们接下来看看这个main()函数里面的代码,它里面的代码实现流程如下图所示:
与上一小节的JS代码相比,多了初始化着色器和绘制的一段代码。
初始化着色器:
if(!initShaders(gl,VSHADER_SOURCE,FSHADER_SOURCE)){
console.log('Failed to initialize shaders.');
return;
}
初始化函数initShaders()被定义在了cuon-utils.js文件中,它在HelloPoint1.html文件中被引用进来了。
我们再来看看两个简单的着色器程序:
VSHADER:
void main(){
gl_Position = vec4(0.0,0.0,0.0,1.0);
gl_PointSize = 10.0;
}
FSHADER:
void main(){
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
在函数initShaders()中,顶点着色器先执行,它对gl_Position和gl_PointSize这两个变量进行赋值,并将它们传入片元着色器(我们现在可以简单地这么认为),然后再执行片元着色器。我们都知道,要画出一个点,需要知道点的位置、大小、颜色这三个信息,在程序中,位置和大小在顶点着色器中设置,颜色在片元着色器中设置。
着色器程序必须要有main()函数且没有函数参数,在顶点着色器中,gl_Position和gl_PointSize是内置变量,都有特殊的含义:gl_Position-顶点位置,gl_PointSize-顶点大小。在片元着色器中,gl_FragColor也是内置变量,为它赋值也就相当于给该片元指定了颜色。
在着色器都设置好了,并且做好一些清理工作(清空绘图区域)之后,就开始绘制了。
gl.drawArrays(gl.POINTS,0,1);
我们使用此行代码来实现,drawArrays()是一个很强大的函数,它可以用来绘制各种图形,它的一些参数及规范如下图所示:
由于我们只绘制单个点,所以第一个参数用了gl.POINTS;从第一个顶点开始画,所以第二个参数设为0;只画一个顶点,所以第三个参数设为1.
示例代码效果如图所示:
我们需要记住的是,在WebGL程序中,JavaScript程序和着色器程序是协同运行的。
好了,这一节就暂时只有这么多。Have a good day!
想要了解更多,请关注:https://blog.csdn.net/swety_gxy