天天看點

Directx11教程(47) alpha blend(4)-霧的實作

     除了用來實作透明效果之外,我們還可以用alpha blend來實作霧(fog)的效果。通過逐漸清晰的霧氣效果,可以增加場景的真實感。

     霧的效果實作很簡單,首先我們要一種顔色來表示霧,通常使用用灰色。

     其實霧的效果和視點有很大關系,距離視點越近,霧就越淡,距離越遠,霧就越濃。

     最終物體顔色是霧的顔色和計算出的pixel顔色的混合,我們使用的公式如下:

     Final Color = FogFactor * computed pixel color + (1.0 - FogFactor) * FogColor

     可以看出,最終的顔色是霧的顔色和計算的pixel顔色基于霧因子的權重平均。

下面我看看如何計算霧因子:

     首先定義一個霧範圍(fogstart, fogend),在這個範圍内,霧逐漸由淡變濃,超出fogend後,就完全是霧的顔色了,再假定頂點到視點的距離為ViewDistance,則霧因子的計算公式有以下幾種:

1、線性因子

    Linear Fog = (FogEnd - ViewpointDistance) / (FogEnd - FogStart)

2、指數因子

   Exponential Fog = exp2(-abs(ViewpointDistance * FogDensity))

3、二次指數因子

    Exponential Fog 2 = exp2(- (ViewpointDistance * FogDensity) *(ViewpointDistance * FogDensity)) 

      下面我們在myTutorialD3D11_41的基礎上來實作霧的效果:

首先需要修改的是lighttex.vs和lighttex.ps, 在vs中,我們定義一個常量緩沖,表示fog的參數,然後根據這幾個參數來計算霧因子,并把霧因子傳遞到ps階段。

lighttex.vs代碼:

cbuffer FogBuffer

{

    float fogStart;

    float fogEnd;

    float fogDensity;

    float padding;

};

    // 計算錄影機的位置.

    cameraPosition = mul(input.position, worldMatrix);

    cameraPosition = mul(cameraPosition, viewMatrix);

    // 計算線性霧.   

    output.fogFactor = saturate((fogEnd - cameraPosition.z) / (fogEnd - fogStart));

lighttex.ps代碼:

    // 混合霧顔色.

   finalcolor = input.fogFactor * finalcolor1 + (1.0 - input.fogFactor) * fogColor;

       另外在LightTexShaderClass中,也要做一些小改動,增加設定FogBuffer的代碼,并在Render函數和 SetShaderParameters中,增加三個參數,用來設定fog。

      最後,在GraphicsClass中,定義四個參數,并把它們傳入shader。

float fogColor, fogStart, fogEnd, fogDensity;

// 霧顔色.

fogColor = 0.5f;

// 霧距離.

fogStart = 20.0f;

fogEnd = 80.0f;

fogDensity = 0.04f;

首先用fogColor設定背景,這樣很遠的地方就是霧的顔色,…

程式執行後,界面如下:

Directx11教程(47) alpha blend(4)-霧的實作

下面我們在vs中嘗試修改霧因子的計算方法,看看指數因子和二次指數因子的效果。

指數因子:

// 計算指數因子.    

output.fogFactor = saturate(exp2(-abs( cameraPosition.z *fogDensity)) );

Directx11教程(47) alpha blend(4)-霧的實作

二次指數因子:

fogDensity = 0.02f;

// 計算指數因子.

output.fogFactor = saturate(exp2(- ( cameraPosition.z *fogDensity)*( cameraPosition.z *fogDensity)) );

Directx11教程(47) alpha blend(4)-霧的實作

完整的代碼請參考:

工程檔案myTutorialD3D11_42

代碼下載下傳:

<a href="http://files.cnblogs.com/mikewolf2002/d3d1139-49.zip">http://files.cnblogs.com/mikewolf2002/d3d1139-49.zip</a>

<a href="http://files.cnblogs.com/mikewolf2002/pictures.zip">http://files.cnblogs.com/mikewolf2002/pictures.zip</a>

繼續閱讀