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

组成纹理的图片数据和其要贴上去的形状的大小往往是不一样的。两种情况:

  1. magnification:纹理图片小,贴图区域大,需要放大纹理
  2. 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 教程--纹理
图片来源

OpenGL: 纹理采样 texture sample的更多相关文章

  1. OpenGL ES: 纹理采样 texture sample

    Sampler (GLSL) Sampler通常是在Fragment shader(片元着色器)内定义的,这是一个uniform类型的变量,即处理不同的片元时这个变量是一致不变的.一个sampler和 ...

  2. openGL 纹理05

    纹理(Texture) 为了能够把纹理映射(Map)到三角形上,我们需要指定三角形的每个顶点各自对应纹理的哪个部分. 这样每个顶点就会关联着一个纹理坐标(Texture Coordinate) 用来标 ...

  3. 一文详解 纹理采样与Mipmap纹理——构建山地渲染效果

    在开发一些相对较大的场景时,例如:一片铺满相同草地纹理的丘陵地形,如果不采用一些技术手段,就会出现远处的丘陵较近处的丘陵相比更加的清晰的视觉效果,而这种效果与真实世界中近处的物体清晰远处物体模糊的效果 ...

  4. CUDA C 纹理提取Texture Fetching

    CUDA C 纹理提取Texture Fetching 一.参数曲面的纹理  使用纹理指定参数曲面属性. 二.CUDA C 纹理获取开发 用于计算纹理函数,根据纹理引用的各种属性返回的值的公式(请参见 ...

  5. 实时渲染基础(4)纹理(Texture)

    目录 纹理映射(Texture Mapping) 球形贴图(Spherical Map) 立方体贴图(Cube Map) 纹理走样问题 Mipmap 各向异性过滤(Ripmap) 纹理应用技术(Tex ...

  6. Unity3d用户手册用户指南 电影纹理(Movie Texture)

    http://www.58player.com/blog-2327-952.html 电影纹理(Movie Texture) 注意:这只是专业/高级功能.   桌面 电影纹理是从视频文件创建的动画纹理 ...

  7. OpenGL 纹理贴图

    前一节实例代码中有个贴图操作. 今天就简单说明一下纹理贴图... 为了使用纹理贴图.我们首先需要启用纹理贴图功能. 我们可以在Renderer实现的onSurfaceCreated中定义启用: // ...

  8. OpenGL纹理

    如果不用头文件,把所有东西堆在同一个cpp文件中,会出现“超出GPU内存的错误!” 1 //我们自己的着色器类 #ifndef SHADER_H #define SHADER_H #include & ...

  9. [OpenGL]纹理贴图实现 总结

    实现步骤 第一步:设置所需要的OpenGL环境 设置上下文环境 删除已经存在的渲染的缓存 设置颜色缓存 设置帧缓存 清除缓存 设置窗口大小 开启功能 编译shander 使用program 获取sha ...

随机推荐

  1. 平台之大势何人能挡? 带着你的Net飞奔吧!

    镇楼图: 跨平台系列: Linux基础 1.Linux基础学习 By dnt http://www.cnblogs.com/dunitian/p/4822807.html 环境配置 1.Hyper-v ...

  2. 一起学微软Power BI系列-使用技巧(5)自定义PowerBI时间日期表

    1.日期函数表作用 经常使用Excel或者PowerBI,Power Pivot做报表,时间日期是一个重要的纬度,加上做一些钻取,时间日期函数表不可避免.所以今天就给大家分享一个自定义的做日期表的方法 ...

  3. HTTPS 互联网世界的安全基础

    近一年公司在努力推进全站的 HTTPS 化,作为负责应用系统的我们,在配合这个趋势的过程中,顺便也就想去搞清楚 HTTP 后面的这个 S 到底是个什么含义?有什么作用?带来了哪些影响?毕竟以前也就只是 ...

  4. 使用Visual Studio SDK制作GLSL词法着色插件

    使用Visual Studio SDK制作GLSL词法着色插件 我们在Visual Studio上开发OpenGL ES项目时,避免不了写Shader.这时在vs里直接编辑shader就会显得很方便. ...

  5. ASP.NET Web API 跨域访问(CORS)

    一.客户端用JSONP请求数据 如果你想用JSONP来获得跨域的数据,WebAPI本身是不支持javascript的callback的,它返回的JSON是这样的: {"YourSignatu ...

  6. Linux下Nodejs安装(完整详细)

    之前安装过windows下以及Mac下的node,感觉还是很方便的,不成想今天安装linux下的坑了老半天,特此记录. 首先去官网下载代码,这里一定要注意安装分两种,一种是Source Code源码, ...

  7. SQL Server-聚焦UNIOL ALL/UNION查询(二十三)

    前言 本节我们来看看有关查询中UNION和UNION ALL的问题,简短的内容,深入的理解,Always to review the basics. 初探UNION和UNION ALL 首先我们过一遍 ...

  8. scp报错 -bash: scp: command not found

    环境:RHEL6.5 使用scp命令报错: [root@oradb23 media]# scp /etc/hosts oradb24:/etc/ -bash: scp: command not fou ...

  9. EC笔记:第4部分:21、必须返回对象时,别返回引用

    使用应用可以大幅减少构造函数与析构函数的调用次数,但是引用不可以滥用. 如下: struct St { int a; }; St &func(){ St t; return t; } 在返回t ...

  10. 云计算下PAAS的解析一

    云计算下PAAS的解析一       PaaS是Platform-as-a-Service的缩写,意思是平台即服务. 把服务器平台作为一种服务提供的商业模式.通过网络进行程序提供的服务称之为SaaS( ...