WebGL需要调用OpenGL的接口的着色器去绘图,具体运行机制,通过WebGL接口将编写在js中的着色器代码编译,首先运行顶点着色器,然后再运行片元着色器,经过缓冲区,最后将绘图结果渲染到canvas上。
着色器语言类似于C语言,必须包含一个main函数,void 表示这个函数不会有返回值,并且不能为main函数指定参数。
例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>WebGL</title>
<script type="text/javascript" src="js/lib/webgl-utils.js" ></script>
<script type="text/javascript" src="js/lib/webgl-debug.js" ></script>
<script type="text/javascript" src="js/lib/cuon-utils.js" ></script>
</head>
<body>
<canvas id="canvas" width="600" height="600">该浏览器不支持WebGL!</canvas>
<!--顶点着色器-->
<script id="vertexShader" type="x-shader/x-vertex">
attribute vec4 a_Position;
void main(){
//设置点的坐标
//gl_Position=vec4(0.0,0.0,0.0,1.0);
gl_Position=a_Position;
//设置尺寸
gl_PointSize=100.0;
}
</script>
<!--片元着色器-->
<script id="fragmentShader" type="x-shader/x-fragment">
void main(){
//设置颜色
gl_FragColor=vec4(1.0,0.0,0.0,1.0);
}
</script>
<script>
(function main(){
var canvas=document.getElementById("canvas");
var gl=getWebGLContext(canvas);
if(!gl){
console.log("该浏览器不支持WebGL!");
return ;
}
var vShader=document.getElementById("vertexShader").textContent;
var fShader=document.getElementById("fragmentShader").textContent;
if(!initShaders(gl,vShader,fShader)){
conso.log("初始化着色器失败!");
return ;
}
//获取attribute变量的存储位置
var a_Position=gl.getAttribLocation(gl.program,"a_Position");
if(a_Position<0){
console.log("无法获取位置!");
return ;
}
//给attribute变量赋值
gl.vertexAttrib3f(a_Position,0.0,0.5,0.0);
gl.clearColor(0.0,0.0,0.0,1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.POINTS,0,1);
}());
</script>
</body>
</html>
两种着色器:
1.顶点着色器(vertext shader):
用于描述顶点特性(位置,大小),顶点指二维或三维空间的点。
2.片元着色器(fragment shader):
用于逐片元处理,显示在屏幕上,如处理光照,颜色等,片元可以理解为像素单元。
GLSL变量限定符
修饰符 | 说明 |
---|---|
attribute | 一般用于保存顶点或法线数据,它可以在数据缓冲区读取数据,只能存在于vertex shader(顶点着色器)中 |
uniform | 一般用来放置程序传递给shader的变换矩阵,如材质,光照参数等等,在shader运行时无法改变uniform变量 |
顶点着色器内置变量
变量名 | 说明 | 类型 |
---|---|---|
gl_Position | 输出属性-变换后的顶点的位置,用于后面的固定的裁剪等操作。所有的顶点着色器都必须写这个值。 | vec4 |
gl_PointSize | 表示顶点的尺寸(像素数) 如果不设置,默认为1.0 | float |
gl_Normal | 输入属性-表示顶点的法线值 | vec3 |
gl_Vertex | 输入属性-表示物体空间的顶点位置 | vec4 |
gl_Color | 输入属性-表示顶点的主颜色 | vec4 |
gl_SecondaryColor | 输入属性-表示顶点的辅助颜色 | vec4 |
gl_MultiTexCoordn | 输入属性-表示顶点的第n个纹理的坐标 | vec4 |
gl_FogCoord | 输入属性-表示顶点的雾坐标 | float |
gl_ClipVertex | 输出坐标,用于用户裁剪平面的裁剪 | vec4 |
gl_FrontColor | 正面的主颜色的varying输出 | vec4 |
gl_BackColor | 背面主颜色的varying输出 | vec4 |
gl_FrontSecondaryColor | 正面的辅助颜色的varying输出 | vec4 |
gl_BackSecondaryColor | 背面的辅助颜色的varying输出 | vec4 |
gl_TexCoord[] | 纹理坐标的数组varying输出 | vec4 |
gl_FogFragCoord | 雾坐标的varying输出 | float |
片元着色器内置变量
变量名 | 说明 | 类型 |
---|---|---|
gl_FragColor | 指定片元颜色,RGBA格式 | vec4 |
gl_Color | 包含主颜色的插值-只读输入 | vec4 |
gl_SecondaryColor | 包含辅助颜色的插值-只读输入 | vec4 |
gl_TexCoord[] | 包含纹理坐标数组的插值-只读输入 | vec4 |
gl_FogFragCoord | 包含雾坐标的插值-只读输入 | float |
gl_FragCoord | 窗口的齐次坐标,x、y、z和1/w-只读输入 | vec4 |
gl_FrontFacing | 如果是窗口正面图元的一部分,则这个值为true-只读输入 | bool |
gl_PointCoord | 点精灵的二维空间坐标范围在(0.0, 0.0)到(1.0, 1.0)之间,仅用于点图元和点精灵开启的情况下。 | vec2 |
gl_FragData[] | 使用glDrawBuffers输出的数据数组。不能与gl_FragColor结合使用。 | vec4 |
gl_FragDepth | 输出的深度用于随后的像素操作,如果这个值没有被写,则使用固定功能管线的深度值代替 | float |
齐次坐标:(x,y,z,w)。
由4个分量组成的矢量被称为齐次坐标,它能够提高处理三维数据的效率。
齐次坐标(x,y,z,w)等价于三维坐标(x/w,y/w,z/w)。所以如果齐次坐标的第四个分量是1,就可以将它当做单位坐标来使用。w的值必须大于等于0的。如果w趋近于0,那么它所表示的点将趋近于无穷远,所以在齐次坐标系中可以有无穷的概念。因为齐次坐标的存在,用矩阵乘法来描述顶点变换成为可能,所有三维图形系统在计算过程中,通常使用齐次坐标来表示顶点的三维坐标。
WebGL常用库及其内置方法
<script type="text/javascript" src="js/lib/webgl-utils.js" ></script>
<script type="text/javascript" src="js/lib/webgl-debug.js" ></script>
<script type="text/javascript" src="js/lib/cuon-utils.js" ></script>
①getWebGLContext(element,debug):
获取WebGL上下文
参数:
- element )指定canvas的元素对象
- debug )可选,默认为false,如果设置为true,Javascript中发生的错误将被显示在控制台上。注意,在调试结束后关闭它,否则会影响性能。
返回值:
WebGL绘图上下文, 如果是 null ,表示WebGL不可用
②initShaders(gl, vshader, fshader);
初始化着色器
参数:
- gl )指定渲染的上下文
- vshader ) 指定顶点着色器程序代码(字符串)
- fshader ) 指定片元着色器程序代码(字符串)
返回值: - true )初始化着色器成功
- false )初始化着色器失败