OpenGL Android课程六:介绍纹理过滤

翻译文

原文标题:Android Lesson Six: An Introduction to Texture Filtering
原文链接:http://www.learnopengles.com/android-lesson-six-an-introduction-to-texture-filtering/


介绍纹理过滤

这节课,我们将介绍基本纹理过滤的不同类型和怎样使用它们,
包括最邻近(nearest-neighbour)过滤,双线性(bilinear)过滤
和使用mipmap的三线性(trilinear)过滤

你将学习如何使纹理看起来更平滑,以及平滑带来的缺点。
[这儿有旋转物体][]的不同方式,本课使用了其中一。
screenshot
screenshot

前提条件

强烈建议您先阅读OpenGL Android课程四:介绍纹理基础,理解纹理映射在OpenGL中的基本使用。

什么是纹理过滤?

OpenGLES中的纹理由元素数组组成,被称为纹素(texels),其中包含颜色和alpha值。这与显示器相对应,显示器由一堆像素组成,并在每个点显示不同的颜色。在OpenGL中纹理被用在三角形上并绘制到屏幕,因此这些纹理能绘制出各种各样的尺寸和方向。OpenGL中的纹理过滤选项告诉它如何根据具体情况将纹理像素过滤到设备的像素上。

有三种情况:

  • 每个纹素映射到多个像素,这被称为放大(magnification)
  • 每个纹素精确的映射到一个像素,过滤不适合这种情况
  • 每个纹素映射少于一个像素,这被称为缩小(minification)

OpenGL允许我们为放大和缩小分配过滤器,并允许我们使用最邻近、双线性和三线性过滤。我们将在下面解释这些意思。

放大和缩小

这里是放大和缩小的最邻近渲染的可视化,当您用USB连接你的Android设备时使用这个可爱的Android显示成功连接。

cute android
cute android

放大

magnification android
magnification android

正如您所见,纹素现在很容易看到,因为当前一个纹素覆盖了很多像素展示出来。

缩小

minification android
minification android

随着缩小,许多纹素不能渲染到有限的像素上,许多细节将会丢失。

纹理过滤模式

双线性插值(Bilinear interpolation)

当纹素值之间没有插值时,在放大示例中,纹理的纹素清晰可见为大正方形。当使用最邻近方式时,像素将会分配到最邻近的像素。

通过切换到双线性插值,渲染质量显著提高。这些值将会在邻近的四个像素之间线性插值,而不是将一组像素分配给邻近相同的纹素值。每个像素被平滑化,使得最后的图片看起来也更平滑:

smoother android
smoother android

一些块效果仍然很明显,但是这个图片看起来比之前更加平滑。那些在3D加速卡出现前玩过3D游戏的人将会记得软件渲染游戏和硬件加速游戏之间的特性:软件渲染游戏根本没有进行预计算处理,所以一切都显示得块状和锯齿状。一旦人们开始使用图形加速,这些东西都将变得平滑。

smooth
smooth

双线性插值大多使用在放大。它也能使用在缩小,但是超过某个度,我们将会遇到同样的问题,我们在尝试将太多的纹素放到相同的像素上。OpenGL仅使用最多4个纹素渲染一个像素,因此许多信息仍然会丢失。

如果我们看应用了双线性插值的纹理,当我们在远处看它移动时看起来会很嘈杂,因为每帧都会选择不同的纹素。

纹理映射(Mipmapping)

我们如何才能在缩小纹理时不引用嘈杂并使用上所有纹素呢?我们可以生成一组优化后的不同尺寸的纹理,然后在我们运行的时候使用它们。由于这些纹理已预先生成,它们能使用更多高昂的技术去过滤所有纹素,并且在运行时OpenGL会根据纹理在屏幕上的最终大小选择最合适的层。

textures set
textures set

生成的图片可以具有更多细节,更少噪点,并且整体上看起来更好。尽管需要更多的内存,但渲染速度也会更快,因为较小的层级能更容易保存在GPU的纹理缓存中。让我们来仔细研究一下原尺寸的1/8倍的图片,在使用了双线性过滤使用纹理映射和双线性过滤没有使用映射。为了清楚图片已被扩大:

双线性过滤没有mipmap

without mipmaps
without mipmaps

双线性过滤+mipmap

with mipmaps
with mipmaps

使用mipmap的版本拥有更多细节,由于图像预处理到单独的层级,所有纹素最终都会在最终的图像中使用。

三线性过滤(Trilinear filtering)

当使用双线性过滤的mipmap时,有时在渲染场景中可以看到明显的跳跃或线,由于OpenGL在纹理的不同mipmap层级之间切换。比较不同的OpenGL纹理的过滤模式将在下面进一步指出。

三线性插值通过在不同mipmap层级之间插值来解决这个问题,这样总共8个纹素将用于插值得到最终的像素值,使得图像更平滑。

OpenGL 纹理过滤模式

OpenGL有两个可被设置的参数:

  • GL_TEXTURE_MIN_FILTER 纹理缩小时的过滤模式
  • GL_TEXTURE_MAG_FILTER 纹理放大时的过滤模式

这些相对应于上面的缩小和放大描述。

  • GL_TEXTURE_MIN_FILTER接受以下选项:
    • GL_NEAREST
    • GL_LINEAR
    • GL_NEAREST_MIPMAP_NEAREST
    • GL_NEAREST_MIPMAP_LINEAR
    • GL_LINEAR_MIPMAP_NEAREST
    • GL_LINEAR_MIPMAP_LINEAR
  • GL_TEXTURE_MAG_FILTER接受以下选项:
    • GL_NEAREST
    • GL_LINEAR

GL_NEAREST 对应最邻近渲染;
GL_LINEAR 对应双线性过滤;
GL_LINEAR_MIPMAP_NEAREST 对应双线性过滤+mipmap;
GL_LINEAR_MIPMAP_LINEAR 对应三线性过滤;
本课中将进一步介绍图形示例和最常见选项的进一步说明。

怎样设置纹理过滤模式

我们首先需要绑定纹理,然后我们在这个纹理上设置合适的过滤参数:

GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureHandle);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, filter);

怎样生成mipmap

这真的很容易!在加载纹理到OpenGL中后,纹理仍然是绑定的,我们可以简单的调用:

GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D);

它将为我们生成所有的mipmap层级,并且这些层级会根据纹理过滤自动使用。

它看起来怎么样?

以下是可用的最常见的组合的屏幕截图,当你看到它运动中时,效果更加引人注目,因此我建议下载这个App并试一试。

最邻近渲染

这个模式让人想起旧版3D游戏软件的渲染。

GL_TEXTURE_MIN_FILTER = GL_NEAREST
GL_TEXTURE_MAG_FILTER = GL_NEAREST
nearest nearest
nearest nearest

双线性过滤,mipmap

许多支持3D加速的首批游戏都使用此模式,这是今天在Android手机上平滑纹理的有效方式。

GL_TEXTURE_MIN_FILTER = GL_LINEAR_MIPMAP_NEAREST
GL_TEXTURE_MAG_FILTER = GL_LINEAR
linear mipmap
linear mipmap

静态图上很难看图问题,但是当物体运动时,您可能会注意到渲染的像素在mipmap层级之间切换的水平条带。

三线性过滤

此模式通过在mipmap层级之间进行插值,改进了使用mipmap的双线性过滤的渲染质量。

GL_TEXTURE_MIN_FILTER = GL_LINEAR_MIPMAP_LINEAR
GL_TEXTURE_MAG_FILTER = GL_LINEAR
trilinear
trilinear

像素在近距离和远距离之间完全平滑;事实上,纹理现在可能在倾斜角度下显示的过于平滑。
各向异性过滤(Anisotropic filtering)是一种更先进的技术,受到某些移动GPU的支持,可用于改善最终结果,超出三线性过滤所能提供的效果。

进一步练习

使用其他模式可以达到什么样的效果?例如,您何时会使用像GL_NEAREST_MIPMAP_LINEAR这样的东西?

教程目录

打包教材

可以在Github下载本课程源代码:下载项目
本课的编译版本也可以再Android市场下:google play 下载apk
“我”也编译了个apk,方便大家下载:github download

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容