directX学习系列8 颜色融合(转)
1, Multipass(多通道)
将一个任务划分成几个阶段,由多个pass处理不同阶段,后续pass总是处理前一个pass的结果。例如复杂的光照方程可以分成几个pass来计算。
用不同的纹理通过多个pass来多次渲染一个图元,这样可以实现许多很酷的特效。例如LightMap,它就是用不同的纹理来表示复杂的光、影效果。
2, Multitexture(多纹理)
很显然,pass越多,效率越低。为了降低pass的数量,有些硬件加速卡支持在一个pass中渲染两个或更多的纹理,这种技术就叫做multitexture。D3D在一个pass中最多支持8个纹理的混合。
3, Pipeline(管道)
可以将管道想像成一条流水线,它完成某项任务。
4, Stage
一个管道可以由多个stage组成,这些stage同时运行,所以管道的速度取决于最慢的stage。
5, Texture blending cascade
Texture blending cascade是一个pipeline,它完成在一个pass中混合多个纹理这个任务。
6, Texture Stage(也叫做texture unit)
Texture blending cascade由许多Texture Stage构成,每个Texture Stage混合两个纹理(或经过计算的顶点集),通常是RGB和Alpha值,并将结果(经过计算的顶点集)传递给下一个Texture Stage。
理解了上面的那些概念,理解SetTextureStageState函数就很容易了。
HRESULT SetTextureStageState(
DWORD Stage,
D3DTEXTURESTAGESTATETYPE Type,
DWORD Value
);
1, Stage参数,D3D支持8个Texture Unit,索引值由0~7,通过此参数你可以指定是哪一个Texture Unit。
2, Type参数,用来选择Texture Stage不同的状态,如D3DTSS_COLOROP代表颜色混合操作,D3DTSS_ALPHAOP代表ALPHA值混合操作。
3, Value参数,根据不同的Type,来设置其状态值。如:SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_ADD ),就是指在第一个Texture Unit中,将两个颜色值的混合操作设定为累加。 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT SetTextureStageState(
DWORD Stage,
D3DTEXTURESTAGESTATETYPE Type,
DWORD Value
);
stage这个参数是指第几层纹理,1.2.3...9,, 这个版本的dx最多支持9层纹理。
Type:Defines the type of operation that a texture stage will perform.//定义对该纹理的哪个属进行设置,值很多。。。
Value: 指的是前面所选属性的值
type:
D3DTSS_ALPHAOP = 4, //alpha通道的运算,
D3DTSS_COLOROP = 1, //颜色的运算
//这里的op 是operations,指对前面设置的颜色进行运算
//既后面的2个type:D3DTSS_COLORARG1,D3DTSS_COLORARG2
//或D3DTSS_ALPHAARG1,D3DTSS_ALPHAARG2 = 6
value:
D3DTOP_DISABLE = 1, //该纹理无效,既不显示
D3DTOP_SELECTARG1 = 2, //Arg1
D3DTOP_SELECTARG2 = 3, //Arg2
D3DTOP_MODULATE = 4, //Arg1 * Arg2
D3DTOP_MODULATE2X = 5, //Arg1 * Arg2 * 2
D3DTOP_MODULATE4X = 6, //Arg1 * Arg2 * 4
D3DTOP_ADD = 7, // Arg1 + Arg2
D3DTOP_ADDSIGNED = 8, //(Arg1 + Arg2 - 0.5)
D3DTOP_ADDSIGNED2X = 9, //(Arg1 + Arg2 - 0.5)*2
D3DTOP_SUBTRACT = 10, //Arg1 - Arg2
D3DTOP_ADDSMOOTH = 11, //Arg1 + Arg2 – Arg1 * Arg2
D3DTOP_BLENDDIFFUSEALPHA = 12, //将Arg1与Arg2使用Alpha值进行线性插值。这是标准的Alpha混合效果。纹理参数常数 TextureArgumentConstants同样可以设置到Value里
D3DTOP_BLENDTEXTUREALPHA = 13,
D3DTOP_BLENDFACTORALPHA = 14,
D3DTOP_BLENDTEXTUREALPHAPM = 15,
D3DTOP_BLENDCURRENTALPHA = 16,
D3DTOP_PREMODULATE = 17,
D3DTOP_MODULATEALPHA_ADDCOLOR = 18,
D3DTOP_MODULATECOLOR_ADDALPHA = 19,
D3DTOP_MODULATEINVALPHA_ADDCOLOR = 20,
D3DTOP_MODULATEINVCOLOR_ADDALPHA = 21,
D3DTOP_BUMPENVMAP = 22,
D3DTOP_BUMPENVMAPLUMINANCE = 23,
D3DTOP_DOTPRODUCT3 = 24,
D3DTOP_MULTIPLYADD = 25, //SRGBA = Arg1 + Arg2 * Arg3
D3DTOP_LERP = 26,
D3DTOP_FORCE_DWORD = 0x7fffffff,
type:
D3DTSS_COLORARG1 = 2,
D3DTSS_COLORARG2 = 3,
D3DTSS_ALPHAARG1 = 5,
D3DTSS_ALPHAARG2 = 6,
D3DTSS_COLORARG0 = 26,
D3DTSS_ALPHAARG0 = 27,
D3DTSS_RESULTARG = 28,
value:
这里的TA指的是texture arguments ,
D3DTA_CURRENT 表示上一个Stage混合的结果。Stage=0时,这个值表示的是D3DTA_DIFFUSE
D3DTA_CONSTANT //给当前纹理一个固定的值;
D3DTA_DIFFUSE; //diffuse的值作为参数 diffuse 可能有多个来源。。比如材质,vertex
D3DTA_SELECTMASK //Mask value for all arguments; not used when setting texture arguments 这句话不理解啊,为什么要伪装呢
D3DTA_SPECULAR //取spercular 的值作为参数 来源同diffuse
D3DTA_TEMP //待定。。
D3DTA_TEXTURE //用纹理的颜色值作为参数
D3DTA_TFACTOR //待定。。
D3DTSS_BUMPENVMAT00 = 7,
D3DTSS_BUMPENVMAT01 = 8,
D3DTSS_BUMPENVMAT10 = 9,
D3DTSS_BUMPENVMAT11 = 10,
D3DTSS_TEXCOORDINDEX = 11,
D3DTSS_BUMPENVLSCALE = 22,
D3DTSS_BUMPENVLOFFSET = 23,
D3DTSS_TEXTURETRANSFORMFLAGS = 24,
D3DTSS_CONSTANT = 32,
D3DTSS_FORCE_DWORD = 0x7fffffff,
m_pD3DDevice->SetTexture( 0, m_pTexture0 ); // 土地材質
m_pD3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );
// TextureStage 0 (不做任何改變)
m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
//------------
m_pD3DDevice->SetTexture( 1, m_pTexture1 ); // 草地材質
m_pD3DDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 0 );
// TextureStage 1 (使用頂點alpha值計算混合)
m_pD3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_BLENDDIFFUSEALPHA );
m_pD3DDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pD3DDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
m_pD3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
//------------
// TextureStage 2 (使用光影遮罩圖) // 光影材質
m_pD3DDevice->SetTexture( 2, m_pTexture2 );
m_pD3DDevice->SetTextureStageState( 2, D3DTSS_TEXCOORDINDEX, 1 );
m_pD3DDevice->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_MODULATE2X );
m_pD3DDevice->SetTextureStageState( 2, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pD3DDevice->SetTextureStageState( 2, D3DTSS_COLORARG2, D3DTA_CURRENT );
m_pD3DDevice->SetTextureStageState( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
//------------
// TextureStage 3 (使用頂點值計算陰影)
m_pD3DDevice->SetTextureStageState( 3, D3DTSS_COLOROP, D3DTOP_MODULATE );
m_pD3DDevice->SetTextureStageState( 3, D3DTSS_COLORARG1, D3DTA_DIFFUSE );
m_pD3DDevice->SetTextureStageState( 3, D3DTSS_COLORARG2, D3DTA_CURRENT );
m_pD3DDevice->SetTextureStageState( 3, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
黑暗纹理
通过纹理映射来模拟逐像素光照效果,通常是将第一层纹理设置为物体原来的表面纹理,将第二层纹理设置为光照纹理,然后将两张纹理的颜色相乘,所以有时将两张纹理的颜色相乘称为光照映射(light mapping)。由于这种技术经常被用于使一张纹理变暗,有时也称为黑暗映射(dark mapping)。
混合纹理与顶点漫反射颜色
当很强的阳光照射在物体表面上时,会使它表面的颜色变得更加明亮,这可以通过将纹理与顶点的漫反射颜色相混合来模拟这种效果。当一个白色材质反射一个方向光时,反射量越多,就意味着纹理颜色在最终显示结果中所占的成分越少。因此,那些被光直接照射到表面会呈现出白色。示例代码如下:
// setup light
ZeroMemory(&g_light, sizeof(D3DLIGHT9));
g_light.Type = D3DLIGHT_DIRECTIONAL;
g_light.Diffuse.r = 0.5f;
g_light.Diffuse.g = 0.5f;
g_light.Diffuse.b = 0.5f;
D3DXVECTOR3 light_dir(0, 0, 10);
D3DXVec3Normalize((D3DXVECTOR3*) &g_light.Direction, &light_dir);
// setup material
ZeroMemory(&g_material, sizeof(D3DMATERIAL9));
g_material.Ambient.r = 1.0f;
g_material.Ambient.g = 1.0f;
g_material.Ambient.b = 1.0f;
g_material.Ambient.a = 1.0f;
g_material.Diffuse.r = 0.7f;
g_material.Diffuse.g = 0.7f;
g_material.Diffuse.b = 0.7f;
g_material.Diffuse.a = 0.5f;
pd3dDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
pd3dDevice->SetRenderState(D3DRS_AMBIENT, 0x00808080);
pd3dDevice->SetLight(0, &g_light);
pd3dDevice->LightEnable(0, TRUE);
pd3dDevice->SetMaterial(&g_material);
pd3dDevice->SetTexture(0, g_base_texture);
pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_ADD);
pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
发光映射
发光映射(glowing mapping)与黑暗映射正好相反,它对于模拟那些具有独立于基础贴图的发光部分的物体很有用,比如模拟发光二极管、按钮、建筑物内的灯光、太空船上的灯光等。发光映射应仅影响基础贴图上的发光区域,而不影响其他部分。因此需要对发光效果做加法,而不是做乘法。
pd3dDevice->SetTexture(0, g_base_texture);
pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
pd3dDevice->SetTexture(1, g_dark_texture);
pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);
pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD);
细节映射
如果要模拟一块粗糙的石灰泥墙壁,可以通过细节映射(detail mapping)来实现。实现过程是:将基础贴图(也就是第一张纹理)的颜色未经修改便作为第二个纹理操作阶段中的第二个参数,然后通过D3DTOP_ADDSIGNED将灰色的细节纹理与基础贴图相加。这个操作本质上是做了一个加法,只是使用了有符号的颜色值来代替平时使用的无符号值。在对两张纹理的像素颜色进行D3DTOP_ADDSIGNED操作时,它将参数的每个成分相加后再减去偏移量0.5,从而使有效值域变为-0.5 ~ 0.5。对一些比较旧的显卡,当其不能支持D3DTOP_ADDSIGNED操作时,可以使用D3DTOP_MODULATE2X代替D3DTOP_ADDSIGNED操作进行模拟。
在细节贴图中较亮的灰色纹理元素会使基础贴图变得更亮,而较暗的灰色纹理元素会使基础贴图变得更暗。由此可使物体呈现出粗糙的表面,从而使之看上去更为真实。示例代码如下:
pd3dDevice->SetTexture(0, g_base_texture);
pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
pd3dDevice->SetTexture(1, g_detail_texture);
pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);
pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
hr = pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADDSIGNED);
if(FAILED(hr))
pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE2X);
ALPHA混合操作
Direct3D在渲染一个场景时,它可以结合几种来源的颜色信息:顶点、当前材质、纹理贴图、先前写入渲染目标的颜色信息,然后将其中的一些颜色混合起来。同时也可以使用Alpha来指定Direct3D该以怎样的权重混合这些颜色,Alpha信息可以存储在顶点中、材质中、纹理贴图中。Alpha值为0表示完全透明,Alpha值为1表示不透明,其余0~1之间的值表示不同程度的透明。
如果要从一张纹理中获取Alpha值,应将D3DTA_TEXTURE作为Alpha参数。
如果要使用来自顶点中的Alpha值,应将D3DTA_DIFFUSE作为Alpha参数,并确保渲染状态D3DRS_DIFFUSEMATERIALSOURCE被设置为D3DMCS_COLOR1(这也是默认状态)。
如果要使用来自材质中的Alpha值,应将D3DTA_DIFFUSE作为Alpha参数,并确保渲染状态D3DRS_DIFFUSEMATERIALSOURCE被设置为D3DMCS_MATERIAL。
如果未用SetRenderState()设置D3DRS_DIFFUSEMATERIALSOURCE参数,则从默认来源(即顶点)获取漫反射颜色。
pd3dDevice->SetTexture(0, g_texture);
pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
纹理坐标自动生成
在Direct3D程序中,不仅可以在模型载入阶段或渲染阶段指定物体的纹理坐标,还可以通过Direct3D渲染引擎自动生成纹理坐标,用于诸如环境映射等特殊的视觉效果。与手动设置纹理坐标相比,纹理坐标自动生成在Direct3D坐标变换和光照流水线中完成,执行速度更快。
Direct3D系统可以使用经过变换的摄像机空间顶点位置坐标、法线信息来生成纹理坐标。如果使用纹理坐标自动生成,那么在顶点中就可以不用包含纹理坐标数据,从而可以降低图形渲染时的数据传输量。纹理坐标自动生成主要用于产生一些特殊效果,在大多数情况下还是手工为每个顶点指定纹理坐标。
通过调用SetTextureStageState()并将第二个参数设置为D3DTSS_TEXCOORDINDEX来控制Direct3D系统如何自动生成纹理坐标。
D3DTSS_TEXCOORDINDEX用于指定特定纹理层使用顶点中的第几组纹理坐标,但如果指定了上表中的成员值,Direct3D将忽略顶点中的纹理坐标,转而使用自动生成的纹理坐标。
D3DTSS_TEXTURETRANSFORMFLAGS用来控制生成的纹理坐标的输出,在大多数情况下纹理坐标是二维的,即将D3DTSS_TEXTURETRANSFORMFLAGS设置为D3DTTFF_COUNT2。但当绘制线段或三维纹理时,纹理坐标可能是一维或三维的。
纹理坐标变换
Direct3D提供了对生成的纹理坐标进行坐标变换的功能,与顶点坐标变换相类似,可以指定一个4x4的纹理坐标变换矩阵,把它与生成的纹理坐标相乘,然后将变换之后的纹理坐标输出至Direct3D渲染流水线。使用纹理坐标变换可以对纹理坐标进行诸如平移、旋转和缩放等三维变换。纹理坐标变换对于生成一些特殊效果是非常有用的,它不用直接修改顶点的纹理坐标。例如可以通过一个简单的平移矩阵对纹理坐标进行变换,从而使物体表面上的纹理不断变换位置,产生动画效果。纹理坐标自动生成在三维图形程序中最广泛的应用是环境映射。
可通过函数IDirect3DDevice9::SetTransform()来设置4x4的纹理坐标变换矩阵,它以D3DTS_TEXTURE0~ D3DTS_TEXTURE7作为第一个参数,表示设置纹理层0~7的纹理矩阵。下列代码对纹理层0设置了一个将纹理坐标u、v缩小到原来一半的纹理矩阵:
D3DXMATRIX mat;
D3DXMatrixIdentity(&mat);
mat._11 = 0.5f;
mat._22 = 0.5f;
pd3dDevice->SetTransform(D3DTS_TEXTURE0, &mat);
下面的代码将原来的纹理坐标平移(1.0, 1.0, 0)个单位。
D3DXMATRIX mat;
D3DXMatrixIdentity(&mat);
mat._41 = 1.0f;
mat._42 = 1.0f;
mat._43 = 0.0f;
pd3dDevice->SetTransform(D3DTS_TEXTURE0, &mat);
示例程序通过下列代码对自动生成的纹理坐标进行变换:
// texture coordinate transform
D3DXMATRIX mat_texture, mat_scale, mat_trans;
D3DXMatrixIdentity(&mat_texture);
D3DXMatrixScaling(&mat_scale, 0.5f, -0.5f, 1.0f);
D3DXMatrixTranslation(&mat_trans, 0.5f, 0.5f, 1.0f);
mat_texture = mat_texture * mat_scale * mat_trans;
pd3dDevice->SetTransform(D3DTS_TEXTURE0, &mat_texture);
立方体环境映射
立方体环境映射图有时又称为立方体映射图,是一组包含物体周围环境图像的纹理贴图,好像物体在立方体的中心。立方体环境图的每个面覆盖水平和垂直方向上各90度视角区域,一共6个面.
球形环境映射
球形环境映射图(或称为球形映射图)和立方体环境映射图类似,也是一幅包含周围场景图像的特殊纹理。和立方体环境映射图不同的是,球形环境映射图不直接代表物体周围的环境。球形映射图就好像通过鱼眼(fish-eye)凸透镜观察到的景象一样,是一个物体周围环境360度全方位视域的三维表现。
首先使用一张球形的背景图作为环境映射纹理,接着在回调函数OnCreateDevice()中加载纹理和网格模型,接着在回调函数OnResetDevice()中自动生成纹理坐标,并设置纹理阶段颜色混合方法,最后在回调函数OnFrameRender()中渲染茶壶:
V_RETURN(D3DXCreateTextureFromFile(pd3dDevice, L"spheremap.bmp", &g_env_texture));
ID3DXBuffer* material_buffer;
V_RETURN(D3DXLoadMeshFromXW(L"teapot.x", D3DXMESH_MANAGED, pd3dDevice, NULL, &material_buffer, NULL, &g_num_materials, &g_mesh));
D3DXMATERIAL* xmaterials = (D3DXMATERIAL*) material_buffer->GetBufferPointer();g_mesh_materials = new D3DMATERIAL9[g_num_materials];
for(DWORD i = 0; i < g_num_materials; i++){ g_mesh_materials[i] = xmaterials[i].MatD3D;
// .x file do not save ambient data, so set it here. g_mesh_materials[i].Ambient = g_mesh_materials[i].Diffuse; }
material_buffer->Release();
pd3dDevice->SetTexture(0, g_env_texture);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_SPHEREMAP);
pd3dDevice->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
// Clear the render target and the zbuffer V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0) );
// Render the scene
if( SUCCEEDED( pd3dDevice->BeginScene() ) )
{ for(DWORD i = 0; i < g_num_materials; i++)
{
pd3dDevice->SetMaterial(&g_mesh_materials[i]);
g_mesh->DrawSubset(i);
}
RenderText();
V(g_button_dlg.OnRender(fElapsedTime));
V( pd3dDevice->EndScene() );
}
DXT纹理压缩
要渲染看起来真实的场景,最好是使用高分辨率而且颜色丰富的纹理,但这样的纹理可能会耗费大量的内存,例如,一张每像素16位颜色的256 x 256纹理将使用128KB的内存。如果在该纹理中使用多级渐进纹理,还需要额外的43KB内存。一个使用50张这种纹理的场景将需要8MB的内存,如果需要更强的真实性,可以使用每像素32位颜色的512 x 512纹理,但那就需要8倍的内存。
为了减少纹理消耗的系统带宽和内存空间,Direct3D支持纹理压缩和实时解压,即DXT纹理压缩。压缩后的纹理被存储在Direct3D纹理指针中,当Direct3D渲染物体时,Direct3D引擎自动对纹理进行解压。应用DXT压缩纹理不仅可以节省内存空间,而且能有效地降低纹理传输带宽,提高图形系统的整体性能。
随着DirectX对纹理压缩格式的推广,目前大部分显卡都支持DXT压缩纹理,而且DXT压缩纹理在图形质量和运行速度之间取得了很好的平衡。
DXT是一种DirectDraw表面,它以压缩形式存储图形数据,该表面可以节省大量的系统带宽和内存。即使不直接使用DXT表面渲染,也可以通过DXT格式创建纹理的方法节省磁盘空间。Direct3D提供了D3DFMT_DXT1 ~ D3DFMT_DXT5共5种压缩纹理格式。其中,D3DFMT_DXT1支持15位RGB和1位alpha图形格式,D3DFMT_DXT2、D3DFMT_DXT3支持12位RGB和4位alpha,D3DFMT_DXT4、D3DFMT_DXT5则采取了线性插值方式生成alpha。
DXT1格式的压缩比例是4 : 1(4x4块16位RGB纹理元素可压缩为64位,2个16位RGB565值和16个2位索引),这样的压缩比并不很高,但足以有效地将3D加速卡用于存储纹理的容量提高4倍