webgl
Web Graphic Library,页面图形库;
借助canvas
元素,使用JavaScript和OpenGL ES 2.0 的 API,进行2D或3D图形渲染。
WebGL 程序构成:
- 控制代码(JavaScript)
- 特效代码(在GPU中执行,shader code,着色代码)
GPU: Graphic Processing Unit,图形处理单元
基础概念
webgl在电脑的GPU中运行,因此需要能够在GPU上运行的代码;
这样的代码需要提供成对的方法;
每对方法中的一个叫顶点着色器,另一个叫片段着色器;
并且使用一种c或c++类似的强类型语言GLSL(GL着色语言);
每一对组合起来称作一个Program(着色程序);
几乎整个webgl API都是关于如何设置这些成对方法的状态值以及运行它们;
顶点着色器
VertexShader,作用是,计算顶点的位置;
根据计算出的一系列顶点位置,webgl可以对点,线和 三角形在内的一些图元进行光栅化(绘制每一个)处理;
片段着色器
fragmentShader,对图元进行光栅化处理,需要使用片段着色器方法;
片段着色器的作用,计算出当前绘制图元中每个像素的颜色值;
案例
- 绘制三角形
- 绘制彩色矩阵,并理解缓冲区(Buffer)的使用
三角形
理解顶点着色器和片段着色器的作用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>WebGL 三角形</title>
<style>
canvas {
display: block;
margin: 20px auto;
border: 1px solid #000;
}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<script>
// 获取WebGL上下文
const canvas = document.getElementById("canvas");
const gl = canvas.getContext("webgl");
// 顶点着色器源码
const vertexShaderSource = `
attribute vec4 aPosition;
void main() {
gl_Position = aPosition; // 设置顶点位置
}
`;
// 片元着色器源码
const fragmentShaderSource = `
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // 设置颜色为红色
}
`;
// 编译着色器
const vertexShader = compileShader(
gl,
gl.VERTEX_SHADER,
vertexShaderSource
);
const fragmentShader = compileShader(
gl,
gl.FRAGMENT_SHADER,
fragmentShaderSource
);
// 创建并链接程序
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
// 定义三角形顶点数据
const vertices = new Float32Array([
0.0,
0.5, // 顶点1
-0.5,
-0.5, // 顶点2
0.5,
-0.5, // 顶点3
]);
// 创建缓冲区并绑定数据
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
// 获取顶点属性位置并启用
const aPosition = gl.getAttribLocation(program, "aPosition");
gl.enableVertexAttribArray(aPosition);
gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0);
// 清空画布并绘制
gl.clearColor(0.0, 0.0, 0.0, 1.0); // 设置背景色为黑色
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 3); // 绘制三角形
// 编译着色器的辅助函数
function compileShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.error("着色器编译失败:", gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
return null;
}
return shader;
}
</script>
</body>
</html>
webgl上下文
canvas.getContext(webgl)
获取webgl上下文- webgl是基于状态机的API,所有操作都通过 gl对象完成
着色器shader
-
顶点着色器:处理顶点数据,计算顶点在裁剪空间中的位置
attribute vec4 aPosition; // 顶点属性
void main() {
gl_Position = aPosition; // 设置顶点位置
} -
片段着色器:处理像素颜色
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // 设置颜色为红色
}
缓冲区Buffer
// 创建缓冲区并绑定数据
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
- gl.createBuffer创建
- gl.bindBuffer绑定
- gl.bufferData将顶点数据上传到GPU
顶点属性Attribute
// 获取顶点属性位置并启用
const aPosition = gl.getAttribLocation(program, "aPosition");
gl.enableVertexAttribArray(aPosition);
gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0);
- gl.getAttribLocation获取顶点属性的位置
- gl.enableVertexAttribArray启用顶点属性
- gl.vertexAttribPointer指定如何从缓冲区读取数据
绘制
// 清空画布并绘制
gl.clearColor(0.0, 0.0, 0.0, 1.0); // 设置背景色为黑色
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 3); // 绘制三角形
- gl.clearColor设置背景色
- gl.clear清空画布
- gl.drawArrays绘制三角形