WebGL 点、线和三角
这个网站的使用三角绘制绝大多数内容。可以说 99% 的 WebGL 都在干这事儿。 但为了完整性,让我们看看其它情况。
在 第一篇文章 中提到了,WebGL 绘制点、线和三角。 当我们调用 gl.drawArrays 或 gl.drawElements 时 WebGL 进行绘制。 我们提供顶点着色器,它输出裁剪空间座标,调用 gl.drawArrays 或 gl.drawElements,根据第一个参数, WebGL 就会绘制点、线或三角了。
gl.drawArrays 或 gl.drawElements 第一个有效参数是:
-
POINTS对于每个顶点着色器输出的裁剪空间顶点,绘制以该顶点为中心的正方形。 正方形的大小,由设置在顶点着色器中的特殊变量
gl_PointSize决定, 它是预期的像素值。注意:正方形的最大(最小)值取决于 WebGL 的实现,可以通过下面代码查询:
- const [minSize, maxSize] = gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE);
也可以看 这里。
-
LINES对于每两个顶点着色器输出的裁剪空间顶点,绘制连接两个点的线。 如果我们有点 A、B、C、D、E、F,我们就得到了三条线。
规范指出,我们可以通过调用
gl.lineWidth并指定像素宽度来设置线的粗细。 尽管宽度的最大值取决于 WebGL 的实现,但通常大多数情况下最大宽度值为 1。- const [minSize, maxSize] = gl.getParameter(gl.ALIASED_LINE_WIDTH_RANGE);
这是因为在桌面 OpenGL 中 > 1 的值被弃用了。
-
LINE_STRIP对于每个顶点着色器输出的裁剪空间顶点,绘制连接到顶点着色器输出的前一个点的线。
所以,如果输出的裁剪空间顶点是 A、B、C、D、E、F,你会得到 5 条线。
-
LINE_LOOP这和
LINE_STRIP一样,但是多了从最后一个点到第一个点的线。 -
TRIANGLES对于每三个顶点着色器输出的裁剪空间顶点,绘制以这三个点为顶点的三角形。 这是最常使用的模式。
-
TRIANGLES_STRIP对于每个顶点着色器输出的裁剪空间顶点,绘制以最后三个点为顶点的三角形。 也就是说,如果输出了 6 个点 A、B、C、D、E、F,就会绘制 4 个三角形: A,B,C 和 B,C,D 和 C,D,E 和 D,E,F。
-
TRIANGLES_FAN对于每个顶点着色器输出的裁剪空间顶点,绘制以第一个点和最后两个点为顶点的三角形。 也就是说,如果输出了 6 个顶点 A、B、C、D、E、F,就会绘制 4 个三角形: A,B,C 和 A,C,D 和 A,D,E 和 A,E,F。
尽管有人不同意,但根据我的经验,TRIANGLE_FAN 和 TRIANGLE_STRIP 最好避免使用。 它们只适用一些特殊情况,而且需要额外的代码来处理,这并不值得。 尤其你可能使用工具来构建法线、生成纹理坐标或对顶点数据做其它处理。 仅仅使用 TRIANGLES 并没有什么问题。只要一开始添加 TRIANGLE_FAN 和 TRIANGLE_STRIP, 你就会需要更多的函数来处理更多的情况。 你可以不同意,按你的想法做。这只是我自身的经验,和一些我咨询过的 3A 游戏开发者的经验。
类似的 LINE_LOOP 和 LINE_STRIP 也不是很有用,它们有类似的问题。 就像 TRIANGLE_FAN 和 TRIANGLE_STRIP,使用它们的场景很少。 比如你想绘制 4 条连接着的线,每条线由 4 个点组成。
如果你使用 LINE_STRIP,每绘制一条线,就会调用 4 次 gl.drawArrays 和更多次的调用来设置属性。 而如果使用 LINES,你可以插入绘制 4 条线所需要的所有点,只调用一次 gl.drawArrays。 那会快非常多。
进一步来说,LINES 对于调试或简单的效果非常好用,不过多数平台给予它 1 像素的最大宽度,这不是个好方案。 如果想要为图形绘制网格,或者在 3D 模型程序中绘制多边形的轮廓,使用 LINES 是不错的选择。 但如果想要绘制结构化的图形,像 SVG 或者 Adobe Illustrator,就不行。 你需要 渲染线的其它方法,通常使用三角形。
浙公网安备 33010602011771号