1、WebGL基础:WebGL是什么、WebGL与OpenGL的关系、WebGL的应用场景、第一个WebGL程序

WebGL到底是什么?

说实话,我第一次接触WebGL时也有点懵。它不是一个独立的图形库,而是JavaScript与OpenGL ES 2.0之间的一座桥梁。说白了,WebGL就是一套能在浏览器里直接调用GPU的API。

你想想看,以前想在网页上做3D效果,要么用Flash,要么得装插件。WebGL的出现彻底改变了这个局面——它不需要任何插件,浏览器原生支持。我2012年第一次在Chrome里跑通一个旋转的立方体时,那种感觉真的很奇妙。

WebGL的核心能力是什么?它允许JavaScript代码直接与GPU通信。你写一段着色器代码,传给GPU,GPU就在显卡上并行计算,把像素渲染出来。整个过程都在浏览器沙箱里完成,安全又高效。

关键点:WebGL不是用来画2D的,虽然它也能画。它的真正价值在于硬件加速的3D渲染。Canvas 2D API走的是CPU,WebGL走的是GPU,性能差距可能达到几十倍。

WebGL与OpenGL的关系

很多初学者会问:WebGL和OpenGL到底啥关系?我简单梳理一下。

OpenGL是桌面端的图形标准,由Khronos Group维护。它从1992年发展到现在,版本迭代了很多次。而WebGL是基于OpenGL ES 2.0(嵌入式系统版本)设计的。ES代表Embedded System,也就是嵌入式系统。

为什么会选ES版本?因为移动端GPU的算力有限,桌面OpenGL那一套完整的功能集太庞大了。ES版本砍掉了一些不常用的功能,保留了核心渲染管线。我当年从OpenGL转到WebGL时,最大的感受就是——API变少了,但核心逻辑没变。

特性 OpenGL WebGL
运行环境 桌面/服务器 浏览器
语言绑定 C/C++ JavaScript
版本基础 OpenGL 4.x OpenGL ES 2.0
着色器语言 GLSL GLSL ES
插件需求 不需要 不需要

嗯,这里要注意:WebGL 2.0对应的是OpenGL ES 3.0。如果你学过OpenGL,学WebGL会非常顺手。反过来也一样——WebGL学扎实了,转OpenGL也就是换个语言的事。

我的经验:我在项目中遇到过一个问题——桌面OpenGL里能用的纹理压缩格式,在WebGL里不一定支持。比如S3TC纹理压缩,在Windows上没问题,到了macOS的Safari里就挂了。所以做跨平台WebGL应用时,一定要先查兼容性表。

WebGL的应用场景

WebGL能做什么?我列几个常见的场景:

  • 数据可视化:大屏展示、3D散点图、地理信息可视化。我做过一个实时监控系统,用WebGL渲染几十万个数据点,帧率还能保持在60fps。
  • 在线3D编辑器:比如Three.js编辑器、Babylon.js沙盒。用户直接在浏览器里拖拽模型、调整材质。
  • 游戏开发:很多H5游戏、微信小游戏底层就是WebGL。像《球球大作战》这类游戏,渲染层用的就是WebGL。
  • AR/VR预览:WebXR标准基于WebGL,可以在浏览器里实现简单的AR效果。我试过用手机浏览器打开一个家具展示页面,AR模式直接看沙发摆在家里的效果。
  • 视频滤镜/特效:用WebGL做实时视频处理,比Canvas 2D快得多。B站的弹幕渲染底层也用了WebGL。

说白了,只要涉及大量像素计算、3D渲染、实时交互,WebGL都是首选方案。

第一个WebGL程序

好了,理论说完了,咱们直接上手写代码。第一个程序很简单——清空画布,设置一个背景色。

为什么从清空画布开始?因为WebGL的渲染流程就是:清空 → 绘制 → 显示。你想想看,如果不先清空,上一帧的画面会残留下来,造成画面混乱。

<!DOCTYPE html>
<html>
<head>
  <title>我的第一个WebGL程序</title>
</head>
<body>
  <canvas id="glCanvas" width="640" height="480"></canvas>
  <script>
    // 1. 获取canvas元素
    const canvas = document.getElementById('glCanvas');
    
    // 2. 获取WebGL上下文
    const gl = canvas.getContext('webgl');
    
    // 检查是否支持WebGL
    if (!gl) {
      alert('你的浏览器不支持WebGL!');
    }
    
    // 3. 设置清空颜色(RGBA)
    gl.clearColor(0.2, 0.3, 0.8, 1.0);
    
    // 4. 清空颜色缓冲区
    gl.clear(gl.COLOR_BUFFER_BIT);
  </script>
</body>
</html>

这段代码做了四件事:

  1. 找到canvas元素——WebGL需要一个画布来渲染
  2. 获取WebGL上下文——这是所有API调用的入口
  3. 设置清空颜色——我习惯用蓝色调,0.2, 0.3, 0.8是RGB值,1.0是不透明度
  4. 执行清空——把整个画布刷成蓝色

注意:getContext('webgl')在部分旧浏览器上可能返回null。我曾经在IE11上踩过这个坑——它只支持experimental-webgl这个前缀。所以生产环境最好加个降级处理:

const gl = canvas.getContext('webgl') || 
            canvas.getContext('experimental-webgl');

运行这段代码,你会看到一个640x480的蓝色画布。虽然只是纯色,但你已经成功调用了GPU!

为什么是蓝色?因为clearColor设置了(0.2, 0.3, 0.8)。RGB值范围是0到1,换算成0-255就是(51, 76, 204)。嗯,这个蓝色看起来挺舒服的。

小技巧:如果你看不到任何效果,打开浏览器的开发者工具,在Console里输入gl.getParameter(gl.VERSION),看看能不能返回WebGL的版本号。如果能,说明WebGL已经正常工作了。

第一个程序就这么简单。别着急,后面我们会一步步加上顶点、着色器、纹理……但今天先把基础打牢。你想想看,连GPU都能被你用几行JavaScript调动起来,是不是挺酷的?

下一章,我们会深入WebGL的渲染管线,看看从数据到像素,中间到底发生了什么。