这是我参与「第五届青训营 」伴学笔记创作活动的第 14 天
初识 WebGL
Why WebGL / Why GPU
- WebGL(Web Graphics Library)是一种基于 JavaScript 和 OpenGL 的图形库,它允许在 Web 浏览器中实时渲染 3D 和 2D 图形,从而使网页能够呈现出更加复杂和丰富的交互式图形效果。 WebGL 利用了浏览器中的 HTML5 Canvas 元素,并将其与 OpenGL ES 2.0 API 结合使用,以实现在 Web 浏览器中进行高性能的图形渲染。它提供了一套强大的 API,包括着色器(shader)、纹理(texture)和缓冲区对象(buffer objects),使开发者可以使用类似于 OpenGL 的方式来创建和控制图形渲染。 WebGL 可以在任何支持它的现代 Web 浏览器中使用,而不需要任何插件或其他附加组件。它在游戏、虚拟现实、数据可视化等领域有广泛的应用,是 Web 开发中一个非常有用的工具。
Modern Graphics System
- 光栅 (Raster): 几乎所有的现代图形系统都是基于光栅来绘制图形的,光栅就是指构成图像的像素阵列。
- 像素 (Pixel) :一个像素对应图像上的一个点,它通常保存图像上的某个具体位置的颜色等信息。
- 帧缓存 (Frame Buffer): 在绘图过程中,像素信息被存放于帧缓存中,帧缓存是一块内存地址。
- CPU (Central Processing Unit) : 中央处理单元,负责逻辑计算。
- GPU (Graphics Processing Unit) : 图形处理单元,负责图形计算。
渲染流程:
- 轮廓提取
- 光栅化
- 帧缓存
- 渲染
WebGL Startup
- 创建 WebGL 上下文
- 创建 WebGL Program
- 将数据存入缓冲区
- 将缓冲区数据读取到 GPU
- GPU 执行 WebGL 程序,输出结果
创建 WebGL 上下文
const canvas = document.querySelector("canvas");
const gl = canvas.getContext("webgl");
function create3DContext(canvas, options) {
const names = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"];
if (options.webgl2) snames.unshift("webgl2");
let context = null;
for (let ii = 0; ii < names.length; ++ii) {
try {
context = canvas.getContext(names[ii], options);
} catch (e) {
// no-empty
}
if (context) {
break;
}
}
return context;
}
Vertex Shader
attribute vec2 position;
void main() {
gl_PointSize = 1.0;
gl_Position = vec4(position, 1.0, 1.0);
}
Fragment Shader
precision mediump float;
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
创建 WebGL Program
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertex);
gl.compileShader(vertexShader);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragment);
gl.compileShader(fragmentShader);
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
将数据存入缓冲区
const points = new Float32Array([-1, -1, 0, 1, 1, -1]);
const bufferId = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, bufferId);
gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);
将缓冲区数据读取到 GPU
const vPosition = gl.getAttribLocation(program, "position"); // 获取顶点着色器中的 position 变量的地址
gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0); // 给变量设置长度和类型
gl.enableVertexAttribArray(vPosition); // 激活这个变量
attribute vec2 position;
void main(){
gl_PointSize = 1.0;
gl_Position = vec4(position, 1.0, 1.0);
}
GPU 执行 WebGL 程序,输出结果
l.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, points.length / 2);
总结
WebGL 是一种用于在网页上呈现 3D 图形的技术,它允许开发者在浏览器中使用 JavaScript 和 OpenGL ES API 来创建交互式 3D 应用程序。
WebGL 的基础知识包括 WebGL 渲染流程、WebGL 坐标系统、WebGL 着色器等。WebGL 渲染流程的基本过程包括创建 WebGL 上下文、设置视口、清除画布、设置投影矩阵、设置模型矩阵、设置顶点属性指针、绑定着色器程序、绘制图形等步骤。WebGL 坐标系统采用的是右手坐标系,坐标原点位于画布中心,坐标范围为 [-1, 1],其中 x 轴向右,y 轴向上,z 轴垂直于画布向外。WebGL 着色器包括顶点着色器和片元着色器,其中顶点着色器负责对每个顶点进行计算和处理,而片元着色器则负责对每个像素进行计算和处理,二者共同决定了每个图元的最终呈现效果。
WebGL 有很多有趣的应用场景,比如游戏、虚拟现实、数据可视化等。通过学习 WebGL,我不仅了解一种新的技术,还了解了更广泛的计算机图形学和计算机科学知识。我相信,在不断的实践和学习中,我会更深入地理解 WebGL 技术,并能够将它应用于更多的实际项目中。 总之,学习 WebGL 是一个具有挑战性但也非常有趣和有价值的过程。