あなたの好きなようにエフェクトを修正することができます。法線マップ、ライティングアルゴリズムなどを追加して下さい。
- エフェクトファイルに、最初にこれから使用する変数を宣言します。
// These are required by the Animation library
float4x4 MatrixPalette[56];
float4x4 World;
// These are not
float4x4 View;
float4x4 Projection;
texture BasicTexture;
// Stores sampler state info for the texture
sampler TextureSampler = sampler_state
{
Texture = (BasicTexture);
};
頂点シェーダの作成
- エフェクトの頂点シェーダを作成します。最初に XNA から頂点シェーダに渡す構造体を宣言します。
// This is passed into our vertex shader from Xna
struct VS_INPUT
{
// This is the position of the vertex in the model file
float4 position : POSITION;
// The vertex normal
float3 normal : NORMAL0;
// This is the texture coordinate for the vertex in the model file
float2 texcoord : TEXCOORD0;
// These are the indices (4 of them) that index the bones that affect
// this vertex. The indices refer to the MatrixPalette.
half4 indices : BLENDINDICES0;
// These are the weights (4 of them) that determine how much each bone
// affects this vertex.
float4 weights : BLENDWEIGHT0;
};
- 次に頂点シェーダからハードウェアに渡す構造体を作成して下さい。
// This is passed out from our vertex shader once we have processed the input
struct VS_OUTPUT
{
// The final position of the vertex in world space
float4 position : POSITION;
// The texture coordinate associated with the vertex
float2 texcoord : TEXCOORD0;
};
- 後でモデルのボーンによって座標変換させる頂点位置を保存する構造体を作成します。
// This is the output from our skinning method
struct SKIN_OUTPUT
{
float4 position;
float4 normal;
};
- 次にボーンによって頂点位置を座標変換するメソッドを作成して下さい。
// This method takes in a vertex and applies the bone transforms to it.
SKIN_OUTPUT Skin4( const VS_INPUT input)
{
SKIN_OUTPUT output = (SKIN_OUTPUT)0;
// Since the weights need to add up to one, store 1.0 - (sum of the weights)
float lastWeight = 1.0;
float weight = 0;
// Apply the transforms for the first 3 weights
for (int i = 0; i < 3; ++i)
{
weight = input.weights[i];
lastWeight -= weight;
output.position += mul( input.position, MatrixPalette[input.indices[i]]) * weight;
output.normal += mul( input.normal, MatrixPalette[input.indices[i]]) * weight;
}
// Apply the transform for the last weight
output.position += mul( input.position, MatrixPalette[input.indices[3]])*lastWeight;
output.normal += mul( input.normal, MatrixPalette[input.indices[3]])*lastWeight;
return output;
};
- 最後に頂点シェーダメソッドを作成することができます。
void TransformVertex (in VS_INPUT input, out VS_OUTPUT output)
{
// Calculate the skinned position
SKIN_OUTPUT skin = Skin4(input);
// This is the final position of the vertex, and where it will be drawn on the screen
float4x4 WorldViewProjection = mul(World,mul(View,Projection));
output.position = mul(skin.position, WorldViewProjection);
// This is not used by is included to demonstrate how to get the normal in world space
float4 transformedNormal = mul(skin.normal, WorldViewProjection);
output.texcoord = input.texcoord;
}
ピクセルシェーダの作成
- 頂点シェーダと同じように、新しい構造体を宣言する必要があります。最初にピクセルシェーダからハードウェアに渡す構造体(頂点シェーダによって処理された後に生成されます)を宣言します。
// This is passed into our pixel shader
struct PS_INPUT
{
float2 texcoord : TEXCOORD0;
};
- ピクセルシェーダから画面スクリーンに渡す構造体を宣言します。
// This is the final color rendered on the screen
struct PS_OUTPUT
{
float4 color : COLOR;
};
- ピクセルシェーダはシンプルに特別なライティング処理は行わないようにしています。
void TransformPixel (in PS_INPUT input, out PS_OUTPUT output)
{
output.color = tex2D(TextureSampler,input.texcoord);
}
- 最後にテクニックを作成する必要があります。これはエフェクト(今回のケースでは適用されません)で使用されるレンダリングステートの情報を宣言し、頂点シェーダとピクセルシェーダの機能が使われます。
technique TransformTechnique
{
pass P0
{
VertexShader = compile vs_2_0 TransformVertex();
PixelShader = compile ps_2_0 TransformPixel();
}
}
最終更新:2008年06月01日 04:50