OpenGL ES 理解纹理与纹理过滤
1.理解纹理
OpenGL中的纹理可以用来表示图像,照片,甚至由一个数学算法生成的分形数据。每个二维的纹理都由许多小的纹理元素组成,它们是小块的数据,类似于我们前面讨论过的片段和像素。要使用纹理,最常用的方式是直接从一个图像文件加载数据。
每个二维纹理都有其自己的坐标空间,其范围是从一个拐角的(0,0)到另一个拐角的(1,1)。按照惯例,一个维度叫做S,而另一个称为T。当我们想要把一个纹理应用于一个三角形或一组三角形的时候,我们要为每个顶点指定一组ST纹理坐标,以便OpenGL知道需要用那个纹理的哪个部分画到每个三角形上。这些纹理坐标有时也会被称为UV纹理坐标。如图:
图1 OpenGL二维纹理坐标
对一个OpenGL纹理来说,它没有内在的方向性,因此我们可以使用不同的坐标把它定向到任何我们喜欢的方向上。然而,大多数计算机图像都有一个默认的方向,它们通常被规定为Y轴向下,Y的值随着向图像的底部移动而增加。只要我们记住,如果想用正确的方向观察图像,那纹理坐标就必须要考虑这点,这就不会给我们带来任何麻烦。
在标准OpenGL ES 2.0中,纹理不必是正方形,但是每个维度都应该是2的幂(POT)。这就意味着每个维度都是这样的一个数字,如128,256,512等。这样规定的原因在于非POT纹理可以被使用的场合非常有限,而POT纹理使用于各种情况。
纹理的尺寸也有一个最大值,它根据不同的实现而变化,但是通常都比较大,比如2048*2048。
2.理解纹理过滤
当纹理的大小被扩大或者缩小时,我们还需要使用纹理过滤明确说明会发生什么。当我们在渲染表面上绘制一个纹理时,那个纹理的纹理元素可能无法精确地映射到OpenGL生成的片段上。有两种情况:缩小和放大。当我们尽力把几个纹理元素挤进一个片段时,缩小就发生了;当我们把一个纹理元素扩展到许多片段时,方法就发生了。针对每一种情况,我们可以配置OpenGL使用一个纹理过滤器。
首先,讲述两个基本的过滤模式:最近邻过滤和双线性插值。还有其他的过滤模式,以后的博文会讲解。我们会使用下面的图像阐述每一种过滤模式。
最近邻过滤
这个方式为每个片段选择最近的纹理元素。当我们放大纹理时,它的锯齿效果看起来相当明显,如下图所示。
每个纹理单元都清楚的显示为一个小方块。
当我们缩小纹理时,因为没有足够的片段用来绘制所有的纹理单元,许多细节将会丢失。
双线性过滤
双线性过滤使用双线性插值平滑像素之间的过渡,而不是为每个片段使用最近的纹理元素,OpenGL会使用四个邻接的纹理元素,并在它们之间用一个线性插值算法做插值,这个算法与前面所讲的平滑坐在着色一样。我们之所以称它为双线性插值,是因为它是沿着两个维度插值的。下面是使用双线性差值放大后的图像,它采用的纹理与前面的相同。
这个纹理现在看起来比以前平滑多了。但还是有些锯齿显现出来,因为我们把这个纹理扩展得太多,但是锯齿不像使用最近邻过滤那么明显。
MIP贴图
尽管双线性过滤很适合处理放大,但是对于缩小到超过一定的大小时,它就不好用了。一个纹理在渲染表面所占大小减少得越多,就会有越多的纹理元素拥挤到每一个片段上。因为OpenGL的双线性过滤只给每个片段使用四个纹理元素,我们将会丢失很多细节。因为每一帧都要选择不同的纹理元素,这还会引起噪音以及移动中的物体闪烁。
为了克服这些缺陷,可以使用MIP贴图技术,它可以用来生成一组优化过的不同大小的纹理。当生成这组纹理的时候,OpenGL会使用所有的纹理元素生成每个级别的纹理,当过滤纹理时,还要确保所有的纹理元素都能被使用。在渲染时,OpenGL会根据每个片段的纹理元素数量为每个片段选择最合适的级别。
下图是一组MIP贴图的纹理,把它们合并在一当个图上是为了方便对比。
图2 MIP贴图的纹理
使用MIP贴图,会占用更多的内存,但是渲染也会更快,这是因为较小级别的纹理在GPU的纹理缓存中占用较少的空间。
为了更好地理解MIP贴图是如何提高缩小情况下的质量,我们比较一下那个可爱的机器人,使用双线性过滤把纹理元素尺寸缩小到其原来的12.5%,如下图:
图3 使用双线性过滤缩小
就这种质量,可能还不如最近邻过滤。看一下当我们加入MIP贴图时会得到什么。如下图:
图4 使用MIP贴图缩小
随着MIP贴图的使用,OpenGL将选择最合适的纹理级别,然后用优化过的纹理做双线性插值。每个级别的纹理都是用来自所有纹理元素的信息构建的,因此得到的图形看起来更好些,保留了更多的细节。
三线性过滤
如果OpenGL在不同的MIP贴图级别之间来回切换,当我们用双线性插值来使用MIP贴图时,在其渲染的场景中,在不同级别的MIP贴图切换时,我们有时候能看到明显的跳跃或者线条。我们可以切换到三线性插值,这样,每个片段总共要使用8个纹理元素插值。这有助于消除每个MIP贴图级别之间的过渡,并且得到一个更平滑的图像。
3.程序中纹理参数表
方法GLES20.glTextParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_FILTER,“纹理过滤模式”);第二个参数指放大的情况。
方法GLES20.glTextParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,“纹理过滤模式”);第二个参数指缩小的情况。
第一个参数是告诉OpenGL这应该被作为一个二维纹理对待。
表1 OpenGL纹理过滤模式
GL_NEAREST |
最近邻过滤 |
GL_NEAREST_MIPMAP_NEAREST |
使用MIP贴图的最近邻过滤 |
GL_NEAREST_MIPMAP_LINEAR |
使用MIP贴图级别之间插值的最近邻过滤 |
GL_LINEAR |
双线性插值 |
GL_LINEAR_MIPMAP_NEAREST |
使用MIP贴图的双线性插值 |
GL_LINEAR_MIPMAP_LINEAR |
三线性插值(使用MIP贴图级别之间插值的双线性过滤) |
表2 每种情况允许的纹理过滤模式
缩小 |
GL_NEAREST GL_NEAREST_MIPMAP_NEAREST GL_NEAREST_MIPMAP_LINEAR GL_LINEAR GL_LINEAR_MIPMAP_NEAREST GL_LINEAR_MIPMAP_LINEAR |
放大 |
GL_NEAREST GL_LINEAR |
下一篇纹理的应用效果图如下:
版权声明:本文为博主原创文章,未经博主允许不得转载。
OpenGL ES 理解纹理与纹理过滤相关推荐
- OpenGL ES教程VI之纹理贴图(原文对照)
注:又是一篇,是否有人能解释得清楚,2是重复两次,那么是否N就是重复N次呢?接近1.0的坐标值整数部分加上几就是重复几次吗?这个好像之前验证过不一定的. 转自:http://melord.iteye. ...
- OPENGL ES 2.0 知识串讲 (10) ——OPENGL ES 详解IV(纹理优化)
上节回顾 上一节学习了如何从一张原始图片中,获取生成纹理所需要的信息,然后根据这些信息,通过OpenGL ES API在GPU内存中生成了一张纹理,并且还介绍了纹理属性,知道了如何通过纹理坐标将纹理映 ...
- Android OpenGL ES (八)纹理绘制
基本原理 与渐变色接近,但有些区别: 渐变色:光栅化过程中,计算出颜色值,然后在片段着色器的时候可以直接赋值 纹理:光栅化过程中,计算出当前片段在纹理上的坐标位置,然后在片段着色器的中,根据这个纹理上 ...
- OpenGL ES实现三棱锥纹理贴图
这是老师布置的课后作业,闲来无事分享出来,也加深一遍自己的印象~ 自己定义一个MyRenderer.java类: package com.example.shiyan3_2;import androi ...
- Android Camera使用OpenGL ES 2.0和GLSurfaceView对预览进行实时二次处理(黑白滤镜)
第一篇 Android Camera使用OpenGL ES 2.0和GLSurfaceView对预览进行实时二次处理(黑白滤镜) 第二篇 Android Camera使用OpenGL ES 2.0和T ...
- 【我的OpenGL学习进阶之旅】OpenGL ES 3.0新功能
目录 1.1 纹理 1.2 着色器 1.3 几何形状 1.4 缓冲区对象 1.5 帧缓冲区 OpenGL ES 2.0 开创了手持设备可编程着色器的时代,在驱动大量设备的游戏.应用程序和用户接口中获得 ...
- Android Camera API 2使用OpenGL ES 2.0和GLSurfaceView对预览进行实时二次处理(黑白滤镜)
这段时间有点忙,一直没时间写第三篇教程,其实代码很早之前就写好了.本系列教程会有三篇文章讲解Android平台滤镜的实现方式,希望在阅读本文之前先阅读前面两篇文档. 第一篇 Android Camer ...
- OpenGL ES for Android 绘制旋转的地球
No 图 No Code,我们先来欣赏下旋转的地球: 是不是很酷炫,要想绘制出上面酷炫的效果需要3个步骤: 计算球体顶点数据 地球纹理贴图 通过MVP矩阵旋转地球 计算球体顶点数据 我们知道OpenG ...
- OpenGL ES之实现“大头小头”和“头部晃动”的效果
一.纹理映射 ① 什么是纹理 ? 纹理(Texture)最通常的作用是装饰 3D 物体,它就像贴纸一样贴在物体表面,丰富了物体的表面和细节.在 OpenGL ES 开发中,纹理除了用于装饰物体表面,还 ...
- android纹理缓存,Android OpenGLES(七) 理解纹理与纹理过滤
1.理解纹理 OpenGL中的纹理可以用来表示图像,照片,甚至由一个数学算法生成的分形数据.每个二维的纹理都由许多小的纹理元素组成,它们是小块的数据,类似于我们前面讨论过的片段和像素.要使用纹理,最常 ...
最新文章
- LeetCode简单题之拥有最多糖果的孩子
- web安全漏洞之CSRF
- linux php curl 安装包下载,linux中php如何安装CURL扩展方法
- Android中使用File文件进行数据存储
- 添加服务引用的本质是什么?
- k-d tree算法
- 维护无后效性的技巧——立即计算代价
- 基于vue + element 的后台管理系统
- DB2中不同于其它数据库的操作
- 【51nod】1776 路径计数
- html ajax get post,jQuery – AJAX get() 和 post() 方法 - jQuery 教程 - 自强学堂
- python3 根据种子文件torrent获取磁力链接
- js ws 状态_使用ws
- 死亡之ping(Ping of Death)
- contiki学习笔记(五)ctimer和etimer
- nexus5 博通芯片WIFI详解 (4)
- ios开发开发之:关于时间戳转化成时间
- [Linux]线程概念_线程控制(线程与进程的区别与联系 | 线程创建 | 线程等待 | 线程终止 | 线程分离 | LWP)
- C语言文件操作+通讯录实现文件操作
- 火车订票管理系统/火车购票网站系统/火车订票网站/火车票售卖系统
热门文章
- 亚利桑那州立大学计算机科学排名,2019上海软科世界一流学科排名计算机科学与工程专业排名亚利桑那州立大学排名第76-100...
- 相亲也内卷?被程序员的相亲规划整不会了......
- CAD几何引擎和图形引擎的关系
- 排序算法——冒泡排序
- “去哪儿”创始人兼总裁庄辰超专访实录
- 浙江大学精品课程视频合集
- 超链接去掉下划线代码
- 两台(或多台)电脑怎么实现文件共享
- 解二元一次方程组程序
- java中的extends与implement