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 ...
随机推荐
- springBoot拦截器的使用
拦截器是动态拦截Action调用的对象.它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行.同时也是提供了一种可以提取action中可 ...
- Spring再接触 模拟Spring
项目分层: 1.最土的方法是直接写到main中去 2.分出model层 2.如下 4.在抽象一个对数据库的访问层(跨数据库实现) 面向抽象编程 User.java package com.bjsxt. ...
- python re模块与正则表达式
首先要先继承re模块: import re re.findall() 方法 # 返回值为列表 \w 表示一个字符,为数字,字母,下滑线之一, \W匹配任意非数字,字母,下划线 print(re.fin ...
- HTML前期学习总结
一.基本结构<!DOCTYPE html> //设置字符编码集格式<html> //<head> //网页头部 <title></title> ...
- cmake find_package 中,include_directories,target_link_libraries 的值怎么知道?
拿Sophus库为例: find_package(Sophus REQUIRED) include_directories(${Sophus_INCLUDE_DIRS}) target_link_li ...
- JAVA中的配置文件XML
一:概念 1.XML Extensible markup Language 可拓展标记语言 2.功能:存储数据(配置文件,在网络中传输数据) 3.html和xml的区别 3.1xml标记全是自定义的 ...
- Linux查看某个端口的连接数
一.查看哪些IP连接本机 netstat -an 二.查看TCP连接数 1)统计80端口连接数 netstat -nat | grep -i "80" | wc -l 2)统计ht ...
- 动态创建js脚本和 css样式
//1.动态添加外部js文件 function loadScript(url){ var script = document.createElement("script"); sc ...
- easyui改变tab标题
截图: 代码: //更改tab的标题 var tab = $('#microAppVersionTabs').tabs('getTab',0);// 取得第一个tab $('#microAppVe ...
- ATM取款机数据库设计
创建文件夹 USE master GO EXEC xp_cmdshell 'mkdir d:\bank', NO_OUTPUT 建库 --检验数据库是否存在,如果为真,删除此数据库-- ...