文章目录

  • 为什么需要纹理过滤
  • 过滤方法
    • 最近点插值法(Nearest-neighbor interpolation )
    • 最近点插值+mipmap的方式
    • 线性过滤+mipmap
    • 双线性过滤(Bilinear filtering)
    • 三线性过滤(Trilinear filtering)
    • 各向异性过滤(Anisotropic filtering)
    • 其他纹理过滤方法

在计算机图形学中,纹理过滤或者说纹理平滑是在纹理采样中使采样结果更加合理,以减少各种人为产生的穿帮现象的技术。纹理过滤分为放大过滤和缩小过滤两种类型。对应于这两种类型,纹理过滤可以是通过对稀疏纹理插值进行填充的重构过滤(需要放大)或者是需要的纹理尺寸低于纹理本身的尺寸时(需要缩小)的一种抗锯齿过滤。简单来讲,纹理过滤就是用来描述在不同形状、大小、角度和缩放比的情况下如何应用纹理。根据使用的过滤算法的不同,会得到不同等级的模糊、细节程度、空域锯齿、时域锯齿和块状结果。根据使用环境的不同,过滤可能是在软件或者专用硬件中完成,也可能是在软件和专用硬件中共同完成。对用大多数常见的可交互图形应用,现代的纹理过滤是使用专用的硬件进行完成。这些硬件通过内存缓冲和预提取技术优化了内存读写,并且实现了多种可供用户和开发者选择的过滤算法。

有多种纹理过滤方法,不同的方法在计算复杂度、内存带宽和图像质量上分别有不同的权衡。

为什么需要纹理过滤

对于任意的3D表面在纹理映射过程中,需要进行纹理查找来找到屏幕上的一个像素对应于纹理上的哪个位置。纹理映射的过程会根据目标点离相机的远近,占用屏幕上不同大小的范围的像素,例如一个三角面在距离相机20m时占用100个屏幕像素,当三角面离相机更远时会看起来更小,此时可能占用20个屏幕像素,但是在两种情况下这个三角面使用的纹理贴图的大小是不变的。换句话说,由于纹理化表面可以相对于观察者处于任意距离和朝向,因此一个像素通常不直接对应于一个纹理像素。必须应用某种形式的滤波来确定像素的最佳颜色。滤波不足或不正确将在图像中显示为伪像(图像中的错误),例如“阻塞”,锯齿状或闪烁。

屏幕的一个像素与它在对应的纹素之间可以存在不同类型的对应关系。这取决于纹理化表面相对于观察者的位置,并且在每种情况下都需要不同形式的过滤。给定映射到世界中的正方形表面的正方形纹理,在某个观看距离处,一个屏幕像素的大小与一个纹理像素完全相同。当观察者靠近时,纹素(纹理上一个颜色点)大小大于屏幕像素,需要适当放大 - 这一过程称为纹理放大。更远时,每个纹素大小小于一个像素,因此一个像素覆盖多个纹素。在这种情况下,必须通过纹理缩小来基于所覆盖的纹理元素拾取适当的颜色。图形API如OpenGL允许程序员为缩小和放大过滤设置不同的过滤方案。

注意,即使在像素和纹素是完全相同的大小的情况下,一个像素也不一定完全匹配一个纹素。它们可能未对齐或发生旋转,一个像素可能覆盖多达四个相邻纹素的部分。因此,仍然需要某种形式的过滤。

Mipmapping是一种标准技术,用于保存纹理缩小过程中所需的一些过滤工作。它对缓存一致性也非常有益- 没有它,从远距离纹理采样期间的存储器访问模式将表现出极差的局部性,即使没有执行滤波也会对性能产生不利影响。

在纹理放大时,需要为任何像素查找的纹素的数量总是四个或更少; 然而,在缩小时,随着纹理多边形移动得更远,潜在地整个纹理可能落入单个像素中。这将需要阅读所有它的纹素和它们的值组合以正确地确定像素颜色,这是一个非常昂贵的操作。Mipmapping通过预先过滤纹理并将其以较小的尺寸存储到单个像素来避免这种情况。随着纹理表面移动得更远,应用的纹理切换到预过滤的较小尺寸。mipmap的不同大小被称为“级别”,级别0是最大的级别(最接近观看者),并且随着距离增加,对应要增加mipmap等级。

过滤方法

下面列出了几种最常见的过滤方法,按照顺序,越靠后的运算开销越大,但采样结果效果也更好。

最近点插值法(Nearest-neighbor interpolation )

最近点插值法是最简单的纹理过滤方法 — 使用最接近采样点纹素作为采样结果的颜色。 简单的代价就是会产生很多人为现象 - 在放大观察时会有明显色块(马赛克),而缩小时会有闪烁和锯齿现象。这种方法在放大的情况下非常快,但是在缩小时开销却极高,因为屏幕上相邻的像素点,可能对应于纹理上距离很远的两个点,而这会破坏纹理采样时的内存连续性,导致L1或者L2缓存的命中率极低,使得纹理采样性能大大降低。

如上图可以看到大量的噪点,这些噪点在运行时则会表现为闪烁,因为噪点基本是随机的

最近点插值+mipmap的方式

这种方式在最近点插值的基础上,引入了mipmap,当距离相机很近时,使用miplevel0,此时和最近点插值完全一样。当距离下相机很远时,使用更高的miplevel等级,此时使用最近点插值采样更小尺寸的纹理。因此可以缓解缩小时的闪烁和锯齿现象,并且能够充分利用纹理采样时的内存连续性,使得纹理采样性能提高。但是在纹理放大时,不能解决产生的色块现象。

加了mipmap之后可以看到噪点消失,但是远处纹理明显模糊,而且不同mipmap过渡处有明显分界,而近处的纹理有明显锯齿

线性过滤+mipmap

OpenGL和其他图形API提供在单独的mipmap层级的贴图上进行最近点采样,但是会对两个相邻的mipmap等级的采样结果进行插值,作为最终结果。该方法很少使用

双线性过滤(Bilinear filtering)

双线性过滤对于锯齿问题会有一个很明显的提升。该方法中,采样目标点附近的4个纹素,并且根据权重(距离中心点的距离)进行加权平均。这种方法使得放大纹理时的色块现象得以消失,因为此时两个相邻像素之间是平滑过度的。当缩小纹理时可以结合mipmap进行使用,尽管当缩小很多时,依然会有和最近点过滤方法一样的锯齿和闪烁现象,但是对于大部分合理的缩小比例,可以作为一种开销较少的有硬件加速的纹理超采样方案。

相比最近点采样,可以看到近处纹理空间的锯齿明显消失,但是不同mipmap等级间的分界依然明显

三线性过滤(Trilinear filtering)

三线性过滤是对双线性过滤中当纹理距离相机的距离刚好处于两个mipmap等级的交界处时,会出现明显的一个过渡现象的解决方案(前图红框标记的地方)。通过对两个相邻的mipmap等级的纹理进行双线性过滤采样,并对两个采样结果线性插值得到最终的颜色。这样当纹理到相机的距离逐渐增加时,可以得到平滑的一个过渡,而不是突兀的变化。当然,对于足够近的纹理,因为使用miplevel0这个等级,因此和双线性过滤完全一致。

三线性过滤解决了mipmap过渡中的分界问题,但是对角方向上的纹理依然很奇怪,并且异常模糊

各向异性过滤(Anisotropic filtering)

到目前为止我们讨论的都是各向同性过滤方法,也就是说在纹理采样时,不考虑纹理的xy轴与屏幕的xy轴的角度,认为在任何角度时采样结果都是应该一致的(各向同性)。事实上,各向异性过滤是当前消费级显卡中的最高质量的过滤方法。各向同性方案只使用了正方形的mipmap来应用于双线性或三线性纹理过滤(各向同性是指在所有方向上都相同,用来描述所有的mipmap贴图都是方形而不是在某一个轴向上有压缩的长方形或者其他形状)。

上图各向异性mipmap图片存储模式(左),和各向同性mipmap存储模式

当一个物体的表面和相机有很大的夹角时,纹理在屏幕上的对应填充区域就不是方形的。例如一个地板,距离相机远的地方,填充区域的宽高是不对等的,此时方形的纹理贴图就不是很合适了,此时就会导致模糊或者闪烁或者两者皆有。各向异性过滤通过采样一个非方形纹理解决了这个问题。

使用各向异性过滤之后,纹理清晰度得到了很大的提升

上图三线性过滤和各向异性过滤的区别,可以看到远处的地面明显清晰很多。

其他纹理过滤方法

其他纹理过滤方法,因为硬件支持不广泛,很多算法中使用的是软件实现,因此Unity引擎默认没有支持,这里列举如下,欢迎补充:

  • bicubic filtering:http://vec3.ca/bicubic-filtering-in-fewer-taps/
  • Percentage Closer filtering:用于shadowmap采样

渲染的本质: 纹理过滤(Texture filtering)技术相关推荐

  1. 初识OpenGL (-)纹理过滤(Texture Filtering)

    1. OpenGL需要知道怎样将纹理像素(Texture Pixel,也叫Texel)映射到纹理坐标. 纹理坐标 不依赖于分辨率(Resolution),它可以是任意浮点值, 给模型顶点设置的那个数组 ...

  2. 【OpenGL】OpenGL入门之纹理(Texture)

    目录 纹理 纹理环绕方式 纹理过滤 多级渐远纹理(Mipmap) 加载与创建纹理 stb_image.h 生成纹理 应用纹理 纹理单元 参考 纹理   在此之前,我们已经可以为每个顶点添加颜色来增加图 ...

  3. OpenGL之纹理过滤(Texture Filtering)、MipMap方法、纹理坐标

    1.1 纹理过滤 像素.片元都是具有面积的,一个像素可能对应物体上的一小块区域,而物体上这个小区域对应于纹理图像上的一个小区域,因此一个像素的颜色可能来自于纹理中的一小个不规则区域,如果纹理的分辨率比 ...

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

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

  5. qnetworkreply 获取状态_谈谈Unity Shader中的采样器状态和(Texture Filtering)纹理滤波方式

    参考文章: 使用采样器状态 - Unity 手册​docs.unity3d.comhttps://blog.csdn.net/chenjinxian_3D/article/details/518169 ...

  6. spine 导出纹理_Spine 纹理打包Texture packing_官方文档中文版

    马上注册,加入CGJOY,让你轻松玩转CGJOY. 您需要 登录 才可以下载或查看,没有帐号?立即注册 x 本帖最后由 笑虾 于 2014-10-7 20:45 编辑 欢迎入群  Spine2D骨骼动 ...

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

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

  8. Spine之六——纹理打包Texture packing

    Texture packing总述(Overview) Spine 能帮你把分散的图片打包成一张完整的纹理贴图集或精灵表(spritesheet)以便在运行时更有效率的渲染.Spine 的纹理打包器( ...

  9. 虚拟纹理与几何图像技术

    虚拟纹理与几何图像技术 一. 基本图形学概念 图1. 几何与纹理. 曲面一般表示成三角网格和纹理图像,三角网格表示曲面的几何拓扑信息,纹理图像给出曲面的颜色材质等信息.将三角网格映射到平面区域的过程被 ...

  10. android纹理缓存,Android OpenGLES(七) 理解纹理与纹理过滤

    1.理解纹理 OpenGL中的纹理可以用来表示图像,照片,甚至由一个数学算法生成的分形数据.每个二维的纹理都由许多小的纹理元素组成,它们是小块的数据,类似于我们前面讨论过的片段和像素.要使用纹理,最常 ...

最新文章

  1. online_judge_1046
  2. C# 消息处理学习总结
  3. Linux基础入门学习笔记之二
  4. php 字符串 中文,php 中文字符串截取乱码
  5. 理解 C++ 的 Memory Order 以及 atomic 与并发程序的关系
  6. 我们都是孩子。』凄美的爱情青春
  7. sourceInsight4 破解笔记(完美破解)【转】
  8. 【代码源 Div1 - 108】#464. 数数(主席树,区间比k小的数的个数)HDU4417
  9. 人工智能和机器学习的前五门课程
  10. matlab2015使用dsolve错误,matlab - 当变量乘以常数时,dsolve中的错误(R2011a) - 堆栈内存溢出...
  11. 有效沟通bic法则_职场中5个有效沟通的法则
  12. 使用Git Bash实现Git代码上传加密
  13. 信号完整性分析中,普遍选用50Ω特性阻抗的原因
  14. Mac 从命令行启动模拟器
  15. 稀疏数组(二维数组)
  16. 震网三代 CVE-2017-8464 关于Powershell 漏洞复现
  17. item_get - 获得淘宝商品详情接口调用
  18. SAS杂谈--001--如何配置使用增强编辑器
  19. SQL:数据去重的三种方法
  20. 自学python(mac)之----读取文件

热门文章

  1. 7-27 冒泡法排序 (20分) Kotlin
  2. flutter之出现 List is not a subtype of type 问题
  3. 从零开始学习CANoe(二)—— CANdb++ 创建 dbc文件
  4. 【Linux】一步一步学Linux——hostid命令(246)
  5. The Porter Stemming Algorithm
  6. TeamViewer安全证书过期,解决办法
  7. python绘制隐含波动率曲面_如何用python计算隐含波动率
  8. 【VS Code 神奇小插件】Code Runner
  9. c语言简单的图案设计,分形艺术图案设计
  10. Android Studio设置签名密钥