目录

WebGLFundamentals.org

Fix, Fork, Contribute

WebGL 点、线和三角

这个网站的使用三角绘制绝大多数内容。可以说 99% 的 WebGL 都在干这事儿。 但为了完整性,让我们看看其它情况。

第一篇文章 中提到了,WebGL 绘制点、线和三角。 当我们调用 gl.drawArraysgl.drawElements 时 WebGL 进行绘制。 我们提供顶点着色器,它输出裁剪空间座标,调用 gl.drawArraysgl.drawElements,根据第一个参数, WebGL 就会绘制点、线或三角了。

gl.drawArraysgl.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_FANTRIANGLE_STRIP 最好避免使用。 它们只适用一些特殊情况,而且需要额外的代码来处理,这并不值得。 尤其你可能使用工具来构建法线、生成纹理坐标或对顶点数据做其它处理。 仅仅使用 TRIANGLES 并没有什么问题。只要一开始添加 TRIANGLE_FANTRIANGLE_STRIP, 你就会需要更多的函数来处理更多的情况。 你可以不同意,按你的想法做。这只是我自身的经验,和一些我咨询过的 3A 游戏开发者的经验。

类似的 LINE_LOOPLINE_STRIP 也不是很有用,它们有类似的问题。 就像 TRIANGLE_FANTRIANGLE_STRIP,使用它们的场景很少。 比如你想绘制 4 条连接着的线,每条线由 4 个点组成。

如果你使用 LINE_STRIP,每绘制一条线,就会调用 4 次 gl.drawArrays 和更多次的调用来设置属性。 而如果使用 LINES,你可以插入绘制 4 条线所需要的所有点,只调用一次 gl.drawArrays。 那会快非常多。

进一步来说,LINES 对于调试或简单的效果非常好用,不过多数平台给予它 1 像素的最大宽度,这不是个好方案。 如果想要为图形绘制网格,或者在 3D 模型程序中绘制多边形的轮廓,使用 LINES 是不错的选择。 但如果想要绘制结构化的图形,像 SVG 或者 Adobe Illustrator,就不行。 你需要 渲染线的其它方法,通常使用三角形

有关于WebGL的疑问? 在Stackoverflow提问
有意见或建议? 在GitHub上提issue
comments powered by Disqus