WebGL第二课:写一个圆

1,604 阅读5分钟
本文标题:WebGL第二课:写一个圆

上节课的结尾,有一位热心读者提出来一个问题: 在屏幕中间,画一个半径是1的圆
关于这个问题,我们这节课就来完成这个小目标。
如果给我一支真实的笔,我能立即马上顷刻间完成这个小目标,太简单了。因为我们人类都能听懂这个目标:屏幕中间半径为1
但是 WebGL 这家伙可听不懂这种描述,我们要更加数学化一点。WebGL 其实就想知道一个事情:在什么(x y)像素,画什么(r g b)颜色
好,我们试图来用数学语言描述这个目标:

有点难,因为一个圆所涵盖的像素点,可不止一个。。。。。。隐隐的感觉告诉我们,
我们需要在屏幕上画圆的话,肯定是画一堆点,然后从远处看起来,就好像一个圆而已

就像下面这样:

很明显,我们在屏幕上画的点越多,这个圆就越完美。好的,我们先不管这个完美度,我们接着来描述我们的这个圆:

假设,我们的笔是黑色的,也就是说,在这些点的地方,我们的颜色都是RGB(0, 0, 0)。
然后,我们只要将这些点的坐标,全部列出来就好了。我们像下面这样来写出来:
xy(1,0) --> RGB(0,0,0)
xy(0,1) --> RGB(0,0,0)
xy(-1,0) --> RGB(0,0,0)
xy(0,-1) --> RGB(0,0,0)
xy(0.5,0.866) --> RGB(0,0,0)
...
...
...
上面我只写了五个坐标,并标明,这些坐标的颜色都是RGB(0,0,0) 黑色。
如此一来,将上面这种数据传给 WebGL,就能得到相应的画面了。
你传给 WebGL 几个坐标,WebGL就会画几个点,你传的越多,就越完美。就这么简单。

当然,WebGL 只是笔而已,我们下面来讲讲我们的纸,也就是屏幕,或者更精确一点,一个 WebGL canvas

还是用画画来做例子吧,你有一只笔,你桌子上有两张纸,那么你到底在哪张纸上画画呢? 当然随你了,WebGL 也是这样,一个网页里,可以共存很多 canvas(纸)。想在哪里画就在哪里画。

我们观察一下上面的坐标,发现一个现象: xy(0.5,0.866) --> RGB(0,0,0),出现了小数。 这很奇怪了,屏幕的像素点不是整数吗,坐标不应该是(300,200)这种风格的吗,怎么出现了小数呢。
小数当然是用来做相对性的啦~我们现在就来精确描述一下一个canvas的坐标轴:

从左到右 x 从 -1 到 1。
从下到上 y 从 -1 到 1。
不管你的屏幕像素点是多少的,都用这个来相对性表示坐标,而不用真正的像素坐标。
就像下面这两幅图这样:

(图2.2) 200 * 200 canvas 上,半径是1,颜色是黑色的圆,用了38个点来模拟

(图2.3) 600 * 300 canvas 上,半径是1,颜色是黑色的圆,用了38个点来模拟

小伙伴们应该已经发现,我们将同样的数据,给同样的 WebGL,但是如果 canvas 的尺寸不一样,那么画出来的效果也是不同的。
很明显,600 * 300 的 canvas 上已经成了椭圆了。这是因为,我们给出的坐标不是像素,而是相对位置。

为了巩固这个知识点,我们不妨来在600 * 300的 canvas 上画几个坐标试试:

// 下面的这些坐标,会出现在 600 * 300 的 canvas 的什么位置呢?
1. (0.5, 0.5)  --> RGB(1, 0, 0) // 红色
2. (-1, -1)    --> RGB(0, 1, 0) // 绿色
3. (0.9, -0.5) --> RGB(0, 0, 1) // 蓝色
好吧,下面的图就是答案(四周的点还是那个半径为1的圆,颜色为黑):为了表示的清楚一些,这三个点画得更大一些

(图2.4) 600 * 300 canvas 上,38点黑色圆,外加三个点
上面的图中,最左下角的绿色的点快看不见了,因为它刚好在最边缘(-1, -1)
仔细思考这几个点为什么出现在那些位置,这至关重要,这就是 WebGL 所做的一切,在什么坐标点,画什么颜色




本文正文结束,以下是答疑部分
小瓜瓜问:我还是不会,因为你根本就没有给我一个能跑的程序。。
  • 答:稍安勿躁,一步一步地把所有关键点厘清才是学习之道啊。
小丫丫问:这篇课程里的图片是 WebGL 画出来的点吗,总是有点不太清楚,我们能画的最小单位到底是什么,为什么能控制点的大小?
  • 答:这是一个好问题,本文的后面几张图,确实是 WebGL 的代码画的。你能控制的最小单位不是像素,而是坐标,一个坐标对应了多少像素,大部分时候我们不用关心。 WebGL 确实能控制点的大小。但实际上,本文图中的所有的点,实际上是一个个下图中的多边形缩小而来的:

(图2.5) 用来模拟点的多边形
也就是说,本文的图,画的不是点,而是一个个多边形。

小丫丫问: 为什么使用这个多边形,而不用 WebGL 直接画点?
  • 答:这里只是在讲解原理而已,后面我们会直接使用 WebGL 来画点的。
小丫丫问: WebGL 能画多边形?我们又是如何以数学的方式来告知 WebGL 去画多边形的呢?
  • 答:WebGL 能画三种基本图形 线三角形。而上图的多边形,其实是一个一个更小的三角形拼出来的。拿三角形做例子吧:三角形核心数据是三个点,对吧,所以首先你要把三个点的坐标传进 WebGL 里面,然后只要告诉 WebGL 将这三个点连起来就行了。
小能能问:连起来就行了吗?那用什么颜色呢?中间是涂色还是不涂色呢?如果涂色的画,我能逐一控制每一个坐标的颜色吗?或者我要用自己上传的图片来填充中间的区域? 这些东西,我怎么告诉 WebGL 呢?
  • 答:当当当,上课不许拖堂!!!下课!!!