这是我参与8月更文挑战的第13天,活动详情查看:8月更文挑战
本文标题:WebGL第二十七课:贴图Mipmap| 8月更文挑战
友情提示
这篇文章是WebGL课程专栏的第27篇,强烈建议从前面开始看起。因为花了大量的工夫来讲解向量的概念和矩阵运算。这些基础知识会影响你的思维。
引子
上一次课,有一行代码,我们没有仔细讲解:
gl.generateMipmap(gl.TEXTURE_2D);
他肯定是有用的。我们这次课就专门来讲这玩意:Mipmap。
贴图的实际问题
我们知道,图片自己有 width * height。
而我们的 canvas 也有自己的 width * height。
我们想要画的形状更是有自己的大小,也不能会占用全部的canvas,比如画一个小小的正方形。
在这个正方形上,我们进行贴图。
假设正方形非常小,像素点只有几个:例如 2 * 2。
但是我们的图片非常大,比如说,512 * 512。
那么如果把这个贴图,锚定到这个小小的正方形上的时候,那肯定是不可能精细的展示出原有的图片的每一个像素的。
那怎么办呢,取平均值呗。
比如说,正方形 是 2 * 2 的。那么他一共有四个像素点。
正方形 左上角的像素点,用原有图片的左上角四分之一所有的像素点进行平均计算。
正方形 右上角的像素点,用原有图片的右上角四分之一所有的像素点进行平均计算。
正方形 左下角的像素点,用原有图片的左下角四分之一所有的像素点进行平均计算。
正方形 右下角的像素点,用原有图片的右下角四分之一所有的像素点进行平均计算。
这样的话,还是能够反映原有图片到底长什么样的。效果是没什么问题的。
那问题是什么呢:效率!!!!!
就平均计算这一步,就要遍历几千几万个像素点,求和,然后求平均值。
WebGL解决上述问题的办法:提前准备好小图片
上述问题就在于,我们要画的像素点,很小。
而给出的实际图片很大,需要遍历求平均值,耗费性能!
好的。
| WebGL说道: 你给我多准备几张图,大的小的都要,我自己根据实际画的像素点,去选择到底用你的大图还是小图进行采样!!!!!! |
| 程序员:美术不给我画,我惹不起 |
| WebGL说道:你个没用的家伙,连图都准备不全乎,你让我怎么画,你让我求平均值,求到死吗!! |
| 程序员:………………………… |
WebGL说道:算了,你给我一个大图,我给你生成几张小图出来!!!!!!调用gl.generateMipmap(gl.TEXTURE_2D)函数吧!!调用之后,其余的你就不用管了,小图自动就有了。 |
| 程序员:你这么厉害,你是怎么生成的啊,你里面还有一个美术吗? |
| WebGL说道:你懂个毛线,我需要美术吗,我就是把平均值计算那一步,先算好了,放到我显存里了,空间换时间,懂吗?????? |
| 程序员:大佬牛逼,服了。 |
| WebGL说道:记住了,这玩意就叫做 Mipmap |
| 程序员:好的! |
WebGL 生成 Mipmap 的细节
WebGL 的 generateMipmap 函数会帮你生成好几张小图,那么小图的尺寸是多少呢?
他是这样搞的,如果你的原图是 16 * 16 的话,那么
- 第 1 张小图: 8 * 8
- 第 2 张小图: 4 * 4
- 第 3 张小图: 2 * 2
- 第 4 张小图: 1 * 1
每一张图都是原来的 1/4。
就这么简单。
WebGL 选取 MipMap 的细节
WebGL 生成好了各个小图之后,连带你的大图一起。
到了真正需要画图,采样的时候,他会自己判断,canvas 像素点的尺寸 和 哪一张图片最贴合。然后自动选择这个图片进行采样。
当然,你还可以进行一些更为细节的控制:
比如说,如果两张图的尺寸都和要画的像素点的尺寸差不多的话,你甚至可以用两张图,来进行平均值。
这里面有一堆控制的模式,我不一一细讲,这个根据你自己的展现需求进行选择,具体的 api 请查询:
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, 某一个模式)
我们 注意一下 gl.TEXTURE_MIN_FILTER 这个参数:
这个参数的意思就是说,如果我们要画的像素的尺寸小于图片的原始尺寸,我们就用后面的某一个模式进行采样。
这某一个模式就包含了:
- gl.NEAREST
- gl.LINEAR
- gl.NEAREST_MIPMAP_NEAREST
- gl.LINEAR_MIPMAP_NEAREST
- gl.NEAREST_MIPMAP_LINEAR
- gl.LINEAR_MIPMAP_LINEAR
这么几种,具体的意思是什么,请诸位自行查阅官方文档。
扩展
如果我们要画的像素的尺寸小于图片的原始尺寸,我们可以用上述几种模式进行采样。
那么反过来呢?
要画的像素的尺寸,很大,而图片很小呢。
一样的:
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, 某一个模式)
此时,我们只能选择 gl.NEAREST 和 gl.LINEAR 两种模式了。
具体为什么,你了解这几种模式的细节就知道了。
正文结束,下面是答疑
小瓜瓜说:WebGL一个人承担了所有。
- 答:你也可以找美术画几个小图,WebGL也支持你自行上传小图。。。。。。