0001: // ------------------------------------------------------------
0002: // Real-time Global Illuminations
0003: // 
0004: // Copyright (c) 2004 IMAGIRE Takashi. All rights reserved.
0005: // ------------------------------------------------------------
0006: #include "paraboloid.fx"
0007: 
0008: // ------------------------------------------------------------
0009: // グローバル変数
0010: // ------------------------------------------------------------
0011: float4x4 mWVP;
0012: float4x4 mWV;
0013: float4 vEye;
0014: 
0015: // ------------------------------------------------------------
0016: // テクスチャ
0017: // ------------------------------------------------------------
0018: texture SrcTex;
0019: sampler SrcSamp = sampler_state
0020: {
0021:     Texture = <SrcTex>;
0022:     MinFilter = LINEAR;
0023:     MagFilter = LINEAR;
0024:     MipFilter = NONE;
0025: 
0026:     AddressU = Clamp;
0027:     AddressV = Clamp;
0028: };
0029: // ------------------------------------------------------------
0030: texture ReductionMap;
0031: sampler ReductionSamp = sampler_state
0032: {
0033:     Texture = <ReductionMap>;
0034:     MinFilter = LINEAR;
0035:     MagFilter = LINEAR;
0036:     MipFilter = NONE;
0037: 
0038:     AddressU = Clamp;
0039:     AddressV = Clamp;
0040: };
0041: // ------------------------------------------------------------
0042: texture SHTex;
0043: sampler SHSamp = sampler_state
0044: {
0045:     Texture = <SHTex>;
0046:     MinFilter = LINEAR;
0047:     MagFilter = LINEAR;
0048:     MipFilter = NONE;
0049: 
0050:     AddressU = Clamp;
0051:     AddressV = Clamp;
0052: };
0053: // ------------------------------------------------------------
0054: texture ParaboloidFrontTex;
0055: sampler ParaboloidFrontSamp = sampler_state
0056: {
0057:     Texture = <ParaboloidFrontTex>;
0058:     MinFilter = LINEAR;
0059:     MagFilter = LINEAR;
0060:     MipFilter = NONE;
0061: 
0062:     AddressU = Clamp;
0063:     AddressV = Clamp;
0064: };
0065: // ------------------------------------------------------------
0066: texture ParaboloidBackTex;
0067: sampler ParaboloidBackSamp = sampler_state
0068: {
0069:     Texture = <ParaboloidBackTex>;
0070:     MinFilter = LINEAR;
0071:     MagFilter = LINEAR;
0072:     MipFilter = NONE;
0073: 
0074:     AddressU = Clamp;
0075:     AddressV = Clamp;
0076: };
0077: 
0078: 
0079: // ------------------------------------------------------------
0080: // 頂点シェーダからピクセルシェーダに渡すデータ
0081: // ------------------------------------------------------------
0082: struct VS_OUTPUT
0083: {
0084:     float4 Pos          : POSITION;
0085:     float4 Color        : COLOR0;
0086:     float2 Tex0         : TEXCOORD0;
0087:     float2 Tex1         : TEXCOORD1;
0088:     float3 Normal       : TEXCOORD2;
0089:     float2 Sphere       : TEXCOORD3;
0090: };
0091: 
0092: // ------------------------------------------------------------
0093: // 背景描画頂点シェーダプログラム
0094: // ------------------------------------------------------------
0095: VS_OUTPUT VS (
0096:       float4 Pos    : POSITION           // モデルの頂点
0097:      ,float4 Normal : NORMAL             // 法線ベクトル
0098:      ,float4 Tex0   : TEXCOORD0          // テクスチャ座標
0099: ){
0100:     VS_OUTPUT Out = (VS_OUTPUT)0;        // 出力データ
0101:     
0102:     // 位置座標
0103:     Out.Pos = mul( Pos, mWVP );
0104:     
0105:     // テクスチャ座標
0106:     Out.Tex0 = Tex0;
0107:     
0108:     return Out;
0109: }
0110: // ------------------------------------------------------------
0111: // 背景描画ピクセルシェーダプログラム
0112: // ------------------------------------------------------------
0113: float4 PS (VS_OUTPUT In) : COLOR
0114: {
0115:     float4 Out;
0116:     
0117:     // 色
0118:     Out = tex2D( SrcSamp, In.Tex0 );
0119:     
0120:     return Out;
0121: }
0122: 
0123: 
0124: 
0125: 
0126: 
0127: // ------------------------------------------------------------
0128: // 放物変換頂点シェーダプログラム
0129: // ------------------------------------------------------------
0130: VS_OUTPUT VS_Parabploid (
0131:       float4 Pos    : POSITION           // モデルの頂点
0132:      ,float4 Tex0   : TEXCOORD0          // テクスチャ座標
0133: ){
0134:     VS_OUTPUT Out = (VS_OUTPUT)0;        // 出力データ
0135:     
0136:     // 位置座標
0137:     Out.Pos = paraboloid( Pos, mWV );
0138:     
0139:     // テクスチャ座標
0140:     Out.Tex0 = Tex0;
0141:     
0142:     return Out;
0143: }
0144: // ------------------------------------------------------------
0145: // 全部込みピクセルシェーダプログラム
0146: // ------------------------------------------------------------
0147: float4 PS_Parabploid (VS_OUTPUT In) : COLOR
0148: {
0149:     float4 Out;
0150:     
0151:     // 色
0152:     Out = tex2D( SrcSamp, In.Tex0 );
0153:     
0154:     return Out;
0155: }
0156: 
0157: 
0158: // ------------------------------------------------------------
0159: // ピクセルシェーダプログラム
0160: // ------------------------------------------------------------
0161: VS_OUTPUT VS_ParabploidEnvmap (
0162:       float4 Pos    : POSITION           // モデルの頂点
0163:     , float4 Normal : NORMAL             // 法線ベクトル
0164:       )
0165: {
0166:     float3 ray;
0167:     float3 ref;
0168:     VS_OUTPUT Out = (VS_OUTPUT)0;        // 出力データ
0169:     
0170:     // 位置座標
0171:     Out.Pos = mul( Pos, mWVP );
0172:     
0173:     // メッシュの色
0174:     Out.Color = 0.0f;
0175:     
0176:     // テクスチャ座標
0177:     ray = normalize( Pos - vEye ).xyz;
0178:     ref = reflect( ray, Normal.xyz );       // 反射ベクトル
0179: 
0180:     Out.Tex0.x = 0.5 * ( 1 + ref.x/(1+ref.z));
0181:     Out.Tex0.y = 0.5 * ( 1 - ref.y/(1+ref.z));
0182:     Out.Tex1.x = 0.5 * ( 1 - ref.x/(1-ref.z));
0183:     Out.Tex1.y = 0.5 * ( 1 - ref.y/(1-ref.z));
0184:     
0185:     Out.Color.w = ref.z + 0.5f;     // 反射ベクトルの正負の判定
0186:     
0187:     // 法線
0188:     Out.Normal = mul( Normal.xyz, mWV );
0189:     
0190:     // SH係数用のスフィア座標
0191:     float3 r = Normal;
0192:     r.z += 1.0f;
0193:     float m = 2 * length(r);
0194:     Out.Sphere.x =   Normal.x / m + 0.5f;
0195:     Out.Sphere.y = - Normal.y / m + 0.5f;
0196:     
0197:     return Out;
0198: }
0199: 
0200: 
0201: // ------------------------------------------------------------
0202: // 全部込みピクセルシェーダプログラム
0203: // ------------------------------------------------------------
0204: float4 PS_ParabploidEnvmap (VS_OUTPUT In) : COLOR
0205: {
0206:     float4 Out;
0207:     
0208:     // GI
0209:     float4 SH = 2.0 * tex2D( SHSamp, In.Sphere ) - 1.0;
0210:     float4 GI =   SH.a * ( 2.0 * tex2D( ReductionSamp, float2(0.25, 0.25) ) - 1.0)
0211:                 + SH.r * ( 2.0 * tex2D( ReductionSamp, float2(0.25, 0.75) ) - 1.0)
0212:                 + SH.g * ( 2.0 * tex2D( ReductionSamp, float2(0.75, 0.25) ) - 1.0)
0213:                 + SH.b * ( 2.0 * tex2D( ReductionSamp, float2(0.75, 0.75) ) - 1.0);
0214: 
0215:     // 環境マップ
0216:     float4 front = tex2D( ParaboloidFrontSamp, In.Tex0 );
0217:     float4 back  = tex2D( ParaboloidBackSamp,  In.Tex1 );
0218:     float4 env;
0219:     
0220:     if( 0.5 < In.Color.w ){
0221:         env = front;
0222:     }else{
0223:         env = back;
0224:     }
0225:     // フレネル項
0226:     float F = 1 - In.Normal.z * In.Normal.z;
0227:     
0228:     // 色
0229:     Out = 5.0 * GI          // GI
0230:         + 0.2f * env * F    // 環境マップ
0231:         + In.Color;         // そのほかの色
0232: 
0233:     return Out;
0234: }
0235: 
0236: 
0237: // ------------------------------------------------------------
0238: // 全部込みピクセルシェーダプログラム
0239: // ------------------------------------------------------------
0240: float4 PS_ParabploidEnvmapNoEnv (VS_OUTPUT In) : COLOR
0241: {
0242:     float4 Out;
0243:     
0244:     // GI
0245:     float4 SH = 2.0 * tex2D( SHSamp, In.Sphere ) - 1.0;
0246:     float4 GI =   SH.a * ( 2.0 * tex2D( ReductionSamp, float2(0.25, 0.25) ) - 1.0)
0247:                 + SH.r * ( 2.0 * tex2D( ReductionSamp, float2(0.25, 0.75) ) - 1.0)
0248:                 + SH.g * ( 2.0 * tex2D( ReductionSamp, float2(0.75, 0.25) ) - 1.0)
0249:                 + SH.b * ( 2.0 * tex2D( ReductionSamp, float2(0.75, 0.75) ) - 1.0);
0250: 
0251:     // 環境マップ
0252:     float4 front = tex2D( ParaboloidFrontSamp, In.Tex0 );
0253:     float4 back  = tex2D( ParaboloidBackSamp,  In.Tex1 );
0254:     float4 env;
0255:     
0256:     if( 0.5 < In.Color.w ){
0257:         env = front;
0258:     }else{
0259:         env = back;
0260:     }
0261:     // フレネル項
0262:     float F = 1 - In.Normal.z * In.Normal.z;
0263:     
0264:     // 色
0265:     Out = 5.0 * GI          // GI
0266:         + In.Color;         // そのほかの色
0267: 
0268:     return Out;
0269: }
0270: 
0271: 
0272: // ------------------------------------------------------------
0273: // 全部込みピクセルシェーダプログラム
0274: // ------------------------------------------------------------
0275: float4 PS_ParabploidEnvmapNoGI (VS_OUTPUT In) : COLOR
0276: {
0277:     float4 Out;
0278:     
0279:     // GI
0280:     float4 SH = 2.0 * tex2D( SHSamp, In.Sphere ) - 1.0;
0281:     float4 GI =   SH.a * ( 2.0 * tex2D( ReductionSamp, float2(0.25, 0.25) ) - 1.0)
0282:                 + SH.r * ( 2.0 * tex2D( ReductionSamp, float2(0.25, 0.75) ) - 1.0)
0283:                 + SH.g * ( 2.0 * tex2D( ReductionSamp, float2(0.75, 0.25) ) - 1.0)
0284:                 + SH.b * ( 2.0 * tex2D( ReductionSamp, float2(0.75, 0.75) ) - 1.0);
0285: 
0286:     // 環境マップ
0287:     float4 front = tex2D( ParaboloidFrontSamp, In.Tex0 );
0288:     float4 back  = tex2D( ParaboloidBackSamp,  In.Tex1 );
0289:     float4 env;
0290:     
0291:     if( 0.5 < In.Color.w ){
0292:         env = front;
0293:     }else{
0294:         env = back;
0295:     }
0296:     // フレネル項
0297:     float F = 1 - In.Normal.z * In.Normal.z;
0298:     
0299:     // 色
0300:     Out = 0.2f * env * F    // 環境マップ
0301:         + In.Color;         // そのほかの色
0302: 
0303:     return Out;
0304: }
0305: 
0306: 
0307: // ------------------------------------------------------------
0308: // ------------------------------------------------------------
0309: // 位置、法線マップの作成
0310: // ------------------------------------------------------------
0311: // ------------------------------------------------------------
0312: struct VS_OUTPUT_MAP
0313: {
0314:     float4 Pos          : POSITION;
0315:     float4 Position     : TEXCOORD0;
0316:     float4 Normal       : TEXCOORD1;
0317: };
0318: struct PS_OUTPUT_MAP
0319: {
0320:     float4 Position     : COLOR0;
0321:     float4 Normal       : COLOR1;
0322: };
0323: 
0324: 
0325: 
0326: // ------------------------------------------------------------
0327: // ------------------------------------------------------------
0328: // 64ボックス サンプリング
0329: // ------------------------------------------------------------
0330: // ------------------------------------------------------------
0331: 
0332: // ------------------------------------------------------------
0333: // グローバル変数
0334: // ------------------------------------------------------------
0335: float MAP_WIDTH;
0336: float MAP_HEIGHT;
0337: 
0338: // ------------------------------------------------------------
0339: // 頂点シェーダからピクセルシェーダに渡すデータ
0340: // ------------------------------------------------------------
0341: struct VS_OUTPUT_REDUCTION
0342: {
0343:     float4 Pos          : POSITION;
0344:     float2 Tex0         : TEXCOORD0;
0345:     float2 Tex1         : TEXCOORD1;
0346:     float2 Tex2         : TEXCOORD2;
0347:     float2 Tex3         : TEXCOORD3;
0348:     float2 Tex4         : TEXCOORD4;
0349:     float2 Tex5         : TEXCOORD5;
0350:     float2 Tex6         : TEXCOORD6;
0351:     float2 Tex7         : TEXCOORD7;
0352: };
0353: 
0354: // ------------------------------------------------------------
0355: // 頂点シェーダプログラム
0356: // ------------------------------------------------------------
0357: VS_OUTPUT_REDUCTION VS_Reduction (
0358:       float4 Pos    : POSITION           // モデルの頂点
0359:      ,float4 Tex    : TEXCOORD0          // テクスチャ座標
0360: ){
0361:     VS_OUTPUT_REDUCTION Out = (VS_OUTPUT_REDUCTION)0;        // 出力データ
0362:     
0363:     // 位置座標
0364:     Out.Pos = Pos;
0365:     
0366:     Out.Tex0 = Tex + float2(3.0f/MAP_WIDTH, 1.0f/MAP_HEIGHT);
0367:     Out.Tex1 = Tex + float2(3.0f/MAP_WIDTH, 3.0f/MAP_HEIGHT);
0368:     Out.Tex2 = Tex + float2(3.0f/MAP_WIDTH, 5.0f/MAP_HEIGHT);
0369:     Out.Tex3 = Tex + float2(3.0f/MAP_WIDTH, 7.0f/MAP_HEIGHT);
0370:     Out.Tex4 = Tex + float2(1.0f/MAP_WIDTH, 1.0f/MAP_HEIGHT);
0371:     Out.Tex5 = Tex + float2(1.0f/MAP_WIDTH, 3.0f/MAP_HEIGHT);
0372:     Out.Tex6 = Tex + float2(1.0f/MAP_WIDTH, 5.0f/MAP_HEIGHT);
0373:     Out.Tex7 = Tex + float2(1.0f/MAP_WIDTH, 7.0f/MAP_HEIGHT);
0374:     
0375:     return Out;
0376: }
0377: 
0378: // ------------------------------------------------------------
0379: // ピクセルシェーダプログラム
0380: // ------------------------------------------------------------
0381: float4 PS_Reduction ( VS_OUTPUT_REDUCTION In ) : COLOR0
0382: {
0383:     float4 t0 = tex2D(ReductionSamp, In.Tex0);
0384:     float4 t1 = tex2D(ReductionSamp, In.Tex1);
0385:     float4 t2 = tex2D(ReductionSamp, In.Tex2);
0386:     float4 t3 = tex2D(ReductionSamp, In.Tex3);
0387:     
0388:     float4 t4 = tex2D(ReductionSamp, In.Tex4);
0389:     float4 t5 = tex2D(ReductionSamp, In.Tex5);
0390:     float4 t6 = tex2D(ReductionSamp, In.Tex6);
0391:     float4 t7 = tex2D(ReductionSamp, In.Tex7);
0392:     
0393:     float4 t8 = tex2D(ReductionSamp, In.Tex0 + float2(+4.0f/MAP_WIDTH, 0));
0394:     float4 t9 = tex2D(ReductionSamp, In.Tex1 + float2(+4.0f/MAP_WIDTH, 0));
0395:     float4 ta = tex2D(ReductionSamp, In.Tex2 + float2(+4.0f/MAP_WIDTH, 0));
0396:     float4 tb = tex2D(ReductionSamp, In.Tex3 + float2(+4.0f/MAP_WIDTH, 0));
0397:     
0398:     float4 tc = tex2D(ReductionSamp, In.Tex4 + float2(+4.0f/MAP_WIDTH, 0));
0399:     float4 td = tex2D(ReductionSamp, In.Tex5 + float2(+4.0f/MAP_WIDTH, 0));
0400:     float4 te = tex2D(ReductionSamp, In.Tex6 + float2(+4.0f/MAP_WIDTH, 0));
0401:     float4 tf = tex2D(ReductionSamp, In.Tex7 + float2(+4.0f/MAP_WIDTH, 0));
0402:     
0403:     return ((t0+t1+t2+t3)
0404:            +(t4+t5+t6+t7)
0405:            +(t8+t9+ta+tb)
0406:            +(tc+td+te+tf))/16;
0407: }
0408: 
0409: 
0410: 
0411: 
0412: // ------------------------------------------------------------
0413: // テクスチャ
0414: // ------------------------------------------------------------
0415: texture WeightTex0;
0416: sampler WeightSamp0 = sampler_state
0417: {
0418:     Texture = <WeightTex0>;
0419:     MinFilter = LINEAR;
0420:     MagFilter = LINEAR;
0421:     MipFilter = NONE;
0422: 
0423:     AddressU = Clamp;
0424:     AddressV = Clamp;
0425: };
0426: texture WeightTex1;
0427: sampler WeightSamp1 = sampler_state
0428: {
0429:     Texture = <WeightTex1>;
0430:     MinFilter = LINEAR;
0431:     MagFilter = LINEAR;
0432:     MipFilter = NONE;
0433: 
0434:     AddressU = Clamp;
0435:     AddressV = Clamp;
0436: };
0437: texture SrcTex0;
0438: sampler SrcSamp0 = sampler_state
0439: {
0440:     Texture = <SrcTex0>;
0441:     MinFilter = LINEAR;
0442:     MagFilter = LINEAR;
0443:     MipFilter = NONE;
0444: 
0445:     AddressU = Clamp;
0446:     AddressV = Clamp;
0447: };
0448: texture SrcTex1;
0449: sampler SrcSamp1 = sampler_state
0450: {
0451:     Texture = <SrcTex1>;
0452:     MinFilter = LINEAR;
0453:     MagFilter = LINEAR;
0454:     MipFilter = NONE;
0455: 
0456:     AddressU = Clamp;
0457:     AddressV = Clamp;
0458: };
0459: // ------------------------------------------------------------
0460: // SH(0,0)
0461: // ------------------------------------------------------------
0462: float4 PS_00 (
0463:       float4 Pos    : POSITION           // モデルの頂点
0464:      ,float4 Tex    : TEXCOORD0          // テクスチャ座標
0465: ) : COLOR0
0466: {
0467:     float4 Tex2 = Tex;
0468:     Tex2.x = 1-Tex2.x;
0469:     
0470:     return 0.5 + 0.25 * (
0471:           (2.0 * tex2D( WeightSamp0, Tex ).a - 1.0) * tex2D( SrcSamp0, Tex ) +
0472:           (2.0 * tex2D( WeightSamp1, Tex ).a - 1.0) * tex2D( SrcSamp1, Tex2) );
0473: }
0474: // ------------------------------------------------------------
0475: // SH(1,0)
0476: // ------------------------------------------------------------
0477: float4 PS_10 (
0478:       float4 Pos    : POSITION           // モデルの頂点
0479:      ,float4 Tex    : TEXCOORD0          // テクスチャ座標
0480: ) : COLOR0
0481: {
0482:     float4 Tex2 = Tex;
0483:     Tex2.x = 1-Tex2.x;
0484:     
0485:     return 0.5 + 0.25 * (
0486:           (2.0 * tex2D( WeightSamp0, Tex).r - 1.0) * tex2D( SrcSamp0, Tex ) +
0487:           (2.0 * tex2D( WeightSamp1, Tex).r - 1.0) * tex2D( SrcSamp1, Tex2) );
0488: }
0489: // ------------------------------------------------------------
0490: // SH(1,1)
0491: // ------------------------------------------------------------
0492: float4 PS_11 (
0493:       float4 Pos    : POSITION           // モデルの頂点
0494:      ,float4 Tex    : TEXCOORD0          // テクスチャ座標
0495: ) : COLOR0
0496: {
0497:     float4 Tex2 = Tex;
0498:     Tex2.x = 1-Tex2.x;
0499:     
0500:     return 0.5 + 0.25 * (
0501:           (2.0 * tex2D( WeightSamp0, Tex).g - 1.0) * tex2D( SrcSamp0, Tex ) +
0502:           (2.0 * tex2D( WeightSamp1, Tex).g - 1.0) * tex2D( SrcSamp1, Tex2) );
0503: }
0504: // ------------------------------------------------------------
0505: // SH(1,2)
0506: // ------------------------------------------------------------
0507: float4 PS_12 (
0508:       float4 Pos    : POSITION           // モデルの頂点
0509:      ,float4 Tex    : TEXCOORD0          // テクスチャ座標
0510: ) : COLOR0
0511: {
0512:     float4 Tex2 = Tex;
0513:     Tex2.x = 1-Tex2.x;
0514:     
0515:     return 0.5 + 0.25 * (
0516:           (2.0 * tex2D( WeightSamp0, Tex).b - 1.0) * tex2D( SrcSamp0, Tex ) +
0517:           (2.0 * tex2D( WeightSamp1, Tex).b - 1.0) * tex2D( SrcSamp1, Tex2) );
0518: }
0519: 
0520: 
0521: // ------------------------------------------------------------
0522: // テクニック
0523: // ------------------------------------------------------------
0524: technique TShader
0525: {
0526:     pass P0 // GI & Envmap
0527:     {
0528:         VertexShader = compile vs_1_1 VS_ParabploidEnvmap();
0529:         PixelShader  = compile ps_2_0 PS_ParabploidEnvmap();
0530:     }
0531:     pass P1// 環境マップなし
0532:     {
0533:         VertexShader = compile vs_1_1 VS_ParabploidEnvmap();
0534:         PixelShader  = compile ps_2_0 PS_ParabploidEnvmapNoEnv();
0535:     }
0536:     pass P2// GIなし
0537:     {
0538:         VertexShader = compile vs_1_1 VS_ParabploidEnvmap();
0539:         PixelShader  = compile ps_2_0 PS_ParabploidEnvmapNoGI();
0540:     }
0541:     
0542:     pass P3 // 縮小
0543:     {
0544:         VertexShader = compile vs_1_1 VS_Reduction();
0545:         PixelShader  = compile ps_2_0 PS_Reduction();
0546:     }
0547:     pass P4
0548:     {
0549:         VertexShader = compile vs_1_1 VS_Parabploid();
0550:         PixelShader  = compile ps_1_1 PS_Parabploid();
0551:     }
0552:     
0553:     // 地形描画
0554:     pass P5
0555:     {
0556:         VertexShader = compile vs_1_1 VS();
0557:         PixelShader  = compile ps_2_0 PS();
0558:     }
0559:     
0560:     pass P6
0561:     {
0562:         PixelShader = compile ps_2_0 PS_00();
0563:     }
0564:     pass P7
0565:     {
0566:         PixelShader = compile ps_2_0 PS_10();
0567:     }
0568:     pass P8
0569:     {
0570:         PixelShader = compile ps_2_0 PS_11();
0571:     }
0572:     pass P9
0573:     {
0574:         PixelShader = compile ps_2_0 PS_12();
0575:     }
0576:     
0577: }
0578: