HTML页面:
<body>
<canvas id="canvas" width="300" height="300"></canvas>
<body/>
一谈起着色器就不得不说下GLSL了,GLSL是一种OpenGL着色语言,WebGL是基于OpenGL ES 2.0实现的。所 以 OpenGL 中使用的着色器可以直接在 WebGL 中使用。
直接上代码:编写着色器程序
<script type="x-shader/x-vertex" id="vertexShader">
attribute vec2 aVertexPosition;
void main() {
gl_Position = vec4(aVertexPosition, 0.0, 1.0);
}
</script>
<script type="x-shader/x-fragment" id="fragmentShader">
precision mediump float;
uniform vec4 uColor;
void main() {
gl_FragColor = uColor;
}
</script>
由于浏览器不能理解GLSL程序,所以通过以上script标签引入代码。也可以直接使用字符串来编写GLSL程序。
下面代码编译着色器:
var vertexGlsl = document.getElementById('vertexShader').text;
var fragmentGlsl = document.getElementById("fragmentShader").text;
var drawing = document.getElementById('canvas');
if (drawing.getContext) {
var gl = drawing.getContext('webgl') || drawing.getContext('experimental-webgl');
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexGlsl);
gl.compileShader(vertexShader);
// 顶点着色器
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
console.log(gl.getShaderInfoLog(vertexShader));
}
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentGlsl);
gl.compileShader(fragmentShader);
// 片元着色器
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
console.log(gl.getShaderInfoLog(fragmentShader));
}
}
这里通过WebGLRenderingContext.createShader创建一个WebGLShader,通过WebGLRenderingContext.shaderSource挂接GLSL源代码,最后进行编译,即完成了着色器的编译。想要使用WebGLShader,还需要将它添加到WebGLProgram里面。
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
// 程序执行状态
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.log(gl.getProgramInfoLog(program));
}
WebGLRenderingContext.createProgram用来创建WebGLProgram对象。然后添加预先定义好的顶点着色器,片元着色器。
useProgram方法将定义好的WebGLProgram对象添加到当前的渲染状态中。至此即可使用GLSL应用程序。下面是一个画三角形的例子:
var vertices = new Float32Array([0, 1, 1, -1, -1, -1]);
var buffer = gl.createBuffer();
var vertexSetSize = 2;
var vertexSetCount = vertices.length / vertexSetSize;
var uColor, aVertexPosition;
// 把数据放到缓冲区
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
// 为片段着色器传入颜色值
uColor = gl.getUniformLocation(program, "uColor");
gl.uniform4fv(uColor, [ 0, 0, 0, 1 ]);
// 为着色器传入顶点信息
aVertexPosition = gl.getAttribLocation(program, "aVertexPosition"); gl.enableVertexAttribArray(aVertexPosition);
gl.vertexAttribPointer(aVertexPosition, vertexSetSize, gl.FLOAT, false, 0, 0);
//绘制三角形
gl.drawArrays(gl.TRIANGLES, 0, vertexSetCount);