webgl学习(1)-着色器

main函数执行流程

  1. 获取canvas元素
  2. 获取webgl上下文
  3. 初始化着色器
  4. 设置canvas背景色
  5. 清除canvas
  6. 绘图

获取绘图上下文

使用canvas.getContex(),但是,在不同的浏览器中会有不同,所以写一个函数getWebGLContext()来隐藏不同浏览器之间的差异。该函数被定义在cuon.utils.js中。

1
var gl = getWebGLContext(canvas)

清空绘图区域

1
2
3
4
5
// 指定清空<canvas>的颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0)

// 清空<canvas>
gl.clear(gl.COLOR_BUFFER_BIT)

顶点着色器

用来描述顶点特性(位置、颜色等),顶点是指二维活三维控件中的一个点,比如端点或交点。

1
2
3
4
5
var VSHADER_SORCE =
'void main(){\n' +
' gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n' +
' gl_PointSize = 10.0;\n' +
'}\n';

片元着色器

进行逐片元处理过程如光照。

1
2
3
4
var FSHADER_SORCE =
'void main(){\n' +
' gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);\n' +
'}\n';

着色器运行在webgl系统中,不是javascript程序中。

  • 绘制一个点

GLSE中的数据类型

  1. float
  2. vec4 由4个浮点数组成的矢量 (v0,v1,v2,v3),返回值为vec4对象。

齐次坐标

能够提高处理三维数据的效率,齐次坐标是四维的,最后一个分量是1.0就可以表示’前三个分量为坐标值’的点.
(x,y,z,w)==(x/w,y/w,z/w),w必须是大于0的,如果w趋近于0,那么点将趋近于无穷远,所以齐次坐标可以有无穷的概念。使得矩阵乘法来描述顶点变换称为可能。

webgl坐标系统

x轴水平(正方向为右),y轴垂直(正方向为下),z轴垂直于屏幕(正方向为外)

attribute变量

从外部向顶点着色器传输与顶点相关的数据,只有顶点着色器能使用它。
步骤:

在顶点着色器中,声明attribute变量;

将attribute变量赋值给gl_Position变量;

1
2
3
4
5
6
var VSHADER_SORCE =
'attribute vec4 a_Position;\n' +
'void main(){\n' +
' gl_Position = a_Position;\n' +
' gl_PointSize = 10.0;\n' +
'}\n';

向attribute变量传输数据。

1
2
3
4
5
// 获取attribute变量的存储位置
var a_Position = gl.getAttributelocation(gl.program,'a_Position')
// 第一个参数是程序对象,包括了顶点着色器和片元着色器
// 将顶点位置传输给attribute变量
gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0)

uniform

传输对于所有顶点都相同(与顶点无关)的数据。
可以使用uniform变量将颜色值传给着色器,其步骤与用attribute变量传递的类似。这次数据传输的目标是片元着色器,非顶点着色器。

在片元着色器中准备uniform变量;

用这个uniform变量向gl_FragClolo赋值;

1
2
3
4
5
6
7
var FSHADER_SORCE =
// 精度限定词来制定变量的范围和精度,本例为中等精度
'precision mediup float;\n' +
'uniform vec4 u_FragColor;\n' +
'void main(){\n' +
' gl_FragColor = u_FragColor;\n' +
'}\n';

将颜色数据从javascript传给改uniform变量。

1
2
3
4
// 获取uniform变量存储地址
var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor');
// 向uniform变量赋值
gl.uniform4f(u_FragColor, rgba[0], rgba[1], rgba[2], rgba[3])