第三章光照模型纹理映射

第三章光照模型纹理映射
第三章光照模型纹理映射

第三章光照模型及纹理映射

基本光照模型

1.在现实生活中,当光照在非透明物体上时,部分光线被物体吸收,剩余的部分光线被反射。人眼依靠这种反射光来感知物体的形状、颜色和其他细节。从光源投向物体的光称为入射光,从物体表面反射回的光称为反射光。

1.1光照模型概述

当光照射到物体表面上时,将出现3种情况:

●光从物体表面反射,形成反射光

●光穿透物体,形成透射光

●光被物体吸收,转化成为物体的内能

在上述三种情形的光线中,通常只有前2种情形的光线会对人眼产生视觉效果,使人察觉到物体的色彩变化。

OpenGL用一种近似的光照模型模拟现实世界的光照效果。在该模型中,仅当物体表面吸收和反射光线时,光源才会起做作用。每一个物体表面都假定是由某种特性的材料构成的。一种材料可能发出自己的光线,也可能在各个方向上发散一些射入的光线,还有可能像镜子一样在某个方向强烈地反射入射光。

1.2光照分量

在OpenGL的简化光照模型中,将光照分为4个独立的组成部分:辐射光、环境光、漫反射光和镜面反射光。

1)辐射光

辐射光是直接从物体或光源发出的,不受任何其他光源的影响。

2)环境光

环境光是这样一种光线,它被环境多次反射,以致于连初始

方向也难以确定。这种光线看起来就像来自于所有的方向,

当它照在一个物体表面时,它在所有的方向上等量地反射。

3)漫反射光

在被照射物体表面的反射光中,那些均匀地向各个方向反射

出去的光,称为漫反射光,如黑板反射就属于漫反射光

4)镜面反射光

镜面反射光是指超一定方向的反射光,如点光源照射光滑金

属球表面时,会在球表面形成一个特别亮的区域,呈现所谓

的高亮(Highlight>,这就是光源在该物体表面形成的镜面反射光(Specular

Light>。点光源照射表面光滑的物体时,高亮区域小而亮;而点光源照射表面粗糙的物体时,高亮区域大而不亮。

1.3创建光源

光源有许多特性,如颜色、位置、方向等。不同特性的光源,作用在物体上的效果是不一样的。

1.3.1定义一个简单光源

在OpenGL中,定义一个光源是由函数glLight(>来实现的,该函数的原型为:void glLight(GLenum light,GLenum pname>;

light为一个光源,pname为光源light指定一个单值的光源参数,

其取值及其含义如下表所示:

光源的数目与具体的实现的系统有关,但至少支持8个光源。它们用符号名称GL_LIGHTi相互区别,这里0≤i≤GL_MAX_LIGHTS,如GL_LIGHT0,GL_LIGHT1,…GL_LIGHT7等。

以下的代码定义了一个编号为GL_LIGHT0的光源的例子:

GLfloat light_ambient[]={0.0,0.0,0.0,1.0}。

GLfloat light_diffuse[]={1.0,1.0,1.0,1.0}。

GLfloat light_specular[]={1.0,1.0,1.0,1.0}。

GLfloat light_position[]={1.0,1.0,1.0,1.0}。

glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient>。

glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse>。

glLightfv(GL_LIGHT0,GL_SPECULAR,light_specular>。

glLightfv(GL_LIGHT0,GL_POSITION,light_position>。

光源定义完毕后,必须调用glEnable(GL_LIGHT0>打开该光源,否则该光源对场景中的物体不起作用。

1.3.2 启用光源和激活光源

在OpenGL中,如果需要使用光源,首先必须启用光照。

启动光照的函数为:glEnable(GL_LIGHTING>。

取消光照的函数为:glDisable(GL_LIGHTING>。

对于具体定义的各个光源,可以为每个光源指定是否使用和停止使用。以上一个光源GL_LIGHT0为例。使用GL_LIGHT0光源的函数

为:glEnable(GL_LIGHT0>,停止使用GL_LIGHT0光源的函数为:glDisab le(GL_LIGHT0>。

1.4光源属性

光源属性主要有光的颜色强度、光源的位置、光源的衰减特性和光源的聚光效果等。

1.4.1光源颜色

定义光源的GL_AMBIENT,GL_DIFFUSE和GL_SPECULAR属性时,参数params

包含4个整数值或浮点值,它们分别用来指定光源的RGBA环境光、RGBA漫反射光和RGBA镜面反射光。整数型数值被线性地映射为浮点格式:最大的正数映射为1.0,最小点的负数映射为-

1.0,。浮点型数值则直接映射。二者不被截断。所有光源的GL_A

MBIENT环境光强度缺省为(0.0,0.0,0.0,1.0>,光源GL_LIGHT0的DIFF USE漫反射光强度缺省值为(1.0,1.0,1.0,1.0>,其他光源的漫反射光强度缺省值为(0.0,0.0,0.0,0.0>。光源GL_LIGHT0的GL_SPECULA R镜面反射光强度缺省值为(1.0,1.0,1.0,1.0> ,其他光源的镜面反射光强度缺省值为(0.0,0.0,0.0,0.0>。以下代码将光源GL_LIGHT0的环境光颜色设置为蓝色:

GLfloat light_ambient[]={0.0,0.0,1.0,1.0}。

glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient>。

1.4.2光源的位置

光源的位置有2种,一种离场景无限远,另一种在附近。远的

称为方向光源,它射到物体上的光可以认为是平行的,现实生活中,太阳就是这样的光源。近的称为位置光源,它的具体位置决定了它对场景的作用效果,尤其是决定了光线的投射方向,台灯就是这样的位置光源。

定义光源的GL_POSITION属性时,参数params包含4个整数值或者浮点值,它们用来指定光源在齐次坐标中的位置。整数型和浮点型都直接映射,不被截断。

下面的代码定义了光源GL_LIGHT0为方向光源,光源方向为(1.0,1.0,1.0>。

GLfloat light_position[]={1.0,1.0,1.0,0.0}。

glLightfv(GL_LIGHT0,GL_POSITION,light_position>。

下面的代码定义了光源GL_LIGHT0为位置光源,光源位置为(1.0,1.0,1.0>。

GLfloat light_position[]={1.0,1.0,1.0,1.0}。

glLightfv(GL_LIGHT0,GL_POSITION,light_position>。

1.4.3光源的衰减

自然世界中的光,光线的强度随光源距离的增加而减少。因为方向光源的距离是无限远的,随距离的增加而衰减其光线强度是没有意义的,因此对方向光源的光线不进行衰减处理。对于位置光源,OpenGL使用下面的衰减因子来衰减光线的强度。

衰减因子=

其中,d为光源位置到物体顶点之间的距离。

●k c为常数衰减因子(GL_CONSTANT_ATTENUATION>,默认值为1.

0。

●k e为线性衰减因子(GL_LINEAR_ATTENUATION>,默认值为0.0。

●k q为二次衰减因子(GL_QUADRATIC_ATTENUATION>,默认值为0.0

注意:GL_CONSTANT_ATTENUATION,GL_LINEAR_ATTENUATION 和GL_QUADRATIC_ATTENUATION属性时,参数params是一个整数值或浮点值,且只能取非负值。

1.4.4聚光效果

控制光源聚光效果的参数有3个,它们分别是:聚光的方向GL_ SPOT_DIRECTION、聚光的发散角GL_SPOT_CUTOFF和光源的强度分布GL_SPOT_EXPONENT。

定义光源的GL_SPOT_DIRECTION属性时,参数params包含3个整数值或浮点值,它们用来指定光源在齐次对象坐标中的方向。整型数值和浮点数值都直接映射。二者不被截断。

定义光源的GL_SPOT_CUTOFF属性时,参数params是一个整数值或浮点值,它们用来指定一个光源的最大发散角。整型数值和浮点数值都直接映射。其取值范围是[0,90]和特殊值180。

如果光照方向与它所照射的顶点的方向之间夹角大于聚光灯的截止角,光线将被完全屏蔽。否则,光的强度将受到聚光指数和发散因子所控制。缺省的聚光灯截止角是180,它产生了均匀的发散光。

定义光源的GL_SPOT_EXPONENT属性时,参数params是一个整数值或浮点值,它们用来指定一个光源的强度分布。整型数值和浮点数值都直接映射。其取值范围为[0,128]。有效的光强度是按照光照方向与它所照射的顶点之间的方向之间的夹角的余弦规律衰减的,一直衰减到聚光指数的幂。因此,较高的聚光指数就会导致一个较高的汇聚光源,而不管其截止角究竟如何。缺省的聚光指数是0,它产生了均匀的光强衰减方式。

下面的代码定义了光源GL_LIGHT0的聚光方向为(1.0,1.0,1.0 >,发散角为45°:

glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,45.0>。

GLfloat spot_direction[]={1.0,1.0,0.0}。

glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,spot_direction>。1.5小结

下面介绍使用一个多光源的实例,其中一个光源是标准的蓝色光源,另一个是红色的聚光灯。代码见附录。

2.纹理映射

纹理映射是真实图形制作的一个重要部分,运用纹理映射可以方便地制作真是图形,而不必花更多的时间去考虑物体的表面纹理。如一张木制桌子其表面的木纹是不规范的,看上去又是那么自然,如果在图形制作中不用纹理映射,那么只是这张桌子面纹理的设计,就要花费很大精力,而且设计结果也未必能像现实中那么自然。如果运用纹理映射就非常方便,可以用扫描仪将这样的一张桌子扫成一个位图。然后具体的操作中,只需把桌面形状用多边形画出来,把桌面纹理贴上去就可以了。

另外,纹理映射能够在多边形进行变换时仍保证纹理的图案与多边形保持一致性。例如,以透视投影方式观察墙面时,远端的砖会变小,而近处的砖就会大一些。

此外,纹理映射也可以用于其他方面。例如,使用一大片植

物的图像映射到一些一些连续的多边形上,以模拟地貌,或者大理石,木纹等自然物质的图像作为纹理映射到相应的多边形上,作为物体的真实表面。

在OpenGL中提供了一系列完整的纹理操作函数,用户可以用它们构造理想的物体表面,可以对光照物体进行处理,使其映射到所处环境的景象,可以用不同方式应用到曲面上,而且可以随几何物体的几何属性变化而变化,从而使制作的三维场景和三维物体更真实,更自然。

纹理映射只能工作在RGB模式下,在OpenGL中,进行纹理映射的基本步骤如下:①定义纹理;②控制纹理;③映射方式;

④纹理坐标。

2.1 纹理的定义

在最简单的情况下,纹理是单个图像。如同大多数图像一样,纹理通常是一维和二维的,在一些应用场合也使用三维纹理进行图形绘制。描述纹理的每个纹素可以由1个、2个、3个或4个元素构成,由1个(R、G、B、A>四元值的调制常数来表示任何内容。

2.1.1 一维纹理映射的定义

在OpenGL中定义一维纹理的函数是glTexImage1D(>,原型为:void glTexImage1D(GLenum target,Glint level,Glint components,GLsizei width,GLint border,GLenum format,GLenum type,const GLvoid* pixels>。

参数说明:

target

指定纹理映射。在这里必须是GL_TEXTURE_1D。width指定纹理的宽,一维纹理没有高度,width必须是2n,n为正数;border指定纹理的边界,必须是1或0;level指定多级分辨率的纹理图像,只有一种分辨

率的level=0。components指定选用RGBA的哪些成分用于混合调整;pixe

ls指定一个指针,指向纹理数据在内存中的位置;format和type指定纹

理的映射格式和数据类型。

Components指定选用RGBA的哪些成分用于混合和调整,可以是1,2,3,4。其中:1表示选用R成分;2表示选用R、A成分;3表示选用R、G、B成分;4表示选择R、G、B、A成分。

Format可以接受一下符号常量:

●GL_COLOR_INDEX●GL_RGB●GL_RGBA ●GL_RED

●GL_GREEN ●GL_BLUE ●GL_ALPHA ●GL_LUMINANCE_ALPHA

type可以接受以下符号常量:

●GL_TYPE●GL_UNSIDNED_BYTE ●GL_SHORT ●GL_INT

●GL_UNSIGNED_SHORT ●GL_UNSIGNED_INT ●GL_FLOAT

●GL_BITMAP

参数level用于指定不同分辨率的纹理,使用时自然要考虑纹理波的问题。

2.1.2 二维纹理映射的定义

在OpenGL中,二维纹理的定义与一维纹理略有不同,使用函数g

lTexImage2D(>,该函数的原型为:void glTexImage2D(GLenum target,Glint level,GLenum components,GLsizei width,GLsizei height,Glint border,GLenum gormat,GLenum type,const GLvoid*pixel>

参数说明:

target指定纹理映射,此处必须是GL_TEXTURE_2D。level指定多级分辨率纹理图像,当只有一种分辨率时level=0;components的含义与一维纹理一样,是选择用于调整和混合的成分,各取值及其含义与一维纹理一样;width指定纹理图像的高度,必须是2n,n为正数;height指定纹理图像的高,必须是2n,n为正数;border为边界宽,必须是0和1;format和type分别指定纹理映射的格式和数据类型。其取及其含义与一维纹理定义一致;pixel指定一个指针,指向纹理数据在内存中的位置。

2.1.3 纹理演示实例

部分代码说明:⑴纹理生成函数,该函数用于产生所需要的纹理数据,源代码如

下:

void makeImage(void>

{

int i, j, r,g,b。

for (i = 0。 i < ImageWidth。 i++>

{

for (j = 0。 j < ImageHeight。 j++>

{

r=(i*j>%255。

g=(4*i>%255。

b=(4*j>%255。

Image[i][j][0] = (GLubyte> r。

Image[i][j][1] = (GLubyte> g。

Image[i][j][2] = (GLubyte> b。

}

}

}

⑵初始化函数,在该函数中主要进行了生成纹理数据、设置像素存储模式、定义二维纹理及其参数等操作,原代码如下:

void myinit(void>

{

glClearColor (0.0, 0.0, 0.0, 0.0>。

glEnable(GL_DEPTH_TEST>。

glDepthFunc(GL_LESS>。

makeImage(>。// 生成纹理数据glPixelStorei(GL_UNPACK_ALIGNMENT, 1>。 // 设置像素存储模式

glTexImage2D(GL_TEXTURE_2D, 0, 3, ImageWidth, ImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, &Image[0][0][0]>。 // 定义二维纹理映射glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP>。

glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP>。 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,

GL_NEAREST>。

glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,

GL_NEAREST>。 // 定义纹理映射参数

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL>。

// 数值纹理环境参数

glEnable(GL_TEXTURE_2D>。 // 使用二维纹理

glShadeModel(GL_FLAT>。

}

场景绘制函数,在该函数中首先清除了颜色和缓冲区,然后绘制

了2个定义纹理坐标的四边形,源代码如下:

void CALLBACK display(void>

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT>。

glBegin(GL_QUADS>。

glTexCoord2f(0.0, 0.0>。 glVertex3f(-2.0, -1.0, 0.0>。

glTexCoord2f(0.0, 1.0>。 glVertex3f(-2.0, 1.0, 0.0>。

glTexCoord2f(1.0, 1.0>。 glVertex3f(0.0, 1.0, 0.0>。

glTexCoord2f(1.0, 0.0>。 glVertex3f(0.0, -1.0, 0.0>。

glTexCoord2f(0.0, 0.0>。 glVertex3f(1.0, -1.0, 0.0>。

glTexCoord2f(0.0, 1.0>。 glVertex3f(1.0, 1.0, 0.0>。

glTexCoord2f(1.0, 1.0>。 glVertex3f(2.41421, 1.0, -1.41421>。

glTexCoord2f(1.0, 0.0>。 glVertex3f(2.41421, -1.0, -1.41421>。

glEnd(>。

glFlush(>。

}

2.2纹理数据的获取

在OpenGL中的纹理映射所使用的纹理数据,既可以是程序生成的一组数据,也可以从外部文件中直接读取。

2.1.1直接创建法

直接创建纹理的方法是利用函数直接设置各纹理像素点的RGB值,使用这种方法只能生成简单的有一定的规律的纹理图像,无法模拟复杂的、比较自然的纹理图像。不过OpenGL提供了从外部图像文件中读取纹理的办法。前面的实例就是采用程序直接生成纹理数据的办法,直接设置了各纹理像素点的RGB颜色数值。

2.1.2 读取外部文件

使用外部文件中的纹理数据最简单的方法是利用Windows下提供

的一个函数auxDIBImageLoad(>,该函数的原型为:

AUX_RGBImageRec auxDIBImageLoad(LPCTSTR filename>。

该函数的功能是获取纹理数据,filename指定读取纹理的文件名,该函数可以读取2种类型的文件格式:bmp格式和rgb格式,并且能够根据扩展名的不同,自动选择读取的方法。

2.3 纹理坐标

2.3.1 纹理坐标的指定

在绘制纹理映射场景时,不仅要给出每个顶点定义的几何坐标,同时还要定义纹理坐标。经过多次变换后,几何坐标决定顶点在屏幕上的绘制位置,而纹理坐标决定纹理图像中的哪一个元素赋予该顶点。

纹理图像是方型数组,纹理坐标通常可以定义成1D、2D、3 D或4D的形式,称为s,t,r和q坐标,以区别于物体坐标(x,y,z,w>和其他坐标。

在OpenGL中,定义纹理坐标函数是glTexCood*(>,该函数的原型如下:

void glTexCoord1(GLint s>。

void glTexCoord2 (GLint s,GLint t>。

void glTexCoord3 (GLint s,GLint t,GLint r>。

void glTexCoord4 (GLint s,GLint t,GLint r,GLint q>。

void glTexCoord v(const TYPE *v>。

以上函数的功能为设置当前纹理坐标,s,t,r,q指定纹理坐标,v指定一个指向一元、二元、三元或四元数组的指针,它将顺次指定相应的纹理坐标s,t,r和q。

纹理映射的过程就是纹理坐标和表示物体的几何坐标一一对应的过程,下面的代码是把装入内存的一块纹理图像映射到一个几何四边形。

glBegin(GL_QUAIDS>//画四边形

glTexCoord2f(0.0,0.0>。

glVertex3f(-4.0,-2.0,0.0>。

glTexCoord2f(0.7,0.7>。

glVertex3f(0.0,-2.0,0.0>。

glTexCoord2f(1.0,0.7>。

glVertex3f(0.0,2.0,0.0>。

glTexCoord2f(0.0,0.7>。

glVertex3f(-4.0,2.0,0.0>。

glEnd(>。

在纹理粘贴到物体以前,必须说明纹理怎样和物体匹配,这样所画的几何物体才既有美丽的纹理,又有几何物体的属性。物体的几何属性是由物体的顶点来描述的,由顶点构成物体的许许多多个面,再由这些面来组成几何物体。所以给几何物体顶点赋予适当的纹理坐标,就可以把纹理成功地映射到几何物体上,从而达到期望的效果。

物体模型是由多边形组成的,纹理一般是长方形或正方形图像。如果所选的纹理坐标不当就可能会引起纹理的扭曲。例如,一个正方形的纹理映射到一个长方形上,如果直接全部映射显然会扭曲,为了避免扭曲,就需要纹理和几何长方形之间有一个正确的比例,设长方形的宽/高(w/h>=3/4,四个顶点的坐标为:(0.0,0.0,d>,(w,0.0,d>,(w,h,d>,(h,0.0,d>,则可用下面的代码实现正确的纹理映射:

glTexCoord2f(0.0,0.0>。

glVertex3f(0.0,0.0,d>。

glTexCoord2f(0.75,0.0>。

glVertex3f(w,0.0,d>。

glTexCoord2f(0.75,1.0>。

glVertex3f(w,h,d>。

glTexCoord2f(1.0,0.0>。

glVertex3f(0.0,h,d>。

2.3.2 纹理坐标的自动计算

在某些场合,为获得特殊效果需要自动产生纹理数据,并不要求用函数glTexCoord*(>为每个物体的顶点赋予纹理坐标值。

OpenGL提供了自动生产纹理坐标函数glTexGen(>,该函数的原型为:void glTexGen v(GLenum coord,GLenum pname,TYPE param>;

该函数的功能是控制纹理坐标的生成,coord指定要产生的一个纹理坐标,它可以取GL_S,GL_T,GL_R或GL_Q。pname指定一个纹理坐标生成函数的符号名,它必须是GL_TEXTURE_GEN_MODE,GL_OGJECT_P LANE,GL_EYE_PLANE中指定的任一个。Params指定一个指向纹理生成参数数组的指针。如果参数pname是GL_TEXTURE_GEN_MODE,则该数组必须包括一个单位符号常量,它可以是GL_OBJECT_LINEAR、G L_EYE_LINEAR或GL_SHPERE_MAP。

关闭和启用自动

计算机图形学课程设计--圆柱面图像纹理映射算法

计算机图形学课程设计--圆柱面图像纹理映射算法

《计算机图形学》 课程学习报告 项目题目:圆柱面图像纹理映射算法

目录 一、项目描述............................................................................... .. (1) 1.1圆柱面的建立和二维图像纹理的绑定 (1) 1.2坐标系的建立............................................................................... (1) 二、项目需求............................................................................... .. (1) 2.1 几何构造的原理............................................................................... . (1) 2.2、动画的设计 (2) 2.3 纹理的设计 (2) 2.3.1 纹理映射的原理 (2) 2.3.2 纹理定义 (2) 三、项目设计...............................................................................

(3) 3.1、窗口设计以及各项功能的实现 (3) 3.1.1 窗口设计函数 (3) 3.1.2 点表函数 (4) 3.1.3 面表函数 (4) 3.1.4 绘制圆柱函数 (6) 3.1.5 透视变换函数 (8) 3.1.6 读入纹理函数 (8) 3.1.7 背景函数 (9) 3.1.8 时间函数............................................................................... . (9) 3.1.9 动画控制函数............................................................................... .. (10) 四、项目效果............................................................................... (10) 4.1构造图形分析以及坐标系变换的效果.....................................错误!未定义书签。 五、项目总

实验六凹凸纹理映射技术样本

实验六: 凹凸纹理映射技术 一、实验目的 掌握凹凸纹理映射的原理, 熟悉Ogre中纹理映射的使用方法。 二、实验仪器 pc、 vs 三、实验原理及过程 1、网上检索凹凸纹理映射相关技术 凹凸纹理映射是一种纹理混合方法, 它能够创立三维物体复杂的纹理外观表面。普通的纹理映射只能模拟比较平滑的三维物体表面, 难以显示表面高低起伏、凹凸不平的效果。凹凸纹理映射能够经过一张表示物体表面凹凸程度的高度图( 称为凹凸纹理) , 对另一张表示物体表面环境映射的纹理图的纹理坐标进行相应的干扰, 经过干扰的纹理坐标将应用于环境映射,从而产生凹凸不平的显示效果。凹凸纹理映射一般由三张纹理映射图组成, 第一张纹理图表示物体表面原始纹理颜色, 第二张凹凸纹理图表示物体表面凹凸的高度起伏值, 用来对下一张环境纹理图坐标进行干扰, 第三张纹理图表示周围镜面反射或漫反射光照的环境光照映射图。让我们来看看一个粗糙的表面。 从远处看, 你判断这个物体是粗糙的的唯一证据是在它表面上下的亮度有改变。你的大脑能够获得这些亮暗不一的图案信息, 然后判断出它们是表面中有凹凸的部位。左边的一幅图就说明了这一点。你能够发现它是一个浮雕式的表面。一些矩型和字母被印入表面, 可是它们摸上去就像是一个隐藏的监控器的玻璃。如果这个图像是在适当的位置上, 那么它除了改变亮度, 不需要再做任何其它的工作。那么你可能会问: 我是怎么知道哪些点要亮, 哪些点要暗呢? 这不难。绝大多数人生活在这样一种环境下——这个环境的大多数光源来自上方( 译者注: 比如白天主要的光来自太阳, 夜晚主要的光来自天花板上的日光灯) 。因此向上倾的

地方就会更亮, 而向下倾的地方就会更暗。因此这种现象使你的眼睛看到一个物体上亮暗区域时, 能够判断出它的凹凸情况。相对亮的块被判断是面向上的, 相对暗的块被判断是面向下的。因此我只需要给物体上的线条简单得上色。如果你想要更多的证据, 这里还有一幅几乎相同的图, 不同于前的是它旋转了180度。因此它是前一幅图倒转的图像。那些先前看起来是凹进去的区域, 现在看起来是凸出来的了。 凹凸映射(凹凸纹理)Bump Mapping 这个时候你的大脑并没有被完全欺骗, 你脑中存留的视觉印象使你依然有能力判断出这是前一幅图, 只是它的光源变了, 是从小往上照的你的大脑可能强迫性地判断出它是第一幅图。事实上, 你只要始终盯着它, 而且努力地想像着光是从右下方向照射的, 你就会理解它是凹的( 译者注: 因为日常生活的习惯, 你会很容易把这些图形判断成凸出的图形, 可是因为有了上一幅对照图的印象, 你可能才会特别注意到这些图块其实还是凹入的, 只是判断方法不符合我们日常生活习惯, 因为这时大多数光不是从上方照射, 而是从下往上照射) 。凹凸纹理映射技术能够用来模拟粗糙物体表面凹凸不平的细节, 如: 橘子、草莓、树皮等。凹凸纹理映射最早只能用于离线绘制系统, 随着图形硬件的发展, 她已经成为游戏引擎中不可缺少的部分。最早的凹凸纹理映射使用一个高度图和曲面参数( 一般是纹理坐标) 的偏导数计算扰动后的法向。这个偏导数表明了物体表面改变的尺度。理论上, 凹凸映射中涉及的法向操作实在像素层次上的。 凹凸纹理映射的步骤如下: ( 1) 计算每个顶点处的T、 B、 N, 并计算切平面坐标的矩阵。 ( 2) 根据该矩阵将光源变换到切平面空间, 变换后光源的x、 y即顶点的相邻点。

计算机图形学大作业报告记录(灯光纹理映射)

计算机图形学大作业报告记录(灯光纹理映射)

————————————————————————————————作者:————————————————————————————————日期:

大作业报告 实验课程名称:计算机图形学 学生姓名: 班级: 学院(系):学生学号: 指导教师:成绩:

一、目的 这次大作业是作为这学期的最后的一个考核,所以必须要用到所有的本学期学过的知识,比如怎样画出三维图形,怎样在图像上在图像上添加纹理光照,怎样使用鼠标和键盘进行人机交互等。 二、主要功能模块设计 1 矩阵运算模块的设计: 功能描述:程序启动后,这部分功能模块会为整个应用程序提供算法支持,具体是矩阵直接的相互运算,在2D向3D转化过程中会起到很重要的作用。 代码设计: float vv(float * v1, float * v2){ return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; } void vxv(float * n, float * v1, float * v2){ n[0] = v1[1] * v2[2] - v1[2] * v2[1]; n[1] = v1[2] * v2[0] - v1[0] * v2[2]; n[2] = v1[0] * v2[1] - v1[1] * v2[0]; } void loadIdentity(Matrix m){ Matrix identity = {{1.0,0.0,0.0,0.0}, {0.0,1.0,0.0,0.0}, {0.0,0.0,1.0,0.0}, {0.0,0.0,0.0,1.0}}; for(int i = 0;i < 4; i++) for(int j = 0;j < 4; j++) m[i][j] = identity[i][j]; } void preMultiply(Matrix p, Matrix m){

简单二维纹理映射

#include #include #define imageWidth 64 #define imageHeight 64 GLubyte image[imageWidth][imageHeight][3]; /*绘制一个简单的二维纹理图*/ void makeImage(void) { int i,j,r,g,b; /*根据点的位置设置不同的颜色*/ for(i = 0;i < imageWidth;i++) { for(j = 0;j

立方体纹理映射

1问题描述与算法思想 1.1纹理映射简介 纹理映射(Texture Mapping)是将纹理空间中的纹理像素映射到屏幕空间中的像素的过程。在三维图形中,纹理映射(Texture Mapping)的方法运用得最广,尤其描述具有真实感的物体。比如绘制一面砖墙,就可以使用一幅具有真实感的图像或者照片作为纹理贴到一个矩形上,这样,一面逼真的砖墙就画好了。如果不用纹理映射的方法,这墙上的每一块砖都要作为一个独立的多边形来绘制。另外,纹理映射能够保证在变换多边形时,多边形上的纹理也会随之变化。例如,用透视投影模式观察墙面时,离视点远的墙壁的砖块的尺寸就会缩小,而离视点近的就会大些,这些是符合视觉规律的。此外,纹理映射也被用在其他一些领域。如飞行仿真中常把一大片植被的图像映射到一些大多边形上用以表示地面,或者用大理石、木材等自然物质的图像作为纹理映射到多边形上表示相应的物体。纹理对象通过一个单独的数字来标识。这允许硬件能够在内存中保存多个纹理,而不是每次使用的时候再加载它们,从而减少了运算量,提高了速度。纹理映射是真实感图像制作的一个重要部分,运用它可以方便的制作出极具真实感的图形而不必花过多时间来考虑物体的表面细节。然而纹理加载的过程可能会影响程序运行速度,当纹理图像非常大时,这种情况尤为明显。如何妥善的管理纹理,减少不必要的开销,是系统优化时必须考虑的一个问题。还好,相关软件提供了纹理对象对象管理技术来解决上述问题。与显示列表一样,纹理对象通过一个单独的数字来标识。 立方体映射(cube-map)纹理是一种特殊类型的纹理,用于环境映射,使用一组图像并把他们作为立方体的面。立方体映射的6个面用正方形并且大小相同的6个子纹理表示。要从立方体纹理中采样的时候,使用的纹理坐标是3维,并且被看做来自原点的方向。方向指向用来读取纹理的立方体映射表面的位置。立方体纹理映射主要思想是通过观察向量和表面的法向量反射来确定采样的纹理坐标。 1.2实验目的 1) 掌握位图纹理读入方法; 2)掌握立方体纹理映射算法。 1.3功能要求 1)建立三维坐标系Oxyz,远点位于屏幕客户区中心,x轴水平向右为正,y轴垂直向上为正,z轴垂直于屏幕指向观察者。 2)设置屏幕背景色为黑色。 3)读入六张构成天空盒的位图作为纹理映射到立方体的可见表面上。 4)按下鼠标左键缩小立方体,按下鼠标右键增大立方体。 5)使用键盘方向旋转纹理立方体。 6)使用动画按钮播放或停止立方体动画。 1.4算法原理(算法思想) 立方体进行纹理映射是纹理对象并不是直接绑定到着色器,而是绑定到一个

二维纹理映射

二维纹理映射 一、实验目的和要求 掌握纹理映射的基本原理,利用VC++ OpenGL实现纹理映射技术。 二、实验原理 纹理映射是真实感图形制作的一个重要部分,运用纹理映射可以方面地制作真实感图形,而不必花更多的时间去考虑物体的表面纹理。如一张木制桌子其表面的木纹是不规范的,看上去又是那么自然,如果在图形制作中不用纹理映射,那么只是这张桌面纹理的设计,就要花费很大精力,而且设计结果也未必能像现实中那么自然。如果运用纹理映射就非常方便,可以用扫描仪将这样的一张桌子扫成一个位图。然后的具体的操作中,只需把桌面形状用多边形画出来,把桌面纹理贴上去就可以了。 另外,纹理映射能够在多边形进行变换时仍保证纹理的图案与多边形保持一致性。例如,以透视投影方式观察墙面时,远端的砖会变小,而近处的砖就会大一些。 此外,纹理映射也可以用于其他方面。例如,使用一大片植被的图像映射到一些连续的多边形上,以模拟地貌,或者以大理石、木纹等自然物质的图像作为纹理映射到相应的多边形上,作为物体的真实表面。 在OpenGL中提供了一系列完整的纹理操作函数,用户可以用它们构造理想的物体表面,可以对光照物体进行处理,使其映射出所处环境的景象,可以用不同方式应用到曲面上,而且可以随几何物体的几何属性变换而变化,从而使制作的三维场景和三维物体更真实更自然。 在OpenGL中要实现纹理映射,需要经历创建纹理、指定纹理应用方式、启用纹理映射、使用纹理坐标和几何坐标绘制场景几个过程。 用于指定一维、二维和三维纹理的函数分别为: Void glTexImage1D(GLenum target, Glint level, Glint components, GLsizei width, Glint border, GLenum format, GLenum type, const GLvoid *texels); Void glTexImage2D(GLenum target, Glint level, Glint components, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *texels); Void glTexImage3D(GLenum target, Glint level, Glint components, GLsizei width, GLsizei height, GLsizei depth, Glint border, GLenum format, GLenum type, const GLvoid *texels); 其中,参数target取值一般为GL_TEXTURE_1D, GL_TEXTURE_2D和GL_TEXTURE_3D,分别与一维、二维和三维的纹理相对应。参数Level表示纹理多分辨率层数,通常取值为0,表示只有一种分辨率。参数components的可能取值为1~4的整数以及多种符号常量(如GL_RGBA),表示纹理元素中存储的哪些分量(RGBA颜色、深度等)在纹理映射中被使用,1表示使用R颜色分量,2表示使用R和A颜色分量,3表示使用RGB颜色分量,4表示使用RGBA颜色分量。参数width,height,depth分别指定纹理的宽度、高度、深度。参数format和type表示给出的图像数据的数据格式和数据类型,这两个参数的取值都是符号常量(比如format指定为GL_RGBA,type指定为GL_UNSIGNED_BYTE,参数texels指向内存中指定的纹理图像数据。 在定义了纹理之后,需要启用纹理的函数: glEnable(GL_TEXTURE_1D);

立方体纹理映射

立方体纹理映射

1问题描述与算法思想 1.1纹理映射简介 纹理映射(Texture Mapping)是将纹理空间中的纹理像素映射到屏幕空间中的像素的过程。在三维图形中,纹理映射(Texture Mapping)的方法运用得最广,尤其描述具有真实感的物体。比如绘制一面砖墙,就可以使用一幅具有真实感的图像或者照片作为纹理贴到一个矩形上,这样,一面逼真的砖墙就画好了。如果不用纹理映射的方法,这墙上的每一块砖都要作为一个独立的多边形来绘制。另外,纹理映射能够保证在变换多边形时,多边形上的纹理也会随之变化。例如,用透视投影模式观察墙面时,离视点远的墙壁的砖块的尺寸就会缩小,而离视点近的就会大些,这些是符合视觉规律的。此外,纹理映射也被用在其他一些领域。如飞行仿真中常把一大片植被的图像映射到一些大多边形上用以表示地面,或者用大理石、木材等自然物质的图像作为纹理映射到多边形上表示相应的物体。纹理对象通过一个单独的数字来标识。这允许硬件能够在内存中保存多个纹理,而不是每次使用的时候再加载它们,从而减少了运算量,提高了速度。纹理映射是真实感图像制作的一个重要部分,运用它可以方便的制作出极具真实感的图形而不必花过多时间来考虑物体的表面细节。然而纹理加载的过程可能会影响程序运行速度,当纹理图像非常大时,这种情况尤为明显。如何妥善的管理纹理,减少不必要的开销,是系统优化时必须考虑的一个问题。还好,相关软件提供了纹理对象对象管理技术来解决上述问题。与显示列表一样,纹理对象通过一个单独的数字来标识。 立方体映射(cube-map)纹理是一种特殊类型的纹理,用于环境映射,使用一组图像并把他们作为立方体的面。立方体映射的6个面用正方形并且大小相同的6个子纹理表示。要从立方体纹理中采样的时候,使用的纹理坐标是3维,并且被看做来自原点的方向。方向指向用来读取纹理的立方体映射表面的位置。立方体纹理映射主要思想是通过观察向量和表面的法向量反射来确定采样的纹理坐标。 1.2实验目的 1) 掌握位图纹理读入方法; 2)掌握立方体纹理映射算法。 1.3功能要求 1)建立三维坐标系Oxyz,远点位于屏幕客户区中心,x轴水平向右为正,y轴垂直向上为正,z轴垂直于屏幕指向观察者。 2)设置屏幕背景色为黑色。 3)读入六张构成天空盒的位图作为纹理映射到立方体的可见表面上。 4)按下鼠标左键缩小立方体,按下鼠标右键增大立方体。 5)使用键盘方向旋转纹理立方体。 6)使用动画按钮播放或停止立方体动画。 1.4算法原理(算法思想) 立方体进行纹理映射是纹理对象并不是直接绑定到着色器,而是绑定到一

纹理映射论文

对于纹理映射的学习报告 摘要: 本文主要对于2d纹理图的纹理映射方法展开描述。其中颜色纹理、几何纹理为两大讨论方向,对于颜色纹理的构造,我们通过函数纹理或图像纹理;对于几何纹理,我们可以通过凹凸映射法或位移映射法来实现。 正文: 在计算机图形学中,纹理映射技术的意义是非常重大的,对于纹理映射的定义,我在不同书本上看到了不同的描述,大致表述的内容却是大同小异的,比较容易理解的一种定义是“纹理映射是为三维物体表面添加纹理的技术”,纹理映射的过程可以表述为“将纹理空间的二维坐标(u,v)映射为物体空间的三维坐标(x,y,z),再进一步映射为图像空间的二维坐标(x,y)的过程”。通过纹理映射技术,我们可以改变物体表面的颜色、图案,增强立体感、真实感。原本死气沉沉的图形通过纹理映射处理瞬间像是一个真实的物体展现在你眼前。当然,其中过程处理的技术也是复杂多样的,大致来说,对于2d纹理图(纹理空间坐标是二维的)的纹理映射,主要有颜色纹理、几何纹理等。颜色纹理是通过颜色色彩或明暗度的变化体现出来的物体表面细节,取决于物体表面的光学属性;而几何纹理则是由不规则的细小凹凸构成的,取决于物体表面的微观几何形态。接下来我就对颜色纹理以及几何纹理做以展开。 首先,颜色纹理的出现是在1974年,由Catmull采用二维图像来定义物体表面材质的漫反射率而产生。实现颜色纹理主要有两种方法,一种是直接用纹理的颜色替代物体表面的颜色,另一种是将纹理数据经过光照计算,物体表面的纹理会显示出光照效果。颜色纹理并不 是简单的把图片覆盖住物体表面,这样会导致物体移动的时候,纹理图片没有移动而漂浮在原地,为了避免这种情况,我们还需要将颜色纹理绑定到物体表面,即建立物体空间坐标(x,y,z)与纹理空间坐标(u,v)之间的对应关系。颜色纹理本身难以构造,于是我们又采用函数纹理(连续纹理)或图像纹理(离散纹理)来进行描述。 通过函数纹理映射技术,我们先要计算出物体空间坐标与纹理空间坐标之间的关系函数表达式,例:P(x,y,z)=Au+Bv+C,这样就可以在纹理坐标上的每一点找

立方体纹理映射

立方体纹理映射. 1问题描述与算法思想 1.1纹理映射简介 纹理映射(Texture Mapping)是将纹理空间中的纹理像素映射到屏幕空间中的像素的过程。在三维图形中,纹理映射(Texture Mapping)的方法运用得 最广,尤其描述具有真实感的物体。比如绘制一面砖墙,就可以使用一幅具有真实感的图像或者照片作为纹理贴到一个矩形上,这样,一面逼真的砖墙就画好了。如果不用纹理映射的方法,这墙上的每一块砖都要作为一个独立的多边形来绘制。另外,纹理映射能够保证在变换多边形时,多边形上的纹理也会随之变化。例如,用透视投影模式观察墙面时,离视点远的墙壁的砖块的尺寸就会缩小,而离视点

近的就会大些,这些是符合视觉规律的。此外,纹理映射也被用在其他一些领域。如飞行仿真中常把一大片植被的图像映射到一些大多边形上用以表示地面,或者用大理石、木材等自然物质的图像作为纹理映射到多边形上表示相应的物体。纹理对象通过一个单独的数字来标识。这允许硬件能够在内存中保存多个纹理,而不是每次使用的时候再加载它们,从而减少了运算量,提高了速度。纹理映射是真实感图像制作的一个重要部分,运用它可以方便的制作出极具真实感的图形而不必花过多时间来考虑物体的表面细节。然而纹理加载的过程可能会影响程序运行速度,当纹理图像非常大时,这种情况尤为明显。如何妥善的管理纹理,减少不必要的开销,是系统优化时必须考虑的一个问题。还好,相关软件提供了纹理对象对象管理技术来解决上述问题。与显示列表一样,纹理对象通过一个单独的数字来标识。 立方体映射(cube-map)纹理是一种特殊类型的纹理,用于环境映射,使用一组图像并把他们作为立方体的面。立方体映射的6个面用正方形并且大小相同的6个子纹理表示。要从立方体纹理中采样的时候,使用的纹理坐标是3维,并且 被看做来自原点的方向。方向指向用来读取纹理的立方体映射表面的位置。立方体纹理映射主要思想是通过观察向量和表面的法向量反射来确定采样的纹理坐标。 1.2实验目的 1) 掌握位图纹理读入方法; 2)掌握立方体纹理映射算法。 1.3功能要求 1)建立三维坐标系Oxyz,远点位于屏幕客户区中心,x轴水平向右为正,y轴垂直向上为正,z轴垂直于屏幕指向观察者。 2)设置屏幕背景色为黑色。 3)读入六张构成天空盒的位图作为纹理映射到立方体的可见表面上。 4)按下鼠标左键缩小立方体,按下鼠标右键增大立方体。 5)使用键盘方向旋转纹理立方体。 6)使用动画按钮播放或停止立方体动画。 1.4算法原理(算法思想)

计算机图形学实验三(纹理映射)

实验三纹理映射 一、实验目的 (1)掌握OpenGl的三维图形制作方法 (2)掌握Visual C++环境下的OpenGL图形开发 二、实验内容 在三维图像上添加纹理映射 三、实验结果 实验代码如下: /*********************************************** * glut_applicationwriten by yyb * ***********************************************/ #include #include #include #include #pragma comment(lib,"glaux.lib") #define MAX_TEXTURES 6 // max textures displayed /* creates a enum type for mouse buttons */ enum { BUTTON_LEFT = 0, BUTTON_RIGHT, BUTTON_LEFT_TRANSLATE, }; intmButton = -1; intmOldY, mOldX; boolfullscreen; //////////////////////////////////// float eye[3] = {0.0f, 0.0f, 7.0f}; float rot[3] = {45.0f, 45.0f, 0.0f}; constint ESC = 27; int wireframe = 0; constint GL_WIN_WIDTH = 640; constint GL_WIN_HEIGHT = 480; constint GL_WIN_INITIAL_X = 0; constint GL_WIN_INITIAL_Y = 0; /* array to hold texture handles */ GLuintg_TexturesArray[MAX_TEXTURES];

相关文档
最新文档