凹凸纹理映射.docx
《凹凸纹理映射.docx》由会员分享,可在线阅读,更多相关《凹凸纹理映射.docx(21页珍藏版)》请在冰豆网上搜索。
![凹凸纹理映射.docx](https://file1.bdocx.com/fileroot1/2022-11/16/865ea495-d735-4cd9-acbd-2a12dc154eb7/865ea495-d735-4cd9-acbd-2a12dc154eb71.gif)
凹凸纹理映射
凹凸纹理映射
关于凹凸映射的原理请参阅凹凸映射(BumpMap)实现原理。
凹凸纹理映射是一种纹理混合方法,它可以创建三维物体复杂的纹理外观表面。
普通的纹理映射只能模拟比较平滑的三维物体表面,难以显示表面高低起伏、凹凸不平的效果。
凹凸纹理映射能够通过一张表示物体表面凹凸程度的高度图(称为凹凸纹理),对另一张表示物体表面环境映射的纹理图的纹理坐标进行相应的干扰,经过干扰的纹理坐标将应用于环境映射,从而产生凹凸不平的显示效果。
凹凸纹理映射通常由三张纹理映射图组成,第一张纹理图表示物体表面原始纹理颜色,第二张凹凸纹理图表示物体表面凹凸的高度起伏值,用来对下一张环境纹理图坐标进行干扰,第三张纹理图表示周围镜面反射或漫反射光照的环境光照映射图。
凹凸纹理映射的纹理映射流程如下图所示:
检查硬件设备
在使用凹凸纹理映射之前,应查询当前的Direct3D设备是否支持D3DTEXOPCAPS_BUMPENVMAP或D3DTEXOPCAPS_BUMPENVMAPLUMINANCE多层纹理混合,以及当前设备是否支持3层纹理映射。
BOOLSupportsBumpMapping()
{
D3DCAPS9d3dCaps;
d3dDevice->GetDeviceCaps(&d3dCaps);
//Doesthisdevicesupportthetwobumpmappingblendoperations?
if(0==d3dCaps.TextureOpCaps&(D3DTEXOPCAPS_BUMPENVMAP|D3DTEXOPCAPS_BUMPENVMAPLUMINANCE))
returnFALSE;
//Doesthisdevicesupportuptothreeblendingstages?
if(d3dCaps.MaxTextureBlendStages<3)
returnFALSE;
returnTRUE;
}
如果当前硬件不支持上面的任何一项,程序框架会自动转而使用参考设备。
凹凸纹理生成
Direct3D的凹凸纹理被用来表示物体表面相邻像素的高度差,它的每个纹理元素由表示水平相邻像素高度差的Du、表示垂直相邻像素高度差的Dv以及表示该点亮度的L组成(某些凹凸纹理像素格式可以不包含L)。
下表列出了Direct3D支持的凹凸纹理像素格式:
凹凸纹理像素格式
说明
D3DFMT_V8U8
每个像素由16位整数表示,分别由8位整数表示Du和Dv
D3DFMT_L6V5U5
每个像素由16位整数表示,6位整数表示L,分别由5位整数表示Du和Dv
D3DFMT_X8L8V8U8
每个像素由32位整数表示,包括8位保留位、8位L、8位Du、8位Dv
D3DFMT_V16U16
每个像素由32位整数表示,分别由16位整数表示Du和Dv
D3DFMT_Q8W8V8U8
每个像素由32位整数表示,分别由8位整数表示Q、W、V、U
D3DFMT_CxV8U8
压缩像素格式,每个像素由16位整数表示,即8位Du和8位Dv,另外C=sqrt(1-Du2-Dv2 )
通常情况下,可以载入一张表示物体表面图像高度的纹理图,通过计算高度图水平相邻和垂直相邻元素的高度差来生成凹凸纹理,也可以通过程序生成凹凸纹理,这里根据纹理图来生成凹凸纹理,代码如下:
//--------------------------------------------------------------------------------------
//Createbumptexturefromheightmaptexture.
//--------------------------------------------------------------------------------------
HRESULTCreateBumpTexture(IDirect3DDevice9*device)
{
HRESULThr;
D3DSURFACE_DESCsurface_desc;
g_height_map_texture->GetLevelDesc(0,&surface_desc);
V_RETURN(device->CreateTexture(surface_desc.Width,surface_desc.Height,1,0,D3DFMT_X8L8V8U8,D3DPOOL_MANAGED,
&g_bump_map_texture,NULL));
D3DLOCKED_RECTlocked_rect;
g_height_map_texture->LockRect(0,&locked_rect,NULL,0);
DWORDsrc_pitch=(DWORD)locked_rect.Pitch;
BYTE*src_row_top=(BYTE*)locked_rect.pBits;
BYTE*src_row_cur=src_row_top;
BYTE*src_row_bot=src_row_top+src_pitch*(surface_desc.Height-1);
g_bump_map_texture->LockRect(0,&locked_rect,NULL,0);
DWORDdest_pitch=(DWORD)locked_rect.Pitch;
BYTE*dest_row_top=(BYTE*)locked_rect.pBits;
BYTE*dest_row_cur=dest_row_top;
//iteratethroughalllines
for(DWORDy=0;y{
BYTE*src_pixel_cur;
BYTE*src_pixel_up;
BYTE*src_pixel_below;
BYTE*dest_pixel;
src_pixel_cur=src_row_cur;
if(y==0)
src_pixel_up=src_row_bot;
else
src_pixel_up=src_row_cur-src_pitch;
if(y==surface_desc.Height-1)
src_pixel_below=src_row_top;
else
src_pixel_below=src_row_cur+src_pitch;
dest_pixel=dest_row_cur;
//iteratethroughallcolumnsincurrentline
for(DWORDx=0;x{
BYTEsrc_pixel_left,src_pixel_right;
if(x==0)
src_pixel_left=*(src_row_cur+(surface_desc.Width-4));
else
src_pixel_left=*(src_pixel_cur-4);
if(x==surface_desc.Width-1)
src_pixel_right=*src_row_cur;
else
src_pixel_right=*(src_pixel_cur+4);
BYTEdu=BYTE(src_pixel_left-src_pixel_right);
BYTEdv=BYTE(src_pixel_up-src_pixel_below);
//theluminancebumpvalue
BYTEu_lumi=(*src_pixel_cur>1)?
63:
127;
*dest_pixel++=du;
*dest_pixel++=dv;
*dest_pixel++=u_lumi;
*dest_pixel++=0;
//moveonepixeltotheright
src_pixel_cur+=4;
src_pixel_up+=4;
src_pixel_below+=4;
}
//movetothenextline
src_row_cur+=src_pitch;
dest_row_cur+=dest_pitch;
}
g_bump_map_texture->UnlockRect(0);
g_height_map_texture->UnlockRect(0);
returnS_OK;
}
凹凸纹理设置
凹凸纹理映射通常使用3层纹理:
物体原始纹理、由原始纹理高度图生成的凹凸纹理、环境纹理,对应于多层纹理混合的0、1、2层。
指定当前纹理层状态为D3DTOP_BUMPENVMAP或D3DTOP_BUMPENVMAPLUMINANCE可设置当前纹理层为凹凸纹理,例如:
pd3dDevice->SetTexture(1,g_bump_map_texture);
pd3dDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_BUMPENVMAP);
或
pd3dDevice->SetTexture(1,g_bump_map_texture);
pd3dDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_BUMPENVMAPLUMINANCE);
纹理状态D3DTOP_BUMPENVMAP和D3DTOP_BUMPENVMAPLUMINANCE表示两种不同的凹凸纹理映射方法。
纹理状态D3DTOP_BUMPENVMAPLUMINANCE表示在凹凸纹理中包含凹凸纹理亮度值L,L将与下一纹理层的纹理颜色相乘作为最后输出的纹理颜色。
纹理状态D3DTOP_BUMPENVMAP默认亮度值L为1,即不改变下一纹理层的纹理颜色。
这里分别使用了3层纹理贴图,如下所示:
原始纹理
原始纹理高度图
环境纹理贴图
Direct3D可设置凹凸纹理矩阵,对凹凸纹理中的每个纹理元素值(Dv、Du,即对于下一纹理层中的每个纹理坐标的扰动值)进行坐标变换:
Du'=Du*M00+Dv*M10
Dv'=Dv*M01+Dv*M11
凹凸纹理的每个纹理元素Dv、Du与一个2x2的凹凸矩阵相乘,其结果Dv、Du对下一纹理层中的每个纹理元素的纹理坐标产生该数值代表的坐标扰动。
2x2的凹凸矩阵值可由函数IDirect3DDevice9:
:
SetTextureStageState()设置,将它的第一个参数设置为纹理层序号,第二个参数设置为D3DTSS_BUMPENVMAT00或D3DTSS_BUMPENVMAT01或D3DTSS_BUMPENVMAT10或D3DTSS_BUMPENVMAT11,分别表示凹凸矩阵的4个矩阵元素,第三个