1. WebGL基础概念
WebGL(Web Graphics Library)是一个JavaScript API,运行在浏览器中的图形库,允许在支持HTML5的浏览器中直接绘制3D图形,而无需安装任何插件。WebGL基于OpenGL ES 2.0,能为Web开发者提供强大的图形渲染功能,广泛应用于游戏、数据可视化、虚拟现实等领域。它可以让我们在网页中实现硬件加速的2D和3D图形渲染。WebGL不仅支持绘制图像,还能实现复杂的着色、纹理映射、光照效果等。
- WebGL与HTML5 Canvas:WebGL依赖于HTML5中的
<canvas>元素。它是通过JavaScript调用底层图形API,进行图形渲染的。 - 着色器:WebGL使用着色器来定义图形如何渲染。通常有顶点着色器和片段着色器两种类型,前者处理顶点数据,后者处理每个像素的颜色。
- 缓冲区和顶点数据:WebGL需要通过缓冲区传递顶点信息,帮助渲染引擎计算出最终的图形。
2. 环境搭建
2.1 创建一个HTML文件
首先,创建一个简单的HTML文件,里面包含一个<canvas>元素,用来绘制图形。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>WebGL入门教程</title>
<style>
body {
margin: 0;
}
canvas {
display: block;
}
</style>
</head>
<body>
<canvas id="webgl-canvas"></canvas>
<script src="app.js"></script>
</body>
</html>
2.2 设置WebGL上下文
接下来,我们需要在JavaScript中获取WebGL渲染上下文,并设置好画布的大小。
// 获取canvas元素
const canvas = document.getElementById('webgl-canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// 获取WebGL上下文
const gl = canvas.getContext('webgl');
// 检查浏览器是否支持WebGL
if (!gl) {
alert("WebGL未被支持!");
}
3. 绘制一个简单的三角形
接下来,我们绘制一个简单的三角形,并将其渲染到页面上。
3.1 创建顶点数据
我们需要定义一个三角形的三个顶点。每个顶点包含两个坐标:x和y,这两个坐标决定了三角形的位置。
const vertices = new Float32Array([
0.0, 0.5, // 顶点1 (x, y)
-0.5, -0.5, // 顶点2 (x, y)
0.5, -0.5 // 顶点3 (x, y)
]);
3.2 编写着色器代码
WebGL需要顶点着色器和片段着色器来控制图形的渲染。下面是一个简单的着色器代码:
顶点着色器(vertex shader)
const vertexShaderSource = `
attribute vec2 a_position;
void main() {
gl_Position = vec4(a_position, 0.0, 1.0);
}
`;
片段着色器(fragment shader)
const fragmentShaderSource = `
precision mediump float;
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // 设置颜色为红色
}
`;
3.3 编译和链接着色器
我们需要将着色器代码编译为WebGL可以执行的程序,并将它们链接到一起。
/**
* 创建着色器
* @param {number} type - gl.VERTEX_SHADER or gl.FRAGMENT_SHADER
* @param {string} source - 着色器源代码
* @return {WebGLShader} - 创建的着色器对象
*/
function createShader(type, source) {
const shader = gl.createShader(type); // 创建着色器
gl.shaderSource(shader, source); // 设置着色器源代码
gl.compileShader(shader); // 编译着色器
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.error('Shader编译失败:', gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
return null;
}
return shader;
}
/**
* 创建WebGL程序对象
* @param {string} vertexShaderSource - 顶点着色器源代码
* @param {string} fragmentShaderSource - 片元着色器源代码
* @return {WebGLProgram} - 创建的程序对象
*/
function createProgram(vertexShaderSource, fragmentShaderSource) {
const vertexShader = createShader(gl.VERTEX_SHADER, vertexShaderSource);
const fragmentShader = createShader(gl.FRAGMENT_SHADER, fragmentShaderSource);
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.error('程序链接失败:', gl.getProgramInfoLog(program));
return null;
}
return program;
}
const program = createProgram(vertexShaderSource, fragmentShaderSource);
gl.useProgram(program);
3.4 创建缓冲区并传递顶点数据
我们需要将顶点数据传递给WebGL,创建一个缓冲区并将其绑定。
// 创建缓冲区
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
// 获取顶点位置属性位置 a_position 在顶点着色器源代码中定义
const positionLocation = gl.getAttribLocation(program, 'a_position');
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionLocation);
3.5 清空画布并绘制三角形
设置清空画布的背景色,并绘制三角形。
// 清空画布
gl.clearColor(0.0, 0.0, 0.0, 1.0); // 背景色为黑色
gl.clear(gl.COLOR_BUFFER_BIT);
// 绘制三角形
gl.drawArrays(gl.TRIANGLES, 0, 3);