頂点シェーダの編集
サンプルの頂点シェーダでは、オブジェクトの頂点1つずつに対して、以下の処理を行っています。
- 頂点座標からスクリーン上の座標に変換する
- ピクセルシェーダに渡す頂点情報を用意する
VS_OUTPUT Basic_VS( float4 Pos : POSITION, float3 Normal : NORMAL, float2 Tex : TEXCOORD0)
{
float4 Pos0 = Pos;
// オブジェクトの座標をスクリーン上の座標へと変換する(ワールドビュー射影変換)
Pos = mul( Pos, WorldViewMatrix );
Pos = mul( Pos, ProjMatrix );
// ピクセルシェーダでのライティング計算用。
// カメラとの相対位置
float3 Eye = CameraPosition - mul( Pos0, WorldMatrix );
// 頂点法線
Normal = normalize( mul( Normal, WorldMatrix ) );
VS_OUTPUT Out = { Pos, Tex, Normal, Eye };
return Out;
}
コード中の変数Posが頂点シェーダの入力となる、オブジェクトの頂点座標です。
オブジェクト座標の改変
では、MMD上でモデルを表示した状態で、simple.fxの頂点シェーダを以下のように更新してみましょう。
VS_OUTPUT Basic_VS( float4 Pos : POSITION, float3 Normal : NORMAL, float2 Tex : TEXCOORD0)
{
Pos.xyz *= 2; //この行を追加
float4 Pos0 = Pos;
すると以下のように、モデルのサイズが倍になります。これは、入力となるモデルの頂点座標のXYZを、それぞれ2倍する処理がシェーダに追加されたためです。
次に以下のように編集してみます。
VS_OUTPUT Basic_VS( float4 Pos : POSITION, float3 Normal : NORMAL, float2 Tex : TEXCOORD0)
{
Pos.x *= 0.3; //この行を追加
float4 Pos0 = Pos;
すると、今度は以下のようにモデルの横幅だけが縮まります。これは頂点座標のX成分が0.3倍されるためです。
今度は、以下のように編集してみます。
VS_OUTPUT Basic_VS( float4 Pos : POSITION, float3 Normal : NORMAL, float2 Tex : TEXCOORD0)
{
if ( Pos.x < 0 ) { //この行を追加
Pos.x = 0; //同上
} //同上
float4 Pos0 = Pos;
結果は以下のとおり、モデルの左半分が潰れてしまいます。シェーダの中で、頂点座標のX成分が0未満の場合、つまりその頂点が左半分に位置している場合に、元の値を無視してX成分が0に設定されるためです。
座標変換の改変
以下のように編集してみましょう(Y,Zを編集しているのは、そのままではモデルが視界に入らないためです)。
// オブジェクトの座標をスクリーン上の座標へと変換する(ワールドビュー射影変換)
// Pos = mul( Pos, WorldViewMatrix ); //この行をコメントアウト
Pos.y -= 10; //この行を追加
Pos.z += 30; //この行を追加
Pos = mul( Pos, ProjMatrix );
すると以下のように、モデルが画面中央に描画され、右ドラッグで視界の向きを変更しても、画面中央に固定されたままになります。
これは、オブジェクトの座標からスクリーン上の座標を計算する処理のうち、座標をカメラ視点に変換する処理(ビュー変換と呼ばれます)が、コードの編集によって無効になったためです。
上記の頂点シェーダのコードで、頂点座標を表す変数Posの型は"float4"で、これは4次元ベクトルを表します。これには、3次元のX,Y,Z成分に加えて、頂点変換に使用するW成分が含まれています。各成分は、"Pos.x"のように記述することで参照できます。また、"Pos.xyz"と記述することで、3次元ベクトルのように扱うこともできます。
"float4"を、色のデータ型(R,G,B,A)として扱うこともでき、"Color.r"や"Color.rgb"のように記述することで各成分を参照できます。
