本文为稀土技术社区首发签约文章,14天内禁止转载,14天后未获授权禁止转载,侵权必究!

经过阅读本文,你将取得以下收成:
1.什么是纹路
2.纹路怎样进行映射
3.纹路映射相关细节要点

上篇回忆

上一篇一看就懂的OpenGL ES教程——缓冲目标优化程序(二)现已讲完了OpenGL中三种最常见的缓冲目标怎样优化程序,可是前面博文讲的图元着色显得过于单一,能不能制作像一幅画一样具有丰厚的图像呢?当然能够。有了前面常识的铺垫,今日就能够开端触摸OpenGL一个十分风趣重要的常识点——纹路映射。经过纹路映射,咱们能够完成体验临摹画手的浪漫之旅了。

我能够预见这又是生动风趣的一堂课。

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

由于纹路映射内容比较多,所以将理论和实践拆分为2篇博文,本文便是先从理论常识入手解说。

纹路目标

首要什么是纹路呢?看到这个名字,许多人榜首反应很可能是以下的条纹状图:

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

在OpenGl中,纹路的概念和这个仍是有差异的,用浅显的说法,其实纹路便是图片,或许严格来说,便是存储图片数据的容器,立刻来个官方界说(纹路 ) :

Atextureis anOpenGL Objectthat contains one or more images that all have the sameimage format. A texture can be used in two ways: it can be the source of a texture access from aShader, or it can be used as a render target.

一个纹路texture,便是一个OpenGL Object(假设你很认真看过一看就懂的OpenGL ES教程——缓冲目标优化程序(一)而且记忆力很好,也许记住在里面有闪现过texture的字样),这是一个包含一张或许多张格式相同的图片信息的OpenGL Object。它能够用来被shader访问,也能够被直接制作

浅显来说,纹路便是包含着一张或许多张图片信息的一个OpenGL目标,这张图片能够是一维、二维或许三维的,而且具有对应的图片格式

纹路保存着纹路类型、纹路巨细,图片类型。其间纹路类型许多,有:

  • GL_TEXTURE_1D: Images in this texture all are 1-dimensional. They have width, but no height or depth.
  • GL_TEXTURE_2D: Images in this texture all are 2-dimensional. They have width and height, but no depth.
  • GL_TEXTURE_3D: Images in this texture all are 3-dimensional. They have width, height, and depth.
  • GL_TEXTURE_RECTANGLE: The image in this texture (only one image. No mipmapping) is 2-dimensional. Texture coordinates used for these textures are not normalized.
  • GL_TEXTURE_BUFFER: The image in this texture (only one image. No mipmapping) is 1-dimensional. The storage for this data comes from aBuffer Object.
  • GL_TEXTURE_CUBE_MAP: There are exactly 6 distinct sets of 2D images, each image being of the same size and must be of a square size. These images act as 6 faces of a cube.
    ……

等等许多种,本文仅针对GL_TEXTURE_2D进行解说,由于这是咱们最熟悉的2维纹路,即平面图片

纹路映射

纹路映射咋一看仍是很让人发生不明觉厉的感觉的,不过用一个浅显的叫法表达,咱们就觉得亲热多了:贴图

如下图所示,将2张图贴到一个物体外表:

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

所以学习纹路映射,便是研究怎样将图贴上去的问题,而将图贴上去,用的方法便是采样。所以本文首要便是解说纹路是怎样采样的,以及怎样用代码来完成这个采样进程

怎样采样呢?咱们都现已知道在图形烘托管线中,在履行片段着色器之前,会进行光栅化操作,将图元切成一个个小片段,那么当咱们需求把一张图片贴到图元外表的时分,实质便是将图片对应的纹路像素的色彩复制到咱们所制作的图元片段上的进程

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

那什么是纹路像素呢?

纹路像素

咱们知道位图都是由一个个点组成的,如下图(当然这是夸大化的作用):

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

这儿的每个点便是纹路像素(简称纹素)。每个纹路像素记录着相应的色彩信息,它相似于屏幕的「像素(pixel)」但又与像素不保证是一一对应的

电脑中咱们能够检查每一张图片的尺度,比方下面的图片(祭出女神图):

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

640*1138即为它的尺度,它表达的含义便是该图片的纹素在横向和纵向的数量

为什么说“与像素不保证是一一对应的”呢?一般状况下假设依照原始尺度显现一张图片,一个屏幕像素点会显现一个图片的纹素,可是咱们能够扩大一张图片在屏幕的显现许多倍,比方扩大上图许多倍:

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

能够清楚看到有一个个小方块,那便是一个纹素,可是屏幕的一个像素点肯定比这个小得多,所以在这种状况下,图片自身的纹素数量并没有改变,所以这儿一个纹素是由多个屏幕像素显现出来的

那么能够更进一步推断出,要把这张图贴上去,其实只要咱们制作的图元的每个片段都去找到对应的纹素,将纹素上的色彩采到自己“身上”即可

所以要怎样找到一个片段对应的纹素呢?

纹路坐标

假设现在咱们要把石原里美的图

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

贴到如下图所示图元外表

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

要怎样做呢?

假设咱们的图元的宽是a,长为b,为了方便界说当时片段在图元里的方位,咱们给图元增加一个虚拟的坐标系,原点在左下角

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

假设当时片段的坐标是(x,y),那么咱们能够别离核算出x占宽度、y占高度的百分比m、n,然后能够在石原美里图也树立一个相同的坐标系,即左下角为原点的坐标系,依照份额取到对应的纹素的色彩

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

咱们现已知道这张图的纹素尺度是640  1138,所以片段(x,y)对应的纹素坐标便是(640 * m,1138 * n)

可是有个问题,便是不同图片的尺度是不一样的,咱们需求一致起来才能够在代码中用一套坐标系统表示,所以这儿又能够用归一化的思想,将坐标规模一致在0.0-1.0之间

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

坐标起始于(0, 0),也便是纹路图片的左下角,终始于(1, 1),即纹路图片的右上角。

这也叫做纹路坐标,经过纹路坐标,咱们能够定位到纹路中的纹素

所以总结纹路映射的流程:遍历图形中一切的片段,依次经过片段地点的方位坐标定位到其对应在纹路中的纹素,再获取到对应的色彩

可能有人会问:“由于片段一般数量很大,所以遍历片段是一个很耗费性能的进程?”。

其实看过一看就懂的OpenGL ES教程——这或许是你遇过最难画的三角形(三) 的童鞋就知道,凭借gpu强壮的功用特点,一切片段的操作都便是并行履行的,所以这儿性能问题咱们不必担心。

根据这样的映射定位关系,实践采样中,咱们的纹路坐标个数需求和极点坐标坚持一一对应的关系

(左面为纹路,右边为图元)

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

更浅显来说,这种贴图方法便是极点一一对应起来,纹路的图片当作用橡皮泥做的(即能够进行拉伸),然后将纹路图片每个点拉到图元对应极点方位贴上去

纹路盘绕

有时分你可能会有更多需求,比方相似贴墙纸,需求重复一个图片许多许多次:

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

或许会玩一些花哨的动作,比方玩重复的镜面对称或许一些边际延伸作用,那么服务交心的OpenGL也现已考虑到了,这也便是所谓的纹路盘绕

(图来历 纹路 )

假设现在的纹路是:

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

则假设传入的纹路坐标规模超越1.0,则有以下4种可能作用:

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

4种作用从左到右依次是:重复、镜面对称、边际延伸、超出部分显现指定色彩

具体指定盘绕方法的代码,卖个关子,咱们下篇文章具体讲代码的时分再讲。

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

纹路过滤

刚说完纹路盘绕,怎样又呈现个纹路过滤?

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

上面现已叙说了纹路映射的基本思路了,可是有个要害细节值得注意,便是当时片段定位到对应的纹路的纹素的时分,应该怎样赋值给当时片段?一定是直接取当时片段方位对应的纹素的色彩值么?

那倒未必~

假设是直接取对应的纹素的色彩值赋值给当时片段的情形,那么纹路映射后可能会呈现的画面是:

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

是不是明晰感受到了锯齿到来的怪异感?

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

为什么会这样呢?

由于要注意的一个点便是,片段和纹路上的纹素巨细很可能不是一样大的,假设一个很大的图元去采样一个纹素低的纹路,就会呈现一个纹素显着比一个片段大的状况,就会呈现某个区域的许多片段对应的纹素是同一个,那么假设直接采那个纹素的色彩,就会呈现某片区域的片段色彩都是相同的状况,也便是上图呈现的锯齿问题

这就触及一个纹路过滤问题,说白了便是一个片段具体怎样采色的问题。

OpenGL最首要的纹路过滤方法有2种,一种是邻近过滤,Nearest Neighbor Filtering,便是刚讲的直接取对应纹素色彩的方法,另外一种是双线性过滤,(Bi)linear Filtering.

邻近过滤示意图

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

邻近过滤是OpenGL默许的纹路过滤方法,会挑选间隔映射坐标点最近的纹素的色彩。

双线性过滤示意图:

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

它会根据纹路坐标邻近的纹路像素,核算出一个插值,近似出这些纹路像素之间的色彩。一个纹路像素的中心间隔纹路坐标越近,那么这个纹路像素的色彩对终究的样本色彩的贡献越大,其实便是加权的叠加核算。

如下图所示,假设映射坐标点是红点,则会先根据周围4个纹素的中心点间隔红点间隔在纵向2排别离进行加权核算出2个色彩值,然后2个色彩值在横向用相同方法在加权核算出终究色彩值,所以叫做双线性过滤

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

运用双线性过滤的作用图如下图所示:

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

显着没有了锯齿,变得光滑了,不过也带来了新问题,变模糊了。所以这也是一个取舍问题。一般在图元尺度比纹路大的时分选用双线性过滤,图元尺度比纹路小的时分选用邻近过滤

纹路单元

假设咱们制作的图像只能贴一个纹路,即贴一张图片,那显现仍是显得有点单调,假设能够贴上许多张图片,那才是一个五彩缤纷的国际。

所以OpenGL提供了纹路单元,浅显来说便是图层,这样咱们就能够进行图层的叠加去发生一些有意思的作用

比方现在有2个纹路:

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

假设要将2个纹路映射到矩形的图形中,则需求激活2个纹路单元,然后一一将其采样过去即可:

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

一个纹路能够绑定多个纹路单元。当然纹路单元的数量也不是无限的,OpenGL规范规定最大图层数量最小为80,程序中界说的常量GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS表示最大纹路单元数量。

至于具体完成代码,仍是那句话:下一篇文章见。

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

总结

本文首要具体解说了纹路的概念以及纹路映射相关的理论常识,经过阅读本文信任各位现已对纹路映射相关理论了然于胸了吧。

一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

不过理论的东西总是让人觉得有些许单调和缥缈,只有落地到实践才能给与咱们满足的充实感,那么下一篇博文,就来将纹路映射从梦想照进现实~

代码地址

opengl-es-study-demo (不断更新中)

参阅

纹路
Texture

原创不易,假设觉得本文对自己有协助,别忘了顺手点赞和重视,这也是我创造的最大动力~

系列文章目录

系统化学习系列博文,请看音视频系统学习的浪漫马车之总目录

实践项目: 介绍一个自己刚出炉的安卓音视频播映录制开源项目

C/C++基础与进阶之路

音视频理论基础系列专栏

音视频开发实战系列专栏

轻松入门OpenGL系列
一看就懂的OpenGL ES教程——图形烘托管线的那些事
一看就懂的OpenGL ES教程——再谈OpenGL作业机制
一看就懂的OpenGL ES教程——这或许是你遇过最难画的三角形(一)
一看就懂的OpenGL ES教程——这或许是你遇过最难画的三角形(二)
一看就懂的OpenGL ES教程——这或许是你遇过最难画的三角形(三)
一看就懂的OpenGL ES教程——这或许是你遇过最难画的三角形(四)
一看就懂的OpenGL ES教程——这或许是你遇过最难画的三角形(五)
一看就懂的OpenGL ES教程——缓冲目标优化程序(一)
一看就懂的OpenGL ES教程——缓冲目标优化程序(二)
一看就懂的OpenGL ES教程——临摹画手的浪漫之纹路映射(理论篇)