TOP

ABOUT

PROGRAM

DIALY







フォグ

 1.はじめに
 今更ですが… フォグやってみました。
それと今回から,Visual Studio 2008 SP1とXNA Game Studio 3.0を使用してプログラムを作成するようにしましたので注意してください。



 2.フォグ
 さて,フォグですが。代表的な使い方は,遠くにある物体ほど霧がかかってかすんで見えないというような使い方です。
「カメラから遠くなれば遠くなるほど,見えづらくなる。」これを実現するにはどうすればよいでしょうか?カメラからの遠さは深度値で取り扱えるので,深度値を使って線形合成するのが,最も基本的な使方のようです。それで,線形合成する際に用いるパラメータですが,下の式を用いて算出します。

 ただし,フォグがかかり始めるカメラからの距離をZnear, フォグが完全にかかるカメラからの距離をZfarとします。
もちろん,これをそのままシェーダ側で毎回計算してもよいのですが,パフォーマンスを考えると除算はあまり使わない方がよろしいようです。
そんなわけで,imagireさんの本に書いてあるように,この式を次のように変形します。

このように変形してしまって,Vector2として,X成分にZfar/(Zfar-Znear),Y成分に-1/(Zfar-Znear)を格納して,シェーダに転送します。このようにしておけば,シェーダで除算する必要がなくなり,乗算でフォグを求めることができます。


 3.実装
さて,シェーダ側での実装ですが,次のようになります。
00065:  //-------------------------------------------------------------------------------------------------
00066:  // Name : VertexShaderFunction()
00067:  // Desc : 頂点シェーダ
00068:  //-------------------------------------------------------------------------------------------------
00069:  VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
00070:  {
00071:      VertexShaderOutput output = (VertexShaderOutput)0;
00072:  
00073:      float4 worldPosition = mul(input.Position, World);
00074:      float4 viewPosition = mul(worldPosition, View);
00075:      output.Position = mul(viewPosition, Projection);
00076:  
00077:      // TODO: add your vertex shader code here.
00078:    output.Texcoord = input.Texcoord;
00079:    output.Normal = input.Normal;
00080:    output.ObjPosition = input.Position;
00081:  
00082:    // フォグ係数算出
00083:    output.Fog = FogCoord.x + output.Position.w * FogCoord.y;
00084:  
00085:      return output;
00086:  }
00087:  
フォグ係数の算出は,上記のように頂点シェーダ側で行うようにしました。フォグ係数はCOLOR0として出力し,ピクセルシェーダ側でオブジェクトカラーとフォグカラーの線形合成を行うのに使用します。
続いて,ピクセルシェーダ側ですが,lerp()関数を使って,オブジェクトカラーとフォグカラーを線形合成します。
00100:  //-------------------------------------------------------------------------------------------------
00101:  // Name : PixelShaderFunction()
00102:  // Desc : ピクセルシェーダ
00103:  //-------------------------------------------------------------------------------------------------
00104:  float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
00105:  {
00106:      // TODO: add your pixel shader code here.
00107:    float3 N = normalize( input.Normal );
00108:    float3 L = normalize( LightPosition - input.ObjPosition.xyz );
00109:    float3 E = normalize( CameraPosition - input.ObjPosition.xyz );
00110:    float3 H = normalize( L + E );
00111:  
00112:    float4 output = HalfLambert( N, L, H );
00113:    output *= tex2D( DecalSmp, input.Texcoord );
00114:  
00115:    // フォグ色とオブジェクト色と線形合成
00116:    output = lerp( FogColor, output, input.Fog );
00117:  
00118:      return output;
00119:  }
00120:  


 Download
本ソースコードおよびプログラムを使用したことによる如何なる損害も製作者は責任を負いません。
本ソースコードおよびプログラムは自己責任でご使用ください。
プログラムの作成にはMicrosoft Visual Studio 2008 SP1 Professional, XNA Game Studio 3.0を用いています。