效果框架(3)

效果框架(3)

雾化效果(以下简称雾)提高了场景的真实性,可以用它来模拟逼真的天气状况。另外,雾可以大大减少远剪裁面 (far-clip)在视觉上带给观者的不自然的感觉。Direct3D雾化是固定功能管线的一部份,受渲染状态限制。

下面的效果文件设置顶点雾,以达到必要的雾化状态。注意:Direct3D也支持像素雾(也叫表格雾table fog),比顶点雾要更精确。

/* *********************************************************************************
  Effect file that handles device states for linear vertex fog.
 *********************************************************************************
*/

technique FogTech
{
    pass pass0
    {
        
//  set misc render states
        pixelshader          =   null ;
        vertexshader     
=   null ;
        fvf                 
=  XYZ  |  Normal;
        Lighting         
=   true ;
        NormalizeNormals 
=   true ;
        SpecularEnable   
=   false ;

        
//  fog states
        FogVertexMode     =  LINEAR;         //  linear fog function
        FogStart         =   50.0f ;         //  fog starts 50 units away from viewpoint
        FogEnd             =   300.0f ;         //  fog ends 300 units away from viewpoint
        FogColor         =   0x00CCCCCC ;     //  gray
        FogEnable         =   true ;             //  enable
    }
}

 

就象你看到的,线性顶点雾能够通过五个简单的渲染状态控制:

         FogVertexMode—使用指定的雾函数用于顶点雾。雾函数指定雾如何根据距离增长,自然界的雾在近视口的地方比较薄并且根据距离增长变得厚起来了。有效的任务类型为LINEAR、EXP、EXP2。这些函数被定义为:

效果框架(3)_第1张图片

注意:如果你用EXP或EXP2雾化函数,你不用设置FogStart 和 FogEnd,因为它们在这些雾函数类型中没被用到。代替的你必须设置雾密度(fog density)渲染状态(如,FogDensity = someFloatType)

         FogStart—标记了物体将开始雾化的起始深度。

         FogEnd—标记了物体将结束雾化的结束深度。

注意:FogStart 与 FogEnd本质上定义了物体被雾化的深度间隔(从视口)。

         FogColor—一个DWORD 或 D3DCOLOR值,以描述雾的颜色

         FogEnable—指定true以开启顶点雾或false以关闭顶点雾

任何我们用FogShader.cxx效果渲染的几何体将被雾化。通过这种方式,我们可以控制哪一物体得到雾化,而哪些不用雾化。这对只雾化特定区域是很有用的。例如,通常屋外是有雾的,屋里不被雾化。同样的,一定地理部分可能有雾,而另外部分可能没有。下图展示了例程的屏幕截图。

效果框架(3)_第2张图片

 

执行程序:

/* *************************************************************************************************
  Demonstrates using an effect file. Use the arrwo keys, and M, N, W, S, keys to move.  
 *************************************************************************************************
*/

#include 
" d3dUtility.h "
#include 
" terrain.h "
#include 
" camera.h "

#pragma warning(disable : 
4100 )

using   namespace  std;

const   int  WIDTH   =   640 ;
const   int  HEIGHT  =   480 ;

IDirect3DDevice9
*             g_device;
cTerrain
*                     g_terrain;
cCamera                        g_camera(AIR_CRAFT);
ID3DXEffect
*                 g_fog_effect;
D3DXHANDLE                    g_fog_tech_handle;

/////////////////////////////////////////////////////////////////////////////////////////////////// /

bool  setup()
{    
    
//  init scene
    D3DXVECTOR3 dir_to_light( 0.0f 1.0f 0.0f );
    g_terrain 
=   new  cTerrain(g_device,  " coastMountain64.raw " 64 64 6 0.5f );
    g_terrain
-> generate_texture( & dir_to_light);

    
//  set texture filters
    g_device -> SetSamplerState( 0 , D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    g_device
-> SetSamplerState( 0 , D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    g_device
-> SetSamplerState( 0 , D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);

    
//  set camera position    
    g_camera.m_pos  =  D3DXVECTOR3( 100.0f 100.0f - 250.0f );

    
//  create effect

    ID3DXBuffer
*  error_buffer;

    HRESULT hr 
=  D3DXCreateEffectFromFile(g_device,  " FogShader.cxx " , NULL, NULL, D3DXSHADER_DEBUG, NULL,
                                          
& g_fog_effect,  & error_buffer);

    
//  output any error messages
     if (error_buffer)
    {
        MessageBox(NULL, (
char * ) error_buffer -> GetBufferPointer(),  " ERROR " , MB_OK);
        safe_release
< ID3DXBuffer *> (error_buffer);
    }

    
if (FAILED(hr))
    {
        MessageBox(NULL, 
" D3DXCreateEffectFromFile() - FAILED " " ERROR " , MB_OK);
        
return   false ;
    }
    
    
//  save frequently accessed parameter handles
    g_fog_tech_handle  =  g_fog_effect -> GetTechniqueByName( " FogTech " );
    
    
//  set projection
    D3DXMATRIX proj_matrix;
    D3DXMatrixPerspectiveFovLH(
& proj_matrix, D3DX_PI  *   0.25f , ( float )WIDTH / HEIGHT,  1.0f 1000.0f );
    g_device
-> SetTransform(D3DTS_PROJECTION,  & proj_matrix);
        
    
// g_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
    
    
return   true ;
}

////////////////////////////////////////////////////////////////////////////////////////////////////// /

void  cleanup()
{    
    safe_delete
< cTerrain *> (g_terrain);    
    safe_release
< ID3DXEffect *> (g_fog_effect);    
}

////////////////////////////////////////////////////////////////////////////////////////////////////// /

bool  display( float  time_delta)
{    
    
//  update the scene: allow user to rotate around scene.

    
if (GetAsyncKeyState(VK_UP)  &   0x8000f )
        g_camera.walk(
100.0f   *  time_delta);

    
if (GetAsyncKeyState(VK_DOWN)  &   0x8000f )
        g_camera.walk(
- 100.0f   *  time_delta);

    
if (GetAsyncKeyState(VK_LEFT)  &   0x8000f )
        g_camera.yaw(
- 1.0f   *  time_delta);
    
    
if (GetAsyncKeyState(VK_RIGHT)  &   0x8000f )
        g_camera.yaw(
1.0f   *  time_delta);

    
if (GetAsyncKeyState( ' N ' &   0x8000f )
        g_camera.strafe(
- 100.0f   *  time_delta);

    
if (GetAsyncKeyState( ' M ' &   0x8000f )
        g_camera.strafe(
100.0f   *  time_delta);

    
if (GetAsyncKeyState( ' W ' &   0x8000f )
        g_camera.pitch(
1.0f   *  time_delta);

    
if (GetAsyncKeyState( ' S ' &   0x8000f )
        g_camera.pitch(
- 1.0f   *  time_delta);

    D3DXMATRIX view_matrix;
    g_camera.get_view_matrix(
& view_matrix);
    g_device
-> SetTransform(D3DTS_VIEW,  & view_matrix);

    
//  activate the technique and render

    g_device
-> Clear( 0 , NULL, D3DCLEAR_TARGET  |  D3DCLEAR_ZBUFFER,  0x00CCCCCC 1.0f 0 );

    g_device
-> BeginScene();

    
//  set the technique to use
    g_fog_effect -> SetTechnique(g_fog_tech_handle);

    UINT num_passes;
    g_fog_effect
-> Begin( & num_passes,  0 );

    D3DXMATRIX world_matrix;
    D3DXMatrixIdentity(
& world_matrix);

    
for (UINT i  =   0 ; i  <  num_passes; i ++ )
    {
        g_fog_effect
-> BeginPass(i);

        g_terrain
-> draw( & world_matrix,  false );        

        g_fog_effect
-> EndPass();
    }

    g_fog_effect
-> End();
    
    g_device
-> EndScene();

    g_device
-> Present(NULL, NULL, NULL, NULL);

    
return   true ;
}

////////////////////////////////////////////////////////////////////////////////////////////////////// /

LRESULT CALLBACK wnd_proc(HWND hwnd, UINT msg, WPARAM word_param, LPARAM long_param)
{
    
switch (msg)
    {
    
case  WM_DESTROY:
        PostQuitMessage(
0 );
        
break ;

    
case  WM_KEYDOWN:
        
if (word_param  ==  VK_ESCAPE)
            DestroyWindow(hwnd);

        
break ;
    }

    
return  DefWindowProc(hwnd, msg, word_param, long_param);
}

////////////////////////////////////////////////////////////////////////////////////////////////////// /

int  WINAPI WinMain(HINSTANCE inst, HINSTANCE, PSTR cmd_line,  int  cmd_show)
{
    
if ( !  init_d3d(inst, WIDTH, HEIGHT,  true , D3DDEVTYPE_HAL,  & g_device))
    {
        MessageBox(NULL, 
" init_d3d() - failed. " 0 , MB_OK);
        
return   0 ;
    }

    
if ( !  setup())
    {
        MessageBox(NULL, 
" Steup() - failed. " 0 , MB_OK);
        
return   0 ;
    }

    enter_msg_loop(display);

    cleanup();
    g_device
-> Release();

    
return   0 ;
}

 


下载源程序


你可能感兴趣的:(效果框架(3))