WebGL 基础入门
什么是 WebGL?
WebGL(Web Graphics Library)是一个 JavaScript API,用于在任何兼容的 Web 浏览器中渲染高性能的交互式 3D 和 2D 图形,而无需使用插件。
主要特点
- 硬件加速:利用 GPU 的强大计算能力
- 跨平台:支持所有现代浏览器
- 标准化:基于 OpenGL ES 2.0/3.0
环境搭建
WebGL 不需要额外的安装,现代浏览器都原生支持。你只需要:
- 一个支持 WebGL 的浏览器(Chrome、Firefox、Safari、Edge)
- 一个文本编辑器
- 本地服务器(可选,用于加载纹理等资源)
第一个三角形
让我们创建最简单的 WebGL 程序 - 绘制一个彩色三角形。
HTML 结构
HTML1<!DOCTYPE html> 2<html> 3<head> 4 <meta charset="utf-8"> 5 <title>WebGL 第一个三角形</title> 6 <style> 7 canvas { width: 100%; height: 100%; } 8 body { margin: 0; overflow: hidden; } 9 </style> 10</head> 11<body> 12 <canvas id="glCanvas"></canvas> 13 <script src="triangle.js"></script> 14</body> 15</html>
JavaScript 代码
JAVASCRIPT1// 获取 Canvas 和 WebGL 上下文 2const canvas = document.getElementById('glCanvas'); 3const gl = canvas.getContext('webgl'); 4 5// 顶点着色器 6const vsSource = ` 7 attribute vec4 aPosition; 8 attribute vec4 aColor; 9 varying vec4 vColor; 10 11 void main() { 12 gl_Position = aPosition; 13 vColor = aColor; 14 } 15`; 16 17// 片段着色器 18const fsSource = ` 19 precision mediump float; 20 varying vec4 vColor; 21 22 void main() { 23 gl_FragColor = vColor; 24 } 25`; 26 27// 创建着色器 28function createShader(gl, type, source) { 29 const shader = gl.createShader(type); 30 gl.shaderSource(shader, source); 31 gl.compileShader(shader); 32 return shader; 33} 34 35const vertexShader = createShader(gl, gl.VERTEX_SHADER, vsSource); 36const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fsSource); 37 38// 创建程序 39const program = gl.createProgram(); 40gl.attachShader(program, vertexShader); 41gl.attachShader(program, fragmentShader); 42gl.linkProgram(program); 43gl.useProgram(program); 44 45// 设置顶点数据 46const vertices = new Float32Array([ 47 // 位置 // 颜色 48 0.0, 0.5, 0.0, 1.0, 0.0, 0.0, 1.0, // 顶点1: 红色 49 -0.5, -0.5, 0.0, 0.0, 1.0, 0.0, 1.0, // 顶点2: 绿色 50 0.5, -0.5, 0.0, 0.0, 0.0, 1.0, 1.0 // 顶点3: 蓝色 51]); 52 53const buffer = gl.createBuffer(); 54gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 55gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); 56 57// 获取属性位置 58const aPosition = gl.getAttribLocation(program, 'aPosition'); 59const aColor = gl.getAttribLocation(program, 'aColor'); 60 61// 配置顶点属性 62const FSIZE = vertices.BYTES_PER_ELEMENT; 63gl.vertexAttribPointer(aPosition, 3, gl.FLOAT, false, FSIZE * 7, 0); 64gl.enableVertexAttribArray(aPosition); 65 66gl.vertexAttribPointer(aColor, 4, gl.FLOAT, false, FSIZE * 7, FSIZE * 3); 67gl.enableVertexAttribArray(aColor); 68 69// 设置清除颜色并清除画布 70gl.clearColor(0.0, 0.0, 0.0, 1.0); 71gl.clear(gl.COLOR_BUFFER_BIT); 72 73// 绘制三角形 74gl.drawArrays(gl.TRIANGLES, 0, 3);
WebGL 坐标系
WebGL 使用裁剪空间(Clip Space)坐标系:
| 坐标轴 | 范围 | 含义 |
|---|---|---|
| X | -1.0 ~ 1.0 | 水平方向,左到右 |
| Y | -1.0 ~ 1.0 | 垂直方向,下到上 |
| Z | -1.0 ~ 1.0 | 深度方向,内到外 |
TEXT1 Y (1.0) 2 │ 3 │ 4(-1,1)────┼────(1,1) 5 │ 6──────────┼─────────→ X (1.0) 7 │ 8(-1,-1)───┼────(1,-1) 9 │ 10 (0,-1)
渲染管线概览
WebGL 的渲染管线包含以下几个主要阶段:
-
顶点处理
- 顶点着色器(Vertex Shader)
- 图元装配
-
光栅化
- 将图元转换为片段
-
片段处理
- 片段着色器(Fragment Shader)
- 深度/模板测试
- 混合
-
输出合并
- 写入帧缓冲
常见问题
黑色屏幕
- 检查 WebGL 上下文是否成功创建
- 确认着色器编译成功
- 验证顶点数据是否正确
性能问题
- 减少绘制调用次数
- 使用顶点缓冲对象(VBO)
- 避免在渲染循环中创建对象
下一步
在下一章中,我们将深入学习:
- 渲染管线的详细流程
- GLSL 着色器语言
- 矩阵变换与投影
继续学习 第2章 渲染管线与着色器。