OpenGL ES: 纹理采样 texture sample
Sampler (GLSL)
Sampler通常是在Fragment shader(片元着色器)内定义的,这是一个uniform类型的变量,即处理不同的片元时这个变量是一致不变的。一个sampler和一个texture对应,类型也是对应的,比如sampler2D 的sampler对应的就是GL_TEXTURE_2D类型的纹理对象。Sampler是个变量,但是它是没有值的,或者說是特殊的一种类型,讨论其数值没有意义,只要明确其同一个texture对应即可。sampler变量在shader内使用的地方就是texture函数。这是一个lookup 函数(我不知道该如何翻译,我的理解是这是一个查找/查询的函数,以给定的纹理坐标去纹理的数据中查到相应的颜色的信息),得到颜色信息渲在每一个片元上。例如,一个三角形,我们只要传递三个纹理坐标给顶点着色器就行了,接着片元着色器会为每个像素生成纹理坐标的插值,根据纹理坐标就得到了每一个像素的颜色值。
纹理采样的机制
Texture Wrapping
纹理坐标通常的范围是从(0, 0)到(1, 1),如果我们把纹理坐标设置为范围以外会发生什么?OpenGL默认的行为是重复这个纹理图像(我们简单地忽略浮点纹理坐标的整数部分),但OpenGL提供了更多的选择:
- GL_REPEAT:纹理的默认行为。重复纹理图像。
- GL_MIRRORED_REPEAT:和GL_REPEAT一样,除了重复的图片是镜像放置的。
- GL_CLAMP_TO_EDGE:纹理坐标会在0到1之间。超出的部分会重复纹理坐标的边缘,就是边缘被拉伸。
- GL_CLAMP_TO_BORDER:超出的部分是用户指定的边缘的颜色。
在生成纹理对象的时候,需要用 glTexParameter() 设置一系列参数,设置的就是这个参数以及下面的 Texture Filtering 的参数。
Texture Filtering
magnification/minification
组成纹理的图片数据和其要贴上去的形状的大小往往是不一样的。两种情况:
- magnification:纹理图片小,贴图区域大,需要放大纹理
- minification:反过来,纹理图片大,贴图区域小,缩小纹理显示出来
在做放大和缩小的操作的时候的具体的策略如下:
- GL_NEAREST:直接选择最临近的像素的颜色,magnification(放大)时:由于多个片元会在同一个纹理像素上面取值,故最终得到的图片颗粒度很大,会有锯齿。
- GL_LINEAR:根据临近四个的像素点的颜色值,做线性的插值计算,得到最终的颜色。magnification(放大)时:不会产生锯齿,显示更加平滑。
在minification(缩小)时,上面的两种方法其实都不理想,无论如何都会丢失很多图片的细节,OpenGL 用Mipmap来解决这个问题。
Mipmap
它就是一系列纹理,每个后面的一个纹理是前一个的二分之一,这一系列的纹理是OpenGL生成的,生成时进行了图像质量的优化,使其拥有更多的细节。这一系列的纹理是提前生成的,程序运行时只需要从中挑出合适大小的纹理应用即可,而不是运行时进行图像大小的处理,效率上会有提高。
OpenGL渲染的时候,两个不同级别的mipmap之间会产生不真实感的生硬的边界。就像普通的纹理过滤一样,也可以在两个不同mipmap级别之间使用NEAREST和LINEAR过滤。指定不同mipmap级别之间的过滤方式可以使用下面四种选项代替原来的过滤方式:
- GL_NEAREST_MIPMAP_NEAREST:接收最近的mipmap来匹配像素大小,并使用最临近插值进行纹理采样。
- GL_LINEAR_MIPMAP_NEAREST:接收最近的mipmap级别,并使用线性插值采样。
- GL_NEAREST_MIPMAP_LINEAR:在两个mipmap之间进行线性插值,通过最邻近插值采样。
- GL_LINEAR_MIPMAP_LINEAR:在两个相邻的mipmap进行线性插值,并通过线性插值进行采样。
总结一下:magnification和minification的时候都可以设置NEAREST和LINEAR两种方式;minification的时候还可以设置mipmap的方式,该方法效果更好。关于具体的算法的实现,可以参考《OpenGL ES specification》的8.13-8.14内容。
Sampler object
一个texture对象包括了两部分的属性,一部分是具体的图片信息,另一部分是纹理采样的设置,即上文提到的不同的方式。通常生成纹理的时候是将这两部分一起设置好的,但是后面这部分的内容可以单独拿出来,封装成为一个对象,就是 sampler object .
使用 GenSamplers() 函数创建一个新的sampler对象,然后用 BindSampler() 做绑定操作,将sampler和texture对象绑定起来,然后调用 glSamplerParameterf() 这一类的函数来设置sampler的具体的参数。
texture object, sampler object, program object 的关系如图:

参考资料:
OpenGL ES: 纹理采样 texture sample的更多相关文章
- OpenGL: 纹理采样 texture sample
Sampler (GLSL) Sampler通常是在Fragment shader(片元着色器)内定义的,这是一个uniform类型的变量,即处理不同的片元时这个变量是一致不变的.一个sampler和 ...
- Android OpenGL ES 开发(九): OpenGL ES 纹理贴图
一.概念 一般说来,纹理是表示物体表面的一幅或几幅二维图形,也称纹理贴图(texture).当把纹理按照特定的方式映射到物体表面上的时候,能使物体看上去更加真实.当前流行的图形系统中,纹理绘制已经成为 ...
- 一文详解 OpenGL ES 纹理颜色混合
在OpenGL中绘制的时候,有时候想使新画的颜色和已经有的颜色按照一定的方式进行混合.例如:想使物体拥有半透明的效果,或者绘制叠加光亮的效果,这时候就需要用到OpenGLES混合. 如上图所示,为石头 ...
- TextureView+SurfaceTexture+OpenGL ES来播放视频(三)
引自:http://www.jianshu.com/p/291ff6ddc164 做好的Demo截图 opengl-video 前言 讲了这么多,可能有人要问了,播放视频用个android封装的Vid ...
- 如何使用Android中的OpenGL ES媒体效果
引自:http://www.2cto.com/kf/201506/404366.html Android的媒体效果框架允许开发者可以很容易的应用多种令人印象深刻的视觉效果到照片或视频之上.作为这个媒体 ...
- OpenGL ES着色器语言之变量和数据类型(一)(官方文档第四章)和varying,uniform,attribute修饰范围
OpenGL ES着色器语言之变量和数据类型(一)(官方文档第四章) 所有变量和函数在使用前必须声明.变量和函数名是标识符. 没有默认类型,所有变量和函数声明必须包含一个声明类型以及可选的修饰符. ...
- Opengl ES之纹理贴图
纹理可以理解为一个二维数组,它可以存储大量的数据,这些数据可以发送到着色器上.一般情况下我们所说的纹理是表示一副2D图,此时纹理存储的数据就是这个图的像素数据. 所谓的纹理贴图,就是使用Opengl将 ...
- OpenGL ES学习笔记(三)——纹理
首先申明下,本文为笔者学习<OpenGL ES应用开发实践指南(Android卷)>的笔记,涉及的代码均出自原书,如有需要,请到原书指定源码地址下载. <OpenGL ES学习笔记( ...
- Android OpenGL ES 3.0 纹理应用
本文主要演示OpenGL ES 3.0 纹理演示.接口大部分和2.0没什么区别,脚本稍微有了点变化而已. 扩展GLSurfaceView package com.example.gles300; im ...
随机推荐
- Kivy 从memory 读取image
借助PIL来处理的图片数据 fp = BytesIO() img = Image.frombytes('RGB', img_size, buf_bytes, 'raw', 'BGR;16', 0, 1 ...
- Python设计模式 - 创建型 - 单例模式(Singleton) - 十种
对于很多开发人员来说,单例模式算是比较简单常用.也是最早接触的设计模式了,仔细研究起来单例模式似乎又不像看起来那么简单.我们知道单例模式适用于提供全局唯一访问点,频繁需要创建及销毁对象等场合,的确方便 ...
- [Java核心技术]第四章-对象与类(4.1-4.6总结)
4.1面向对象程序设计概述 OOP(面向对象编程Object Oriented Programming) OOP中数据第一位,算法第二位. 类 封装:关键在于不能让其他方法直接访问类的实例域,程序仅通 ...
- easyui 改变单元格背景颜色
另外一种方法:https://www.cnblogs.com/raitorei/p/9989649.html easyui的datagrid改变整行颜色:https://www.cnblogs.com ...
- MYSQL(Mariadb)
CentOS7下安装MariaDB 添加 MariaDB yum 仓库(官网的,也可以直接用aliyun云的) vi /etc/yum.repos.d/MariaDB.repo [mariadb] n ...
- 如何访问dashed filename
第一关:boJ9jbbUNNfktd78OOpsqOltutMc3MY1 第二关:CV1DtqXWVFXTvM2F0k09SHz0YwRINYA9 cat <- 第三关:如何访问spaces i ...
- Django formset
一 什么是formset Form组件或ModelForm用于做一个表单验证而formset是用于做多个表单的验证组件,用于做批量操作 二 formset的使用方法 1 设置form信息 class ...
- Android,重新出发!
接触Android差不多一年,工作也有快半年的时间了. 现在回头看看自己写的代码,虽然功能可以实现,但是还是有很多不足的地方. 比如代码结构,一个类中的代码过多,知道这样做不好,但是不知道怎么把这些 ...
- SQLite 安装
Windows 平台安装 下载地址:https://www.sqlite.org/download.html 下载预编译的安装包 将下载的安装包=解压到一个文件夹,有三个重要文件: sqlite3.e ...
- VBA找相似体积的单元格值
在VBA中做了一个比较体积,如果体积相似就显示隔壁单元格的内容 Function VC(a, b As Range) 'VolumeCompare体积比较 Dim arry() As Variant ...