按照《webgl编程指南》学习着色器,webgl分为两种着色器,顶底着色器,片元着色器。
- 顶点着色器:描述顶点的特性(位置、颜色等)的程序,顶点:二维、三维空间的点,图形的端点或交点、
- 片元着色器:进行着片元处理过程的程序。
着色器使用类似c语言的OpenGL ES着色器语言来编写,下面分别编写顶点和片元着色器程序。
//顶点着色器
var VSHADER_SOURCE=
'void main(){\n'+
'gl_Position=vec4(0.0,0.0,0.0,1.0);\n'+//点的位置
'gl_PointSize=10.0;\n'+//点尺寸
'}\n';
//片元着色器
var FSHADER_SOURCE=
'void main(){\n'+
'gl_FragColor=vec4(1.0,0.0,0.0,1.0);\n'+//设置颜色
'}\n'
写好了的着色器程序,需要拿去创建program。来创建shader。
function createProgram(gl, vshader, fshader) {
// 创建着色器对象
var vertexShader = loadShader(gl, gl.VERTEX_SHADER, vshader);
var fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fshader);
if (!vertexShader || !fragmentShader) {
return null;
}
// 创建程序对象
var program = gl.createProgram();
if (!program) {
return null;
}
// 为程序对象分配顶点着色器和片元着色器
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
// 连接着色器
gl.linkProgram(program);
// 检查连接
var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
if (!linked) {
var error = gl.getProgramInfoLog(program);
console.log('无法连接程序对象: ' + error);
gl.deleteProgram(program);
gl.deleteShader(fragmentShader);
gl.deleteShader(vertexShader);
return null;
}
return program;
}
最后,webgl将程序添加。
gl.useProgram(program);
gl.program = program;
好了,我们来看一下完整的代码。
<html>
<head>
<title>webgl学习</title>
<meta charset="utf-8"/>
</head>
<body onload="main()">
<canvas width="200" height="300" id="canvas"></canvas>
<script>
function main() {
//顶点着色器
var VSHADER_SOURCE=
'void main(){\n'+
'gl_Position=vec4(0.0,0.0,0.0,1.0);\n'+//点的位置
'gl_PointSize=10.0;\n'+//点尺寸
'}\n';
//片元着色器
var FSHADER_SOURCE=
'void main(){\n'+
'gl_FragColor=vec4(1.0,0.0,0.0,1.0);\n'+//设置颜色
'}\n'
var canvas=document.getElementById('canvas');
var ctx= canvas.getContext("webgl");
if(!initShaders(ctx,VSHADER_SOURCE,FSHADER_SOURCE)){
console.log("初始化chader出现了错误");
};
/*设置canvas的背景颜色*/
ctx.clearColor(0.0,0.0,0.0,1.0);
/*清空canvas*/
ctx.clear(ctx.COLOR_BUFFER_BIT);
/*绘制点*/
ctx.drawArrays(ctx.POINTS,0,1);
}
function initShaders(gl, vshader, fshader) {
var program = createProgram(gl, vshader, fshader);
if (!program) {
console.log('无法创建程序对象');
return false;
}
gl.useProgram(program);
gl.program = program;
return true;
}
function loadShader(gl, type, source) {
// Create shader object
var shader = gl.createShader(type);
if (shader == null) {
console.log('unable to create shader');
return null;
}
// Set the shader program
gl.shaderSource(shader, source);
// Compile the shader
gl.compileShader(shader);
// Check the result of compilation
var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
if (!compiled) {
var error = gl.getShaderInfoLog(shader);
console.log('Failed to compile shader: ' + error);
gl.deleteShader(shader);
return null;
}
return shader;
}
function createProgram(gl, vshader, fshader) {
// 创建着色器对象
var vertexShader = loadShader(gl, gl.VERTEX_SHADER, vshader);
var fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fshader);
if (!vertexShader || !fragmentShader) {
return null;
}
// 创建程序对象
var program = gl.createProgram();
if (!program) {
return null;
}
// 为程序对象分配顶点着色器和片元着色器
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
// 连接着色器
gl.linkProgram(program);
// 检查连接
var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
if (!linked) {
var error = gl.getProgramInfoLog(program);
console.log('无法连接程序对象: ' + error);
gl.deleteProgram(program);
gl.deleteShader(fragmentShader);
gl.deleteShader(vertexShader);
return null;
}
return program;
}
</script>
</body>
</html>
最后,来看一下绘制效果。
这其中遇到的错误,如下所示。
如下所示,缺少了main函数的定义,主要是定义错了main名称。