一起学 WebGL:绘制一个点

开发 前端
WebGL 是浏览器支持的一种绘制图形的 API,是一个标准。我们可以通过 Canvas 元素在网页的特定区域绘制 2D 和 3D 图形。

大家好,我是前端西瓜哥。

本文讲解如何用 WebGL 绘制一个点。

WebGL

WebGL 是浏览器支持的一种绘制图形的 API,是一个标准。我们可以通过 Canvas 元素 在网页的特定区域绘制 2D 和 3D 图形。

相比 Canvas 2D,WebGL 利用了 GPU 的计算能力,绘制速度更快,性能更优。

WebGL 基于 OpenGL 发展而来,某种意义上就是 Web 版的 OpenGL,但是阉割了一些功能。

更具体点,是来自 OpenGL 的一个特殊版本 OpenGL ES 2.0,全称为 OpenGL for Embedded Systems,“用于嵌入式系统的 OpenGL”。

使用 WebGL,除了浏览器正统脚本语言 JavaScript,还要使用一种 名为 GLSL ES 的类 C  着色器语言。

绘制过程和着色器

将代码描述的效果真正绘制到屏幕上的过程,称为 渲染管线。

管线(pipeling)这个词有点奇怪,因为它没有对应的比较好的翻译,是一个直译。

管线指的是 数据处理的流水线,这个流水线上有很多处理器,会将数据一步步地进行处理,最终得到一个成品。渲染管线,就是渲染过程中执行的一个个步骤。

渲染管线的流程为:

  1. 顶点处理阶段。接收顶点信息,比如我要画一个三角形,三个点的位置在哪里,尺寸、颜色分别是多少。
  2. 图形装配。多个点组合成怎样的图形。我们会用 API 进行指定,比如点、线段、三角形。
  3. 光栅化。将顶点转换为需要绘制的像素信息,比如位置、深度。
  4. 片元处理阶段。设置像素的颜色信息。

这四个流程中,我们能操作的是第 1 和第 4 步。

绘制一个点

Demo 地址:

https://codesandbox.io/s/webgl-hui-zhi-yi-ge-dian-2-bpwz8p。

下面我们来讲解如何绘制一个点。

首先是 WebGL 绘制的地方 Canvas。我们需要在 HTML 中添加一个 Canvas 元素,然后在 JavaScript 中获取这个元素,并拿到 WebGL 渲染上下文。

const canvas = document.querySelector("canvas");
const gl = canvas.getContext("webgl");

如果你用过 Canvas 2D,它对应的上下文变量命名通常是 ctx(context)。但对于 WebGL,我们通常会跟随 OpenGL 的习惯,将变量命名为 gl(OpenGL 的 gl,Graphics Library 的意思)。

接着是顶点着色器。

顶点着色器,用于设置图形的顶点相关的信息,设置好顶点,WebGL 才能确定好图形的位置等信息,好绘制出来。

着色器的代码是在 JavaScript 脚本中,用字符串来写 glsl。

顶点着色器

先是顶点着色器。

const vertexShaderSrc = `
void main() {
gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
gl_PointSize = 20.0;
}
`;

gl_Postion 和 gl_PointSize 是 WebGL 顶点着色器的内部变量,用于设置点的位置和点的大小。

vec4 表示矢量类型,同时也是内置函数,调用它就能得到一个 vec4 类型。

这里设置了顶点的位置 (0.0, 0.0, 0.0, 1.0)。WebGL 使用的是三维坐标系,并使用右手坐标系,就是 x 轴指向右侧,y 轴指向上方,z 轴指向观察者。原点就在画布的正中央。

三维中,一个点只要三个维度 x、y、z 就够了,但引入了第四个维度 w,从笛卡尔坐标升维为齐次坐标,作用是方便做矩阵变换和透视投影。齐次坐标 ​​(x, y, z, w)​​​ 等价于三维坐标 ​​(x/w, y/w, z/w)​​。w 通常会设置为 1。

需要注意的是,着色器中的的数值需要加上小数点,表示用的是浮点数类型。这和 JavaScript 随便写都会变成浮点数不一样。

片元着色器

然后是片元着色器。

顶点着色器确定图形的点的位置,片元着色器则是用于设置多个顶点围成的图形的像素点的 颜色

const fragmentShaderSrc = `
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`;

gl_FragColor 是片元着色器的内部变量,这里设置为红色。

创建渲染器

因为是入门文章,细节不展开讲了。

总之下面这段代码,将前面声明的顶点着色器和片元着色器的两段源码,进行了编译。

/**** 渲染器生成处理 ****/
// 创建顶点渲染器
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSrc);
gl.compileShader(vertexShader);

// 创建片元渲染器
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSrc);
gl.compileShader(fragmentShader);

// 程序对象
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
gl.program = program;

清空缓存

gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);

首先第一行代码将背景色设置为黑色。当然你也可以设置为其他颜色,比如绿色 (0, 1, 0, 1)。

第二行是清空缓存区,填充背景色。

绘制点

gl.drawArrays(gl.POINTS, 0, 1);

该 API 用于调用绘制指令,有三个参数:

  1. mode。绘制怎样的图元。比如点(gl.POINTS)、各种类型的线段、各种类型的三角形。也就这三种图元。再复杂的图形也是由一个个三角形组成的。这里用到的微积分的思想,将三维物体不断的细分,其实就是一个个非常小的平面组成的,三个点确定一个平面,也就是三角形。正方形也是两个三角形组成。
  2. first。从哪个顶点开始绘制,通常是 0。本文只是画一个点,这个参数没太大意义,存在多个顶点时才有用,虽然也少用。
  3. count。使用到几个顶点。

绘制结果如下:

图片

结尾

下一篇画个三角形。

责任编辑:姜华 来源: 前端西瓜哥
相关推荐

2023-04-12 07:46:24

JavaScriptWebGL

2023-05-31 20:10:03

WebGL绘制立方体

2023-05-16 07:44:03

纹理映射WebGL

2023-04-13 07:45:15

WebGL片元着色器

2023-04-17 09:01:01

WebGL绘制三角形

2023-03-29 07:31:09

WebGL坐标系

2023-05-04 08:48:42

WebGL复合矩阵

2023-06-26 15:14:19

WebGL纹理对象学习

2023-04-26 07:42:16

WebGL图元的类型

2023-05-17 08:28:55

2023-03-02 07:44:39

pixijsWebGL

2023-04-27 08:27:29

WebGL变形矩阵

2023-02-22 09:27:31

CanvasWebGL

2022-11-29 16:35:02

Tetris鸿蒙

2022-12-02 14:20:09

Tetris鸿蒙

2023-05-08 07:29:48

WebGL视图矩阵

2023-03-30 09:32:27

2022-11-14 17:01:34

游戏开发画布功能

2022-09-28 13:57:41

鸿蒙开源

2022-11-25 16:48:54

鸿蒙Stage HAP
点赞
收藏

51CTO技术栈公众号