NEAREST 和 LINEAR 的区别 白鹭的smoothing实现

case 10 /* SMOOTHING */:
gl.bindTexture(gl.TEXTURE_2D, data.texture);
if (data.smoothing) {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
}
else {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
}

OpenGL在放大图片时有两种方法,一种是最近点(NEAREST),一种是线性(LINEAR),

虽然在OpenGL里面,设置纹理参数的时候都称为过滤(filter),都通过glTexParameteri函数设置。

比如二维时,设置线性过滤:

glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR );

放大时实际算法为插值( interpolation)。

具体的 最近点过滤算法参考 , 线性过滤算法参考 。

简单的讲,最近点过滤算法就是用最靠近像素中心的那个纹理单元进行放大和缩小,效率更高,效果不好,锯齿严重。

线性过滤算法是对靠近像素中心的22纹理单元(二维时,三维为22*2),取加权平均值,用于放大和缩小。效果更好,效率稍低。(参看《OpenGL编程指南》第六版)

一般来说,我们常用Linear方式,但是Linear方式有个问题,那就是碰到边缘时怎么处理的问题,一种是取边缘外元素作为普通点进行加权计算,一种是不取。

前者表示“使用纹理中坐标最接近的一个像素的颜色作为需要绘制的像素颜色”,

后者表示“使用纹理中坐标最接近的若干个颜色,通过加权平均算法得到需要绘制的像素颜色”。

前者只经过简单比较,需要运算较少,可能速度较快,

后者需要经过加权平均计算,其中涉及除法运算,可能速度较慢(但如果有专门的处理硬件,也可能两者速度相同)。

从视觉效果上看,前者效果较差,在一些情况下锯齿现象明显,后者效果会较好(但如果纹理图象本身比较大,则两者在视觉效果上就会比较接近)。

具体效果可以看这个
https://wow.techbrood.com/fiddle/2716

在这里插入图片描述
在这里插入图片描述
最近滤镜(Nearest Filter)
第1个纹理的gl.TEXTURE_MAG_FILTER 和 gl.TEXTURE_MIN_FILTER 参数都被设置为gl.NEAREST。它表示当纹理被放大或缩小时(通常是通过缩放一个3D对象),WebGL需要使用一个滤镜(filter)来决定缩放后的一个给定点的颜色,在设定颜色时取原图中距离最近的点。如果纹理没有缩放,这个当然没问题,缩小时也还行。但是当放大时,会因为不连续而出现块状效应。但这个滤镜最简单,因此性能最好。

线性滤镜(Linear filter)
第2个纹理缩小和放大滤镜参数均设置为gl.LINEAR。对于纹理放大而言,线性滤镜取原图中相邻像素并使用线性插值获得中间值来填充新点的颜色,比如黑白像素之间插入灰度颜色点,这样显然会获得更好的平滑过滤。当然只要是图像放大,都会产生一定的模糊感,因为无论你怎么处理,都不可能和原图一样清晰。线性滤镜对于纹理缩小处理效果不佳。

多级纹理图(Mipmaps)
第3个纹理gl.TEXTURE_MAG_FILTER取值gl.LINEAR 而 gl.TEXTURE_MIN_FILTER取值gl.LINEAR_MIPMAP_NEAREST。

上述的线性滤镜能很好的处理纹理放大的情况,但对于纹理缩小的处理和最近滤镜是半斤八两。

假如WebGL场景中的一个立方体被放到较远的地方,只有当前窗口的1/10,最近滤镜和线性滤镜将使用原图中的10个像素来生成新的像素点,假如这是一个条纹质地的对象,那么就有1/10的几率会出现条纹色,而9/10的机率不出现条纹色。这就会导致纹理缩小后,有些条纹仍然显示,有些不显示,而且随着缩小比率的变化(持续缩小对象时),条纹也会随机变化呈现闪烁不定的视觉效果。

通过pageDown按键让它缩小,pageUp按键让它放大。默认使用纹理1,按“F”字母键,将切换到纹理2,再按“F”,切换到纹理3。

我们可能想通过计算原图周边10*10像素来获得新的纹理像素点,这样将会平滑得多,但实时执行这样的计算是昂贵的。这就是为什么我们要使用纹理3中的Mipmaps滤镜。

Mipmap滤镜通过预先生成一系列平滑过渡的辅助图像(称之为多级纹理图Mip Levels),比如1/2,1/4,1/8原图等等。每个mip level是上一级大图的平滑平均版本(即通过像素矩阵求平均)。当gl.TEXTURE_MIN_FILTER参数的值被设置为gl.LINEAR_MIPMAP_NEAREST时,我们告诉WebGL选择最接近的mip level并在它上面执行线性过滤得到新的纹理像素。

最后一行代码 gl.generateMipmap(gl.TEXTURE_2D);

告诉WebGL来生成多级纹理图(mipmap)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值