纹理映射理论与实践-论文最终稿

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

纹理映射理论与实践
学生姓名:指导教师:
内容提要:
在计算机图形学这个技术领域当中,真实感图形计算与显示算法是一个比较重要的课题,也是一项备受关注的研究方向。

通常一个图形或图像所表现出来的真实感效果,指的就是某个通过计算机的程序运算生成的图形对客观存在的实体物件的一种反映程度。

一直以来,图形的真实感问题都是图形学界探讨和研究的热点课题。

其主要原因有以下两点,一是快速发展的计算机技术扩展了越来越广的应用领域,而在某些领域当中,如何制作具有超高真实感效果的图形就是他们最终发展的目标;二是计算机所能显示图形的真实程度也是对我们目前技术水平的一个度量,假若我们不能生成相对真实的图形,那么,对图形进行艺术加工和控制又从何而谈。

然而要使用计算机程序来生成一个可以高度反映客观世界的图形却不是一件容易的事情,例如在制作的过程中,为了使生成的图像更加具有真实感,需要采用许多的算法或技术来进行处理,如明暗度的处理、消除隐藏线或隐藏面、混合与反走样的处理、光线追迹等等。

以往,人们对这方面的研究主要是投入在基本算法上,一直在通过建立模型的方法模仿真实的客观世界,但是,结构复杂以及变化万千的客观世界致使我们想把客观世界的各种细微的结构直接用几何模型表达出来,不但模型很难建立,而且计算量非常巨大,不能满足随时呈现效果的需求。

因此,可以考虑能否采用类似“贴墙纸”的方法将某些细节图案贴到某个物体表面上,从而开辟了一个新的研究领域——纹理映射。

关键词:计算机图形学纹理映射 OpenGL
Texture mapping theory and practice
Abstract:
In computer graphics, realistic graphics technology is an important issue, is also one of the most compelling research direction. The so-called graphical realism, refers to computer-generated graphics to reflect the extent of the objective world. For a long time, the graphic realism of contemporary graphics academic research hotspot. This is mainly for two reasons, first, due to the rapid development of computer technology, the increasingly wide application, certain application areas highly realistic graphics as the ultimate goal of development; computer can display the true extent of the graphics also on our current technical level of a measure, if we can not generate more realistic graphics, graphic art processing and control out of the question. However, with more realistic computer-generated graphics is not so easy, in the nature of computer generated simulation of three-dimensional objects, in order to generate images more realistic, the need to adopt a number of algorithms to deal with, such as shading, elimination implicit processing, mixed and
anti-aliasing, ray tracing processing technology.
Early research focused on the basic algorithm, it has been the objective world through modeling method simulation due to the objective world is
ever-changing and complex, should the objective world in a variety of subtle structure of the direct use of the geometric model, not only the model is difficult to establish , and a large amount of computation, it is difficult to meet the requirements of real-time display. So, people had to imagine whether "wallpaper paste" method can be used to reflect the pattern of the surface details paste it into the surface of the object, thus opening up a new field of study - texture mapping.
Key words: Computer Graphics Texture mapping OpenGL
目录
1、纹理映射概述 (5)
1.1 颜色纹理映射 (6)
1.2 凸包纹理映射 (6)
1.3 环境纹理映射 (6)
2、纹理的定义 (6)
3、纹理映射的实践 (7)
3.1 OpenGL纹理的定义 (7)
3.2 OpenGL纹理对象 (7)
3.2.1 生成纹理名 (7)
3.2.2纹理对象的生成和使用 (7)
3.2.3 OpenGL纹理的控制 (8)
3.2.4 纹理滤波 (8)
3.2.5 重复与缩限 (8)
3.3 纹理映射的方式 (8)
3.4纹理的使用 (8)
4、纸盒贴图的应用 (9)
4.1初始化定义和控制纹理 (9)
4.2纸盒几何坐标的定义 (9)
4.3纹理坐标的定义 (10)
4.4坐标映射关系的建立 (12)
4.5 实例演示 (12)
4.6 结语 (13)
参考文献: (13)
纹理映射理论与实践
所谓纹理映射,是指将某种指定的映射图像或纹理依据一种算法将其类似贴墙纸一般的附于某个三维立体物件的各个面片上,建立该物体与映射图像或纹理的坐标对应关系。

针对不同的纹理和需要进行映射的具体三维立体模型而选用不同的映射算法,已达到描绘客观世界中真实物体表面各种特征的目标。

现实世界中的物体,其表面常常具有比较复杂并且各种各样的纹理图案,也就是表面细节,例如:抛光的木材表面有木纹,建筑物墙壁上有装饰的图案等等。

类似的这种纹理是通过颜色或者明暗程度的变化来展现出表面的细节,我们称这种为颜色纹理;还有一类纹理则是由于不规则的细小凹凸而造成的,例如:橘子皮表面的褶皱和没有磨光石材表面的凹凸痕,我们把这种类型的纹理称为凸包纹理。

虽然能够用很小的三角形单元通过改变不同三角形的反射特性来模拟上述各种不同类型的纹理,但是这样的系统效率明显会降低。

处理这种反射特性变化问题的一个常见方法是将物体的反射性作为一个函数或保存在一个图像中,然后将函数或保存的图像“映射”到物体表面模型上,所用的函数或图像称为映射纹理,而用此方法控制物体表面反射特性的过程称为纹理映射,换句话说,也就是将纹理空间中的纹理像素映射到屏幕空间中的像素的过程。

在三维图形中,纹理映射的方法最为普及,特别是在描述物体的真实感方面。

例如制作一个地砖,在一个个矩形中间贴上一些具有真实效果感觉的照片或是图案。

这样,一面逼真生动的地砖就画好了。

如果不这样做的话,我们就要绘制这地砖上的每一个单独的多边形方格,操作起来就显示十分笨拙且繁琐。

此外,纹理映射还能够确保这个多边形上面的纹理也会随着变换多边形的变化而变化。

比如,我们用透视投影仪在观察地面时,按照一般规律来说,如果我们观察的位置远离地面,那么地砖的尺寸就显得很小,而近点观察就会被放的很大。

此外,在很多其他领域中,纹理映射也在被广泛的运用。

如:飞行仿真中常把一大片景物的图案映射到某些大多边形上用来表示某一墙面,或是用花岗岩石、木头的纹理等自然界中的物质的图案当作纹理映射到某个多边形上来展出相对应的物体。

制作具有真实感效果图形的重要组成部分之一便是纹理映射,此技术使得不必在研究物体表面的细节上花费太多的精力和时间便可以非常轻松的制作出一个具有高度真实感的立体图形。

但是在这个过程中,计算机程序的运行速度却受到了纹理加载过程的影响,尤其当定义的纹理图案很大时,运行效率就会明显的降低。

因此在这种情况下我们就不得不去考虑一些问题来优化计算机的制作程序和减轻系统开销,例如怎样来合理的管理映射纹理或图像。

幸运的是,OpenG程序库为解决上述常见的问题提供了丰富的接口和纹理管理技术。

由于可以使用某
个单独的数字来标识一个纹理对象,这便使得OpenGL可以存储多个不同的纹理于内存当中,避免在使用时才逐步加载,如此一来,可以大大简化计算机的运算量,以使速度得到很大程度的提高。

1、纹理映射概述
纹理映射算法可以看做是一个基于二维或多维数组或映射来修改明暗度的
算法,或者使用映射改变表面参数(如材质属性或法向量)来改变明暗度的算法。

它主要划分为以下三类:
1.1 颜色纹理映射
也称纹理映射,是指用一个模式或纹理来确定物体颜色的方法,这些模式可以由一个固定的模式(如用于填充多边形的规则图案)来确定,或者通过一个纹理产生的函数来确定,还可以用一个数字图像来确定,在各种情况下,我们都可以描述怎样通过映射纹理到物体的各个面片来产生图像的过程。

1.2 凸包纹理映射
通过改变物体表面参数(如法向量)来改变表面明暗度。

1.3 环境纹理映射
允许产生一个纹理映射的背景,并且背景上的物体具有高光反射,这种图像通常需要光线跟踪方法才能得到,也就是说,物体的纹理是物体所在环境所形成的图像。

三种方法有许多共性:它们都改变物体的明暗度,并且是明暗度计算过程的一个部分,它们都使用保存在一维、二维或三维数字图像中的映射。

2、纹理的定义
纹理可以被理解为一种模式,可以是规则的模式,如条带和棋盘类型,也可以是描述自然材质的复杂模式,在现实中,可以通过物体的纹理来区分具有相似大小和形状的物体,纹理的定义一般分为连续法、离散法,连续法其实就是一个二元的函数,纹理空间就是由该函数的定义域表示;离散法把纹理定义在一个数组中,代表纹理空间中一组网格上的纹理值,网格点之间的纹理值可以通过网格点上的值得到。

纹理通常是被定义在一个单位的正方形区域(边长为1,0≤s≤1,0≤t≤1)之内,即纹理空间,实际中往往采用定义在此空间的一些特殊函数来作为纹理函数,以便模拟客观世界中经常遇到和熟知的纹理。

例如:下面的函数常用于模拟黑白相间的国际象棋的棋盘纹理:
其中,0<a<b<1,[x]表示小于x的最大整数。

纹理定义的离散法用一数组来表示一个纹理,数组可以是二维、三维等,二维数组对应二维的纹理,用二维数组表示的纹理可以是二维的数字图像,也可以是程序生成的图形,然后保存在此二维数组中。

3、纹理映射的实践
纹理映射是制作具有真实效果的图形的一个重要环节,只要合理的运用适当的纹理便可以很轻松的制作出具有真实感的图形,而不必在物体的表面细节上花过多的精力和时间。

但需要注意的一点是,纹理只被允许在RGB色彩模式下工作, 纹理映射在OpenGL中运算的基本步骤一般如下:
(1) 定义纹理
(2) 控制滤波
(3) 指定映射方式
(4) 先定义顶点的几何、纹理坐标,之后进行场景的绘制
3.1 OpenGL纹理的定义
有时我们说纹理是一个单个的图像,这是基于最简单情况下的说法,而在通常情况下来说,纹理则是一个二维的,其数据是由一个矩形的数组来存储。

在OpenGL图形程序接口中二维的纹理函数由glTexImage2D()来指定,如下所示:void glTexImage2D(GLenum target, Glint level, Glint components, GLsizei width, GLsizei height, Glint border, GLenum format, GLenum type, const GLvoid * texels);
3.2 OpenGL纹理对象
纹理对象允许用户保存纹理数据以备将来使用,通过使用纹理对象,可以一次把多个纹理调入内存,并且在场景绘制过程中的任何时间可以调用任何一个纹理,这种技术动态的增加了性能,因为纹理在每次使用时不必再调入内存,使用纹理对象的过程如下:
3.2.1 生成纹理名
关于纹理对象的使用,其第一步是必须生成一个纹理名,一般使用无符号、非零的整数数字来命名纹理,为了避免多次使用相同的纹理名,可以使用函数glGenTextures()生成纹理名:
void glGenTextures(GLsizei n, GLuint * texturesArray );
其中,纹理名的数量由参数n来指定,这些纹理名被保存在texturesArray 中,例如,如果有一个大小为3的数组来保存纹理名,函数 glGenTextures()的使用方法可以如下:
Unsigned int textureName[3];
……
glGenTextures(3,texturesArray);
3.2.2纹理对象的生成和使用
生成纹理名后,需要把纹理名“绑定”到纹理数据上才能使用。

函数glBindTexture()提供了路径来完成这个步骤:
void glBindTexture(GLenum target, GLuint textureName);
3.2.3 OpenGL纹理的控制
纹理在定义了之后还需要一些相应的设置才能使用, 例如:纹理的控制。

如何将纹理映射在物体表面上就是由OpenGL的纹理控制所定义的,其对应的是glTexParameter *()函数,主要表现在缩小或者放大纹理的滤波和纹理的重复平铺方面。

OpenGL库中,控制纹理的函数如下所示:
Void glTexParameter{if}[v](GLenum pname, TYPE param);
3.2.4 纹理滤波
由于纹理映射在赋给一个多边形时常常会发生扭曲,一般情况下不可能是屏幕图像上的每个像素对应纹理上的每个纹素。

于是,就必须定义一个适当的滤波来实现局部的缩小或者放大,其指定OpenGL如何来计算纹素、像素,以得到最终预想的效果。

在纹理滤波中,放大指当一个像素描述很小一部分纹素的情况,缩小指当一个像素描述大量纹素的情况,使用函数glTexParameter*()设置放大和缩小滤波的示例如下:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3.2.5 重复与缩限
(0, 1)作为纹理坐标的坐标范围,是可以被超出的,根据这一理论,重复的映射和缩限映射在映射的过程中则是被允许的。

例如在s、t坐标方向纹理就可以进行重复的映射,如下函数所示:
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3.3 纹理映射的方式
纹理图案在通常情况下是直接作为颜色投射到一个多边形的图形上。

事实上,我们使用纹理的值也可以调整这个多边形,甚至原来的颜色都可以被曲面原本的颜色进行融合,在OpenGL图形程序接口中,提供了函数glTexEnv *()来控制纹理的映射方式 ,共有三种模式:
(1) GL_MODULATE,纹理图像以透明方式贴在物体的表面上;
(2) GL_BLEND,使用一个RGBA常量来融合物体原色和纹理图像的颜色;
(3) GL_DECAL,贴纸纹理的映射方式。

3.4纹理的使用
纹理映射是为了实现可以把真实的客观世界简单的描绘出来而产生的一项新的计算机应用技术。

通俗的来说,在绘制好的三维图形表面映射上物体真实的纹理图案,使其显示效果更加栩栩如生。

为了实现三维图形的模拟,电脑公司研发出了很多的三维图形软件包,其中,SGI公司推出的OpenGL尤为突出,也做的非常成功。

它是一个定义了跨平台、跨编程语言的接口规格,功能强大且调用方便。

一般它被使用于三维的图像上(当然二维的亦可),其实现了纹理贴图、材质及光照处理,以及动画的演示等一系列功能。

目前,它在上述纸盒的cad系统
中,特别是在映射图形的效果图的演示中充当着重要的角色,倘若使用一般的编程技术来实现这种技术,绝非一件轻松的事,因此,借助于SGI公司的OpenGL 所提供的强大纹理映射技术能够很大程度上简化我们的工作。

4、纸盒贴图的应用
一般来说,比较常见的一种图片格式就是位图,它的格式比较简单且计算机读取也较为方便,在此例中我们就使用位图来作为装潢图案。

纹理图形的数据及计算可以是由计算机程序来运算完成的,当然也可以从某些性能优越的外部文件的API中读取。

装潢图案在纸盒CAD系统中大多数情况下是随机的,因此在这里采用从第二种方式,也就是从外部文件中读取图形的方法,以示程序的简单且效率高。

4.1 初始化定义和控制纹理
按照之前介绍的理论基础来看,在制作之前首先要实现纸盒的结构图,然后像贴墙纸一般在该基础上进行纸盒的贴图。

可以应用OpenGL的建模、变换、光照材质设置等功能来实现纸盒的三维结构图。

定义初始化和控制纹理可用如下函数实现:
//命名并指定图形为预定义的位图
GLubyte * pTextureBits = (GLubyte*)m_pDib ->Get -Bits();
//图形高度和宽度的定义
GLint heigt = m_pDib - >Height();
Glint width = m_pDib - >Width();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
//定义纹理图形
glTexImage2D(GLJEXTURE_2D, 0, 3, width, height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pTextureBits);
//控制纹理
glTexParameterf(......);
......
//纹理映射方式
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, GL_DECAL);
//启动纹理映射
glEnable(GL_TExTuRE_2D);
glShadeModel(GL_SM00TH);
4.2 纸盒几何坐标的定义
一旦我们初始化控制了纹理图案,接下里主要的部分是如何定义纹理图形的坐标(s,t)和三维物体的空间几何坐标(x,y,z),还有把它们之间对应的关系一一建立起来。

对于三维的纸盒模型,可以用一定数量的面片来搭建其结构。


文档中的图2所示,就是纸盒的一张盒片图,分别用S1、S2、S3和S4来定义这个盒体的四个面。

这里我们以面S1为例,纹理映射物体的几何坐标就由面S1
中的a、b、c、d四个顶点来确定;但需要注意的一点是,其面片特性决定了该纸盒的厚度、长高宽和压痕线等参数都与每个面片顶点的坐标有关,所以这里我们则以纸盒的中心为原点坐标建立一个坐标系,正如图3中所示的那样,用纸盒的设计参数来表示它的每个面片,若以X、Y、Z轴方向分别表示纸盒的长度、高度和宽度,其压痕线、纸厚则用T轴方向来表示,则面S1的a、b、c、d四个顶点的坐标就可以做如下定义(2X=长度,2Y=高度,2Z=宽度):
a:glVertex3d(-X,-Y-2*T,Z);
b:glVertex3d(X+2*T,-Y-2*T,Z);
c:glVertex3d(X+2*T,Y+2*T,Z);
d:glVenex3d(-X,Y+2*T,Z);
4.3 纹理的坐标定义
对于一个二维的图像而言,在沿着两个不同方向上,其纹理的坐标都是在(0.0—1.0)的范围内变化。

若将一种映射图案整张的贴于纸盒的某个面片之上,则图4中所示的图像的各个顶点坐标就可以定义成:
e:glTexcoord2f(0.0, 0.0);
f:glTexcoord2f(1.0, 0.0);
g:glTexcoord2f(1.0, 1.0);
h:glTexcoord2f(0.0, 1.0);
图4 装潢图形
如果你只是想要选中整个图案的某些部位,而不是整个图形,那么,我们只需要在定义纹理几何坐标的时候修改函数中的某些参数,用这个被修改了的坐标来标识选中的部分。

比如,当我们将参数1.0修改为0.5时,就表示只截取实际图形的四分之一,也就是图中黑色框内标注的左上角部分来进行纹理的映射,如下图所示:
图5 装潢图形的左上部分(四分之一)
由此可见,我们可以根据实际的需要来对纹理坐标进行修改。

对于上述图4所示的装潢图片,定义不同纹理坐标就会呈现出的不同的映射效果(见图6)。

(0.0, 0.0) (0.0, 0.0) (0.2, 0.2)
(1.0, 0.0) (0.7, 0.0) (0.7, 0.2)
(1.0, 1.0) (0.7, 0.7) (0.7, 0.7)
(0.0, 1.0) (0.0, 0.7) (0.2, 0.7)
图6 坐标定义的不同效果图
4.4 坐标映射关系的建立
在纹理坐标定义完成后,就需要进行纹理的映射过程。

此处需要做的就是建立三维图像的空间几何坐标和映射图像的纹理坐标之间的对应关系,即a对应e、c对应g、b对应f,以及d对应h等。

但是在进行映射时,还应该注意保持整个过程顺序的一致性,例如在对面片S2进行图像的映射过程时,应使点b与e、a1与f、d1与g、c与h一一对应,以使生成的映射图像保持其顺序一致性。

拿面片S1来说,将上述图4中的整张图像附于其表面的对应坐标函数可定义为如下:
glTexcoord2f(0.0, 0.0);
glTexcoord3f(-X, -Y-2*T, Z);
glTexcoord2f(1.0,0.0);
glTexcoord3f(X+2*T, -Y-2*T, Z);
glTexcoord2f(1.0, 1.0);
glTexcoord3f(X+2*T,Y+2*T,Z);
glTexcoord2f(0.0,1.0);
glTexcoord3f(-X,Y+2*T,Z);
在初始化的定义和纹理控制、选定映射图像、定义纹理坐标以及建立三维立体图形的几何坐标及映射纹理坐标之间的一一对应关系后,就能将一张完整的图像犹如贴墙纸一般贴在生成的三维立体纸盒上,以产生预期的效果。

4.5 实例演示
如下图所示,即是采用0penGL图形程序接口以及VC++6.0软件实现的三维立体纸盒效果。

图7 纸盒贴图过程
该工具使用OpenGL库提供的函数建模、纹理贴图、材质及光照处理以及双缓存动画等实现了三维立体纸盒的参数化设计、动画的演示整个纸盒的生成过程、纹理贴图等功能。

在纹理贴图的过程中,我们可以选择各式各样的图形来进行贴图,还可以任意选择需要贴图的面,图7是将上文中图4所示的图形贴在一个三维立体的纸盒上,针对纸盒不同的面片指定不同的纹理坐标来映射不同的图形区域。

综上所述,利用该方法就可以简单的实现各式各样的图形贴图。

下图则是对不同的图形进行不同的变幻而产生的一组三维立体纸盒结构图的效果:
图8 三维立体纸盒结构图
4.6 结语
上述三维纸盒的生成过程中不可或缺的一个部分就是纹理贴图的实现,然而借助OpenGL图形程序库提供的丰富的且跨编程语言的API函数接口能够很大程度的简化这个过程,而且还可以根据各种需求指定各式各样的映射图像来进行纹理贴图,以生成各种不同的效果。

以上应用技术也为设计和包装一般的CAD
图形设计软件提供了非常便捷的研究方法。

参考文献:
1.周建龙:《计算机图形学理论与OpenGL编程实践》,华南理工大学出版社,2007年版;
2.理查德(Richard.S 美)、怀特(Wright.J 美):《OpenGL超级宝典》,人民邮电出版社,2001年版;
3.倪明田、吴良芝:《计算机图形学》,北京大学出版社,2012年版;
4.杨涛、陈少为、朱英杰《包装工程》—基于面模型的三维纸箱纸盒CAD系统[J],2003年第二期版;
5.乔林、费广正,《OpenGL程序设计[M]》北京;清华大学出版社,2000年版。

相关文档
最新文档