0001: // -------------------------------------------------------------
0002: // レリーフテクスチャ
0003: // 
0004: // Copyright (c) 2003 IMAGIRE Takashi. All rights reserved.
0005: // -------------------------------------------------------------
0006: 
0007: // -------------------------------------------------------------
0008: // グローバル変数
0009: // -------------------------------------------------------------
0010: float4x4 mWVP;      // ローカルから射影空間への座標変換
0011: float4   vLightDir; // ライトの方向
0012: 
0013: // -------------------------------------------------------------
0014: // -------------------------------------------------------------
0015: //
0016: // 頂点座標を2Dテクスチャにマップする
0017: //
0018: // -------------------------------------------------------------
0019: // -------------------------------------------------------------
0020: 
0021: // -------------------------------------------------------------
0022: // データ受け渡しのための構造体
0023: // -------------------------------------------------------------
0024: // 頂点シェーダ入力データ
0025: struct VS_INPUT_Pos
0026: {
0027:     float4 Pos      : POSITION;
0028:     float4 Tex      : TEXCOORD0;
0029: };
0030: // -------------------------------------------------------------
0031: // 頂点シェーダ出力データ
0032: struct VS_OUTPUT_Pos
0033: {
0034:     float4 Pos      : POSITION;
0035:     float3 Tex      : TEXCOORD0;
0036: };
0037: // -------------------------------------------------------------
0038: // ピクセルシェーダ出力データ
0039: struct PS_OUTPUT_Pos
0040: {
0041:     float4 Col      : COLOR0;
0042: };
0043: // -------------------------------------------------------------
0044: // 頂点シェーダプログラム
0045: // -------------------------------------------------------------
0046: VS_OUTPUT_Pos PosV ( VS_INPUT_Pos In )
0047: {
0048:     VS_OUTPUT_Pos Out = (VS_OUTPUT_Pos)0;        // 出力データ
0049:     float4 offsetS = { 2.0f, -2.0f, 0.0f, 0.0f};
0050:     float4 offsetB = {-1.0f, +1.0f, 0.5f, 1.0f};
0051:     
0052:     // 座標変換
0053:     Out.Pos = In.Tex * offsetS + offsetB;
0054:     
0055:     // テクスチャ座標
0056:     Out.Tex = 0.1f*In.Pos+0.5f;
0057:     
0058:     return Out;
0059: }
0060: // -------------------------------------------------------------
0061: // ピクセルシェーダプログラム
0062: // -------------------------------------------------------------
0063: PS_OUTPUT_Pos PosP ( VS_OUTPUT_Pos In )
0064: {
0065:     
0066:     PS_OUTPUT_Pos Out = ( PS_OUTPUT_Pos ) 0;
0067:     
0068:     Out.Col.xyz = In.Tex;
0069:     
0070:     return Out;
0071: }
0072: // -------------------------------------------------------------
0073: // テクニック
0074: // -------------------------------------------------------------
0075: technique TPos
0076: {
0077:     pass P0
0078:     {
0079:         CullMode = None;
0080: 
0081:         // シェーダ
0082:         VertexShader = compile vs_1_1 PosV();
0083:         PixelShader  = compile ps_1_1 PosP();
0084: 
0085:     }
0086: }
0087: 
0088: 
0089: // -------------------------------------------------------------
0090: // -------------------------------------------------------------
0091: //
0092: // 隣接するピクセルとの距離を測る
0093: //
0094: // -------------------------------------------------------------
0095: // -------------------------------------------------------------
0096: 
0097: texture TexPos;
0098: sampler TexPosSamp = sampler_state
0099: {
0100:     Texture = <TexPos>;
0101:     MinFilter = POINT;
0102:     MagFilter = POINT;
0103:     MipFilter = NONE;
0104: 
0105:     AddressU = Clamp;
0106:     AddressV = Clamp;
0107: };
0108: // -------------------------------------------------------------
0109: // データ受け渡しのための構造体
0110: // -------------------------------------------------------------
0111: // 頂点シェーダ入力データ
0112: struct VS_INPUT_Distance
0113: {
0114:     float4 Pos      : POSITION;
0115:     float4 Tex      : TEXCOORD0;
0116: };
0117: // -------------------------------------------------------------
0118: // 頂点シェーダ出力データ
0119: struct VS_OUTPUT_Distance
0120: {
0121:     float4 Pos      : POSITION;
0122:     float2 Tex      : TEXCOORD0;
0123: };
0124: // -------------------------------------------------------------
0125: // ピクセルシェーダ出力データ
0126: struct PS_OUTPUT_Distance
0127: {
0128:     float4 Col      : COLOR0;
0129: };
0130: // -------------------------------------------------------------
0131: // 頂点シェーダプログラム
0132: // -------------------------------------------------------------
0133: VS_OUTPUT_Distance DistanceV ( VS_INPUT_Distance In )
0134: {
0135:     VS_OUTPUT_Distance Out = (VS_OUTPUT_Distance)0;        // 出力データ
0136:     
0137:     // 座標変換
0138:     Out.Pos = In.Pos;
0139:     
0140:     // テクスチャ座標
0141:     Out.Tex = In.Tex;
0142:     
0143:     return Out;
0144: }
0145: // -------------------------------------------------------------
0146: // ピクセルシェーダプログラム
0147: // -------------------------------------------------------------
0148: PS_OUTPUT_Distance DistanceP ( VS_OUTPUT_Distance In )
0149: {
0150:     PS_OUTPUT_Distance Out = ( PS_OUTPUT_Distance ) 0;
0151:     
0152:     float2 dx = {1.0f/256.0f, 0.0f};
0153:     float2 dy = {0.0f, 1.0f/256.0f};
0154:     
0155:     float3 center = tex2D( TexPosSamp, In.Tex );
0156:     float3 left   = tex2D( TexPosSamp, In.Tex + dx ) - center;
0157:     float3 down   = tex2D( TexPosSamp, In.Tex + dy ) - center;
0158:     
0159:     Out.Col.r = 100.0f*sqrt(dot(left,left));
0160:     Out.Col.g = 100.0f*sqrt(dot(down,down));
0161:     Out.Col.b = 100000.0f*abs(cross(left, down));
0162:     
0163:     return Out;
0164: }
0165: // -------------------------------------------------------------
0166: // テクニック
0167: // -------------------------------------------------------------
0168: technique TDistance
0169: {
0170:     pass P0
0171:     {
0172:         CullMode = None;
0173: 
0174:         // テクスチャ
0175:         Sampler[0] = (TexPosSamp);
0176:         
0177:         // シェーダ
0178:         VertexShader = compile vs_1_1 DistanceV();
0179:         PixelShader  = compile ps_2_0 DistanceP();
0180: 
0181:     }
0182: }
0183: 
0184: // -------------------------------------------------------------
0185: // -------------------------------------------------------------
0186: //
0187: // 照射されたライトの強さを求める
0188: //
0189: // -------------------------------------------------------------
0190: // -------------------------------------------------------------
0191: 
0192: // -------------------------------------------------------------
0193: // データ受け渡しのための構造体
0194: // -------------------------------------------------------------
0195: // 頂点シェーダ入力データ
0196: struct VS_INPUT_Irradiance
0197: {
0198:     float4 Pos      : POSITION;
0199:     float4 Normal   : NORMAL;
0200:     float4 Tex      : TEXCOORD0;
0201: };
0202: // -------------------------------------------------------------
0203: // 頂点シェーダ出力データ
0204: struct VS_OUTPUT_Irradiance
0205: {
0206:     float4 Pos      : POSITION;
0207:     float4 Color    : DIFFUSE;
0208: };
0209: // -------------------------------------------------------------
0210: // 頂点シェーダプログラム
0211: // -------------------------------------------------------------
0212: VS_OUTPUT_Irradiance IrradianceV ( VS_INPUT_Irradiance In )
0213: {
0214:     VS_OUTPUT_Irradiance Out = (VS_OUTPUT_Irradiance)0;// 出力データ
0215:     float4 offsetS = { 2.0f, -2.0f, 0.0f, 0.0f};
0216:     float4 offsetB = {-1.0f, +1.0f, 0.5f, 1.0f};
0217:     
0218:     // 座標変換
0219:     Out.Pos = In.Tex * offsetS + offsetB;
0220:     
0221:     // 色
0222:     Out.Color = vLightDir.w                              // 環境色
0223:             + max( dot(vLightDir.xyz, In.Normal.xyz), 0);// 拡散色
0224:     
0225:     return Out;
0226: }
0227: // -------------------------------------------------------------
0228: // ピクセルシェーダプログラム
0229: // -------------------------------------------------------------
0230: float4 IrradianceP ( VS_OUTPUT_Irradiance In ) : COLOR0
0231: {
0232:     float4 Col = 0;
0233:     
0234:     Col = In.Color;
0235:     
0236:     return Col;
0237: }
0238: // -------------------------------------------------------------
0239: // テクニック
0240: // -------------------------------------------------------------
0241: technique TIrradiance
0242: {
0243:     pass P0
0244:     {
0245:         Cullmode=None;
0246: 
0247:         // シェーダ
0248:         VertexShader = compile vs_1_1 IrradianceV();
0249:         PixelShader  = compile ps_1_1 IrradianceP();
0250: 
0251:     }
0252: }
0253: 
0254: // -------------------------------------------------------------
0255: // -------------------------------------------------------------
0256: //
0257: // 表面下散乱マップの作成
0258: //
0259: // -------------------------------------------------------------
0260: // -------------------------------------------------------------
0261: 
0262: texture TexIrradiance;
0263: sampler IrradianceSamp = sampler_state
0264: {
0265:     Texture = <TexIrradiance>;
0266:     MinFilter = LINEAR;
0267:     MagFilter = LINEAR;
0268:     MipFilter = NONE;
0269: 
0270:     AddressU = Clamp;
0271:     AddressV = Clamp;
0272: };
0273: 
0274: texture TexSubLight;
0275: sampler SubLightSamp = sampler_state
0276: {
0277:     Texture = <TexSubLight>;
0278:     MinFilter = LINEAR;
0279:     MagFilter = LINEAR;
0280:     MipFilter = NONE;
0281: 
0282:     AddressU = Clamp;
0283:     AddressV = Clamp;
0284: };
0285: // -------------------------------------------------------------
0286: // データ受け渡しのための構造体
0287: // -------------------------------------------------------------
0288: // 頂点シェーダ入力データ
0289: struct VS_INPUT_SubLight
0290: {
0291:     float4 Pos      : POSITION;
0292:     float4 Tex      : TEXCOORD0;
0293: };
0294: // -------------------------------------------------------------
0295: // 頂点シェーダ出力データ
0296: struct VS_OUTPUT_SubLight
0297: {
0298:     float4 Pos      : POSITION;
0299:     float2 Tex      : TEXCOORD0;
0300: };
0301: // -------------------------------------------------------------
0302: // 頂点シェーダプログラム
0303: // -------------------------------------------------------------
0304: VS_OUTPUT_SubLight SubLightV ( VS_INPUT_SubLight In )
0305: {
0306:     VS_OUTPUT_SubLight Out = (VS_OUTPUT_SubLight)0;// 出力データ
0307:     
0308:     // 座標変換
0309:     Out.Pos = In.Pos;
0310:     
0311:     // テクスチャ座標
0312:     Out.Tex = In.Tex;
0313:     
0314:     return Out;
0315: }
0316: // -------------------------------------------------------------
0317: // ピクセルシェーダプログラム
0318: // -------------------------------------------------------------
0319: float4 SubLightP ( VS_OUTPUT_SubLight In ) : COLOR0
0320: {
0321:     float4 Col = 0;
0322:     
0323:     float4 irr = tex2D( IrradianceSamp, In.Tex );
0324:     
0325:     float2 offsetP0 = { +1.0f/256.0f, 0.0f };
0326:     float2 offsetN0 = { -1.0f/256.0f, 0.0f };
0327:     float2 offset0P = { 0.0f, +1.0f/256.0f };
0328:     float2 offset0N = { 0.0f, -1.0f/256.0f };
0329:     
0330:     float4 colP0 = tex2D( SubLightSamp, In.Tex + offsetP0 );
0331:     float4 colN0 = tex2D( SubLightSamp, In.Tex + offsetN0 );
0332:     float4 col0P = tex2D( SubLightSamp, In.Tex + offset0P );
0333:     float4 col0N = tex2D( SubLightSamp, In.Tex + offset0N );
0334:     
0335:     Col = 0.20f * irr
0336:         + 0.20f * (colP0 + colN0 + col0P + col0N);
0337:     
0338:     return Col;
0339: }
0340: // -------------------------------------------------------------
0341: // テクニック
0342: // -------------------------------------------------------------
0343: technique TSubLight
0344: {
0345:     pass P0
0346:     {
0347:         Cullmode=None;
0348: 
0349:         // テクスチャ
0350:         Sampler[0] = (IrradianceSamp);
0351:         Sampler[1] = (SubLightSamp);
0352:         
0353:         // シェーダ
0354:         VertexShader = compile vs_1_1 SubLightV();
0355:         PixelShader  = compile ps_2_0 SubLightP();
0356: 
0357:     }
0358: }
0359: 
0360: // -------------------------------------------------------------
0361: // -------------------------------------------------------------
0362: //
0363: // 照射されたライトの強さを求める
0364: //
0365: // -------------------------------------------------------------
0366: // -------------------------------------------------------------
0367: 
0368: texture TexDecale;
0369: sampler DecaleSamp = sampler_state
0370: {
0371:     Texture = <TexDecale>;
0372:     MinFilter = LINEAR;
0373:     MagFilter = LINEAR;
0374:     MipFilter = NONE;
0375: 
0376:     AddressU = Clamp;
0377:     AddressV = Clamp;
0378: };
0379: // -------------------------------------------------------------
0380: // データ受け渡しのための構造体
0381: // -------------------------------------------------------------
0382: // 頂点シェーダ入力データ
0383: struct VS_INPUT_Final
0384: {
0385:     float4 Pos      : POSITION;
0386:     float4 Normal   : NORMAL;
0387:     float4 Tex      : TEXCOORD0;
0388: };
0389: // -------------------------------------------------------------
0390: // 頂点シェーダ出力データ
0391: struct VS_OUTPUT_Final
0392: {
0393:     float4 Pos      : POSITION;
0394:     float4 Color    : COLOR0;
0395:     float4 Tex0     : TEXCOORD0;
0396:     float4 Tex1     : TEXCOORD1;
0397: };
0398: // -------------------------------------------------------------
0399: // 頂点シェーダプログラム
0400: // -------------------------------------------------------------
0401: VS_OUTPUT_Final FinalV ( VS_INPUT_Irradiance In )
0402: {
0403:     VS_OUTPUT_Final Out = (VS_OUTPUT_Final)0;// 出力データ
0404:     
0405:     // 座標変換
0406:     Out.Pos = Out.Pos = mul(In.Pos, mWVP);
0407:     
0408:     Out.Tex0 = In.Tex;
0409:     Out.Tex1 = In.Tex;
0410:     
0411:     // 色
0412:     Out.Color = vLightDir.w                              // 環境色
0413:             + max( dot(vLightDir.xyz, In.Normal.xyz), 0);// 拡散色
0414: 
0415:     return Out;
0416: }
0417: // -------------------------------------------------------------
0418: // ピクセルシェーダプログラム
0419: // -------------------------------------------------------------
0420: float4 FinalP ( VS_OUTPUT_Final In ) : COLOR0
0421: {
0422:     float4 Col = 0;
0423:     
0424:     float4 decale = tex2D( DecaleSamp,   In.Tex0 );
0425:     float4 light  = saturate(1.0f*tex2D( SubLightSamp, In.Tex1 ));
0426: //light=In.Color;
0427: decale = float4(0.8f, 0.8f, 0.8f, 1.0f);// 白色にする
0428:     Col = decale * light;
0429:     
0430:     return Col;
0431: }
0432: // -------------------------------------------------------------
0433: // テクニック
0434: // -------------------------------------------------------------
0435: technique TFinal
0436: {
0437:     pass P0
0438:     {
0439:         // テクスチャ
0440:         Sampler[0] = (DecaleSamp);
0441:         Sampler[1] = (SubLightSamp);
0442: 
0443:         // シェーダ
0444:         VertexShader = compile vs_1_1 FinalV();
0445:         PixelShader  = compile ps_1_1 FinalP();
0446: 
0447:     }
0448: }