转自:http://www.legalsoft.com.cn/docs/docs/17/267.html

 当你做纹理映射的时候,是否经常会注意到屏幕上显示出的那些明显锯齿,而且你用的纹理像素化得太明显了?现在,我们将谈论如何来解决这个问题,而我们使用的方法就是对你的纹理进行滤波。下面我们将介绍几种常用的滤波方法,最后再详细介绍双线性插值滤波的具体实现。
Bi-linear Interpolation
  双线性插值是通过对纹理中的相邻像素进行处理来平滑掉屏幕输出像素间的锯齿的。使用双线性插值会使屏幕输出的图像显得更平滑。下面先来看看它的基本计算公式。
double texture[N][M]; // x = [0, N), y = [0, M)
double xReal; // xReal = [0, N - 1]
double yReal; // yReal = [0, M - 1]
int x0 = int(xReal), y0 = int(yReal);
double dx = xReal - x0, dy = yReal - y0,
omdx = 1 - dx, omdy = 1 - dy;
double bilinear = omdx * omdy * texture[x0][y0] +
omdx * dy * texture[x0][y0+1] +
dx * omdy * texture[x0+1][y0] +
dx * dy * texture[x0+1][y0+1];
  观察这段公式,你会看出,我们很有效地使用了纹理座标的小数部分来对四个纹理中的相邻像素进行插值。我们按对应像素的距离来决定各个像素所占的权重。也就是说,当纹理的U座标的小数部分增加时,左边相邻像素的权重就会减少,减少出来的权重会增加右边的相邻像素上去。对垂直方向的V座标的情况也同此类似。
  在实际应用中,直接按这段公式来计算显然会很慢,你可以用定点整数和查表法来取消浮点和整型的混合运算以及去掉乘法。(提示:针对A、B两种颜色的混合建立 x*A+(1-x)*B 的结果表)
Mip-Mapping
  我第一次看到Mip-mapping技术是在游戏QUAKE里,而现在这种技术早已是随处可见了。这种技术是由Williams在1983年发明的,"Mip"这个名称起源于"multum in parvo",大概就是在一小块地方有很多东西的意思。
  具体说来,Mip-Mapping的思想就是构建一套纹理,总共需要大约1.3倍的内存。其中,每块子纹理是通过对父纹理过滤而得到,它的长和宽都是其父纹理的1/2,其面积为父纹理的1/4。接下来,在应用的时候,你根据距离选取最合适的一块来进行映射,实践证明,这种技术虽然简单,但对提高纹理映射的质量确实非常有效。
  通过Mip-Mapping,可以为较小的多边形映射上面积较小的纹理,这对减少纹理的扰动大有好处。举个例子,你有一块256x256大小的纹理,当它开始向远离观察者的方向开始移动时,你会看到它开始闪烁和颤动。这种现象的出现是因为我们把一大块纹理映射到一个很小的区域而引起的。你可能在上一帧时,画的是纹理中(50,20)处的像素,到了下一帧,却画的是纹理中(60,30)处的像素。如果这两个像素相差很大,你就会观察到前面所说的现象了。总的来说,这种剧烈的纹理座标的变化,会损害图像的品质,并且影响CACHE的效率,而Mip-Mapping无疑是解决这个问题的好办法。
Tri-linear Interpolation
  在介绍了双线性插值和Mip-Mapping以后,该来讲讲三线性插值了。其实三线性插值也很简单,它就是前两种技术的结合。它在对Mip-Mapping的每块纹理做双线性插值的同时,还要对Mip-Mapping中相邻的两块纹理按距离再做一次插值。既算出较大的一块纹理上的某点双线性插值像素值和较小的一块纹理上的某点双线性插值像素值,再按目标同两块纹理的距离做一次类似的插值。
  使用三线性插值,可以消除Mip-Mapping里纹理切换(既上一帧时用的是某个大小的一块纹理,而下一帧时又换了一块的情况)时的突然变化,从而可以提供很平畅的高质图像输出。
  同前两种技术相比,三线性插值的运算量非常大,目前只能依靠硬件来实现。
双线性插值纹理映射的实现
  下面,我们通过一段描述性代码来简单看看双线性插值纹理映射是如何实现的。
此处略去各种初始化代码,直接观察我们最关心的部分
其中:U和V是16.16格式的定点整数
du和dv是浮点数
du = (U & 0xFFFF) / 65536.0
dv = (V & 0xFFFF) / 65536.0
invdu = 1.0 - du
invdv = 1.0 - dv
// 根据到相邻四个像素的距离计算各自的权重
Weight1 = invdu*invdv
Weight2 = invdu*dv
Weight3 = du*invdv
Weight4 = du*dv
// 求得各个像素的RGB颜色分量
r00 = Texture[V >> 16][U >> 16].Red
g00 = Texture[V >> 16][U >> 16].Green
b00 = Texture[V >> 16][U >> 16].Blue
r01 = Texture[(V >> 16) + 1][U >> 16].Red
g01 = Texture[(V >> 16) + 1][U >> 16].Green
b01 = Texture[(V >> 16) + 1][U >> 16].Blue
r10 = Texture[V >> 16][(U >> 16) + 1].Red
g10 = Texture[V >> 16][(U >> 16) + 1].Green
b10 = Texture[V >> 16][(U >> 16) + 1].Blue
r11 = Texture[(V >> 16) + 1][(U >> 16) + 1].Red
g11 = Texture[(V >> 16) + 1][(U >> 16) + 1].Green
b11 = Texture[(V >> 16) + 1][(U >> 16) + 1].Blue
// 按权重混合RGB颜色分量
Red = Weight1*r00 + Weight2*r01 + Weight3*r10 + Weight4*r11
Green = Weight1*g00 + Weight2*g01 + Weight3*g10 + Weight4*g11
Blue = Weight1*b00 + Weight2*b01 + Weight3*b10 + Weight4*b11
// 按最后求得的RGB颜色分量画点
PutPixel(X, Y, Pack(Red, Green, Blue))
  这段代码显然未经优化(起码不要去用那个PutPixel),如果你程序功力不够,可能会无法达到理想的优化目标,这时你可以直接使用硬件去实现(新的3D硬件都能支援这些功能)。但我相信你在理解了双线性插值滤波的思想以后,一定能举一反三,利用它为你的游戏图像更添魅力。

线性插值(双线性)(三线性)相关推荐

  1. 三线性注意力采样网络——用于细粒度图像识别

    CVPR2019--论文链接 摘要 学习精细有区分度的特征(例如鸟喙和鸟的眼睛)在细粒度图像识别中起着十分重要的作用.现有的基于注意力的方法通过定位和放大重要部位来学习细粒度细节,但常常受到part数 ...

  2. 立方卷积插值 matlab,matlab旋转实现(最近邻值,双线性,三次卷积插值实现插值)

    数字图像处理,使用matlab实现旋转(最近邻值,双线性,三次卷积插值实现插值) 对图像进行旋转,使用最近邻插值法,双线性插值,三次卷积插值三种方法进行插值. 源码: clc;clear all;cl ...

  3. 《算法零基础100讲》(第59讲) 前缀和(三) 线性前缀和统计

    文章目录 零.写在前面 一.概念定义 1.问题引入 2.最坏时间复杂度 3.优化算法 二.题目描述 三.算法详解 四.源码剖析 五.推荐专栏 六.习题练习 零.写在前面   这是<算法零基础10 ...

  4. opengl 三线性和各项异性过滤

    概念 在纹理倾斜的时候如何设置边缘模糊,否则图像看起来会很怪异,对眼睛不适合,这个技术其实ffmpeg做得非常好,在合适的参属下,ffmpeg缩小会把这些做好. 各项异性过滤 Anisotropic ...

  5. 纹理过滤模式中的Bilinear、Trilinear以及Anistropic Filtering

    转载自:http://www.cnblogs.com/cxrs/archive/2009/10/18/JustAProgramer.html 1. 为什么在纹理采样时需要texture filter( ...

  6. 纹理基础知识和过滤模式详解

    转载自 纹理基础知识和过滤模式详解 1. 为什么在纹理采样时候需要 texture filter (纹理过滤) 我们的纹理 要贴到三维图形表面,而三维图形上的pixel中心与纹理上的texel中心并不 ...

  7. 纹理过滤中的双线,三线过滤

    2019独角兽企业重金招聘Python工程师标准>>> 为什么在纹理采样时需要texture filter(纹理过滤). 我们的纹理是要贴到三维图形表面的,而三维图形上的pixel中 ...

  8. mipmap以及滤波相关的理解

    pixel和texel不一致时出现,当texel不够时所产生的模糊现象(纹理太小) 解决方式:纹理滤波 Bilinear(双线性过滤) 给出的纹理坐标(纹素坐标)不是整数时,如何计算当前采样值 双线性 ...

  9. 各项异性滤波简介Anisotropic Filtering(AF)

    本文主要整理简绍来自互联网的各项异性滤波的知识. 原文链接:http://www.linuxgraphics.cn/graphics/using_anisotropic_texture_filteri ...

最新文章

  1. R语言ggplot2可视化气泡图:无填充色的气泡图、自定义填充色的气泡图
  2. javaWeb实现文件上传与下载 (转)
  3. sysbench压测服务器及结果解读(重点)
  4. python 彩票 遗漏值_荐Python遗漏知识点一
  5. Spring重试–与项目集成的方式
  6. Java 8:从PermGen到元空间
  7. Windows Server 2008 R2 安全加固
  8. STM32 MDK常见错误与解决
  9. Zerotier Moon服务器配置
  10. 非常经典的java编程题全集-共50题(11-30)
  11. Python爬虫实战|爬取视频
  12. 嵌入式方向的毕业生,找工作很迷茫
  13. 网站搭建之PHP安装教程
  14. 实验报告-Excel数据可视化
  15. 随便聊聊,关于大学,未来的规划
  16. 广告中的DSP、SSP和ADX
  17. linux cat命令缩写,linux下cat命令详解
  18. display、visibility和opactity的区别
  19. 服务器系统server2008 qq,WindowsServer2008R2服务器系统安装教程
  20. qq联合登陆失败 错误码100044

热门文章

  1. python 语音交互_Python调用WIN10语音交互+识别+控制+自定义对话
  2. HBase入门到精通——培训资料分享
  3. Ultra Mobile Paygo美国手机号教程
  4. 富文本关键字搜索高亮,解决方法及优化(收藏!)
  5. python 基本知识总结1
  6. java号码分身_电话号码分身问题
  7. 全国计算机c++考试,2018年全国计算机二级C++考试考什么内容
  8. mysql数据库设计工具_四种优秀的数据库设计工具
  9. 二进制分析工具自动发现DLL劫持漏洞
  10. 谈谈数据库里的时间戳