深入解析纹理贴图——纹理过滤及MipMap技术

作者:STANCH

1.纹理过滤概述

当纹理被应用到三维物体上时,随着物体表面的形状和相机视角的变化,会导致纹理在渲染过程中出现一些问题,如锯齿状边缘、失真、模糊等。

纹理过滤的作用是解决这些问题,以获得更好的渲染效果。其目的是在纹理被应用到三维模型上时,通过对纹理上的像素进行插值或采样,使得纹理在不同距离和角度下呈现出更平滑、更真实的外观。

原始图片(左)和贴图到三维表面失真现象(右),来源:fundamentals-of-computer-graphics-4th

2.为什么需要纹理过滤

对于任意的3D表面在纹理映射过程中,需要进行纹理查找来找到屏幕上的一个像素对应于纹理上的哪一个纹素(纹理上一个颜色点)。纹理映射的过程会根据目标点离相机的远近,占用屏幕上不同大小的范围的像素,例如一个三角面在距离相机20m时占用100个屏幕像素,当三角面离相机更远时会看起来更小,此时可能占用20个屏幕像素,但是在两种情况下这个三角面使用的纹理贴图的大小是不变的。

屏幕的一个像素与它在对应的纹素之间可以存在不同类型的对应关系。这取决于纹理化表面相对于观察者的位置,有两种情况:

  • 每个纹素映射到多个像素,这被称为放大(magnification)
  • 每个纹素映射少于一个像素,这被称为缩小(minification)

比如,给定映射到世界中的正方形表面的正方形纹理,假设在某个观看位置,一个屏幕像素的大小与一个纹理像素完全相同。当观察者靠近时,纹素大小大于屏幕像素,需要适当放大。更远时,每个纹素大小小于一个像素,因此一个像素覆盖多个纹素。在这种情况下,必须通过纹理缩小来基于所覆盖的纹理元素拾取适当的颜色。

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

3.多级渐远纹理(Mipmap)

假设我们有一个包含着上千物体的大房间,每个物体上都有纹理。有些物体会很远,但其纹理会拥有与近处物体同样高的分辨率。由于远处的物体可能只产生很少的片段,OpenGL从高分辨率纹理中为这些片段获取正确的颜色值就很困难,因为它需要对一个跨过纹理很大部分的片段只拾取一个纹理颜色。在小物体上这会产生不真实的感觉,更不用说对它们使用高分辨率纹理浪费内存的问题了。

多级渐远纹理(Mipmap)的概念来解决这个问题,它简单来说就是一系列的纹理图像,后一个纹理图像是前一个的二分之一(纹理图像的尺寸必须为2幂次方)。假设我们有一个正方形的纹理贴图,分辨率为512x512像素。该纹理贴图用于映射到一个距离相对远的平面上。它们旨在提高渲染速度并减少锯齿伪影。高分辨率 mipmap 图像用于高密度样本,例如靠近相机的物体;当物体看起来较远时,使用较低分辨率的图像。

来源:JoeyDeVries

在没有Mipmap的情况下,如果我们直接将512x512的纹理贴图映射到远处的平面上,由于远处的像素数量较少,会导致纹理缩小的情况。这可能会导致失真和锯齿效应。

现在,我们使用Mipmap来优化纹理过滤。根据Mipmap的原理,我们生成一系列不同分辨率的图像,每个级别是前一级别的一半分辨率。假设我们生成了以下级别的Mipmap纹理:

Level 0: 512x512
Level 1: 256x256
Level 2: 128x128
Level 3: 64x64
Level 4: 32x32
Level 5: 16x16
Level 6: 8x8
Level 7: 4x4
Level 8: 2x2
Level 9: 1x1

在渲染过程中,当我们将纹理映射到远处的平面上时,根据距离和像素数量,我们选择最接近所需分辨率的Mipmap级别进行插值。

假设远处的平面上每个像素区域相当于纹理上的4x4像素区域。在这种情况下,Level 7的分辨率是4x4,因此,应该使用Level 7的Mipmap级别进行插值计算,将Level 7的纹理映射到远处的每个像素上。

4.纹理过滤技术

  • 最近点采样(Nearest Point Sampling)

在放大和缩小过程中,最近点采样算法选择中心点最接近纹理坐标的那个像素。下图中可以看到四个像素,加号代表纹理坐标。左上角那个纹理像素的中心距离纹理坐标最近,所以它会被选择为样本颜色:

来源:JoeyDeVries

  • 双线性过滤(Bilinear)

双线性过滤算法通过对目标像素周围的四个最近纹理像素进行加权平均,计算出一个插值,近似出这些纹理像素之间的颜色。一个纹理像素的中心距离纹理坐标越近,那么这个纹理像素的颜色对最终的样本颜色的贡献越大。下图中返回的颜色是邻近像素的混合色:

来源:JoeyDeVries

那么这两种纹理过滤方式有怎样的视觉效果呢?让我们看看在一个很大的物体上应用一张低分辨率的纹理会发生什么吧(纹理被放大了,每个纹理像素都能看到):

来源:JoeyDeVries

最近邻插值产生了锯齿状的边缘和马赛克效果,但我们能够清晰看到组成纹理的像素,而双线性插值能够产生更平滑的图案,但很难看出单个的纹理像素,会比较模糊。

  • 三线性过滤(Trilinear)

三线性过滤是对双线性过滤中当纹理距离相机的距离刚好处于两个mipmap等级的交界处时,会出现明显的一个过渡现象的解决方案(下图红框)。三线性插值在双线性插值的基础上再进行了一次线性插值,最接近的两层Mipmap 层级分别进行双线性过滤,然后再对两层得到的结果进生线性插值。这种方法在处理近大远小的纹理映射时能够提供更好的质量和平滑度。

双线性过滤(左),和三线性过滤(右),来源:https://blog.csdn.net/u013746357/article/details/90723268

  • 各向异性过滤(Anisotropic Filtering)

在纹理采样时,需要贴图的三维表面平行于屏幕,则是各向同性的。当要贴图的三维表面与屏幕有一定角度的倾斜,则是各向异性的,上面过滤方法都是各向同性过滤方法。事实上,各向异性过滤是当前消费级显卡中的最高质量的过滤方法。各向同性方案只使用了正方形的mipmap来应用于双线性或三线性纹理过滤(各向同性是指在所有方向上都相同,用来描述所有的mipmap贴图都是正方形而不是在某一个轴向上有压缩的长方形或者其他形状)。各向异性过滤通过改变纹理采样的方式,使得在视线方向附近的纹理细节得到更高质量的采样,而在远离视线方向时则采样较低质量的纹理。这样可以提高纹理的清晰度和真实感,特别是在斜视角或观察远处物体时。

各向同性Mipmap存储模式(左),各向异性Mipmap图片存储模式(右),来源: 维基百科

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

三线性过滤(左),和各向异性过滤(右),来源:techbrood

LearnOpenGL - Textures

渲染的本质: 纹理过滤(Texture filtering)技术-CSDN博客


 关注Mapmost,持续更新GIS、三维美术、计算机技术干货

Mapmost是一套以三维地图和时空计算为特色的数字孪生底座平台,包含了空间数据管理工具(Studio)、应用开发工具(SDK)、应用创作工具(Alpha)。平台能力已覆盖城市时空数据的集成、多源数据资源的发布管理,以及数字孪生应用开发工具链,满足企业开发者用户快速搭建数字孪生场景的切实需求,助力实现行业领先。

欢迎进入官网体验使用:Mapmost——让人与机器联合创作成为新常态

  • 18
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenGL纹理精简技术是一种优化渲染性能的技术,它通过减少不必要的纹理贴图,降低纹理分辨率等方式,来提高渲染效率。本文将介绍OpenGL纹理精简技术的使用方法,包括以下内容: 一、选择适合的纹理格式 OpenGL支持多种纹理格式,如GL_RGB、GL_RGBA、GL_LUMINANCE等。在选择纹理格式时,需要考虑到纹理的大小和颜色深度,以及对渲染性能的影响。一般情况下,如果纹理不需要透明度,可以选择GL_RGB格式,如果需要透明度,可以选择GL_RGBA格式。对于灰度纹理,可以选择GL_LUMINANCE格式。较低的颜色深度可以降低纹理的大小和渲染的开销。 二、压缩纹理 OpenGL支持多种纹理压缩格式,如S3TC、ETC等。这些格式可以将高质量的纹理数据压缩成更小的大小,从而减少纹理的加载和渲染的时间。在支持这些格式的硬件上,使用压缩纹理可以显著提高渲染性能。在使用压缩纹理时,需要注意纹理的格式和支持的硬件。 三、减少纹理贴图 纹理贴图是OpenGL中最基本的操作之一。在使用纹理时,需要注意不要过多地使用纹理贴图,尤其是对于不可见的物体。可以使用纹理合并技术,将多个纹理合并成一个纹理,从而减少纹理贴图的次数。这样可以减少纹理的大小和内存的占用,同时提高渲染性能。 四、降低纹理分辨率 纹理的分辨率越高,需要的内存和渲染开销就越大。在使用纹理时,可以根据实际需要,选择合适的纹理分辨率。如果纹理的分辨率过高,可以通过降低纹理分辨率的方式来减少内存的占用和渲染开销。可以使用OpenGL提供的纹理过滤器,如GL_LINEAR、GL_NEAREST等,来控制纹理的分辨率。 五、使用Mipmap技术 Mipmap技术是一种纹理精简技术,它可以根据物体的远近程度,自动选择合适的纹理分辨率。在使用Mipmap技术时,需要先生成多个纹理,每个纹理的分辨率是前一个纹理的一半。然后在渲染时,根据距离远近自动选择合适的纹理。这样可以减少纹理的大小和内存的占用,同时提高渲染性能。 六、使用纹理压缩库 除了OpenGL自带的纹理压缩格式外,还有许多第三方纹理压缩库可以使用。这些库通常提供更高效的压缩算法和更多的压缩格式,可以进一步减小纹理的大小和提高渲染性能。在使用第三方纹理压缩库时,需要注意库的兼容性和使用方式。 总结 OpenGL纹理精简技术是一种优化渲染性能的重要手段。通过选择适合的纹理格式、压缩纹理、减少纹理贴图、降低纹理分辨率、使用Mipmap技术和使用纹理压缩库等方式,可以显著提高渲染效率和降低内存占用。在实际开发中,需要根据具体情况选择合适的技术和方式,以达到最优的渲染性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值