纹理基础知识和过滤模式详解
1、 为什么在纹理采样时需要texture filter(纹理过滤)。
我们的纹理是要贴到三维图形表面的,而三维图形上的pixel中心和纹理上的texel中心并不一至(pixel不一定对应texture上的采样中心texel),大小也不一定一至。当纹理大于三维图形表面时,导至一个像素被映射到许多纹理像素上;当维理小于三维图形表面时,许多个像素都映射到同一纹理。
当这些情况发生时,贴图就会变得模糊或发生错位。要解决此类问题,必须通过技术平滑texel和pixel之间的对应。这种技术就是纹理滤波。
不同的过滤模式,计算复杂度不一样,会得到不同的效果。过滤模式由简单到复杂包括:Nearest Point Sampling(最近点采样),Bilinear(双线性过滤)、Trilinear(三线性过滤)、Anisotropic Filtering(各向异性过滤)。
在了解这些之前,有必要了解什么是多级纹理贴图(MipMap)和什么是各向同性,各向异性。
2、 什么是MipMap?
Mipmap由Lance Williams 在1983的一篇文章“Pyramidal parametrics”中提出。Wiki中有很详细的介绍(http://en.wikipedia.org/wiki/Mipmap ) . 比如一张256X256的图,在长和宽方向每次减少一倍,生成:128X128,64X64,32X32,16X16,8X8,4X4,2X2,1X1,八张图,组成MipMap,如下图示。
Mipmap早已被硬件支持,硬件会自动为创建的Texture生成mipmap的各级。在D3D的API:CreateTexture中有一个参数levels,就是用于指定生成mipmap到哪个级别,当不指定时就一直生成到1X1。
3、 什么是各向同性和各向异性?
当需要贴图的三维表面平行于屏幕(viewport),则是各向同性的。当要贴图的三维表面与屏幕有一定角度的倾斜,则是各向异性的。
也可以这样理解,当一个texture贴到三维表面上从Camera看来没有变形,投射到屏幕空间中后U方向和V方向比例仍然是一样的,便可以理解成各向同性。反之则认为是各向异性。
4、 Nearest Point Sampling(最近点采样)
这个最简单,每个像素的纹理坐标,并不是刚好对应Texture上的一个采样点texel,怎么办呢?最近点采样取最接近的texel进行采样。
当纹理的大小与贴图的三维图形的大小差不多时,这种方法非常有效和快捷。如果大小不同,纹理就需要进行放大或缩小,这样,结果就会变得矮胖、变形或模糊。
5、 Bilinear(双线性过滤)
双线性过滤以pixel对应的纹理坐标为中心,采该纹理坐标周围4个texel的像素,再取平均,以平均值作为采样值。
双线性过滤像素之间的过渡更加平滑,但是它只作用于一个MipMap Level,它选取texel和pixel之间大小最接近的那一层MipMap进行采样。当和pixel大小匹配的texel大小在两层Mipmap level之间时,双线性过滤在有些情况效果就不太好。于是就有了三线性过滤。
6、 Trilinear(三线性过滤)
三线性过滤以双线性过滤为基础。会对pixel大小与texel大小最接近的两层Mipmap level分别进行双线性过滤,然后再对两层得到的结果进生线性插值。
三线性过滤在一般情况下效果非常理想了。但是到目前为止,我们均是假设是texture投射到屏幕空间是各向同性的。但是当各向异性的情况时,效果仍然不理想,于是产生了Anisotropic Filtering(各向异性过滤)。
7、 Anisotropic Filtering(各向异性过滤)
先看效果,左边的图采用三线性过滤,右边的图采用各向异性过滤。
各向同性的过滤在采样的时候,是对正方形区域里行采样。各向异性过滤把纹理与屏幕空间的角度这个因素考虑时去。简单地说,它会考滤一个pixel(x:y=1:1)对应到纹理空间中在u和v方向上u和v的比例关系,当u:v不是1:1时,将会按比例在各方向上采样不同数量的点来计算最终的结果(这时采样就有可能是长方形区域)。
我们一般指的Anisotropic Filtering(AF)均是基于三线过滤的Anisotropic Filtering,因此当u:v不为1:1时,则Anisotropic Filtering比Trilinear需要采样更多的点,具体要采多少,取决于是多少X的AF,现在的显卡最多技持到16X AF。
当开启16X AF的时候,硬件并不是对所有的texture采样都用16X AF,而是需要先计算屏幕空间与纹理空间的夹角(量化后便是上面所说的u:v),只有当夹角大到需要16X时,才会真正使用16X.
如果想了解AF的实现原理,可以查阅此篇Paper: “Implementing an anisotropic texture filter”. 现在AF都是硬件实现,因此只有少数人才清楚AF的具体实现,也可以由Pixel Shader来实现AF,当然性能远不如使用硬件来完成。
8、 各过滤模式性能比较。
下表是各种过滤模式采一个pixel需要sample的次数:
类型 | 采样数 |
Nearest Point Sampling | 1 |
Bilinear | 4 |
Trilinear | 8 |
Anisotropic Filtering 4X | 32 |
Anisotropic Filtering 16X | 128 |
一般而言,采样数越多,效果最好,但具体使用时要综合考虑性能。


最新评论
- 相关文章
React JSX语法简介
JSX是一种类似XML的标签语法,用来简化代码,我们可以不使用JSX,但了解并使用也没什么坏处:)在React中,JSX是一个使用 React.createElement() API的快捷方式...
通过实例深入理解HTML5/CSS3/SVG/WebGL的技术本质
HTML5动画背后的数学2 - 仿生智能算法综述
使用SVG和CSS3创建圆形进度条动画
圆形进度条是一个经典的控制面板元素,常用于显示任务进度,比如用户档案的完整程度,或者升级状态。有很多方法来实现圆形进度条,比如用JS, CSS3, Canvas, SVG...
学习使用CSS制作进度条
进度条是基础的界面控件,可用于多种场合,比如任务完成进度,手机充电状态等。本文介绍一个简单实用的进度条制作方法。预期效果如下图所示:直观上,我们可以把该进度条控件分为2个部分,外部的边界用来表示固定的目标范围,里面的条形部分用来表示当前进度。外部目标范围元素的CSS代码编写如下:.pb-scope
如何使用WebGL创建一个逼真的下雨动画
之前写过文章来分别讲解如何使用CSS3和Canvas2D实现过雨滴和下雨动画。通过背景处理看起来也有视觉上的3D效果,但并非真正的3D场景,如果要加入用户交互,进行36...
WebGL入门教程2 - GPU基本概念和工作流水线(渲染管道)
如何使用CSS3实现一个平滑的3D文本标题
要实现3D文本,基本上有3种方法:1. 使用CSS3的投影滤镜(filter: drop-shadow)2. 使用3d建模和CSS3 3d变换来实现(最真实)3. 使用CSS3 text-shadow属性来实现...
使用requestAnimationFrame和Canvas给按钮添加绕边动画
要给按钮添加酷炫的绕边动画,可以使用Canvas来实现。基本的思路是创建一个和按钮大小相同的Canvas元素,内置在按钮元素中。然后在Canvas上实现边线环绕的动画。...
如何使用CSS3实现书页(书本)卷角效果
我们有时候想在页面显示一个公告或用户提示信息。一个常用设计是使用书签形状。我们可以给书签添加卷角效果,以使其更为逼真。所谓的“卷角”实际上可以用小角度...
在PHP网页程序中执行Sass/Compass命令
我们需要在wow云开发平台支持sass/compass等预编译样式语言,为此我们首先尝试了scssphp扩展,但是在支持最新语法上,经常会出现异常。所以我们采用了代理的方式...
更多...