エフェクト編集
では、早速fxファイルを開いて中を見てみましょう。
頂点シェーダ
構造体の編集
まずは頂点シェーダからピクセルシェーダにデータを送る構造体に必要な情報を追加します。
//PSへの受け渡し用構造体定義
struct OutVS
{
float4 Pos : POSITION;
//追加
float3 Normal : TEXCOORD0;
float3 Eye : TEXCOORD1;
float2 ScreenTex : TEXCOORD2;
//
};
まず「Normal」ですが、これは法線情報を代入する項目です。法線とは、その頂点がどの方向を向いているかを表す数値のことで、X:0,Y:1,Z:0で上方向を向いていることになります。XYZ3方向の数値が必要なのでfloat3型で宣言します。
次に「Eye」ですが、これは視線のベクトルを代入する項目です。単純にカメラ(視点)座標から頂点座標を引くことで求めることができます。このデータもXYZ3方向の数値が必要なためfloat3で宣言します。
最後のScreenTexは、背景を歪ませて表示する際に必要になる「現在の頂点のスクリーン上の座標」を代入する項目です。計算方法については後述します。2D的な位置情報を格納するため、float2型で宣言を行います。
以上で構造体の編集は終了です。
本体の編集
それでは頂点シェーダ本体を編集していきます。
//頂点シェーダ本体
OutVS TestShader_VS(float4 Pos : POSITION,float3 Normal : NORMAL)
{
//構造体宣言
OutVS Out;
// カメラ視点のワールドビュープロジェクション変換
Out.Pos = mul( Pos, WorldViewProjMatrix );
//---追加---//
// 法線をワールド行列で回転
Out.Normal = mul( Normal, WorldMatrix );
// カメラとの相対位置計算
Out.Eye = CameraPosition - mul( Pos, WorldMatrix );
// スクリーン座標を計算
Out.ScreenTex.x = (Out.Pos.x / Out.Pos.w)*0.5f+0.5f;
Out.ScreenTex.y = (-Out.Pos.y / Out.Pos.w)*0.5f+0.5f;
//----------//
//PSへ渡す
return Out;
}
次の部分では、ワールドビュープロジェクション変換(以下WVP変換)を行い、頂点座標を画面の表示位置座標に変換しています。
Out.Pos = mul( Pos, WorldViewProjMatrix );
法線の計算
頂点シェーダ宣言時の引数で受け取っている法線情報を使用し、移動、回転、拡大を計算するワールド変換を行ったものを代入しています。
Out.Normal = mul( Normal, WorldMatrix );
なお、MMEの仕様としてキャラクター等のモデル(*.pmd)はすでに計算済みの数値が格納されており、ステージや小物等のアクセサリ(*.x)のみ計算の必要がありますが、ここでは両種類に対応するため計算を行っています。
視線ベクトルの計算
カメラの座標を格納している変数CameraPositionから引数として渡される頂点座標Posを引き、視線ベクトルを計算します。ここでも前述した通り、モデル、アクセサリ両方に対応するためワールド変換を行っています。
Out.Eye = CameraPosition - mul( Pos, WorldMatrix );
スクリーン座標計算
先ほどワールドビュープロジェクション変換を行った画面の表示位置座標を元に、数値を0~1になるよう調節しています。
// スクリーン座標を計算 Out.ScreenTex.x = (Out.Pos.x / Out.Pos.w)*0.5f+0.5f; Out.ScreenTex.y = (-Out.Pos.y / Out.Pos.w)*0.5f+0.5f;
次は今回頂点シェーダから送った情報を使い、ピクセルシェーダを書き変えていきます。


