Android OpenGL ES(七)----理解纹理与纹理过滤

1.理解纹理

 

OpenGL中的纹理能够用来表示图像。照片,甚至由一个数学算法生成的分形数据。每一个二维的纹理都由很多小的纹理元素组成。它们是小块的数据,类似于我们前面讨论过的片段和像素。要使用纹理,最经常使用的方式是直接从一个图像文件载入数据。

 

每一个二维纹理都有其自己的坐标空间,其范围是从一个拐角的(00)到还有一个拐角的(11)。依照惯例,一个维度叫做S,而还有一个称为T。当我们想要把一个纹理应用于一个三角形或一组三角形的时候。我们要为每一个顶点指定一组ST纹理坐标,以便OpenGL知道须要用那个纹理的哪个部分画到每一个三角形上。

这些纹理坐标有时也会被称为UV纹理坐标。如图:



图1  OpenGL二维纹理坐标

 

对一个OpenGL纹理来说,它没有内在的方向性,因此我们能够使用不同的坐标把它定向到不论什么我们喜欢的方向上。

然而,大多数计算机图像都有一个默认的方向。它们通常被规定为Y轴向下,Y的值随着向图像的底部移动而添加。仅仅要我们记住,假设想用正确的方向观察图像,那纹理坐标就必需要考虑这点。这就不会给我们带来不论什么麻烦。

 

在标准OpenGL ES 2.0中。纹理不必是正方形,可是每一个维度都应该是2的幂(POT)。

这就意味着每一个维度都是这种一个数字,如128256512等。这样规定的原因在于非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

下一篇纹理的应用效果图例如以下:




本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/281856.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WPF 基础控件之托盘

WPF 基础控件之托盘控件名:NotifyIcon作者: WPFDevelopersOrg - 吴锋|驚鏵原文链接: https://github.com/WPFDevelopersOrg/WPFDevelopers框架使用大于等于.NET40。Visual Studio 2022。项目使用 MIT 开源许可协议。新建NotifyIcon自定义…

java 匿名 异常_JAVA类(内部类、匿名内部类、异常、自定义异常)

内部类package AA;public class类 {int de123;StringBuffer deenewStringBuffer();public class成员内部类{public voidff() {System.out.println("这是成员内部类方法");}}/*1.可以访问外部类所有的成员,包括被声明为私有(private)的;2.可以使…

ASP.NET 多环境下配置文件web.config的灵活配置---转

注意:本功能在.Net Core中已经不可用,暂时需手动修改web.config中的信息,或者将其设置在appsettings.XXX.json中,然后再使用web.config中的环境变量来制定使用的具体appsettings文件。 转自:https://www.cnblogs.com/h…

Uranium UI Kit

Uranium UI Kit控件名:Uranium UI Ki作者:enisn原文链接: https://github.com/enisn/UraniumUI项目使用 Apache-2.0 开源许可协议。Uranium 是用于 .NET MAUI 的免费和开源 UI 工具包。它提供了一组控件和实用程序来构建现代应用程序。它建…

《Java多线程编程核心技术》读后感(十五)

线程的状态 线程对象在不同的运行时期有不同的状态,状态信息就存在与State枚举类中。 验证New,Runnable,Terminated new:线程实例化后还从未执行start()方法时的状态 runnable:线程进入运行的状态 terminated:线程被销毁时的状态 …

队列(queue)

队列(queue)和栈一样支持push和pop两个操作。但与栈不同的是,pop两个操作。但与栈的不同的是,pop完成的不是取出最顶端的元素,而是最底端的元素。也就是说最初放入的元素能够最先被取出(这种行为被叫做FIFO:First In First Out,即…

一题多解,ASP.NET Core应用启动初始化的N种方案[上篇]

ASP.NET Core应用本质上就是一个由中间件构成的管道,承载系统将应用承载于一个托管进程中运行起来,其核心任务就是将这个管道构建起来。在ASP.NET Core的发展历史上先后出现了三种应用承载的编程方式,而且后一种编程模式都提供了针对之前编程…

WPF 简单模仿 VSCode 界面布局

WPF 简单模仿 VSCode 界面布局本文经原作者授权以原创方式二次分享,欢迎转载、分享。WPF 简单模仿 VSCode 界面布局作者:弈虎-吕女士会翻墙原文链接: https://github.com/Chen-Lin-Zhao-Wei/WPFLikeVSCode分享一篇群友这几天自己写的 WPF 简…

compare()方法+使用compare方法

compare()方法 compare(lob1,lob2,amount,offset_1,offset_2) 1用于比较2个lob存储的数据,比较的方式是从指定偏移量开始,对指定数量的字符或者字节进行比较。 2如果比较内容相同,返回0,否则返回-1或1. 3如果参数设置有误或不合…

linux 下 mysql默认表_linux环境下mysql默认是区分表名大小写的

在linux环境下,mysql默认表明是区分大小写的,我们可以查看全局变量发现:mysql> show variables like lower%;-------------------------------| Variable_name | Value |-------------------------------| lower_case_file_system | OFF || lower_cas…

两将军问题和TCP三次握手

两将军问题,又被称为两将军悖论、两军问题, 是一个经典的计算机思想实验。首先, 为避免混淆,我们需要认识到两将军问题虽然与拜占庭将军问题相关,但两者不是一个东西。拜占庭将军问题是一个更通用的两将军问题版本&…

微信小程序开发系列五:微信小程序中如何响应用户输入事件

2019独角兽企业重金招聘Python工程师标准>>> 微信小程序开发系列教程 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 微信小程序开发系列二:微信小程序的视图设计 微信小程序开发系列三:微信小程序的调试方法 微信小程序…

理解Object.defineProperty的作用

Object.defineProperty 是vue中双向绑定的基础。vue是通过数据劫持的方式来做数据绑定的,最核心的方法是通过 Object.defineProperty()方法来实现对属性的劫持,达到能监听到数据的变动。要实现数据的双向绑定, 当使用存取器描述属性的特性的时…

直播修仙:使用.NET 的 WebView2 如何获取请求的响应内容,以微信直播的互动直播为例...

背景近几年直播行业快速发展,门槛也越来越低,越来越的人涌入直播大军。不得不说,直播不仅带来了更多的娱乐消遣,还提供了一个新型的就业方式。说起直播的类型,有一个非常小众的娱乐直播,没有主播&#xff0…

web第6次作业position

position 属性指定了元素的定位类型。 position 属性的五个值: static (静态定位) HTML元素的默认值,即没有定位,元素出现在正常的流中。 静态定位的元素不会受到 top, bottom, left, right影响。 div.stati…

GeneralUpdate版本更新公告20221009

大家好我是juster,GeneralUpdate的开源项目作者。这次将发布GeneralUpdate兼容.NET MAUI和多平台为核心的版本。经过国庆假期的打磨修复了大量开源社区开发者的提交的bug和不合理修改建议,重构、删除了大量代码和结构使用和上一个版本没有太大变化。1.更…

实验2 java_《Java程序设计》实验2

1、使用java语言编程,从键盘输入N个整数存储到数组中,求数组所有元素的和、最大值和平均值。import java.util.Scanner;public class Program01{public static void main(String [] args){Scanner scanner new Scanner(System.in);System.out.println(&…

WPF遍历当前容器中某种控件的方法

原文:WPF遍历当前容器中某种控件的方法版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37591671/article/details/79528845 WPF遍历当前容器中某种控件的方法 WPF遍历当前容器中某种控件的方法1.目的:2.实现思…

善用Object.defineProperty巧妙找到修改某个变量的准确代码位置

2019独角兽企业重金招聘Python工程师标准>>> 我今天的工作又遇到一个难题。前端UI右下角这个按钮被设置为"禁用(disabled)"状态。 这个按钮的可用状态由属性enabled控制。我通过调试发现,一旦下图第88行代码执行完毕之后,这个按钮的…

使用 C# 开发的轻量级开源数据库 LiteDB

你好,这里是 Dotnet 工具箱,定期分享 Dotnet 有趣,实用的工具或组件,希望对您有用!简介 LiteDB 是一个小型、快速、轻量级的 .NET NoSQL 嵌入式数据库,也就是我们常说的 K/V 数据库,完全用 C# …