WebGL 初相识

763 阅读4分钟

楔子

怎么说,目前有点迷茫吧,鱼了很久都不知道后续的发展方向,感觉很难在有突破了(能体现在工作当中,作为能力象征的),思来想去也不知道接下来的路怎么走,那就换个赛道先学点皮毛再说吧,之所以选择 WebGL 一是以前稍微用过 three.js 做过点东西,二是这玩意门槛比较高,并且会的人相对较少。

Canvas

再说 WebGL 之前,先简单了解一下 Canvas ,Canvas 是 HTML5 的一部分,它是一个在浏览器中绘制 2D 图形的 API,相信这个大家都不陌生了,毕竟 HTML5 已经普及了很久,目前基本上都用的是 HTML5 协议,就算没具体使用过 Canvas 但是还是有一定的了解的。

这里也稍微写一个 Canvas 的用例:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <canvas id="canvas" width="400" height="400"></canvas>
        <script>
            // 获取 canvas 元素
            const canvas = document.getElementById('canvas') 
            
            // 获取 2D 绘图上下文,也就是常规理解下的(至少我是这么理解的) Canvas API
            const ctx = canvas.getContext('2d') 

            ctx.fillStyle = 'blue' // 绘制填充样式
            ctx.fillRect(150, 150, 100, 100) // 绘制矩形,入参分别代表 x, y, w, h
        </script>
    </body>
</html>

WebGL

WebGL 是基于 OpenGL ES 标准的 Web 图形库,它提供了在浏览器中进行 3D 图形绘制的能力,相较于 Canvas API ,WebGL 提供了更底层的能力,允许开发者直接操作 GPU 来实现更复杂和高性能的图形绘制效果,而且 WebGL 相对于 Canvas API 来说学习曲线更为陡峭,还需要对 图形学 和 渲染管线 有一定的了解。

WebGL 能做什么?

  • 数据可视化 - 交互式的动态数据图表,还能结合 3D 动画,来更好的展示
  • 图形/游戏引擎 - 游戏开发
  • 虚拟现实和增强现实 - WebVR 和 WevAR
  • 室内设计 - 例如装修,建筑设计等
  • 城市规划 - 可交互的城市的微缩模型
  • 物品展示 - 电商场景下和数字藏品等
  • 教育培训 - 模拟实验等

WebGL 的优势是什么?

这里个人理解 WebGL 最大的优势就是 Web (跨平台,灵活性高,只要有个浏览器基本都能用)。

WebGL 是基于 Web 标准的技术,可以在不同的操作系统和浏览器中运行,无需额外的插件或软件,也就是说只需要打开浏览器就可以访问和运行 WebGL 应用。同理只需要服务器上进行部署/更新 WebGL 工程,即可通过 浏览器 进行访问相应(最新)的 WebGL 应用,极其便利。

当然 WebGL 还有 高性能、3D 可视化、开放性的生态系统等优势。

WebGL2

WebGL2 是 WebGL 的升级版,WebGL2 扩展了 WebGL 的功能,并添加的许多的新特性,但是相对来说 WebGL2 存在一定的兼容性问题,当然大部分支持 WebGL 的浏览器基本都能支持 WebGL2

WebGL Hello Word

接下来用 WebGL 来写一个例子吧!

这里我们会用 WebGL 来实现上面 Canvas API 实现的案例,这里会用到 GLSL(OpenGL Shading Language)语言来编写着色器,不要着急不会 GLSL 我们一起慢慢来(我也不会)。

const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('webgl')

// 顶点着色器
const vertexShaderSource = `
    void main () {
        // 要绘制点的坐标
        // 这里的入参分别代表 x, y, z, w
        // 其中 w 代表的是齐次坐标
        // 下面的参数最终可以理解成 x/w, y/w, z/w
        gl_Position = vec4(0.0, 0.0, 0.0, 1.0); 
        gl_PointSize = 100.0; // 点的大小
    }
`

// 片元着色器
const fragmentShaderSource = `
    void main () {
        // 要绘制的颜色信息
        // 这里的入参分别代表 r, g, b, a
        gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0); 
    }
`

// 创建着色器
const vertexShader = ctx.createShader(ctx.VERTEX_SHADER)
const fragmentShader = ctx.createShader(ctx.FRAGMENT_SHADER)

// 指定着色器的代码
ctx.shaderSource(vertexShader, vertexShaderSource)
ctx.shaderSource(fragmentShader, fragmentShaderSource)

// 编译着色器
ctx.compileShader(vertexShader)
ctx.compileShader(fragmentShader)

// 创建程序对象
const program = ctx.createProgram()

// 绑定着色器
ctx.attachShader(program, vertexShader)
ctx.attachShader(program, fragmentShader)

// 将顶点着色器和片元着色器连接成一个可执行的程序
ctx.linkProgram(program)

// 将指定的程序对象设置为当前绘制的程序,可以理解为注册的意思?
ctx.useProgram(program)

// 执行绘制
// 入参分别是 要绘制的基本图元类型、从哪个顶点开始绘制、要绘制的顶点数量
ctx.drawArrays(ctx.POINTS, 0, 1)

效果如下图所示:

image.png

总结

内容不多,基本上也只是把 WebGL 的一些概念上的东西聊了一下,算是初步对 WebGL 有一个简单的了解,知道 WebGL 是个什么东西了,下一篇文章(如果有的话)会具体聊一聊上述 WebGL 例子中的代码,以及用到的 API。

代码用例的 地址