这里有两个着色器:面着色器和顶点着色器。
关于这两个着色器,这里有必要说明一下,计算机中的3D模型基本都是由点结合三角面片去描述的,顶点着色器就是去处理这些点的数据,而面着色器就是通过插值的方式,去处理三角面片上点的数据。
上面定义的顶点着色器就定义了顶点的位置和颜色计算方式;而面着色器定义了插值点的颜色计算方式。实际的应用场景中,还会涉及到在着色器中处理光线等效果。
定义了着色器,在程序中就可以查找到它们并可以去使用:
varshaderProgram;
functioninitShaders(){
varfragmentShader=getShader(gl,"shader-fs");
varvertexShader=getShader(gl,"shader-vs");
shaderProgram=gl.createProgram();
gl.attachShader(shaderProgram,vertexShader);
gl.attachShader(shaderProgram,fragmentShader);
gl.linkProgram(shaderProgram);
if(!gl.getProgramParameter(shaderProgram,gl.LINK_STATUS)){
alert("Couldnotinitialiseshaders");
}
gl.useProgram(shaderProgram);
shaderProgram.vertexPositionAttribute=gl.getAttribLocation(shaderProgram,"aVertexPosition");
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
shaderProgram.vertexColorAttribute=gl.getAttribLocation(shaderProgram,"aVertexColor");
gl.enableVertexAttribArray(shaderProgram.vertexColorAttribute);
shaderProgram.pMatrixUniform=gl.getUniformLocation(shaderProgram,"uPMatrix");
shaderProgram.mvMatrixUniform=gl.getUniformLocation(shaderProgram,"uMVMatrix");
}
着色器是有了,但是怎么让显卡去执行,Program就是这种桥梁,它是WebGL原生的二进制码,它的作用基本上就是让显卡运行着色器代码去渲染指定的模型数据。
这里还用到一个辅助方法getShader,这个方法就是遍历html文档,查找着色器的定义,拿到定义后创建着色器,这里就不细说了:
functiongetShader(gl,id){
varshaderScript,theSource,currentChild,shader;
shaderScript=document.getElementById(id);
if(!shaderScript){
returnnull;
}
theSource="";
currentChild=shaderScript.firstChild;
while(currentChild){
if(currentChild.nodeType==currentChild.TEXT_NODE){
theSource+=currentChild.textContent;
}
currentChild=currentChild.nextSibling;
}
if(shaderScript.type=="x-shader/x-fragment"){
shader=gl.createShader(gl.FRAGMENT_SHADER);
}elseif(shaderScript.type=="x-shader/x-vertex"){
shader=gl.createShader(gl.VERTEX_SHADER);
}else{
//Unknownshadertype
returnnull;
}
gl.shaderSource(shader,theSource);
//Compiletheshaderprogram
gl.compileShader(shader);
//Seeifitcompiledsuccessfully
if(!gl.getShaderParameter(shader,gl.COMPILE_STATUS)){
alert("Anerroroccurredcompilingtheshaders:"+gl.getShaderInfoLog(shader));
returnnull;
}
returnshader;
}