1.创建步骤
- 创建着色器对象(
gl.createShader()
) - 向着色器对象中填充着色器程序源码(
gl.shaderSource()
) - 编译着色器(
gl.compileShader()
) - 创建程序对象(
gl.createProgrom()
) - 为程序对象分配着色器(
gl.attachShader()
) - 链接程序对象(
gl.linkProgram()
) - 使用程序对象(
gl.useProgram()
)
着色器对象:管理一个顶点着色器或一个片元着色器。每个着色器都有一个着色器对象。
程序对象:管理着色器对象的容器。webGl中,一个程序对象必须包含一个顶点着色器和一个片源着色器。
2.例子
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float;
varying vec4 v_Color;
void main(void) {
gl_FragColor = v_Color;
}
</script>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec4 aVertexPosition;
attribute vec4 a_Color;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
varying vec4 v_Color;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * aVertexPosition;
v_Color=a_Color;
}
</script>
<script>
var gl;
canvas = document.getElementById("webgl");
//获取三维绘图环境
function initGL(canvas) {
try {
gl = canvas.getContext("experimental-webgl");
} catch (e) {
}
if (!gl) {
alert("Could not initialise WebGL, sorry :-(");
}
}
//根据script创建着色器对象。
function getShader(gl, id)
{
var shaderScript = document.getElementById(id);
if (!shaderScript) {
return null;
}
var str = "";
var k = shaderScript.firstChild;
while (k) {
if (k.nodeType == 3) {
str += k.textContent;
}
k = k.nextSibling;
}
var shader;
if (shaderScript.type == "x-shader/x-fragment") {
//步骤一创建着色器对象
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (shaderScript.type == "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else {
return null;
}
//步骤二,为着色器对象填充代码
gl.shaderSource(shader, str);
//步骤三,编译着色器对象
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
var shaderProgram;
function initShaders() {
var fragmentShader = getShader(gl, "shader-fs");
var vertexShader = getShader(gl, "shader-vs");
//步骤四,创建程序对象
shaderProgram = gl.createProgram();
//步骤五,为程序对象分配片元着色器与顶点着色器
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
步骤6,链接着色器
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Could not initialise shaders");
}
//步骤7,使用这个着色器,可以使用这个函数进行多个着色器间的切换。
gl.useProgram(shaderProgram);
}
</script>
3.函数说明
1.gl.createShader(type),type值为gl.VERTEX_SHADER或gl.FRAGMENT_SHADER,返回创建的着色器shader
2.gl.shaderSource(shader,source),shader为第一步骤中的返回的着色器。source为着色器代码字符串。
3.gl.compileShader(shader),为第一步中返回的着色器对象。
4.gl.createProgram(),无参数,返回program对象
5.gl.attachShader(program,shader),program为第4步骤中返回的程序对象,shader为顶点着色器对象或是片元着色器对象,该函数需要调用两次。
6.gl.linkProgram(program),program为创建的程序对象。
7.gl.useProgram(program)
(google对webgl有写好的cuon-utils.js文件可以方便的创建程序对象)部分代码如下
function initShaders(gl,vsshader,fshader)
{
var program=createProgram(gl,vshader,fsahder);
gl.useProgram(program);
gl.program=program;
return true;
}
function createProgram(gl,vshader,fsahder)
{
var vertexShader=loaderShader(gl,gl.VERTEX_SHADER,vshader);
var fragmentShader=loaderShader(gl,gl.FRAGMENT_SHADER,fshader);
var program=gl.createProgram();
gl.attachShader(program,vertexShader);
gl.attachSahder(program,fragmentShader);
gl.linkProgram(program) ;
return program;
}