天行健 君子当自强而不息

效果框架(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。这些函数被定义为:

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

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

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

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

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

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

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

 

执行程序:

/**************************************************************************************************
  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.0f1.0f0.0f);
    g_terrain 
= new cTerrain(g_device, "coastMountain64.raw"646460.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.0f100.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.0f1000.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, 0x00CCCCCC1.0f0);

    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;
}

 


下载源程序


posted on 2008-04-13 11:07 lovedday 阅读(1310) 评论(1)  编辑 收藏 引用

评论

# re: 效果框架(3) 2009-06-03 10:35 fengguo8210@163.com

你写的技术文档详细且系统,是不可多得的学习资料,可能的话出书吧,或者整理一下惠及大众。  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

导航

统计

常用链接

随笔分类(178)

3D游戏编程相关链接

搜索

最新评论