这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战
本文标题:WebGL第二十五课:贴图的基础知识| 8月更文挑战
友情提示
这篇文章是WebGL课程专栏的第25篇,强烈建议从前面开始看起。因为花了大量的工夫来讲解向量的概念和矩阵运算。这些基础知识会影响你的思维。
引子
我们知道一张图片,就算很小,像素点也有成千上百个。
但是我们传入WebGL的顶点的个数,一般没这么多。
比如,用我们上次课的办法,画一个正方形的话,也就传入了12个点而已。(如果认为是四个点的,可以回到上次课先看一下,再品尝本次课的内容)
那么,如果我们需要将这个正方形填充一个图片,该怎么办呢。
我们总不能,一个像素点,就准备一个顶点吧,这样还不炸了。
所以说,还是要回顾一下WebGL画三角形的原理:
-
- 将三角形的三个点定好位置
-
- 将三个点根据传入的颜色,或者根据shader中的颜色,将点画出来
-
插值(重点就是这一句)
插值深入讲解
两点插值
什么叫两点插值?也就是说,现在有两个点: A(xA,yA) 和B(xB,yB)。
点A的颜色用RGB来表示就是(1,1,1), 也就是纯白色。
点B的颜色用RGB来表示就是(0,0,0), 也就是纯黑色。
问题来了,将AB连接起来,问AB线段上任意一点的颜色是什么?
我们用我们朴素的感觉去得出结论:
近朱者赤近墨者黑, 也就是 近A者白 近B者黑
具体的式子就不列出来了,等到用到的时候,再列。
三点插值
这个就要稍微花点时间来说说了。假设有三个点: ABC,颜色分别是:红 绿 蓝。
就像下图这样:

好了,那么这三个点,组成的三角形内部,任意一点,比如说吧,我们搞一个点D出来,那么这个点D,如果用插值的话,应该是什么颜色呢?

先给出一个比较有意思的结论:
如果ABC三个点的坐标分别是
(xAyA)(xByB)(xCyC)
如果 D 点的坐标
(xDyD)=a∗(xAyA)+b∗(xByB)+c∗(xCyC) (式1)
那么 D 点的颜色
D颜=a∗A颜+b∗B颜+c∗C颜 (式2)
也就是说:我们找到 三个数 a b c。如果这三个数能够将ABC的坐标组合成D点的坐标,那么D点的颜色,也就是这三个数将ABC的颜色进行组合。
用矩阵来表达一下 式1, 也就是D点坐标的得出:
(xDyD)=(xAyAxByBxCyC)∗⎝⎛abc⎠⎞
用矩阵来表达一下 式2,也就是D点颜色的得出:
⎝⎛RDGDBD⎠⎞=⎝⎛RAGABARBGBBBRCGCBC⎠⎞∗⎝⎛abc⎠⎞
从形式上来讲,但凡是ABC三个点拥有的东西,不管你是坐标,还是颜色,还是别的什么东西,全部都可以用abc这三个数进行组合。
ABC三个点的温度分别是 1℃, 30℃, 50 ℃。已知D点坐标:
(xDyD)=(xAyAxByBxCyC)∗⎝⎛abc⎠⎞
问:如果用插值算法的话,那么D点的温度应该是多少?
答:我们用abc三个数进行组合。
(温度D)=(温度A温度B温度C)∗⎝⎛abc⎠⎞=a∗1+b∗30+c∗50
采样信息:UV
要知道,我们本次课的目的,并不是简单的合成一个颜色。
而是要在中间填充一个图片。
这势必要增加一个步骤,就是我们传入WebGL的点,到底跟图片本身是怎么对应的。
我们知道一个图片,就是一个 width * height 的矩形区域。
我们把这个矩形区域的
-
左下角看做原点(0,0)
-
右上角看做(1,1)的话
那么中间任意一个地方,都有一个坐标,我们把这个坐标写成(u, v)。
例如,
- 图片中心的 (u, v) = (0.5, 0.5)
- 左上角的 (u, v) = (0, 1)
- 右下角的 (u, v) = (1, 0)
也就是说,任意一个(u,v)都能够在一个图片上,找到一个位置,而这个位置肯定有图片本身的RGB颜色信息。
我们就是这样来指定一个坐标点的图片信息的,这个信息就是UV信息。
例如,A 点的(u,v) = (0,0), 那么,A点采样的时候,就是在图片的左下角进行采样。
例如,B 点的(u,v) = (0,1), 那么,B点采样的时候,就是在图片的左上角进行采样。
例如,C 点的(u,v) = (1,1), 那么,C点采样的时候,就是在图片的右上角进行采样。
那么假如 有一点D,D点的坐标:
(xDyD)=(xAyAxByBxCyC)∗⎝⎛abc⎠⎞
那么D点的(u,v)是多少呢?根据上面一小节,三个数插值的算法得出:
(UDVD)=(UAVAUBVBUCVC)∗⎝⎛abc⎠⎞
好了,现在D点的(u,v)出来了,那么相应的,D点也可以在图片上,找到一个点,进而进行采样了。
结论
WebGL画三角形的时候,如果我们同时提供了图片和坐标点的UV信息,那么一个三角形中其他的点的UV信息,就是可以插值出来,有了UV信息之后,就可以在图片上进行采样了,然后,三角形内部就可以被图片上采样到的颜色进行填充了。
正文结束,下面是答疑
小能能说:还行,比较好理解,下次课是不是要搞实践,也就是搞一搞代码?
- 答:对, 这一次课就是来讲原理,下一次课会放出代码。