DDS支持的Mipmap Texture/Cubemap Texture/Volume Texture 纹理理解

来源:互联网 发布:简单的java程序代码 编辑:程序博客网 时间:2024/05/22 10:28

1)DDS支持的mipmap Texture多级渐进纹理映射技术(DX Texture Tool 默认):
在三维计算机图形的贴图渲染中有一个常用的技术被称为Mipmapping。为了加快渲染速度和减少图像锯齿,贴图被处理成由一系列被预先计算和优化过的图片组成的文件,这样的贴图被称为 MIP map 或者 mipmap。这个技术在三维游戏中被非常广泛的使用。“MIP”来自于拉丁语 multum in parvo 的首字母,意思是“放置很多东西的小空间”。Mipmap 需要占用一定的内存空间,同时也遵循小波压缩规则 (wavelet compression)。
D3DXCreateTextureFromFileEx()自动生成多级渐进纹理序列,MipLevels参数含义[in] Number of mip levels requested. If this value is zero or D3DX_DEFAULT, a complete mipmap chain is created. If D3DX_FROM_FILE, the size will be taken exactly as it is in the file, and the call will fail if this violates device capabilities.
默认是0级,将自动的产生一直降到1*1的所有mip。将usage设为D3DUSAGE_AUTOGENMIPMAP将自动产生mipmap如果贴图的基本尺寸是256x256像素的话,则每个层级是上一层级的四分之一的大小,依次层级大小就是:128x128;64x64;32x32;16x16;8x8;4x4;2x2;1x1(一个像素))。

2)DDS支持的Cubemap Texture立方环境映射是现在常用环境映射技术(DX Texture Tool 要求填面)
我们知道游戏场景中经常通过在一个正方体上的六个面贴上前后左右上下六个贴图来模拟天空、宇宙等环境,称为 Cubemap有的引擎中成为Skybox,立方环境映射的原理就是在游戏中所需要产生映射的物体的位置动态生成一套Cubemap,再对Cubemap 进行采样生成物体表面应该反射出的周遭环境。
可以使用它是作为6个面的纹理,也可以设置它是那个面的纹理
pd3dDevice->CreateCubeTexture(256,1,D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT , &m_pCubeMap,NULL );

or( int nFace = 0; nFace < 6; ++nFace ) //依次完成Cubemap中的六个面的绘制
{
LPDIRECT3DSURFACE9 pSurf;
V( m_pCubeMap->GetCubeMapSurface( (D3DCUBEMAP_FACES)nFace, 0, &pSurf ) );
V( pd3dDevice->SetRenderTarget( 0, pSurf ) );
SAFE_RELEASE( pSurf );
...
}

3)DDS支持的Volume Texture 3D纹理或者叫体纹理(DX Texture Tool 要求填多少片(层次),2,4,6,8,..,1024等)

体纹理的定义是:

3D texture (Three Dimensional Texture), also known as "volume texture," is a logical extension of the traditional (and better known) 2D texture. In this context, a texture is simply a bitmap image that is used to provide surface coloring for a 3D model. A 3D texture can be thought of as a number of thin pieces of texture used to generate a three dimensional image map. 3D textures are typically represented by 3 coordinates.

翻译成中文就是 “ 三维纹理,即体纹理,是传统 2D 纹理在逻辑上的扩展。二维纹理是一张简单的位图图片,用于为三维模型提供表面点的颜色值;而一个三维纹理,可以被认为由很多张 2D 纹理组成的,用于描述三维空间数据的图片。三维纹理通过三维纹理坐标进行访问 ” 。

从上面这句话,可以得到两点信息:

1.        三维纹理和体纹理是同一概念;三维纹理和二维纹理是不同的;

2.        三维纹理通过三维纹理坐标进行访问。

这时可能会有人提出问题了,图片都是平面的,怎么能表示三维数据?请注意,我们通常所看到的图片确实都是平面的,但是并 不意味着 x,y 平面上的像素点不能存放三维数据,举一个例子:在高级语言编程中,我们完全可以用一维数组去存放三维数组中的数据,只要按照一定规则存放即可!

按照一定规则将三维数据存放在 XY 像素平面所得到的纹理,称之为 volume texture 。

体数据通常是由 CT 仪器进行扫描得到的,然后保存在图片的像素点上。目前国际上比较常用的体纹理格式有,基于 DirectX 的 .dds 格式和 .raw 格式。注意,很多人会将 .raw 格式当作摄像器材使用的那种格式,其实这两个格式的后缀虽然都是 .raw ,但是其数据组织形式是不同的。用于体纹理的 .raw 格式,存放的是三维数据,用于摄像器材的 .raw 格式只是普通的二维图片。

立体纹理

立体纹理是三维像素(texel)的集合,可以用来绘制诸如三角形或线之类的二维图元。对于每个使用立体纹理的图元来说,图元的每个顶点需要包含三 元素纹理坐标。在绘制图元时,图元覆盖的每个像素的颜色来自立体纹理中的某个像素,这和二维纹理中的情况相一致。因为不存在可以用立体纹理进行绘制的真正 的三维图元,所以立体纹理不能直接用来渲染。

应用程序可以把立体纹理用于诸如patchy fog,爆炸等特效

立体纹理由多片(层次)组织而成,可以把它想象成把大小为width height的二维表面叠在一起形成的大小为width x height x depth的立体纹理。每片为一行。立体纹理可以有后续的级,每一级的大小为前一级大小的一半。下图给出了一个多级立体纹理看起来的样子。


以下示例代码显示了使用立体纹理所需的步骤。

首先,定义一个包含三个纹理坐标的自定义顶点类型,如以下示例代码所示。

struct VOLUMEVERTEX

{

    FLOAT x, y, z;

    DWORD color;

    FLOAT tu, tv, tw;

};

 

#define D3DFVF_VOLUMEVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|

                             D3DFVF_TEX1|D3DFVF_TEXCOORDSIZE3(0))

然后,把数据填入顶点。

VOLUMEVERTEX g_vVertices[4] =

{

    { 1.0f, 1.0f, 0.0f, 0xffffffff, 1.0f, 1.0f, 0.0f },

    {-1.0f, 1.0f, 0.0f, 0xffffffff, 0.0f, 1.0f, 0.0f },

    { 1.0f,-1.0f, 0.0f, 0xffffffff, 1.0f, 0.0f, 0.0f },

    {-1.0f,-1.0f, 0.0f, 0xffffffff, 0.0f, 0.0f, 0.0f }

};

现在,创建一个顶点缓存,并填入顶点数据。

下一步是用IDirect3DDevice9::CreateVolumeTexture创建一个立体纹理,如以下示例代码所示。

LPDIRECT3DVOLUMETEXTURE9 pVolumeTexture;

d3dDevice->CreateVolumeTexture( 8, 4, 4, 1, 0, D3DFMT_R8G8B8,D3DPOOL_MANAGED,

                                &pVolumeTexture );

在渲染图元之前,把当前纹理设为前面创建的立体纹理。以下示例代码显示了渲染一个三角形带的整个过程。

if( SUCCEEDED( d3dDevice->BeginScene() ) )

{

    // 用立体纹理绘制四边形。

    d3dDevice->SetTexture( 0, pVolumeTexture );

    d3dDevice->SetFVF( D3DFVF_VOLUMEVERTEX );

    d3dDevice->SetStreamSource( 0, pVB, sizeof(VOLUMEVERTEX) );

    d3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2);

 

   // 结束绘制。

   d3dDevice->EndScene();


0 0
原创粉丝点击