0001: // -------------------------------------------------------------
0002: // ハロ
0003: // 
0004: // Copyright (c) 2003 IMAGIRE Takashi. All rights reserved.
0005: // -------------------------------------------------------------
0006: 
0007: // -------------------------------------------------------------
0008: // グローバル変数
0009: // -------------------------------------------------------------
0010: 
0011: float  MAP_WIDTH;
0012: float  MAP_HEIGHT;
0013: float4 weight[8];
0014: float2 offsetX;
0015: float2 offsetY;
0016: 
0017: float4x4 mWVP;
0018: float3 vEyePos;
0019: float3 vLightDir;
0020: float4 vCol;
0021: 
0022: // -------------------------------------------------------------
0023: // テクスチャ
0024: // -------------------------------------------------------------
0025: texture SrcMap;
0026: sampler SrcSamp = sampler_state
0027: {
0028:     Texture = <SrcMap>;
0029:     MinFilter = POINT;
0030:     MagFilter = POINT;
0031:     MipFilter = NONE;
0032: 
0033:     AddressU = Clamp;
0034:     AddressV = Clamp;
0035: };
0036: texture SrcMap2;
0037: sampler SrcSamp2 = sampler_state
0038: {
0039:     Texture = <SrcMap2>;
0040:     MinFilter = POINT;
0041:     MagFilter = POINT;
0042:     MipFilter = NONE;
0043: 
0044:     AddressU = Clamp;
0045:     AddressV = Clamp;
0046: };
0047: // -------------------------------------------------------------
0048: // 頂点シェーダからピクセルシェーダに渡すデータ
0049: // -------------------------------------------------------------
0050: struct VS_OUTPUT
0051: {
0052:     float4 Pos          : POSITION;
0053:     float2 ofset        : COLOR0;
0054:     float2 Tex0         : TEXCOORD0;
0055:     float2 Tex1         : TEXCOORD1;
0056:     float2 Tex2         : TEXCOORD2;
0057:     float2 Tex3         : TEXCOORD3;
0058:     float2 Tex4         : TEXCOORD4;
0059:     float2 Tex5         : TEXCOORD5;
0060:     float2 Tex6         : TEXCOORD6;
0061:     float2 Tex7         : TEXCOORD7;
0062: };
0063: // -------------------------------------------------------------
0064: struct OUTPUT
0065: {
0066:     float4 Pos          : POSITION;
0067:     float4 Color        : COLOR0;
0068:     float3 Normal       : TEXCOORD0;
0069:     float3 Eye          : TEXCOORD1;
0070: };
0071: // -------------------------------------------------------------
0072: // シーンの描画
0073: // -------------------------------------------------------------
0074: OUTPUT VS(
0075:       float4 Pos    : POSITION,          // モデルの頂点
0076:       float3 Normal : NORMAL             // モデルの法線
0077: ){
0078:     OUTPUT Out = (OUTPUT)0;        // 出力データ
0079:     float4  uv;
0080:     
0081:     // 座標変換
0082:     Out.Pos = mul(Pos, mWVP);
0083:     
0084:     // 色
0085:     Out.Color = vCol * (0.7*max( dot(vLightDir, Normal), 0)+0.3);
0086:     
0087:     Out.Normal = Normal;        // 色
0088:     Out.Eye    = Pos - vEyePos; // 視線
0089:     
0090:     return Out;
0091: }
0092: // -------------------------------------------------------------
0093: float4 PS(OUTPUT In) : COLOR
0094: {   
0095:     float3 e = normalize(In.Eye);   // 視線ベクトル
0096:     float3 n = normalize(In.Normal);// 法線ベクトル
0097:     float3 r = reflect(e,n);        // 反射ベクトル
0098:     
0099:     float power = pow(max(0,dot(r,vLightDir)), 32); // Phone
0100:     float4 SpecCol = float4(5,5,5,0);           // 鏡面反射色
0101:     
0102:     return In.Color + SpecCol * power;
0103: }
0104: 
0105: // -------------------------------------------------------------
0106: // 縮小バッファへ明るい部分を抽出
0107: // -------------------------------------------------------------
0108: float4 PS_Reduction(VS_OUTPUT In) : COLOR
0109: {   
0110:     float4 Out;
0111:     
0112:     // 16ボックスサンプリング
0113:     float2 t01 = float2( 0.0/512.0, 0.0/512.0);
0114:     float2 t02 = float2( 0.0/512.0, 1.0/512.0);
0115:     float2 t03 = float2( 0.0/512.0,-1.0/512.0);
0116:     float2 t10 = float2(-1.0/512.0,-2.0/512.0);
0117:     float2 t11 = float2(-1.0/512.0, 0.0/512.0);
0118:     float2 t12 = float2(-1.0/512.0, 1.0/512.0);
0119:     float2 t13 = float2(-1.0/512.0,-1.0/512.0);
0120:     float2 t20 = float2( 1.0/512.0,-2.0/512.0);
0121:     float2 t21 = float2( 1.0/512.0, 0.0/512.0);
0122:     float2 t22 = float2( 1.0/512.0, 1.0/512.0);
0123:     float2 t23 = float2( 1.0/512.0,-1.0/512.0);
0124:     float2 t30 = float2(-2.0/512.0,-2.0/512.0);
0125:     float2 t31 = float2(-2.0/512.0, 0.0/512.0);
0126:     float2 t32 = float2(-2.0/512.0, 1.0/512.0);
0127:     float2 t33 = float2(-2.0/512.0,-1.0/512.0);
0128: 
0129:     Out  =(tex2D( SrcSamp, In.Tex0 )   
0130:          + tex2D( SrcSamp, In.Tex0+t01 )
0131:          + tex2D( SrcSamp, In.Tex0+t02 )
0132:          + tex2D( SrcSamp, In.Tex0+t03 )
0133:          + tex2D( SrcSamp, In.Tex0+t10 )
0134:          + tex2D( SrcSamp, In.Tex0+t11 )
0135:          + tex2D( SrcSamp, In.Tex0+t12 )
0136:          + tex2D( SrcSamp, In.Tex0+t13 )
0137:          + tex2D( SrcSamp, In.Tex0+t20 )
0138:          + tex2D( SrcSamp, In.Tex0+t21 )
0139:          + tex2D( SrcSamp, In.Tex0+t22 )
0140:          + tex2D( SrcSamp, In.Tex0+t23 )
0141:          + tex2D( SrcSamp, In.Tex0+t30 )
0142:          + tex2D( SrcSamp, In.Tex0+t31 )
0143:          + tex2D( SrcSamp, In.Tex0+t32 )
0144:          + tex2D( SrcSamp, In.Tex0+t33 ))/16;
0145:     
0146:     // 明るい部分を強く書き込む
0147:     Out = 0.02f*exp(Out);
0148:     
0149:     return Out;
0150: }
0151: // -------------------------------------------------------------
0152: // x軸方向に伸ばす
0153: // -------------------------------------------------------------
0154: VS_OUTPUT VS_pass1 (
0155:       float4 Pos    : POSITION,          // モデルの頂点
0156:       float4 Tex    : TEXCOORD0          // テクスチャ座標
0157: ){
0158:     VS_OUTPUT Out = (VS_OUTPUT)0;        // 出力データ
0159:     
0160:     // 位置座標
0161:     Out.Pos = Pos;
0162:     
0163:     Out.Tex0 = Tex + float2( -1.0f/MAP_WIDTH, 0.0f/MAP_HEIGHT );
0164:     Out.Tex1 = Tex + float2( -2.0f/MAP_WIDTH, 0.0f/MAP_HEIGHT );
0165:     Out.Tex2 = Tex + float2( -3.0f/MAP_WIDTH, 0.0f/MAP_HEIGHT );
0166:     Out.Tex3 = Tex + float2( -4.0f/MAP_WIDTH, 0.0f/MAP_HEIGHT );
0167:     Out.Tex4 = Tex + float2( -5.0f/MAP_WIDTH, 0.0f/MAP_HEIGHT );
0168:     Out.Tex5 = Tex + float2( -6.0f/MAP_WIDTH, 0.0f/MAP_HEIGHT );
0169:     Out.Tex6 = Tex + float2( -7.0f/MAP_WIDTH, 0.0f/MAP_HEIGHT );
0170:     Out.Tex7 = Tex + float2( -8.0f/MAP_WIDTH, 0.0f/MAP_HEIGHT );
0171:     
0172:     return Out;
0173: }
0174: // -------------------------------------------------------------
0175: float4 PS_pass1(VS_OUTPUT In) : COLOR
0176: {   
0177:     float4 Color;
0178:     
0179:     Color  = weight[0] * (tex2D( SrcSamp, In.Tex0 )
0180:                         + tex2D( SrcSamp, In.Tex7 + offsetX ));
0181:     Color += weight[1] * (tex2D( SrcSamp, In.Tex1 )
0182:                         + tex2D( SrcSamp, In.Tex6 + offsetX ));
0183:     Color += weight[2] * (tex2D( SrcSamp, In.Tex2 )
0184:                         + tex2D( SrcSamp, In.Tex5 + offsetX ));
0185:     Color += weight[3] * (tex2D( SrcSamp, In.Tex3 )
0186:                         + tex2D( SrcSamp, In.Tex4 + offsetX ));
0187:     Color += weight[4] * (tex2D( SrcSamp, In.Tex4 )
0188:                         + tex2D( SrcSamp, In.Tex3 + offsetX ));
0189:     Color += weight[5] * (tex2D( SrcSamp, In.Tex5 )
0190:                         + tex2D( SrcSamp, In.Tex2 + offsetX ));
0191:     Color += weight[6] * (tex2D( SrcSamp, In.Tex6 )
0192:                         + tex2D( SrcSamp, In.Tex1 + offsetX ));
0193:     Color += weight[7] * (tex2D( SrcSamp, In.Tex7 )
0194:                         + tex2D( SrcSamp, In.Tex0 + offsetX ));
0195:     
0196:     return Color;
0197: }
0198: // -------------------------------------------------------------
0199: // y軸方向に伸ばす
0200: // -------------------------------------------------------------
0201: VS_OUTPUT VS_pass2 (
0202:       float4 Pos    : POSITION,          // モデルの頂点
0203:       float4 Tex    : TEXCOORD0          // テクスチャ座標
0204: ){
0205:     VS_OUTPUT Out = (VS_OUTPUT)0;        // 出力データ
0206:     
0207:     // 位置座標
0208:     Out.Pos = Pos;
0209:     
0210:     Out.Tex0 = Tex + float2( 0.0f/MAP_WIDTH, -1.0f/MAP_HEIGHT );
0211:     Out.Tex1 = Tex + float2( 0.0f/MAP_WIDTH, -2.0f/MAP_HEIGHT );
0212:     Out.Tex2 = Tex + float2( 0.0f/MAP_WIDTH, -3.0f/MAP_HEIGHT );
0213:     Out.Tex3 = Tex + float2( 0.0f/MAP_WIDTH, -4.0f/MAP_HEIGHT );
0214:     Out.Tex4 = Tex + float2( 0.0f/MAP_WIDTH, -5.0f/MAP_HEIGHT );
0215:     Out.Tex5 = Tex + float2( 0.0f/MAP_WIDTH, -6.0f/MAP_HEIGHT );
0216:     Out.Tex6 = Tex + float2( 0.0f/MAP_WIDTH, -7.0f/MAP_HEIGHT );
0217:     Out.Tex7 = Tex + float2( 0.0f/MAP_WIDTH, -8.0f/MAP_HEIGHT );
0218:     
0219:     return Out;
0220: }
0221: // -------------------------------------------------------------
0222: float4 PS_pass2(VS_OUTPUT In) : COLOR
0223: {   
0224:     float4 Color;
0225:     
0226:     Color  = weight[0] * (tex2D( SrcSamp, In.Tex0 )
0227:                         + tex2D( SrcSamp, In.Tex7 + offsetY ));
0228:     Color += weight[1] * (tex2D( SrcSamp, In.Tex1 )
0229:                         + tex2D( SrcSamp, In.Tex6 + offsetY ));
0230:     Color += weight[2] * (tex2D( SrcSamp, In.Tex2 )
0231:                         + tex2D( SrcSamp, In.Tex5 + offsetY ));
0232:     Color += weight[3] * (tex2D( SrcSamp, In.Tex3 )
0233:                         + tex2D( SrcSamp, In.Tex4 + offsetY ));
0234:     Color += weight[4] * (tex2D( SrcSamp, In.Tex4 )
0235:                         + tex2D( SrcSamp, In.Tex3 + offsetY ));
0236:     Color += weight[5] * (tex2D( SrcSamp, In.Tex5 )
0237:                         + tex2D( SrcSamp, In.Tex2 + offsetY ));
0238:     Color += weight[6] * (tex2D( SrcSamp, In.Tex6 )
0239:                         + tex2D( SrcSamp, In.Tex1 + offsetY ));
0240:     Color += weight[7] * (tex2D( SrcSamp, In.Tex7 )
0241:                         + tex2D( SrcSamp, In.Tex0 + offsetY ));
0242:     
0243:     return Color;
0244: }
0245: // -------------------------------------------------------------
0246: // 最終的に合成する
0247: // -------------------------------------------------------------
0248: float4 PS_pass3(VS_OUTPUT In) : COLOR
0249: {   
0250:     float4 Color;
0251:     
0252:     float2 t0 = float2( 0.5/MAP_WIDTH, 0.0/MAP_HEIGHT);// 右
0253:     float2 t1 = float2(-0.5/MAP_WIDTH, 0.0/MAP_HEIGHT);// 左
0254:     float2 t2 = float2( 0.0/MAP_WIDTH, 0.5/MAP_HEIGHT);// 下
0255:     float2 t3 = float2( 0.0/MAP_WIDTH,-0.5/MAP_HEIGHT);// 上
0256:     
0257:     // 大きくぼかした画像と小さくぼかした画像の差を取る
0258:     Color  = tex2D( SrcSamp, In.Tex0    ) - tex2D( SrcSamp2, In.Tex1    );
0259:     Color += tex2D( SrcSamp, In.Tex0+t0 ) - tex2D( SrcSamp2, In.Tex1+t0 );
0260:     Color += tex2D( SrcSamp, In.Tex0+t1 ) - tex2D( SrcSamp2, In.Tex1+t1 );
0261:     Color += tex2D( SrcSamp, In.Tex0+t2 ) - tex2D( SrcSamp2, In.Tex1+t2 );
0262:     Color += tex2D( SrcSamp, In.Tex0+t3 ) - tex2D( SrcSamp2, In.Tex1+t3 );
0263:     
0264:     return 10.0f*Color;
0265: }
0266: // -------------------------------------------------------------
0267: // テクニック
0268: // -------------------------------------------------------------
0269: technique TShader
0270: {
0271:     pass P0
0272:     {
0273:         // シーンの描画
0274:         VertexShader = compile vs_1_1 VS();
0275:         PixelShader  = compile ps_2_0 PS();
0276:     }
0277:     pass P1
0278:     {
0279:         // 縮小バッファへ明るい部分を描画
0280:         PixelShader  = compile ps_2_0 PS_Reduction();
0281:     }
0282:     pass P2
0283:     {
0284:         // x軸方向に伸ばす
0285:         VertexShader = compile vs_1_1 VS_pass1();
0286:         PixelShader  = compile ps_2_0 PS_pass1();
0287:     }
0288:     pass P3
0289:     {
0290:         // y軸方向に伸ばす
0291:         VertexShader = compile vs_1_1 VS_pass2();
0292:         PixelShader  = compile ps_2_0 PS_pass2();
0293:     }
0294:     pass P4
0295:     {
0296:         // 最終的に合成する
0297:         PixelShader  = compile ps_2_0 PS_pass3();
0298:     }
0299: }
0300: