soief的专栏

穷人吧

纹理

本文译自微软DirectX 6.1帮助文件,英文版权属MicroSoft公司所有,中文版权(如果有的话:-))属程连冀、刘长松所有。

Direct3D支持广泛的纹理特性设置,使程序员可以轻松的访问提供高级纹理技术。下面我们来讨论Direct3D中的纹理的一些内容:

1. 纹理的基本概念

这一部分中讲述了Direct3D中有关纹理的一些概念,我们分以下几个部分来分别讨论:

1.1 什么是纹理?

早期的计算机生成的3-D图象,它们的表面看起来就象是一个发亮的塑料表面。它们总是缺少一些能使物体看起来更加真实的东西,如表面的磨损、裂纹、人手的印记或是一些污点等等。近几年来,纹理的使用使得计算机三维图象具有了更好的真实感。

一个纹理实际上就是一个位图。从这个意义上来讲,当纹理一词被用于计算机图形学时,它就有了一个明确的定义。从语义学角度来讲,纹理一词既是指一个物体上颜色的模式,又是指物体表面是粗糙的还是光滑的。Direct3D的纹理不会使物体表面真的变得“崎岖不平”,而只是使它的表面看起来是“崎岖不平”的。

由于Direct3D的纹理就是简单的位图,因此任何纹理否可以被用在Direct3D图元上。例如,我们可以创建一些具有木头和谷物图案的对象;也可以将一些青草、泥土和岩石用于一些三维图元,并将它们堆成一座小山,这样就有了一个山坡的背景;或者搞一些路标、悬崖等等。

另外,Direct3D还支持一些高级的纹理技术,如纹理融合(透明或不透明)、光线映射(light mapping)等。

如果程序创建了一个HAL设备、MMX设备或RGB设备,它就可以使用8-、16-、24-或32-bit纹理。使用单色设备的程序可以使用8-bit纹理。

1.2 纹理坐标

纹理实际上是一个二维数组,它的元素是一些颜色值。单个的颜色值被称为纹理元素(texture elements)或纹理像素(texel)。每一个纹理像素在纹理中都有一个唯一的地址。这个地址可以被认为是一个列(column)和行(row)的值,它们分别由U和V来表示。

纹理坐标位于纹理空间中。也就是说,它们和纹理中的(0,0)位置相对应。当我们将一个纹理应用于一个图元时,它的纹理像素地址必须要映射到对象坐标系中。然后再被平移到屏幕坐标系或像素位置上。

Direct3D直接将纹理空间中的纹理像素

映射到屏幕空间中的像素,跳过了中间过程,从而提高了效率。这一映射过程实际上是一个相反的(inverse)映射。也就是说,对于屏幕空间中的每一个像素,我们来计算相应的纹理空间中的纹理像素位置。对那一点上的或那一点周围的纹理颜色进行采样(sample)。采样过程被称为纹理过滤(texture filtering)。

纹理中的每一个纹理像素可以通过它的坐标来声明。但是,为了将纹理像素映射到图元上,对于所有纹理上的所有纹理像素,Direct3D需要有一个统一的地址范围。因此,它使用了一个通用的地址方案,在这个方案中所有纹理像素地址的范围都在0.0到1.0之间,包括0.0和1.0。Direct3D程序用U、V的值来声明纹理坐标,它和用x、y坐标来声明二维迪卡尔坐标系一样。

在这种情况下,不同纹理中的同一纹理地址又可能被映射为不同的纹理像素坐标。如左面插图中的纹理地址(0.0,0.5)。由于纹理的大小有所不同,因此纹理地址将会映射为不同的纹理像素。左边的纹理1,大小为5×5,纹理地址(0.0,0.5)映射到纹理像素(0,2);右边的纹理2,大小为7×7,纹理地址(0.0,0.5)映射到纹理像素(0,3)。

左图展示了一个简单的纹理像素映射的过程:

我们要给图中左边的像素确定一定的颜色。像素四个角的地址被映射到对象空间中的图元上,这时,像素的形状会有一些变形,这是由图元的形状和观察的角度造成的。然后,与像素角相对应的图元表面上的几个角被映射到纹理空间中。这一映射过程再次使像素的形状产生变形。像素最终的颜色值就由该像素映射到的区域中的纹理像素计算而得。在设置纹理过滤方法时,要决定Direct3D使用什么方法来得到像素的颜色。

程序可以直接将纹理坐标分配给顶点。这一能力使我们能够控制将一个纹理的哪些部分映射到一个图元上。现在假定我们要创建一个矩形图元,它的大小恰好与下图中纹理的大小一样。我们要将整个纹理都映射到一整堵墙上,那么分配给图元顶点的纹理坐标就应该是(0.0,0.0)、(1.0,0.0)、(1.0,1.0)和(0.0,1.0)。

现在我们要将墙的高度缩小一半。我们可以将纹理变形以适应墙的变化,也可以在分配纹理坐标时只使用纹理的下面一半。

如果使用纹理变形或缩放的方法,那么所使用的纹理过滤方法就会对图象的质量产生影响。详细内容见“纹理过滤”。

如果采用分配纹理坐标的方法,那么分配给图元顶点的纹理坐标就应该是(0.0,0.0)、(1.0,0.0)、(1.0,0.5)和(0.0,0.5)。Direct3D会将纹理的下面一半应用到墙上。

有时,一个顶点的纹理坐标可能比1.0大。当分配给顶点的纹理坐标不在0.0到1.0(包括它们)范围内时,就要设置纹理寻址模式了。

1.3 纹理寻址模式

下面我们来讨论Direct3D纹理寻址模式。

1.3.1 什么是纹理寻址模式?

Direct3D程序可以将纹理坐标分配给任何图元的顶点。一般来说,分配的U、V纹理坐标值都在0.0到1.0范围内(包括它们)。但是,如果我们分配了超出这个范围的纹理坐标,可能会得到一些特别的纹理效果。

通过设置纹理寻址模式,我们就可以在纹理坐标超出范围时进行控制。详细的内容请看下面的相关讨论:

1.3.2 Wrapping纹理寻址模式

“Wrapping”纹理寻址模式由D3DTEXTUREADDRESS枚举类型的D3DTADDRESS_WRAP成员来确定,它使Direct3D在每一个整数结点(integer junction)对纹理进行重复。假设我们要创建一个正方形图元,并将纹理坐标声明为(0.0,0.0)、(0.0,3.0)、(3.0,3.0)和(3.0,0.0)。这时,如果我们设置了纹理寻址模式,就可以使纹理在U、V方向都重复三次。,如下图所示:

这种纹理寻址模式的效果与“镜像”模式比较相似,但在本质上是不同的。

1.3.3 镜像纹理寻址模式

飞机一阵抖动,我终于说出了最后一句再见。

soief的专栏

相关文章:

你感兴趣的文章:

标签云: