WebGL 学习笔记
埋了很久很久的坑,还是需要开始填了,记吧记吧~
挺好的 wenGL 教程: https://webglfundamentals.org/webgl/lessons/zh_cn/
基本概念
WebGL只关心两件事:裁剪空间中的坐标值和颜色值。使用WebGL只需要给它提供这两个东西。 你需要提供两个着色器来做这两件事,一个顶点着色器提供裁剪空间坐标值,一个片断着色器提供颜色值。
- 顶点着色器
- 片元(片段)着色器
顶点着色器:
1 | // 一个属性值,将会从缓冲中获取数据 |
片元着色器:
1 | // 片断着色器没有默认精度,所以我们需要设置一个精度 |
一个简单 webGL 示例
1 | /* eslint no-console:0 consistent-return:0 */ |
简单来说一个 webGL 创建显示的过程大体如下:
1 数据数据创建
- 创建顶点着色器与片断着色器
- 创建着色程序链接着色器(顶点着色器与片断着色器)
- 获取着色器定义的变量地址
- 创建缓存
- 绑定一个数据源到绑定点
- 通过绑定点向缓冲中存放数据
主要梳理下创建缓存和绑定数据的操作
1 | // Create a buffer and put three 2d clip space points in it |
这里的 gl.ARRAY_BUFFER
类似于 WebGL 内部的全局变量,将 positionBuffer
绑定到 gl.ARRAY_BUFFER
后面的对 ARRAY_BUFFER
其实就对 positionBuffer
的操作,有点类似 ARRAY_BUFFER = positionBuffer
;
而后的:
1 | gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW); |
其实就是往 positionBuffer
写入数据(顶点信息),gl.ARRAY_BUFFER
有点像代理,对 gl.ARRAY_BUFFER
的操作会映射到 positionBuffer
上。
2 渲染
- 设置渲染视口
- 清空画布
- 使用上一步创建的着色器程序
- 启用对应属性(声明的着色器变量)
- 指定从缓冲中读取数据的方式
- 指定绘制方式(点,线,三角形…)绘制
注意点:
一个隐藏信息是 gl.vertexAttribPointer
是将属性绑定到当前的 ARRAY_BUFFER,这里的操作类似于:
1 | gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset); |
positionAttributeLocation = ARRAY_BUFFER
这里 positionAttributeLocation 绑定到当前的 ARRAY_BUFFER,
而之前 ARRAY_BUFFER = positionBuffer
ARRAY_BUFFER 实际是绑定了 positionBuffer,
最终的结果类似:positionAttributeLocation = positionBuffer
。
canvas width
height
与 css 样式设置的 width
height
区别(类似 SVG 的视口)。
WebGL 裁剪空间的 -1 -> +1 分别对应到 x 轴的 0 -> gl.canvas.width 和 y 轴的 0 -> gl.canvas.height。
3 webGL 坐标变换
坐标的变化在顶点着色器中实现
webGL 的坐标系范围之前提到过在 (-1, 1) 之间,和数学书上的自然坐标系很像(咱不讨论 Z 轴),中点是 (0,0),上面为 Y 轴正负,左右 X 轴负正
而屏幕的坐标系:左上角为 (0,0) 下为 Y 正轴,右为 X 正轴,所以为了符合屏幕坐标系,直接使用像素单位,需要做个坐标的转换
具体操作如下,其实都是矩阵的变换
1 | attribute vec4 a_position; |