上节我们通过三角形的绘制方式,了解到 WebGL 开发的基本要素,以及如何通过缓冲区向着色器传递数据。本节我们学习最后一种基本图元线段
。
本节内容虽然简单,但是我仍然想向那些钟爱 WebGL 的新手同学们详细地讲解一下,毕竟这是 WebGL 知识体系中的一部分,有经验的同学可以略过哈~
目标
本节通过鼠标点击动态绘制线段的示例,学习线段图元的分类以及绘制特点,效果如下:
线段图元的分类
线段图元分为三种:
- LINES:基本线段。
- LINE_STRIP:带状线段。
- LINE_LOOP:环状线段。
接下来我们还是以实战为主,练习线段图元的绘制,并介绍他们之间的区别。
LINES 图元
LINES 图元称为基本线段图元,绘制每一条线段都需要明确指定构成线段的两个端点。
我们还是通过每次点击产生一个点,并将点击位置坐标放进 positions 数组中。
注意,我们的坐标还是相对于屏幕坐标系,顶点着色器中会将屏幕坐标系转换到裁剪坐标系,也就是坐标区间在[-1, 1]之间。
var positions = [];
canvas.addEventListener('mouseup', e => {
var x = e.pageX;
var y = e.pageY;
positions.push(x);
positions.push(y);
if (positions.length > 0) {
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array(positions),
gl.DYNAMIC_DRAW
);
render(gl);
}
});
之后进行绘制,注意执行 drawArrays 时,图元参数应该设置为 gl.LINES。
gl.drawArrays(gl.LINES, 0, positions.length / 2);
可以看到,每次点击两次之后才能绘制一条新的线段,也就是说,采用 gl.LINES 进行绘制的话,必须制定两个端点坐标。
基本线段图元的绘制比较简单,我们看一下带状线段
的绘制特点。
LINE_STRIP
LINE_STRIP
图元的绘制特点和 LINES
的有所区别,在绘制线段时,它会采用前一个顶点作为当前线段的起始端点。我们还是通过一个例子理解一下。
依然采用上面的代码,只不过这次在绘制时,将图元设置为 LINE_STRIP:
gl.drawArrays(gl.LINE_STRIP, 0, positions.length);
可以看到,除了第一条线段需要指定两个端点,之后每次点击一个新的点,都会自动绘制一条新线段,新线段的起点是上一个线段的终点。
LINE_STRIP 也比较简单,接下来看下环状线段LINE_LOOP
的特点。
LINE_LOOP
顾名思义,环状线段除了包含 LINE_STRIP 的绘制特性,还有一个特点就是将线段的终点和第一个线段的起点进行连接,形成一个线段闭环。
废话不多说,看下效果大家就明白了。
注意,不要忘记将绘制图元更改为
LINE_LOOP
。
gl.drawArrays(gl.LINE_LOOP, 0, positions.length);
回顾
线段图元的绘制方式到此就结束了,比较简单。我们可以用线段做路线标注,也可以用它绘制一些线状图形,再加上一些动画做出有创意的效果。
事实上,webgl 的知识是有限的,但是我们的创意是无限的,有的时候并不需要技术多牛逼,只要创意够好,简单的技术也能实现让人惊艳的效果。
题外话:我一直觉得我的想象力是很差的,有时候还不如自己三岁的女儿。在做这个 demo 的时候,我女儿的一次胡乱点击,让我大吃一惊,她的绘制路径像极了一个五角星,我在此大致还原了一下她的点击路径:
一个胖胖、扁扁的的五角星,PS:偷笑。
下一节进入本节的一个重点,我会通过绘制渐变三角形
来带大家深入学习顶点缓冲区
的使用,并解答第三章节的三个遗留问题。