场景

你需要开发 3D 可视化应用(如数据大屏、游戏、产品展示),或实现 复杂图形处理(如滤镜、特效),同时要求高性能渲染。


一、核心概念

1. WebGL 基础架构
  • 基于 OpenGL ES 2.0 的浏览器 API
  • 渲染管线
    顶点数据 → 顶点着色器 → 图元装配 → 光栅化 → 片元着色器 → 帧缓冲
    
  • 着色器:用 GLSL 语言编写(类 C 语法)
2. 核心对象
  • WebGLRenderingContext:渲染上下文
  • WebGLBuffer:数据缓冲区
  • WebGLProgram:着色器程序
  • WebGLTexture:纹理对象

二、实战代码示例

步骤 1:初始化 WebGL 上下文
<canvas id="glCanvas"></canvas>

<script>
const canvas = document.getElementById('glCanvas');
const gl = canvas.getContext('webgl');

if (!gl) {
  alert('浏览器不支持 WebGL');
}
</script>
步骤 2:创建着色器程序
// 顶点着色器
const vsSource = `
  attribute vec4 aVertexPosition;
  void main() {
    gl_Position = aVertexPosition;
  }
`;

// 片元着色器
const fsSource = `
  void main() {
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // 输出红色
  }
`;

function initShaderProgram(gl, vsSource, fsSource) {
  const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
  const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);

  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;
}
步骤 3:渲染三角形
function initBuffers(gl) {
  const vertices = new Float32Array([
     0.0,  0.5, 0.0,
    -0.5, -0.5, 0.0,
     0.5, -0.5, 0.0
  ]);

  const buffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
  gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

  return { position: buffer };
}

function drawScene(gl, program, buffers) {
  gl.clearColor(0.0, 0.0, 0.0, 1.0);
  gl.clear(gl.COLOR_BUFFER_BIT);

  const positionLocation = gl.getAttribLocation(program, 'aVertexPosition');
  gl.bindBuffer(gl.ARRAY_BUFFER, buffers.position);
  gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
  gl.enableVertexAttribArray(positionLocation);

  gl.drawArrays(gl.TRIANGLES, 0, 3);
}

// 初始化流程
const shaderProgram = initShaderProgram(gl, vsSource, fsSource);
const buffers = initBuffers(gl);
gl.useProgram(shaderProgram);
drawScene(gl, shaderProgram, buffers);

三、性能优化技巧

  1. 批处理绘制:合并多个物体的绘制调用
  2. 实例化渲染:使用 ANGLE_instanced_arrays 扩展
  3. 纹理压缩:使用 WEBGL_compressed_texture_etc 扩展
  4. 避免状态切换:集中设置全局状态(如混合模式)

四、常用库对比

库名称 特点 学习曲线
Three.js 功能全面,生态丰富 中等
Babylon.js 游戏开发友好,物理引擎集成 较陡
Regl 函数式 API,轻量级 较低
P5.js 创意编程友好,2D 优先

五、调试工具

  1. Chrome 开发者工具
    • Performance 面板分析渲染性能
    • WebGL Inspector 扩展查看渲染状态
  2. Spector.js:捕获和分析 WebGL 调用
  3. glMatrix:数学库辅助矩阵计算

六、注意事项

  1. 内存泄漏:及时删除不再使用的 buffers 和 textures
    gl.deleteBuffer(buffer);
    gl.deleteTexture(texture);
    
  2. 设备兼容性:检测 WebGL 版本和扩展支持
    if (!gl.getExtension('OES_texture_float')) {
      alert('不支持浮点纹理');
    }
    
  3. 移动端优化:降低分辨率,简化着色器

明日预告WebRTC —— 如何实现实时音视频通信?

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐