0001: // ------------------------------------------------------------
0002: // モーションブラー
0003: // 
0004: // Copyright (c) 2003 IMAGIRE Takashi. All rights reserved.
0005: // ------------------------------------------------------------
0006: 
0007: // -------------------------------------------------------------
0008: // グローバル変数
0009: // -------------------------------------------------------------
0010: float4x4 mWV;
0011: float4x4 mLastWV;
0012: float4x4 mVP;
0013: float3 vEyePos;
0014: float3 vLightDir;
0015: float4 vCol;
0016: 
0017: // ------------------------------------------------------------
0018: // テクスチャ
0019: // ------------------------------------------------------------
0020: texture SrcMap;
0021: sampler SrcSamp = sampler_state
0022: {
0023:     Texture = <SrcMap>;
0024:     MinFilter = LINEAR;
0025:     MagFilter = LINEAR;
0026:     MipFilter = NONE;
0027: 
0028:     AddressU = Clamp;
0029:     AddressV = Clamp;
0030: };
0031: // -------------------------------------------------------------
0032: // 頂点シェーダからピクセルシェーダに渡すデータ
0033: // -------------------------------------------------------------
0034: struct OUTPUT
0035: {
0036:     float4 Pos          : POSITION;
0037:     float4 Color        : COLOR0;
0038:     float3 Normal       : TEXCOORD0;
0039:     float3 Eye          : TEXCOORD1;
0040: };
0041: // -------------------------------------------------------------
0042: struct VS_OUTPUT
0043: {
0044:     float4 Pos          : POSITION;
0045:     float4 Color        : COLOR0;
0046:     float4 Tex          : TEXCOORD0;
0047:     float4 Velocity     : TEXCOORD1;
0048: };
0049: // -------------------------------------------------------------
0050: OUTPUT VS(
0051:       float4 Pos    : POSITION,          // モデルの頂点
0052:       float3 Normal : NORMAL             // モデルの法線
0053: ){
0054:     OUTPUT Out = (OUTPUT)0;        // 出力データ
0055:     
0056:     // 座標変換
0057:     Out.Pos = mul(mul(Pos, mWV), mVP);      // 中間の座標を使用する
0058:     
0059:     // 色
0060:     Out.Color = vCol * (0.7*max( dot(vLightDir, Normal), 0)// 拡散色
0061:                         +0.3);// 環境色
0062:     
0063:     Out.Normal = Normal;        // 色
0064:     Out.Eye    = Pos - vEyePos; // 視線
0065:     
0066:     return Out;
0067: }
0068: // -------------------------------------------------------------
0069: float4 PS(OUTPUT In) : COLOR
0070: {   
0071:     float3 e = normalize(In.Eye);   // 視線ベクトル
0072:     float3 n = normalize(In.Normal);// 法線ベクトル
0073:     float3 r = reflect(e,n);        // 反射ベクトル
0074:     float3 RGB2Lum = {0.299, 0.587, 0.114};
0075:     
0076:     float power = pow(max(0,dot(r,vLightDir)), 32); // Phone
0077:     float4 SpecCol = float4(10,13,15,0);            // 鏡面反射色
0078:     
0079:     float4 Out = In.Color + SpecCol * power;
0080:     
0081:     // オブジェクトが存在する場所にはアルファを1にする
0082:     Out.a = 1;
0083:     
0084:     return Out;
0085: }
0086: // -------------------------------------------------------------
0087: VS_OUTPUT VS_Blur(
0088:       float4 Pos    : POSITION,          // モデルの頂点
0089:       float3 Normal : NORMAL             // モデルの法線
0090: ){
0091:     VS_OUTPUT Out = (VS_OUTPUT)0;        // 出力データ
0092:     
0093:     // 座標変換
0094:     float4 x1 = mul(Pos, mWV);          // 今回のビュー座標
0095:     float4 x0 = mul(Pos, mLastWV);      // 1フレーム前のビュー座標
0096:     float4 v = x1-x0;                   // 速度
0097:     float3 n = mul(Normal, mWV);        // ビュー座標系での法線
0098:     
0099:     bool bFront = (0<=dot(n, v.xyz));   // 速度方向を向いてる?
0100:     float4 x = bFront ? x1 : x0;        // 向きによって、位置を決める
0101:     
0102:     Out.Pos = mul(x, mVP);              // 射影空間に変換
0103:     
0104:     // 射影空間からテクスチャ空間に変換する
0105:     Out.Tex.x =  Out.Pos.x + Out.Pos.w;
0106:     Out.Tex.y = -Out.Pos.y + Out.Pos.w;
0107:     Out.Tex.w = 2.0f*Out.Pos.w;
0108:     
0109:     // テクスチャ座標での速度を求める
0110:     float4 s0 = mul(x0, mVP); s0 /= s0.w;
0111:     float4 s1 = mul(x1, mVP); s1 /= s1.w;
0112:     Out.Velocity = s1 - s0;
0113:     Out.Velocity.x *= +0.5f;
0114:     Out.Velocity.y *= -0.5f;
0115:     
0116:     return Out;
0117: }
0118: // ------------------------------------------------------------
0119: // ピクセルシェーダプログラム
0120: // ------------------------------------------------------------
0121: float4 PS_Blur (VS_OUTPUT In) : COLOR
0122: {   
0123:     float4 Out = 0;
0124:     const int   SAMPLES = 26;
0125:     const float samples = SAMPLES;
0126:     
0127:     for(int i=0;i<SAMPLES;i++){
0128:         float t = (float)(i+1)/samples;
0129:         Out += tex2D( SrcSamp, In.Tex/In.Tex.w + t*In.Velocity );
0130:     }
0131:     Out /= samples;
0132:     
0133:     return Out;
0134: }
0135: 
0136: // ------------------------------------------------------------
0137: // テクニック
0138: // ------------------------------------------------------------
0139: technique TShader
0140: {
0141:     pass P0
0142:     {
0143:         // 通常描画
0144:         VertexShader = compile vs_1_1 VS();
0145:         PixelShader  = compile ps_2_0 PS();
0146:     }
0147:     pass P1
0148:     {
0149:         // モーションブラー
0150:         VertexShader = compile vs_1_1 VS_Blur();
0151:         PixelShader  = compile ps_2_0 PS_Blur();
0152:     }
0153: }
0154: