0001: // ------------------------------------------------------------
0002: // Real-time Global Illumination
0003: // 
0004: // Copyright (c) 2004 IMAGIRE Takashi. All rights reserved.
0005: // ------------------------------------------------------------
0006: #include "paraboloid.fx"
0007: 
0008: // ------------------------------------------------------------
0009: // Global variables(グローバル変数)
0010: // ------------------------------------------------------------
0011: float4x4 mWVP;      // Local-Projection matrix
0012: float4x4 mWV;       // Local-View matrix
0013: float4x4 mST;                   // ローカル→サーフェス座標系への変換行列の転置
0014: float4 vEye;        // Eye position(Local coordinate)
0015: 
0016: float MAP_WIDTH;    // texture width
0017: float MAP_HEIGHT;   // texture height
0018: 
0019: // ------------------------------------------------------------
0020: // Textures(テクスチャ)
0021: // ------------------------------------------------------------
0022: texture SrcTex;
0023: sampler SrcSamp = sampler_state
0024: {
0025:     Texture = <SrcTex>;
0026:     MinFilter = LINEAR;
0027:     MagFilter = LINEAR;
0028:     MipFilter = NONE;
0029: 
0030:     AddressU = Clamp;
0031:     AddressV = Clamp;
0032: };
0033: // ------------------------------------------------------------
0034: texture DecaleTex;
0035: sampler DecaleSamp = sampler_state
0036: {
0037:     Texture = <DecaleTex>;
0038:     MinFilter = LINEAR;
0039:     MagFilter = LINEAR;
0040:     MipFilter = NONE;
0041: 
0042:     AddressU = Clamp;
0043:     AddressV = Clamp;
0044: };
0045: // ------------------------------------------------------------
0046: texture PRTTex;
0047: sampler PRTSamp = sampler_state
0048: {
0049:     Texture = <PRTTex>;
0050:     MinFilter = LINEAR;
0051:     MagFilter = LINEAR;
0052:     MipFilter = NONE;
0053: 
0054:     AddressU = Clamp;
0055:     AddressV = Clamp;
0056: };
0057: // ------------------------------------------------------------
0058: // Dual paraboloid maps(双放物マップ)
0059: // ------------------------------------------------------------
0060: texture WeightTexFront;
0061: sampler WeightSampFront = sampler_state
0062: {
0063:     Texture = <WeightTexFront>;
0064:     MinFilter = LINEAR;
0065:     MagFilter = LINEAR;
0066:     MipFilter = NONE;
0067: 
0068:     AddressU = Clamp;
0069:     AddressV = Clamp;
0070: };
0071: // ------------------------------------------------------------
0072: texture WeightTexBack;
0073: sampler WeightSampBack = sampler_state
0074: {
0075:     Texture = <WeightTexBack>;
0076:     MinFilter = LINEAR;
0077:     MagFilter = LINEAR;
0078:     MipFilter = NONE;
0079: 
0080:     AddressU = Clamp;
0081:     AddressV = Clamp;
0082: };
0083: // ------------------------------------------------------------
0084: // Dual paraboloid environment maps(双放物環境マップ)
0085: // ------------------------------------------------------------
0086: texture ParaboloidFrontTex;
0087: sampler ParaboloidFrontSamp = sampler_state
0088: {
0089:     Texture = <ParaboloidFrontTex>;
0090:     MinFilter = LINEAR;
0091:     MagFilter = LINEAR;
0092:     MipFilter = NONE;
0093: 
0094:     AddressU = Clamp;
0095:     AddressV = Clamp;
0096: };
0097: // ------------------------------------------------------------
0098: texture ParaboloidBackTex;
0099: sampler ParaboloidBackSamp = sampler_state
0100: {
0101:     Texture = <ParaboloidBackTex>;
0102:     MinFilter = LINEAR;
0103:     MagFilter = LINEAR;
0104:     MipFilter = NONE;
0105: 
0106:     AddressU = Clamp;
0107:     AddressV = Clamp;
0108: };
0109: 
0110: 
0111: // ------------------------------------------------------------
0112: // Vertex shader output(頂点シェーダからピクセルシェーダに渡すデータ)
0113: // ------------------------------------------------------------
0114: struct VS_OUTPUT
0115: {
0116:     float4 Pos          : POSITION;
0117:     float4 Color        : COLOR0;
0118:     float2 Tex0         : TEXCOORD0;
0119:     float2 Tex1         : TEXCOORD1;
0120:     float3 Normal       : TEXCOORD2;
0121:     float2 DecaleTex    : TEXCOORD3;
0122: };
0123: // ------------------------------------------------------------
0124: struct VS_OUTPUT_64BOX_SAMPLING
0125: {
0126:     float4 Pos          : POSITION;
0127:     float2 Tex0         : TEXCOORD0;
0128:     float2 Tex1         : TEXCOORD1;
0129:     float2 Tex2         : TEXCOORD2;
0130:     float2 Tex3         : TEXCOORD3;
0131:     float2 Tex4         : TEXCOORD4;
0132:     float2 Tex5         : TEXCOORD5;
0133:     float2 Tex6         : TEXCOORD6;
0134:     float2 Tex7         : TEXCOORD7;
0135: };
0136: 
0137: // ------------------------------------------------------------
0138: // Simple vertex shader program(背景描画頂点シェーダプログラム)
0139: // ------------------------------------------------------------
0140: VS_OUTPUT VS (
0141:       float4 Pos    : POSITION           // (モデルの頂点)
0142:      ,float4 Normal : NORMAL             // (法線ベクトル)
0143:      ,float4 Tex0   : TEXCOORD0          // (テクスチャ座標)
0144: ){
0145:     VS_OUTPUT Out = (VS_OUTPUT)0;
0146:     
0147:     // Position(位置座標)
0148:     Out.Pos = mul( Pos, mWVP );
0149:     
0150:     // Texture coordinate(テクスチャ座標)
0151:     Out.Tex0 = Tex0;
0152:     
0153:     return Out;
0154: }
0155: 
0156: 
0157: 
0158: 
0159: // ------------------------------------------------------------
0160: // Simple pixel shader program(背景描画ピクセルシェーダプログラム)
0161: // ------------------------------------------------------------
0162: float4 PS (VS_OUTPUT In) : COLOR
0163: {
0164:     float4 Out;
0165:     
0166:     // Color(色)
0167:     Out = tex2D( SrcSamp, In.Tex0 );
0168:     
0169:     return Out;
0170: }
0171: 
0172: 
0173: 
0174: 
0175: 
0176: // ------------------------------------------------------------
0177: // Parabploid vertex shader program(放物変換頂点シェーダプログラム)
0178: // ------------------------------------------------------------
0179: VS_OUTPUT VS_Parabploid (
0180:       float4 Pos    : POSITION           // (モデルの頂点)
0181:      ,float4 Tex0   : TEXCOORD0          // (テクスチャ座標)
0182: ){
0183:     VS_OUTPUT Out = (VS_OUTPUT)0;
0184:     
0185:     // Position(位置座標)
0186:     Out.Pos = paraboloid( Pos, mWV );
0187:     
0188:     // Texture coordinate(テクスチャ座標)
0189:     Out.Tex0 = Tex0;
0190:     
0191:     return Out;
0192: }
0193: 
0194: 
0195: // ------------------------------------------------------------
0196: // Dual-Parabploid environment mapping vertex shader program(放物環境マップ頂点シェーダプログラム)
0197: // ------------------------------------------------------------
0198: VS_OUTPUT VS_ParabploidEnvmap (
0199:       float4 Pos    : POSITION           // (モデルの頂点)
0200:     , float4 Normal : NORMAL             // (法線ベクトル)
0201:     , float2 Tex    : TEXCOORD0          // (テクスチャ座標)
0202:       )
0203: {
0204:     VS_OUTPUT Out = (VS_OUTPUT)0;
0205:     float3 ray;
0206:     float3 ref;
0207:     
0208:     // Position(位置座標)
0209:     Out.Pos = mul( Pos, mWVP );
0210:     
0211:     // Color(色)
0212:     Out.Color = 0.0f;
0213:     
0214:     // Texture Coordinate(テクスチャ座標)
0215:     ray = normalize( Pos - vEye ).xyz;
0216:     ref = reflect( ray, Normal.xyz );       // Reflection vector(反射ベクトル)
0217: 
0218:     Out.Tex0.x = 0.5 * ( 1 + ref.x/(1+ref.z));
0219:     Out.Tex0.y = 0.5 * ( 1 - ref.y/(1+ref.z));
0220:     Out.Tex1.x = 0.5 * ( 1 - ref.x/(1-ref.z));
0221:     Out.Tex1.y = 0.5 * ( 1 - ref.y/(1-ref.z));
0222:     
0223:     Out.Color.w = ref.z + 0.5f;     // The judgement of the signature of the z-component of the reflection vector(反射ベクトルの正負の判定)
0224:     
0225:     // Normal vector in the view coordinate system(ビュー座標系での法線ベクトル)
0226:     Out.Normal = mul( Normal.xyz, mWV );
0227:     
0228:     Out.DecaleTex = Tex;
0229:     
0230:     return Out;
0231: }
0232: 
0233: 
0234: // ------------------------------------------------------------
0235: // Sampling environment map(環境マップの読み込み)
0236: // ------------------------------------------------------------
0237: float4 GetEnvMap( float2 tex_front, float2 tex_back, float NE, bool front_or_back )
0238: {
0239:     float4 env;
0240:     
0241:     if( front_or_back ){
0242:         env = tex2D( ParaboloidFrontSamp, tex_front );
0243:     }else{
0244:         env = tex2D( ParaboloidBackSamp,  tex_back  );
0245:     }
0246:     
0247:     // Fresnel term (フレネル項)
0248:     float F = 1-NE*NE;
0249:     
0250:     return F * env;
0251: }
0252: 
0253: // ------------------------------------------------------------
0254: // Sampling Global Illumination(大域照明の読み込み)
0255: // ------------------------------------------------------------
0256: float4 GetGI( float2 tex_coord, bool front_or_back )
0257: {
0258: #if 0
0259:     float4 SH = 2.0 * tex2D( PRTSamp, tex_coord ) - 1.0;
0260:     float4 GI =   SH.a * ( 2.0 * tex2D( SrcSamp, float2(0.25, 0.25) ) - 1.0)
0261:                 + SH.r * ( 2.0 * tex2D( SrcSamp, float2(0.25, 0.75) ) - 1.0)
0262:                 + SH.g * ( 2.0 * tex2D( SrcSamp, float2(0.75, 0.25) ) - 1.0)
0263:                 + SH.b * ( 2.0 * tex2D( SrcSamp, float2(0.75, 0.75) ) - 1.0);
0264: #else
0265:     // Tuned
0266:     float4 SH = 4.0 * tex2D( PRTSamp, tex_coord ) - 2.0;
0267:     float4 GI =   SH.a * tex2D( SrcSamp, float2(0.25, 0.25))
0268:                 + SH.r * tex2D( SrcSamp, float2(0.25, 0.75))
0269:                 + SH.g * tex2D( SrcSamp, float2(0.75, 0.25))
0270:                 + SH.b * tex2D( SrcSamp, float2(0.75, 0.75));
0271:     
0272:     GI -= dot(SH, float4(0.5,0.5,0.5,0.5));
0273: #endif
0274:                 
0275:     return GI;
0276: }
0277: 
0278: 
0279: 
0280: 
0281: // ------------------------------------------------------------
0282: // Full Global Illumination(全部込みピクセルシェーダプログラム)
0283: // ------------------------------------------------------------
0284: float4 PS_ParabploidEnvmap (VS_OUTPUT In) : COLOR
0285: {
0286:     float4 Env = 0.2 * GetEnvMap( In.Tex0, In.Tex1, In.Normal.z, 0.5 < In.Color.w );// Environment map(環境マップ)
0287:     float4 GI  = GetGI( In.DecaleTex, 0.5 < In.Color.w );                       // Global Illumination
0288:     float4 decale = tex2D( DecaleSamp, In.DecaleTex );
0289:     
0290:     return (3.0 * GI) * decale + Env;
0291: //  return (0.3 + 3.0 * GI) * decale + Env;
0292: }
0293: 
0294: 
0295: // ------------------------------------------------------------
0296: // No environment mapping(環境マップなしピクセルシェーダプログラム)
0297: // ------------------------------------------------------------
0298: float4 PS_ParabploidEnvmapNoEnv (VS_OUTPUT In) : COLOR
0299: {
0300:     float4 Out;
0301:     
0302:     // Color(色)
0303:     Out = 1.5 * GetGI( In.DecaleTex, 0.5 < In.Color.w );                    // Global Illumination
0304: 
0305:     return Out;
0306: }
0307: 
0308: 
0309: // ------------------------------------------------------------
0310: // No global illumination (GIなしピクセルシェーダプログラム)
0311: // ------------------------------------------------------------
0312: float4 PS_ParabploidEnvmapNoGI (VS_OUTPUT In) : COLOR
0313: {
0314:     float4 Out;
0315:     
0316:     // Color(色)
0317:     Out = 0.4 * GetEnvMap( In.Tex0, In.Tex1, In.Normal.z, 0.5 < In.Color.w );   // Environment map(環境マップ)
0318: 
0319:     return Out;
0320: }
0321: 
0322: 
0323: 
0324: 
0325: 
0326: // ------------------------------------------------------------
0327: // 64 box sampling (64ボックス サンプリング)
0328: // ------------------------------------------------------------
0329: 
0330: // ------------------------------------------------------------
0331: // Vertex shader program(頂点シェーダプログラム)
0332: // ------------------------------------------------------------
0333: VS_OUTPUT_64BOX_SAMPLING VS_Reduction (
0334:       float4 Pos    : POSITION           // (モデルの頂点)
0335:      ,float4 Tex    : TEXCOORD0          // (テクスチャ座標)
0336: ){
0337:     VS_OUTPUT_64BOX_SAMPLING Out = (VS_OUTPUT_64BOX_SAMPLING)0;
0338:     
0339:     // Position(位置座標)
0340:     Out.Pos = Pos;
0341:     
0342:     // Texture Coordinates(テクスチャ座標)
0343:     Out.Tex0 = Tex + float2(3.0f/MAP_WIDTH, 1.0f/MAP_HEIGHT);
0344:     Out.Tex1 = Tex + float2(3.0f/MAP_WIDTH, 3.0f/MAP_HEIGHT);
0345:     Out.Tex2 = Tex + float2(3.0f/MAP_WIDTH, 5.0f/MAP_HEIGHT);
0346:     Out.Tex3 = Tex + float2(3.0f/MAP_WIDTH, 7.0f/MAP_HEIGHT);
0347:     Out.Tex4 = Tex + float2(1.0f/MAP_WIDTH, 1.0f/MAP_HEIGHT);
0348:     Out.Tex5 = Tex + float2(1.0f/MAP_WIDTH, 3.0f/MAP_HEIGHT);
0349:     Out.Tex6 = Tex + float2(1.0f/MAP_WIDTH, 5.0f/MAP_HEIGHT);
0350:     Out.Tex7 = Tex + float2(1.0f/MAP_WIDTH, 7.0f/MAP_HEIGHT);
0351:     
0352:     return Out;
0353: }
0354: 
0355: // ------------------------------------------------------------
0356: // Pixel shader program(ピクセルシェーダプログラム)
0357: // ------------------------------------------------------------
0358: float4 PS_Reduction ( VS_OUTPUT_64BOX_SAMPLING In ) : COLOR0
0359: {
0360:     float4 t0 = tex2D(SrcSamp, In.Tex0);
0361:     float4 t1 = tex2D(SrcSamp, In.Tex1);
0362:     float4 t2 = tex2D(SrcSamp, In.Tex2);
0363:     float4 t3 = tex2D(SrcSamp, In.Tex3);
0364:     
0365:     float4 t4 = tex2D(SrcSamp, In.Tex4);
0366:     float4 t5 = tex2D(SrcSamp, In.Tex5);
0367:     float4 t6 = tex2D(SrcSamp, In.Tex6);
0368:     float4 t7 = tex2D(SrcSamp, In.Tex7);
0369:     
0370:     float4 t8 = tex2D(SrcSamp, In.Tex0 + float2(+4.0f/MAP_WIDTH, 0));
0371:     float4 t9 = tex2D(SrcSamp, In.Tex1 + float2(+4.0f/MAP_WIDTH, 0));
0372:     float4 ta = tex2D(SrcSamp, In.Tex2 + float2(+4.0f/MAP_WIDTH, 0));
0373:     float4 tb = tex2D(SrcSamp, In.Tex3 + float2(+4.0f/MAP_WIDTH, 0));
0374:     
0375:     float4 tc = tex2D(SrcSamp, In.Tex4 + float2(+4.0f/MAP_WIDTH, 0));
0376:     float4 td = tex2D(SrcSamp, In.Tex5 + float2(+4.0f/MAP_WIDTH, 0));
0377:     float4 te = tex2D(SrcSamp, In.Tex6 + float2(+4.0f/MAP_WIDTH, 0));
0378:     float4 tf = tex2D(SrcSamp, In.Tex7 + float2(+4.0f/MAP_WIDTH, 0));
0379:     
0380:     return ((t0+t1+t2+t3)
0381:            +(t4+t5+t6+t7)
0382:            +(t8+t9+ta+tb)
0383:            +(tc+td+te+tf))/16;
0384: }
0385: 
0386: 
0387: 
0388: 
0389: // ------------------------------------------------------------
0390: // SH(0,0)
0391: // ------------------------------------------------------------
0392: float4 PS_00 (
0393:       float4 Pos    : POSITION           // (モデルの頂点)
0394:      ,float4 Tex    : TEXCOORD0          // (テクスチャ座標)
0395: ) : COLOR0
0396: {
0397:     float4 Tex2 = Tex;
0398:     Tex2.x = 1-Tex2.x;
0399:     
0400:     return 0.5 + 0.25 * (
0401:           (2.0 * tex2D( WeightSampFront, Tex ).a - 1.0) * tex2D( ParaboloidFrontSamp, Tex ) +
0402:           (2.0 * tex2D( WeightSampBack,  Tex ).a - 1.0) * tex2D( ParaboloidBackSamp,  Tex2) );
0403: }
0404: // ------------------------------------------------------------
0405: // SH(1,0)
0406: // ------------------------------------------------------------
0407: float4 PS_10 (
0408:       float4 Pos    : POSITION           // (モデルの頂点)
0409:      ,float4 Tex    : TEXCOORD0          // (テクスチャ座標)
0410: ) : COLOR0
0411: {
0412:     float4 Tex2 = Tex;
0413:     Tex2.x = 1-Tex2.x;
0414:     
0415:     return 0.5 + 0.25 * (
0416:           (2.0 * tex2D( WeightSampFront, Tex).r - 1.0) * tex2D( ParaboloidFrontSamp, Tex ) +
0417:           (2.0 * tex2D( WeightSampBack,  Tex).r - 1.0) * tex2D( ParaboloidBackSamp,  Tex2) );
0418: }
0419: // ------------------------------------------------------------
0420: // SH(1,1)
0421: // ------------------------------------------------------------
0422: float4 PS_11 (
0423:       float4 Pos    : POSITION           // (モデルの頂点)
0424:      ,float4 Tex    : TEXCOORD0          // (テクスチャ座標)
0425: ) : COLOR0
0426: {
0427:     float4 Tex2 = Tex;
0428:     Tex2.x = 1-Tex2.x;
0429:     
0430:     return 0.5 + 0.25 * (
0431:           (2.0 * tex2D( WeightSampFront, Tex).g - 1.0) * tex2D( ParaboloidFrontSamp, Tex ) +
0432:           (2.0 * tex2D( WeightSampBack,  Tex).g - 1.0) * tex2D( ParaboloidBackSamp,  Tex2) );
0433: }
0434: // ------------------------------------------------------------
0435: // SH(1,2)
0436: // ------------------------------------------------------------
0437: float4 PS_12 (
0438:       float4 Pos    : POSITION           // (モデルの頂点)
0439:      ,float4 Tex    : TEXCOORD0          // (テクスチャ座標)
0440: ) : COLOR0
0441: {
0442:     float4 Tex2 = Tex;
0443:     Tex2.x = 1-Tex2.x;
0444:     
0445:     return 0.5 + 0.25 * (
0446:           (2.0 * tex2D( WeightSampFront, Tex).b - 1.0) * tex2D( ParaboloidFrontSamp, Tex ) +
0447:           (2.0 * tex2D( WeightSampBack,  Tex).b - 1.0) * tex2D( ParaboloidBackSamp,  Tex2) );
0448: }
0449: 
0450: 
0451: // ------------------------------------------------------------
0452: // ------------------------------------------------------------
0453: // Create height map and normal map(位置、法線マップの作成)
0454: // ------------------------------------------------------------
0455: // ------------------------------------------------------------
0456: struct VS_OUTPUT_MAP
0457: {
0458:     float4 Pos          : POSITION;
0459:     float4 Position     : TEXCOORD0;
0460:     float4 Normal       : TEXCOORD1;
0461: };
0462: struct PS_OUTPUT_MAP
0463: {
0464:     float4 Position     : COLOR0;
0465:     float4 Normal       : COLOR1;
0466: };
0467: 
0468: // ------------------------------------------------------------
0469: // Vertex shader(頂点シェーダ)
0470: // ------------------------------------------------------------
0471: VS_OUTPUT_MAP VS_Map (
0472:       float4 Pos    : POSITION           // モデルの頂点
0473:     , float4 Normal : NORMAL             // 法線ベクトル
0474:     , float4 Tex0   : TEXCOORD0          // テクスチャ座標
0475: ){
0476:     float MAP_SIZE = 512;
0477:     VS_OUTPUT_MAP Out = (VS_OUTPUT_MAP)0;        // 出力データ
0478:     
0479:     float4 pos = mul( Pos, mWVP );
0480:     
0481:     // 位置座標
0482:     Out.Pos.x =  2.0 * (Tex0.x*(MAP_SIZE+1)/MAP_SIZE - 1/MAP_SIZE) - 1.0;
0483:     Out.Pos.y = -2.0 * (Tex0.y*(MAP_SIZE+1)/MAP_SIZE - 1/MAP_SIZE) + 1.0;
0484:     Out.Pos.z = 0.5;
0485:     Out.Pos.w = 1;
0486:     
0487:     // 色
0488:     Out.Position = Pos;
0489:     Out.Normal   = Normal;
0490:     Out.Normal.w = 0;
0491: 
0492:     return Out;
0493: }
0494: 
0495: 
0496: // ------------------------------------------------------------
0497: // Pixel shader(ピクセルシェーダ)
0498: // ------------------------------------------------------------
0499: PS_OUTPUT_MAP PS_Map (VS_OUTPUT_MAP In)
0500: {
0501:     PS_OUTPUT_MAP Out;
0502:     
0503:     Out.Position = In.Position;
0504:     Out.Normal   = normalize(In.Normal);
0505: 
0506:     return Out;
0507: }
0508: 
0509: 
0510: 
0511: // ------------------------------------------------------------
0512: // ------------------------------------------------------------
0513: // PRT
0514: // ------------------------------------------------------------
0515: // ------------------------------------------------------------
0516: struct VS_OUTPUT_SH
0517: {
0518:     float4 Pos          : POSITION;
0519:     float4 Tex          : TEXCOORD0;
0520:     float4 Position     : TEXCOORD1;
0521: };
0522: 
0523: 
0524: // ------------------------------------------------------------
0525: // Vertex shader(頂点シェーダ)
0526: // ------------------------------------------------------------
0527: VS_OUTPUT_SH VS_SH (
0528:       float4 Pos    : POSITION           // モデルの頂点
0529:     , float4 Tex0   : TEXCOORD0          // テクスチャ座標
0530: ){
0531:     VS_OUTPUT_SH Out = (VS_OUTPUT_SH)0;        // 出力データ
0532:     
0533:     // 位置座標
0534:     Out.Pos = Pos;
0535:     
0536:     // 位置ベクトル
0537:     Out.Position = Pos;
0538:     Out.Position.zw = 0;
0539:     
0540:     // テクスチャ座標
0541:     Out.Tex   = Tex0;
0542: 
0543:     return Out;
0544: }
0545: 
0546: 
0547: // ------------------------------------------------------------
0548: // SH(0,0), SH(1,-1), SH(1,0), SH(1,1)
0549: // ------------------------------------------------------------
0550: float4 PS_SH0 (VS_OUTPUT_SH In) : COLOR0
0551: {
0552:     float4 N = In.Position;
0553:     float4 val;
0554:     
0555:     float l = dot(N,N);
0556:     if(1.0<l) N *= rsqrt(l);
0557:     N.z = sqrt(1-dot(N,N));
0558:     // サーフェス座標系からローカル座標系に変換
0559:     N = mul( N, mST );
0560:     
0561:     val.w = 1;
0562:     val.x = -N.x;
0563:     val.y =  N.y;
0564:     val.z = -N.z;
0565: 
0566:     return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ));
0567: }
0568: 
0569: 
0570: 
0571: 
0572: // ------------------------------------------------------------
0573: // SH(2,-2), SH(2,-1), SH(2,0), SH(2,1)
0574: // ------------------------------------------------------------
0575: float4 PS_SH1 (VS_OUTPUT_SH In) : COLOR0
0576: {
0577:     float4 N = In.Position;
0578:     float4 val;
0579:     
0580:     float l = dot(N,N);
0581:     if(1.0<l) N *= rsqrt(l);
0582:     N.z = sqrt(1-dot(N,N));
0583:     // サーフェス座標系からローカル座標系に変換
0584:     N = mul( N, mST );
0585:     
0586:     val.x = N.x * N.x - N.z * N.z;
0587:     val.y = - N.y * N.x;
0588:     val.z =  (N.y * N.y - 1/3)/2;
0589:     val.w = - N.y * N.z;
0590: 
0591:     return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ));
0592: }
0593: 
0594: 
0595: // ------------------------------------------------------------
0596: // SH(2,2), SH(3,-3), SH(3,-2), SH(3,-1)
0597: // ------------------------------------------------------------
0598: float4 PS_SH2 (VS_OUTPUT_SH In) : COLOR0
0599: {
0600:     float4 N = In.Position;
0601:     float4 val;
0602:     
0603:     float l = dot(N,N);
0604:     if(1.0<l) N *= rsqrt(l);
0605:     N.z = sqrt(1-dot(N,N));
0606:     // サーフェス座標系からローカル座標系に変換
0607:     N = mul( N, mST );
0608:     
0609:     val.x = 2 * N.x * N.z;
0610:     val.y = - N.z * (N.x * N.x - N.z * N.z/3);
0611:     val.z = 2 * N.x * N.y * N.z;
0612:     val.w = 0.5 * N.z * (0.2 - N.y * N.y);
0613: 
0614:     return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ));
0615: }
0616: // ------------------------------------------------------------
0617: // SH(3,0), SH(3,1), SH(3,2), SH(3,3)
0618: // ------------------------------------------------------------
0619: float4 PS_SH3 (VS_OUTPUT_SH In) : COLOR0
0620: {
0621:     float4 N = In.Position;
0622:     float4 val;
0623:     
0624:     float l = dot(N,N);
0625:     if(1.0<l) N *= rsqrt(l);
0626:     N.z = sqrt(1-dot(N,N));
0627:     // サーフェス座標系からローカル座標系に変換
0628:     N = mul( N, mST );
0629:     
0630:     val.x = N.y * (N.y * N.y - 3/5) / 6;
0631:     val.y = 0.5 * N.x * (0.2 - N.y * N.y);
0632:     val.z = N.y * (N.x * N.x - N.z * N.z);
0633:     val.w = -N.x * (N.x * N.x/3 - N.z * N.z);
0634: 
0635:     return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ));
0636: }
0637: 
0638: 
0639: // ------------------------------------------------------------
0640: // ------------------------------------------------------------
0641: // 遮蔽項の計算
0642: // ------------------------------------------------------------
0643: // ------------------------------------------------------------
0644: struct VS_OUTPUT_RADIANCE
0645: {
0646:     float4 Pos          : POSITION;
0647:     float4 Color        : COLOR0;
0648: };
0649: 
0650: // ------------------------------------------------------------
0651: // 頂点シェーダプログラム
0652: // ------------------------------------------------------------
0653: VS_OUTPUT_RADIANCE VS_Radiance (
0654:       float4 Pos    : POSITION           // モデルの頂点
0655:      ,float4 Normal : NORMAL             // 法線ベクトル
0656:      ,float4 Tex0   : TEXCOORD0          // テクスチャ座標
0657: ){
0658:     VS_OUTPUT_RADIANCE Out = (VS_OUTPUT_RADIANCE)0;        // 出力データ
0659:     
0660:     float4 pos = mul( Pos, mWV );
0661:     
0662:     // 位置座標
0663:     float rlen = rsqrt(dot(pos.xyz, pos.xyz));
0664:     pos *= rlen;
0665:     Out.Pos = pos;
0666:     // 背面に来た頂点は無限遠に引き伸ばす
0667:     if(pos.z<=0){
0668:         Out.Pos.w = 0;
0669:     }else{
0670:         Out.Pos.w = 1;
0671:     }
0672:     
0673:     Out.Color = 0.5;
0674:     
0675:     return Out;
0676: }
0677: // ------------------------------------------------------------
0678: // ピクセルシェーダプログラム
0679: // ------------------------------------------------------------
0680: float4 PS_Radiance (VS_OUTPUT_RADIANCE In) : COLOR
0681: {
0682:     return In.Color;
0683: }
0684: 
0685: 
0686: 
0687: 
0688: // ------------------------------------------------------------
0689: // テクニック
0690: // ------------------------------------------------------------
0691: technique TShader
0692: {
0693:     pass P0 // Full Global Illuminations
0694:     {
0695:         VertexShader = compile vs_1_1 VS_ParabploidEnvmap();
0696:         PixelShader  = compile ps_2_0 PS_ParabploidEnvmap();
0697:     }
0698:     pass P1 // No environment mapping(環境マップなし)
0699:     {
0700:         VertexShader = compile vs_1_1 VS_ParabploidEnvmap();
0701:         PixelShader  = compile ps_2_0 PS_ParabploidEnvmapNoEnv();
0702:     }
0703:     pass P2 // No Global illumination(GIなし)
0704:     {
0705:         VertexShader = compile vs_1_1 VS_ParabploidEnvmap();
0706:         PixelShader  = compile ps_2_0 PS_ParabploidEnvmapNoGI();
0707:     }
0708:     
0709:     pass P3 // reduction(縮小)
0710:     {
0711:         VertexShader = compile vs_1_1 VS_Reduction();
0712:         PixelShader  = compile ps_2_0 PS_Reduction();
0713:     }
0714:     
0715:     pass P4 // Paraboloid transform(放物変換地形描画)
0716:     {
0717:         VertexShader = compile vs_1_1 VS_Parabploid();
0718:         PixelShader  = compile ps_1_1 PS();
0719:     }
0720:     pass P5 // Simple transform(地形描画)
0721:     {
0722:         VertexShader = compile vs_1_1 VS();
0723:         PixelShader  = compile ps_1_1 PS();
0724:     }
0725:     
0726:     pass P6
0727:     {
0728:         PixelShader = compile ps_2_0 PS_00();
0729:     }
0730:     pass P7
0731:     {
0732:         PixelShader = compile ps_2_0 PS_10();
0733:     }
0734:     pass P8
0735:     {
0736:         PixelShader = compile ps_2_0 PS_11();
0737:     }
0738:     pass P9
0739:     {
0740:         PixelShader = compile ps_2_0 PS_12();
0741:     }    
0742:     pass P10 // Height map and normal map(位置、法線マップ)
0743:     {
0744:         VertexShader = compile vs_1_1 VS_Map();
0745:         PixelShader  = compile ps_2_0 PS_Map();
0746:     }
0747:     pass P11
0748:     {
0749:         VertexShader = compile vs_1_1 VS_SH();
0750:         PixelShader  = compile ps_2_0 PS_SH0();
0751:     }
0752:     pass P12
0753:     {
0754:         VertexShader = compile vs_1_1 VS_SH();
0755:         PixelShader  = compile ps_2_0 PS_SH1();
0756:     }
0757:     pass P13
0758:     {
0759:         VertexShader = compile vs_1_1 VS_SH();
0760:         PixelShader  = compile ps_2_0 PS_SH2();
0761:     }
0762:     pass P14
0763:     {
0764:         VertexShader = compile vs_1_1 VS_SH();
0765:         PixelShader  = compile ps_2_0 PS_SH3();
0766:     }
0767:     pass P15 // ラディアンスの計算
0768:     {
0769:         VertexShader = compile vs_1_1 VS_Radiance();
0770:         PixelShader  = compile ps_2_0 PS_Radiance();
0771:     }
0772: }
0773: