NormalMap效果

 第5章05节,制作法线贴图效果.

实现法线贴图应该还是用HLSL多些,,不过这个示例还是有些东西挺有用,记下备忘.

 

    POINT pt;
    GetCursorPos( &pt );   /// 获取光标的屏幕坐标.
    ScreenToClient( g_hwnd, &pt ); /// 将屏幕坐标变换为客户区坐标系.

 

   g_vLight.x = -( ( ( 2.0f * pt.x ) / WINDOW_W ) - 1 ); /// 光标的坐标值设定为﹣1~﹢1之间的值,
    g_vLight.y = -( ( ( 2.0f * pt.y ) / WINDOW_H ) - 1 );
    g_vLight.z = 0.0f;

    if( D3DXVec3Length( &g_vLight ) > 1.0f )
        D3DXVec3Normalize( &g_vLight, &g_vLight );  /// 向量单位化
    else
        g_vLight.z = sqrtf( 1.0f - g_vLight.x*g_vLight.x
                                 - g_vLight.y*g_vLight.y );

这段代码获取光源向量,也就是假想的从鼠标位置射向窗口中心的方向光,这个向量通过下面的函数被转换成颜色

 

DWORD VectortoRGBA( D3DXVECTOR3* v, FLOAT fHeight )
{
    DWORD r = (DWORD)( 127.0f * v->x + 128.0f );
    DWORD g = (DWORD)( 127.0f * v->y + 128.0f );
    DWORD b = (DWORD)( 127.0f * v->z + 128.0f );
    DWORD a = (DWORD)( 255.0f * fHeight );
   
    return( (a<<24L) + (r<<16L) + (g<<8L) + (b<<0L) );
}

其中x,y的值都在[-1,1]的区间里,而z值在[0,1].返回值是一个32位的颜色

最后,在Render函数中,

 

0号阶段的纹理是法线贴图,1号阶段的纹理是DIFFUSE贴图

        DWORD dwFactor = VectortoRGBA( &g_vLight, 0.0f ); /// 向量变换为RGB
        g_pd3dDevice->SetRenderState( D3DRS_TEXTUREFACTOR, dwFactor ); /// 变换为RGB的向量登录为TextureFactor值

///0号纹理阶段

  g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );  /// 纹理的RGB和光源向量内积运算,
  g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_DOTPRODUCT3 ); /// 运算中使用内积
  g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_TFACTOR );///使用上面的TextureFactor值为第二个颜色参数

 

///1号纹理阶段,//把第2层纹理和上面合成的纹理乘法叠加,然后再和上面合成的纹理相加

  g_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_MULTIPLYADD ); /// 合成壁面贴图纹理和法线贴图后输出
  g_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );//DIFFUSE贴图
  g_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );//CURRENT表示上一阶段的纹理运算结果
 

//透明处理,透明度以第二层纹理的透明度为准,即DIFFUSE贴图的

 g_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG1 );
  g_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );

 

 

总结:法线贴图效果的制作方法如下,应该对制作HLSL的法线贴图有帮助的.

第一步:把法线贴图和光源向量转换成的颜色贴图做DOTPRODUCT运算,

第二步:用DIFFUSE贴图和第一步得出的纹理进行MULTIPLYADD运算,也就是先乘法叠加,再加上第一步纹理

 

 


 

 

你可能感兴趣的:(NormalMap效果)