OpenGL Android课程六:介绍纹理过滤
翻译文
原文标题:Android Lesson Six: An Introduction to Texture Filtering 原文链接:www.learnopengles.com/android-les…
介绍纹理过滤
这节课,我们将介绍基本纹理过滤的不同类型和怎样使用它们, 包括最邻近(nearest-neighbour)过滤,双线性(bilinear)过滤, 和使用mipmap的三线性(trilinear)过滤。 你将学习如何使纹理看起来更平滑,以及平滑带来的缺点。 |
前提条件
强烈建议您先阅读OpenGL Android课程四:介绍纹理基础,理解纹理映射在OpenGL中的基本使用。
什么是纹理过滤?
OpenGLES中的纹理由元素数组组成,被称为纹素(texels),其中包含颜色和alpha值。这与显示器相对应,显示器由一堆像素组成,并在每个点显示不同的颜色。在OpenGL中纹理被用在三角形上并绘制到屏幕,因此这些纹理能绘制出各种各样的尺寸和方向。OpenGL中的纹理过滤选项告诉它如何根据具体情况将纹理像素过滤到设备的像素上。
有三种情况:
- 每个纹素映射到多个像素,这被称为放大(magnification)
- 每个纹素精确的映射到一个像素,过滤不适合这种情况
- 每个纹素映射少于一个像素,这被称为缩小(minification)
OpenGL允许我们为放大和缩小分配过滤器,并允许我们使用最邻近、双线性和三线性过滤。我们将在下面解释这些意思。
放大和缩小
这里是放大和缩小的最邻近渲染的可视化,当您用USB连接你的Android设备时使用这个可爱的Android显示成功连接。
放大
正如您所见,纹素现在很容易看到,因为当前一个纹素覆盖了很多像素展示出来。
缩小
随着缩小,许多纹素不能渲染到有限的像素上,许多细节将会丢失。
纹理过滤模式
双线性插值(Bilinear interpolation)
当纹素值之间没有插值时,在放大示例中,纹理的纹素清晰可见为大正方形。当使用最邻近方式时,像素将会分配到最邻近的像素。
通过切换到双线性插值,渲染质量显著提高。这些值将会在邻近的四个像素之间线性插值,而不是将一组像素分配给邻近相同的纹素值。每个像素被平滑化,使得最后的图片看起来也更平滑:
一些块效果仍然很明显,但是这个图片看起来比之前更加平滑。那些在3D加速卡出现前玩过3D游戏的人将会记得软件渲染游戏和硬件加速游戏之间的特性:软件渲染游戏根本没有进行预计算处理,所以一切都显示得块状和锯齿状。一旦人们开始使用图形加速,这些东西都将变得平滑。
双线性插值大多使用在放大。它也能使用在缩小,但是超过某个度,我们将会遇到同样的问题,我们在尝试将太多的纹素放到相同的像素上。OpenGL仅使用最多4个纹素渲染一个像素,因此许多信息仍然会丢失。
如果我们看应用了双线性插值的纹理,当我们在远处看它移动时看起来会很嘈杂,因为每帧都会选择不同的纹素。
纹理映射(Mipmapping)
我们如何才能在缩小纹理时不引用嘈杂并使用上所有纹素呢?我们可以生成一组优化后的不同尺寸的纹理,然后在我们运行的时候使用它们。由于这些纹理已预先生成,它们能使用更多高昂的技术去过滤所有纹素,并且在运行时OpenGL会根据纹理在屏幕上的最终大小选择最合适的层。
生成的图片可以具有更多细节,更少噪点,并且整体上看起来更好。尽管需要更多的内存,但渲染速度也会更快,因为较小的层级能更容易保存在GPU的纹理缓存中。让我们来仔细研究一下原尺寸的1/8倍的图片,在使用了双线性过滤使用纹理映射和双线性过滤没有使用映射。为了清楚图片已被扩大:
双线性过滤没有mipmap
双线性过滤+mipmap
使用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
复制代码
双线性过滤,mipmap
许多支持3D加速的首批游戏都使用此模式,这是今天在Android手机上平滑纹理的有效方式。
GL_TEXTURE_MIN_FILTER = GL_LINEAR_MIPMAP_NEAREST
GL_TEXTURE_MAG_FILTER = GL_LINEAR
复制代码
静态图上很难看图问题,但是当物体运动时,您可能会注意到渲染的像素在mipmap层级之间切换的水平条带。
三线性过滤
此模式通过在mipmap层级之间进行插值,改进了使用mipmap的双线性过滤的渲染质量。
GL_TEXTURE_MIN_FILTER = GL_LINEAR_MIPMAP_LINEAR
GL_TEXTURE_MAG_FILTER = GL_LINEAR
复制代码
像素在近距离和远距离之间完全平滑;事实上,纹理现在可能在倾斜角度下显示的过于平滑。 各向异性过滤(Anisotropic filtering)是一种更先进的技术,受到某些移动GPU的支持,可用于改善最终结果,超出三线性过滤所能提供的效果。
进一步练习
使用其他模式可以达到什么样的效果?例如,您何时会使用像GL_NEAREST_MIPMAP_LINEAR
这样的东西?
教程目录
- OpenGL Android课程一:入门
- OpenGL Android课程二:环境光和漫射光
- OpenGL Android课程三:使用每片段照明
- OpenGL Android课程四:介绍纹理基础
- OpenGL Android课程五:介绍混合(Blending)
- OpenGL Android课程六:介绍纹理过滤
打包教材
可以在Github下载本课程源代码:下载项目
本课的编译版本也可以再Android市场下:google play 下载apk
“我”也编译了个apk,方便大家下载:github download
OpenGL Android课程六:介绍纹理过滤相关推荐
- OpenGL学习十九:纹理过滤
当物体放大缩小时导致投影在上面的纹理也随着变化,OpenGL为了 优化其细节使其效果更好,因此可以采用纹理过滤 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MA ...
- android openGL ES2 一切从绘制纹理開始
纹理.在openGL中,能够理解为载入到显卡显存中的图片.Android设备在2.2開始支持openGL ES2.0.从前都是ES1.0 和 ES1.1的版本号.简单来说,openGL ES是为了嵌入 ...
- Android OpenGL ES (八)纹理绘制
基本原理 与渐变色接近,但有些区别: 渐变色:光栅化过程中,计算出颜色值,然后在片段着色器的时候可以直接赋值 纹理:光栅化过程中,计算出当前片段在纹理上的坐标位置,然后在片段着色器的中,根据这个纹理上 ...
- Android OpenGL ES 学习(六) – 使用 VBO、VAO 和 EBO/IBO 优化程序
OpenGL 学习教程 Android OpenGL ES 学习(一) – 基本概念 Android OpenGL ES 学习(二) – 图形渲染管线和GLSL Android OpenGL ES 学 ...
- android纹理缓存,Android OpenGLES(七) 理解纹理与纹理过滤
1.理解纹理 OpenGL中的纹理可以用来表示图像,照片,甚至由一个数学算法生成的分形数据.每个二维的纹理都由许多小的纹理元素组成,它们是小块的数据,类似于我们前面讨论过的片段和像素.要使用纹理,最常 ...
- C++ Opengl纹理过滤和光照实例源码
C++ Opengl纹理过滤和光照实例源码 项目开发环境 项目功能 项目演示 项目源码传送门 项目开发环境 开发语言:C++和IDE:VS2017,操作系统Windows版本windows SDK8. ...
- OpenGL之纹理过滤(Texture Filtering)、MipMap方法、纹理坐标
1.1 纹理过滤 像素.片元都是具有面积的,一个像素可能对应物体上的一小块区域,而物体上这个小区域对应于纹理图像上的一个小区域,因此一个像素的颜色可能来自于纹理中的一小个不规则区域,如果纹理的分辨率比 ...
- 初识OpenGL (-)纹理过滤(Texture Filtering)
1. OpenGL需要知道怎样将纹理像素(Texture Pixel,也叫Texel)映射到纹理坐标. 纹理坐标 不依赖于分辨率(Resolution),它可以是任意浮点值, 给模型顶点设置的那个数组 ...
- OpenGL纹理过滤以及纹理Wrapping mode
在三维动态场景中,如果一个纹理对象迅速地远离观察点而去,此时纹理图像必须随被投影的图像一起缩小,否则很产生抖动或者闪烁的现象.为了避免产生抖动或者闪烁,OpenGL必须对纹理图像进行过滤,适当的 ...
- OpenGL之纹理过滤的四种方式
I.纹理过滤: 当三维空间里面的多边形经过坐标变换.投影.光栅化等过程,变成二维屏幕上的一组象素的时候,对每个象素需要到相应纹理图像中进行采样,这个过程就称为纹理过滤. II.纹理过滤通常分为2种情况 ...
最新文章
- 您知道为何要采用固定的迭代周期吗
- 异常详细信息: System.Web.HttpException: 请求在此上下文中不可用
- 多线程处理器 适用于 已知要处理任务的个数,进行多线程处理
- sql中set命令解析
- 一到关于js函数的前端面试题引发的血案
- IsDlgButtonChecked()
- ImportError: libicui18n.so.56 and/or libicui18n.so.58 when importing cv2
- 网站随机动态密码代码
- 地推HTTP成长介绍
- Tips of keras
- js 中call,apply,bind的区别
- hexo部署时出现excepted token解决方法
- docker容器的前台后台运行
- 网络研讨会|为什么在开发流程中应用静态代码分析工具?
- python上的包嗅探
- 观大数据有感_读《大数据时代》有感-大数据时代的取舍
- php和mysql_用php和mysql做登陆注册系统
- 如何搭建一个集群项目
- Firefly-rk3288 开发板Linux系统编译
- 手机CPU与电脑CPU性能究竟相差多少?
热门文章
- android人脸抠图,人脸框抠图如何实现
- 服务器装系统报0x0000005d,虚拟机不能安装Win10系统,提示your PC needs to restart,错误代码0x0000005D该怎么办-电脑自学网...
- 大数据基础课18 数据中台:用大数据赋能业务
- 网易163邮箱模拟登录
- python微信群管理开禁言_微信群主怎么禁言一个人?操作方法介绍!
- 你租的房子遇 “坑” 了么?
- 量子计算机模拟黑洞纠缠,科学家想用量子纠缠探查黑洞内部?那得先找到自旋方向相反的光子...
- LabVIEW编程LabVIEW开发在LabVIEW中复用现有代码
- 任意7个数字,选出5个进行组合排列,并使用Excel打印组合的所有情况。
- 《分形艺术,当科学嫁给了艺术》作者:林晨 风达