0001: // ------------------------------------------------------------
0002: // Real-time Global Illumination
0003: // 
0004: // Copyright (c) 2004 IMAGIRE Takashi. All rights reserved.
0005: // ------------------------------------------------------------
0006: #include "paraboloid.fx"
0007: 
0008: #define NV4X
0009:  
0010: // ------------------------------------------------------------
0011: // Global variables(グローバル変数)
0012: // ------------------------------------------------------------
0013: float4x4 mWVP;      // Local-Projection matrix
0014: float4x4 mWV;       // Local-View matrix
0015: float4x4 mST;                   // ローカル→サーフェス座標系への変換行列の転置
0016: float4 vEye;        // Eye position(Local coordinate)
0017: 
0018: float diffuse;
0019: float specular;
0020: float translucent;
0021: 
0022: float MAP_WIDTH;    // texture width
0023: float MAP_HEIGHT;   // texture height
0024: 
0025: // ------------------------------------------------------------
0026: // Textures(テクスチャ)
0027: // ------------------------------------------------------------
0028: texture SrcTex;
0029: sampler SrcSamp = sampler_state
0030: {
0031:     Texture = <SrcTex>;
0032:     MinFilter = LINEAR;
0033:     MagFilter = LINEAR;
0034:     MipFilter = NONE;
0035: 
0036:     AddressU = Clamp;
0037:     AddressV = Clamp;
0038: };
0039: // ------------------------------------------------------------
0040: texture SSTex;
0041: sampler SSSamp = sampler_state
0042: {
0043:     Texture = <SSTex>;
0044:     MinFilter = LINEAR;
0045:     MagFilter = LINEAR;
0046:     MipFilter = NONE;
0047: 
0048:     AddressU = Clamp;
0049:     AddressV = Clamp;
0050: };
0051: // ------------------------------------------------------------
0052: texture DecaleTex;
0053: sampler DecaleSamp = sampler_state
0054: {
0055:     Texture = <DecaleTex>;
0056:     MinFilter = LINEAR;
0057:     MagFilter = LINEAR;
0058:     MipFilter = NONE;
0059: 
0060:     AddressU = Clamp;
0061:     AddressV = Clamp;
0062: };
0063: // ------------------------------------------------------------
0064: texture PRTTex;
0065: sampler PRTSamp = sampler_state
0066: {
0067:     Texture = <PRTTex>;
0068:     MinFilter = LINEAR;
0069:     MagFilter = LINEAR;
0070:     MipFilter = NONE;
0071: 
0072:     AddressU = Clamp;
0073:     AddressV = Clamp;
0074: };
0075: // ------------------------------------------------------------
0076: // Dual paraboloid maps(双放物マップ)
0077: // ------------------------------------------------------------
0078: texture WeightTexFront;
0079: sampler WeightSampFront = sampler_state
0080: {
0081:     Texture = <WeightTexFront>;
0082:     MinFilter = LINEAR;
0083:     MagFilter = LINEAR;
0084:     MipFilter = NONE;
0085: 
0086:     AddressU = Clamp;
0087:     AddressV = Clamp;
0088: };
0089: // ------------------------------------------------------------
0090: texture WeightTexBack;
0091: sampler WeightSampBack = sampler_state
0092: {
0093:     Texture = <WeightTexBack>;
0094:     MinFilter = LINEAR;
0095:     MagFilter = LINEAR;
0096:     MipFilter = NONE;
0097: 
0098:     AddressU = Clamp;
0099:     AddressV = Clamp;
0100: };
0101: // ------------------------------------------------------------
0102: // Dual paraboloid environment maps(双放物環境マップ)
0103: // ------------------------------------------------------------
0104: texture ParaboloidFrontTex;
0105: sampler ParaboloidFrontSamp = sampler_state
0106: {
0107:     Texture = <ParaboloidFrontTex>;
0108:     MinFilter = LINEAR;
0109:     MagFilter = LINEAR;
0110:     MipFilter = NONE;
0111: 
0112:     AddressU = Clamp;
0113:     AddressV = Clamp;
0114: };
0115: // ------------------------------------------------------------
0116: texture ParaboloidBackTex;
0117: sampler ParaboloidBackSamp = sampler_state
0118: {
0119:     Texture = <ParaboloidBackTex>;
0120:     MinFilter = LINEAR;
0121:     MagFilter = LINEAR;
0122:     MipFilter = NONE;
0123: 
0124:     AddressU = Clamp;
0125:     AddressV = Clamp;
0126: };
0127: 
0128: 
0129: // ------------------------------------------------------------
0130: // Vertex shader output(頂点シェーダからピクセルシェーダに渡すデータ)
0131: // ------------------------------------------------------------
0132: struct VS_OUTPUT
0133: {
0134:     float4 Pos          : POSITION;
0135:     float4 Color        : COLOR0;
0136:     float2 Tex0         : TEXCOORD0;
0137:     float2 Tex1         : TEXCOORD1;
0138:     float3 Normal       : TEXCOORD2;
0139:     float2 DecaleTex    : TEXCOORD3;
0140: };
0141: 
0142: // ------------------------------------------------------------
0143: // Simple vertex shader program(背景描画頂点シェーダプログラム)
0144: // ------------------------------------------------------------
0145: VS_OUTPUT VS (
0146:       float4 Pos    : POSITION           // (モデルの頂点)
0147:      ,float4 Normal : NORMAL             // (法線ベクトル)
0148:      ,float4 Tex0   : TEXCOORD0          // (テクスチャ座標)
0149: ){
0150:     VS_OUTPUT Out = (VS_OUTPUT)0;
0151:     
0152:     // Position(位置座標)
0153:     Out.Pos = mul( Pos, mWVP );
0154:     
0155:     // Texture coordinate(テクスチャ座標)
0156:     Out.Tex0 = Tex0;
0157:     
0158:     return Out;
0159: }
0160: 
0161: 
0162: 
0163: 
0164: // ------------------------------------------------------------
0165: // Simple pixel shader program(背景描画ピクセルシェーダプログラム)
0166: // ------------------------------------------------------------
0167: float4 PS (VS_OUTPUT In) : COLOR
0168: {
0169:     float4 Out;
0170:     
0171:     // Color(色)
0172:     Out = tex2D( SrcSamp, In.Tex0 );
0173:     
0174:     return Out;
0175: }
0176: 
0177: 
0178: 
0179: 
0180: 
0181: // ------------------------------------------------------------
0182: // Parabploid vertex shader program(放物変換頂点シェーダプログラム)
0183: // ------------------------------------------------------------
0184: VS_OUTPUT VS_Parabploid (
0185:       float4 Pos    : POSITION           // (モデルの頂点)
0186:      ,float4 Tex0   : TEXCOORD0          // (テクスチャ座標)
0187: ){
0188:     VS_OUTPUT Out = (VS_OUTPUT)0;
0189:     
0190:     // Position(位置座標)
0191:     Out.Pos = paraboloid( Pos, mWV );
0192:     
0193:     // Texture coordinate(テクスチャ座標)
0194:     Out.Tex0 = Tex0;
0195:     
0196:     return Out;
0197: }
0198: 
0199: 
0200: // ------------------------------------------------------------
0201: // Dual-Parabploid environment mapping vertex shader program(放物環境マップ頂点シェーダプログラム)
0202: // ------------------------------------------------------------
0203: VS_OUTPUT VS_ParabploidEnvmap (
0204:       float4 Pos    : POSITION           // (モデルの頂点)
0205:     , float4 Normal : NORMAL             // (法線ベクトル)
0206:     , float2 Tex    : TEXCOORD0          // (テクスチャ座標)
0207:       )
0208: {
0209:     VS_OUTPUT Out = (VS_OUTPUT)0;
0210:     float3 ray;
0211:     float3 ref;
0212:     
0213:     // Position(位置座標)
0214:     Out.Pos = mul( Pos, mWVP );
0215:     
0216:     // Color(色)
0217:     Out.Color = 0.0f;
0218:     
0219:     // Texture Coordinate(テクスチャ座標)
0220:     ray = normalize( Pos - vEye ).xyz;
0221:     ref = reflect( ray, Normal.xyz );       // Reflection vector(反射ベクトル)
0222: 
0223:     Out.Tex0.x = 0.5 * ( 1 + ref.x/(1+ref.z));
0224:     Out.Tex0.y = 0.5 * ( 1 - ref.y/(1+ref.z));
0225:     Out.Tex1.x = 0.5 * ( 1 - ref.x/(1-ref.z));
0226:     Out.Tex1.y = 0.5 * ( 1 - ref.y/(1-ref.z));
0227:     
0228:     Out.Color.w = ref.z + 0.5f;     // The judgement of the signature of the z-component of the reflection vector(反射ベクトルの正負の判定)
0229:     
0230:     // Normal vector in the view coordinate system(ビュー座標系での法線ベクトル)
0231:     Out.Normal = mul( Normal.xyz, mWV );
0232:     
0233:     Out.DecaleTex = Tex;
0234:     
0235:     return Out;
0236: }
0237: 
0238: 
0239: // ------------------------------------------------------------
0240: // Sampling environment map(環境マップの読み込み)
0241: // ------------------------------------------------------------
0242: float4 GetEnvMap( float2 tex_front, float2 tex_back, float NE, bool front_or_back )
0243: {
0244:     float4 env;
0245:     
0246:     if( front_or_back ){
0247:         env = tex2D( ParaboloidFrontSamp, tex_front );
0248:     }else{
0249:         env = tex2D( ParaboloidBackSamp,  tex_back  );
0250:     }
0251:     
0252:     // Fresnel term (フレネル項)
0253:     float F = 1-NE*NE;
0254:     
0255:     return F * env;
0256: }
0257: 
0258: // ------------------------------------------------------------
0259: // Sampling Global Illumination(大域照明の読み込み)
0260: // ------------------------------------------------------------
0261: float4 GetGI( float2 tex_coord, sampler Samp )
0262: {
0263: #if 0
0264:     float4 SH = 2.0 * tex2D( Samp, tex_coord ) - 1.0;
0265:     float4 GI =   SH.a * ( 2.0 * tex2D( SrcSamp, float2(0.25, 0.25) ) - 1.0)
0266:                 + SH.r * ( 2.0 * tex2D( SrcSamp, float2(0.25, 0.75) ) - 1.0)
0267:                 + SH.g * ( 2.0 * tex2D( SrcSamp, float2(0.75, 0.25) ) - 1.0)
0268:                 + SH.b * ( 2.0 * tex2D( SrcSamp, float2(0.75, 0.75) ) - 1.0);
0269: #else
0270:     // Tuned
0271:     float4 SH = 4.0 * tex2D( Samp, tex_coord ) - 2.0;
0272:     float4 GI =   SH.a * tex2D( SrcSamp, float2(0.25, 0.25))
0273:                 + SH.r * tex2D( SrcSamp, float2(0.25, 0.75))
0274:                 + SH.g * tex2D( SrcSamp, float2(0.75, 0.25))
0275:                 + SH.b * tex2D( SrcSamp, float2(0.75, 0.75));
0276:     
0277:     GI -= dot(SH, float4(0.5,0.5,0.5,0.5));
0278: #endif
0279:                 
0280:     return GI;
0281: }
0282: 
0283: 
0284: 
0285: // ------------------------------------------------------------
0286: // Full Global Illumination(全部込みピクセルシェーダプログラム)
0287: // ------------------------------------------------------------
0288: float4 PS_ParabploidEnvmap (VS_OUTPUT In) : COLOR
0289: {
0290:     float4 Env = GetEnvMap( In.Tex0, In.Tex1, In.Normal.z, 0.5 < In.Color.w );// Environment map(環境マップ)
0291:     float4 GI  = GetGI( In.DecaleTex, PRTSamp );                        // Global Illumination
0292:     float4 SS  = GetGI( In.DecaleTex, SSSamp );                     // Sub surface
0293:     float4 decale = tex2D( DecaleSamp, In.DecaleTex );
0294: decale=1;
0295:     return (diffuse * GI + translucent * SS) * decale + specular * Env;
0296: //  return (0.3 + 3.0 * GI) * decale + Env;
0297: }
0298: 
0299: 
0300: // ------------------------------------------------------------
0301: // No environment mapping(環境マップなしピクセルシェーダプログラム)
0302: // ------------------------------------------------------------
0303: float4 PS_ParabploidEnvmapNoEnv (VS_OUTPUT In) : COLOR
0304: {
0305:     float4 Out;
0306:     float4 decale = tex2D( DecaleSamp, In.DecaleTex );
0307:     float4 GI  = GetGI( In.DecaleTex, PRTSamp );                        // Global Illumination
0308:     
0309:     // Color(色)
0310:     Out = 3.0 * GI;// * decale;                 // Global Illumination
0311: 
0312:     return Out;
0313: }
0314: 
0315: 
0316: // ------------------------------------------------------------
0317: // No global illumination (GIなしピクセルシェーダプログラム)
0318: // ------------------------------------------------------------
0319: float4 PS_ParabploidEnvmapNoGI (VS_OUTPUT In) : COLOR
0320: {
0321:     float4 Out;
0322:     float4 SS  = GetGI( In.DecaleTex, SSSamp );                     // Sub surface
0323:     
0324:     // Color(色)
0325:     Out = 5.0 * SS; // Sub surface
0326: 
0327:     return Out;
0328: }
0329: 
0330: 
0331: 
0332: 
0333: 
0334: // ------------------------------------------------------------
0335: // 64 box sampling (64ボックス サンプリング)
0336: // ------------------------------------------------------------
0337: // ------------------------------------------------------------
0338: struct VS_OUTPUT_64BOX_SAMPLING
0339: {
0340:     float4 Pos          : POSITION;
0341:     float2 Tex0         : TEXCOORD0;
0342:     float2 Tex1         : TEXCOORD1;
0343:     float2 Tex2         : TEXCOORD2;
0344:     float2 Tex3         : TEXCOORD3;
0345:     float2 Tex4         : TEXCOORD4;
0346:     float2 Tex5         : TEXCOORD5;
0347:     float2 Tex6         : TEXCOORD6;
0348:     float2 Tex7         : TEXCOORD7;
0349: };
0350: 
0351: // ------------------------------------------------------------
0352: // Vertex shader program(頂点シェーダプログラム)
0353: // ------------------------------------------------------------
0354: VS_OUTPUT_64BOX_SAMPLING VS_Reduction (
0355:       float4 Pos    : POSITION           // (モデルの頂点)
0356:      ,float2 Tex    : TEXCOORD0          // (テクスチャ座標)
0357: ){
0358:     VS_OUTPUT_64BOX_SAMPLING Out = (VS_OUTPUT_64BOX_SAMPLING)0;
0359:     
0360:     // Position(位置座標)
0361:     Out.Pos = Pos;
0362: 
0363:     // Texture Coordinates(テクスチャ座標)
0364:     Out.Tex0 = Tex + float2(3.0f/MAP_WIDTH, 1.0f/MAP_HEIGHT);
0365:     Out.Tex1 = Tex + float2(3.0f/MAP_WIDTH, 3.0f/MAP_HEIGHT);
0366:     Out.Tex2 = Tex + float2(3.0f/MAP_WIDTH, 5.0f/MAP_HEIGHT);
0367:     Out.Tex3 = Tex + float2(3.0f/MAP_WIDTH, 7.0f/MAP_HEIGHT);
0368:     Out.Tex4 = Tex + float2(1.0f/MAP_WIDTH, 1.0f/MAP_HEIGHT);
0369:     Out.Tex5 = Tex + float2(1.0f/MAP_WIDTH, 3.0f/MAP_HEIGHT);
0370:     Out.Tex6 = Tex + float2(1.0f/MAP_WIDTH, 5.0f/MAP_HEIGHT);
0371:     Out.Tex7 = Tex + float2(1.0f/MAP_WIDTH, 7.0f/MAP_HEIGHT);
0372:     
0373:     return Out;
0374: }
0375: 
0376: // ------------------------------------------------------------
0377: // Pixel shader program(ピクセルシェーダプログラム)
0378: // ------------------------------------------------------------
0379: float4 PS_Reduction ( VS_OUTPUT_64BOX_SAMPLING In ) : COLOR0
0380: {
0381:     float4 t0 = tex2D(SrcSamp, In.Tex0);
0382:     float4 t1 = tex2D(SrcSamp, In.Tex1);
0383:     float4 t2 = tex2D(SrcSamp, In.Tex2);
0384:     float4 t3 = tex2D(SrcSamp, In.Tex3);
0385:     
0386:     float4 t4 = tex2D(SrcSamp, In.Tex4);
0387:     float4 t5 = tex2D(SrcSamp, In.Tex5);
0388:     float4 t6 = tex2D(SrcSamp, In.Tex6);
0389:     float4 t7 = tex2D(SrcSamp, In.Tex7);
0390:     
0391:     float4 t8 = tex2D(SrcSamp, In.Tex0 + float2(+4.0f/MAP_WIDTH, 0));
0392:     float4 t9 = tex2D(SrcSamp, In.Tex1 + float2(+4.0f/MAP_WIDTH, 0));
0393:     float4 ta = tex2D(SrcSamp, In.Tex2 + float2(+4.0f/MAP_WIDTH, 0));
0394:     float4 tb = tex2D(SrcSamp, In.Tex3 + float2(+4.0f/MAP_WIDTH, 0));
0395:     
0396:     float4 tc = tex2D(SrcSamp, In.Tex4 + float2(+4.0f/MAP_WIDTH, 0));
0397:     float4 td = tex2D(SrcSamp, In.Tex5 + float2(+4.0f/MAP_WIDTH, 0));
0398:     float4 te = tex2D(SrcSamp, In.Tex6 + float2(+4.0f/MAP_WIDTH, 0));
0399:     float4 tf = tex2D(SrcSamp, In.Tex7 + float2(+4.0f/MAP_WIDTH, 0));
0400:     
0401: #ifndef NV4X
0402:     return ((t0+t1+t2+t3)
0403:            +(t4+t5+t6+t7)
0404:            +(t8+t9+ta+tb)
0405:            +(tc+td+te+tf))/16;
0406: #else //!NV4X
0407:     return 0.25*(
0408:             0.25*(t0+t1+t2+t3
0409:            +      t4+t5+t6+t7)
0410:            +0.25*(t8+t9+ta+tb
0411:            +      tc+td+te+tf));
0412: #endif// !NV4X
0413: }
0414: 
0415: 
0416: 
0417: 
0418: // ------------------------------------------------------------
0419: // SH(0,0)
0420: // ------------------------------------------------------------
0421: float4 PS_00 (
0422:       float4 Pos    : POSITION           // (モデルの頂点)
0423:      ,float4 Tex    : TEXCOORD0          // (テクスチャ座標)
0424: ) : COLOR0
0425: {
0426:     float4 Tex2 = Tex;
0427:     Tex2.x = 1-Tex2.x;
0428:     
0429:     return 0.5 + 0.25 * (
0430:           (2.0 * tex2D( WeightSampFront, Tex ).a - 1.0) * tex2D( ParaboloidFrontSamp, Tex ) +
0431:           (2.0 * tex2D( WeightSampBack,  Tex ).a - 1.0) * tex2D( ParaboloidBackSamp,  Tex2) );
0432: }
0433: // ------------------------------------------------------------
0434: // SH(1,0)
0435: // ------------------------------------------------------------
0436: float4 PS_10 (
0437:       float4 Pos    : POSITION           // (モデルの頂点)
0438:      ,float4 Tex    : TEXCOORD0          // (テクスチャ座標)
0439: ) : COLOR0
0440: {
0441:     float4 Tex2 = Tex;
0442:     Tex2.x = 1-Tex2.x;
0443:     
0444:     return 0.5 + 0.25 * (
0445:           (2.0 * tex2D( WeightSampFront, Tex).r - 1.0) * tex2D( ParaboloidFrontSamp, Tex ) +
0446:           (2.0 * tex2D( WeightSampBack,  Tex).r - 1.0) * tex2D( ParaboloidBackSamp,  Tex2) );
0447: }
0448: // ------------------------------------------------------------
0449: // SH(1,1)
0450: // ------------------------------------------------------------
0451: float4 PS_11 (
0452:       float4 Pos    : POSITION           // (モデルの頂点)
0453:      ,float4 Tex    : TEXCOORD0          // (テクスチャ座標)
0454: ) : COLOR0
0455: {
0456:     float4 Tex2 = Tex;
0457:     Tex2.x = 1-Tex2.x;
0458:     
0459:     return 0.5 + 0.25 * (
0460:           (2.0 * tex2D( WeightSampFront, Tex).g - 1.0) * tex2D( ParaboloidFrontSamp, Tex ) +
0461:           (2.0 * tex2D( WeightSampBack,  Tex).g - 1.0) * tex2D( ParaboloidBackSamp,  Tex2) );
0462: }
0463: // ------------------------------------------------------------
0464: // SH(1,2)
0465: // ------------------------------------------------------------
0466: float4 PS_12 (
0467:       float4 Pos    : POSITION           // (モデルの頂点)
0468:      ,float4 Tex    : TEXCOORD0          // (テクスチャ座標)
0469: ) : COLOR0
0470: {
0471:     float4 Tex2 = Tex;
0472:     Tex2.x = 1-Tex2.x;
0473:     
0474:     return 0.5 + 1.7 * (
0475: //  return 0.5 + 0.25 * (//???
0476:           (2.0 * tex2D( WeightSampFront, Tex).b - 1.0) * tex2D( ParaboloidFrontSamp, Tex ) +
0477:           (2.0 * tex2D( WeightSampBack,  Tex).b - 1.0) * tex2D( ParaboloidBackSamp,  Tex2) );
0478: }
0479: 
0480: 
0481: // ------------------------------------------------------------
0482: // ------------------------------------------------------------
0483: // Create height map and normal map(位置、法線マップの作成)
0484: // ------------------------------------------------------------
0485: // ------------------------------------------------------------
0486: struct VS_OUTPUT_MAP
0487: {
0488:     float4 Pos          : POSITION;
0489:     float4 Position     : TEXCOORD0;
0490:     float4 Normal       : TEXCOORD1;
0491: };
0492: struct PS_OUTPUT_MAP
0493: {
0494:     float4 Position     : COLOR0;
0495:     float4 Normal       : COLOR1;
0496: };
0497: 
0498: // ------------------------------------------------------------
0499: // Vertex shader(頂点シェーダ)
0500: // ------------------------------------------------------------
0501: VS_OUTPUT_MAP VS_Map (
0502:       float4 Pos    : POSITION           // モデルの頂点
0503:     , float4 Normal : NORMAL             // 法線ベクトル
0504:     , float4 Tex0   : TEXCOORD0          // テクスチャ座標
0505: ){
0506:     float MAP_SIZE = 512;
0507:     VS_OUTPUT_MAP Out = (VS_OUTPUT_MAP)0;        // 出力データ
0508:     
0509:     float4 pos = mul( Pos, mWVP );
0510:     
0511:     // 位置座標
0512:     Out.Pos.x =  2.0 * (Tex0.x*(MAP_SIZE+1)/MAP_SIZE - 1/MAP_SIZE) - 1.0;
0513:     Out.Pos.y = -2.0 * (Tex0.y*(MAP_SIZE+1)/MAP_SIZE - 1/MAP_SIZE) + 1.0;
0514:     Out.Pos.z = 0.5;
0515:     Out.Pos.w = 1;
0516:     
0517:     // 色
0518:     Out.Position = Pos;
0519:     Out.Normal   = Normal;
0520:     Out.Normal.w = 0;
0521: 
0522:     return Out;
0523: }
0524: 
0525: 
0526: // ------------------------------------------------------------
0527: // Pixel shader(ピクセルシェーダ)
0528: // ------------------------------------------------------------
0529: PS_OUTPUT_MAP PS_Map (VS_OUTPUT_MAP In)
0530: {
0531:     PS_OUTPUT_MAP Out;
0532:     
0533:     Out.Position = In.Position;
0534:     Out.Normal   = normalize(In.Normal);
0535: 
0536:     return Out;
0537: }
0538: 
0539: 
0540: 
0541: // ------------------------------------------------------------
0542: // ------------------------------------------------------------
0543: // PRT
0544: // ------------------------------------------------------------
0545: // ------------------------------------------------------------
0546: struct VS_OUTPUT_SH
0547: {
0548:     float4 Pos          : POSITION;
0549:     float4 Tex          : TEXCOORD0;
0550:     float4 Position     : TEXCOORD1;
0551: };
0552: 
0553: 
0554: // ------------------------------------------------------------
0555: // Vertex shader(頂点シェーダ)
0556: // ------------------------------------------------------------
0557: VS_OUTPUT_SH VS_SH (
0558:       float4 Pos    : POSITION           // モデルの頂点
0559:     , float4 Tex0   : TEXCOORD0          // テクスチャ座標
0560: ){
0561:     VS_OUTPUT_SH Out = (VS_OUTPUT_SH)0;        // 出力データ
0562:     
0563:     // 位置座標
0564:     Out.Pos = Pos;
0565:     
0566:     // 位置ベクトル
0567:     Out.Position = Pos;
0568:     Out.Position.zw = 0;
0569:     
0570:     // テクスチャ座標
0571:     Out.Tex   = Tex0;
0572: 
0573:     return Out;
0574: }
0575: 
0576: 
0577: // ------------------------------------------------------------
0578: // SH(0,0), SH(1,-1), SH(1,0), SH(1,1)
0579: // ------------------------------------------------------------
0580: float4 PS_SH0 (VS_OUTPUT_SH In) : COLOR0
0581: {
0582:     float4 N = In.Position;
0583:     float4 val;
0584:     
0585:     float l = dot(N,N);
0586:     if(1.0<l) N *= rsqrt(l);
0587:     N.z = sqrt(1-dot(N,N));
0588:     // サーフェス座標系からローカル座標系に変換
0589:     N = mul( N, mST );
0590:     
0591:     val.w = 1;
0592:     val.x = -N.x;
0593:     val.y =  N.y;
0594:     val.z = -N.z;
0595: 
0596:     return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ));
0597: }
0598: 
0599: 
0600: 
0601: 
0602: // ------------------------------------------------------------
0603: // SH(2,-2), SH(2,-1), SH(2,0), SH(2,1)
0604: // ------------------------------------------------------------
0605: float4 PS_SH1 (VS_OUTPUT_SH In) : COLOR0
0606: {
0607:     float4 N = In.Position;
0608:     float4 val;
0609:     
0610:     float l = dot(N,N);
0611:     if(1.0<l) N *= rsqrt(l);
0612:     N.z = sqrt(1-dot(N,N));
0613:     // サーフェス座標系からローカル座標系に変換
0614:     N = mul( N, mST );
0615:     
0616:     val.x = N.x * N.x - N.z * N.z;
0617:     val.y = - N.y * N.x;
0618:     val.z =  (N.y * N.y - 1/3)/2;
0619:     val.w = - N.y * N.z;
0620: 
0621:     return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ));
0622: }
0623: 
0624: 
0625: // ------------------------------------------------------------
0626: // SH(2,2), SH(3,-3), SH(3,-2), SH(3,-1)
0627: // ------------------------------------------------------------
0628: float4 PS_SH2 (VS_OUTPUT_SH In) : COLOR0
0629: {
0630:     float4 N = In.Position;
0631:     float4 val;
0632:     
0633:     float l = dot(N,N);
0634:     if(1.0<l) N *= rsqrt(l);
0635:     N.z = sqrt(1-dot(N,N));
0636:     // サーフェス座標系からローカル座標系に変換
0637:     N = mul( N, mST );
0638:     
0639:     val.x = 2 * N.x * N.z;
0640:     val.y = - N.z * (N.x * N.x - N.z * N.z/3);
0641:     val.z = 2 * N.x * N.y * N.z;
0642:     val.w = 0.5 * N.z * (0.2 - N.y * N.y);
0643: 
0644:     return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ));
0645: }
0646: // ------------------------------------------------------------
0647: // SH(3,0), SH(3,1), SH(3,2), SH(3,3)
0648: // ------------------------------------------------------------
0649: float4 PS_SH3 (VS_OUTPUT_SH In) : COLOR0
0650: {
0651:     float4 N = In.Position;
0652:     float4 val;
0653:     
0654:     float l = dot(N,N);
0655:     if(1.0<l) N *= rsqrt(l);
0656:     N.z = sqrt(1-dot(N,N));
0657:     // サーフェス座標系からローカル座標系に変換
0658:     N = mul( N, mST );
0659:     
0660:     val.x = N.y * (N.y * N.y - 3/5) / 6;
0661:     val.y = 0.5 * N.x * (0.2 - N.y * N.y);
0662:     val.z = N.y * (N.x * N.x - N.z * N.z);
0663:     val.w = -N.x * (N.x * N.x/3 - N.z * N.z);
0664: 
0665:     return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ));
0666: }
0667: 
0668: 
0669: // ------------------------------------------------------------
0670: // ------------------------------------------------------------
0671: // 遮蔽項の計算
0672: // ------------------------------------------------------------
0673: // ------------------------------------------------------------
0674: struct VS_OUTPUT_RADIANCE
0675: {
0676:     float4 Pos          : POSITION;
0677:     float4 Color        : COLOR0;
0678: };
0679: 
0680: // ------------------------------------------------------------
0681: // 頂点シェーダプログラム
0682: // ------------------------------------------------------------
0683: VS_OUTPUT_RADIANCE VS_Radiance (
0684:       float4 Pos    : POSITION           // モデルの頂点
0685:      ,float4 Normal : NORMAL             // 法線ベクトル
0686:      ,float4 Tex0   : TEXCOORD0          // テクスチャ座標
0687: ){
0688:     VS_OUTPUT_RADIANCE Out = (VS_OUTPUT_RADIANCE)0;        // 出力データ
0689:     
0690:     float4 pos = mul( Pos, mWV );
0691:     
0692:     // 位置座標
0693:     float rlen = rsqrt(dot(pos.xyz, pos.xyz));
0694:     pos *= rlen;
0695:     Out.Pos = pos;
0696:     // 背面に来た頂点は無限遠に引き伸ばす
0697:     if(pos.z<=0){
0698:         Out.Pos.w = -0.00001;
0699:     }else{
0700:         Out.Pos.w = 1;
0701:     }
0702:     
0703:     Out.Color = 0.5;
0704:     
0705:     return Out;
0706: }
0707: // ------------------------------------------------------------
0708: // ピクセルシェーダプログラム
0709: // ------------------------------------------------------------
0710: float4 PS_Radiance (VS_OUTPUT_RADIANCE In) : COLOR
0711: {
0712:     return In.Color;
0713: }
0714: 
0715: // ------------------------------------------------------------
0716: // ------------------------------------------------------------
0717: // 遮蔽項の計算
0718: // ------------------------------------------------------------
0719: // ------------------------------------------------------------
0720: struct VS_OUTPUT_SS_RADIANCE
0721: {
0722:     float4 Pos          : POSITION;
0723:     float4 Color        : COLOR0;
0724:     float4 ProjPos      : TEXCOORD0;
0725: };
0726: 
0727: struct PS_OUTPUT_SS_RADIANCE
0728: {
0729:     float4 Color        : COLOR0;
0730:     float  Depth        : DEPTH;
0731: };
0732: 
0733: // ------------------------------------------------------------
0734: // 頂点シェーダプログラム
0735: // ------------------------------------------------------------
0736: VS_OUTPUT_SS_RADIANCE VS_SSRadiance (
0737:       float4 Pos    : POSITION           // モデルの頂点
0738:      ,float4 Normal : NORMAL             // 法線ベクトル
0739:      ,float4 Tex0   : TEXCOORD0          // テクスチャ座標
0740: ){
0741:     VS_OUTPUT_SS_RADIANCE Out = (VS_OUTPUT_SS_RADIANCE)0;        // 出力データ
0742:     
0743:     float4 pos = mul( Pos, mWV );
0744:     
0745:     // 位置座標
0746:     float rlen = rsqrt(dot(pos.xyz, pos.xyz));
0747:     pos *= rlen;
0748:     // 背面に来た頂点は無限遠に引き伸ばす
0749:     if(pos.z<=0){
0750:         pos.w = -0.00001;
0751:     }else{
0752:         pos.w = 1;
0753:     }
0754:     Out.Pos = pos;
0755:     Out.ProjPos = pos;
0756:     
0757:     float color = exp( -0.5f * pos.z / pos.w );
0758:     Out.Color = color;
0759:     
0760:     return Out;
0761: }
0762: // ------------------------------------------------------------
0763: // ピクセルシェーダプログラム
0764: // ------------------------------------------------------------
0765: PS_OUTPUT_SS_RADIANCE PS_SSRadiance (VS_OUTPUT_SS_RADIANCE In)
0766: {
0767:     PS_OUTPUT_SS_RADIANCE o;
0768:     
0769:     // 普通とは逆のz比較
0770:     o.Depth = 1.0f-In.ProjPos.z/In.ProjPos.w;
0771:     
0772:     o.Color = In.Color;
0773: 
0774:     return o;
0775: }
0776: 
0777: 
0778: 
0779: // ------------------------------------------------------------
0780: // ------------------------------------------------------------
0781: // SSPRT
0782: // ------------------------------------------------------------
0783: // ------------------------------------------------------------
0784: struct VS_OUTPUT_SS_SH
0785: {
0786:     float4 Pos          : POSITION;
0787:     float4 Tex          : TEXCOORD0;
0788:     float2 Tex2         : TEXCOORD1;
0789:     float4 Position     : TEXCOORD2;
0790: };
0791: 
0792: 
0793: // ------------------------------------------------------------
0794: // Vertex shader(頂点シェーダ)
0795: // ------------------------------------------------------------
0796: VS_OUTPUT_SS_SH VS_SS_SH (
0797:       float4 Pos    : POSITION           // モデルの頂点
0798:     , float4 Tex0   : TEXCOORD0          // テクスチャ座標
0799: ){
0800:     VS_OUTPUT_SS_SH Out = (VS_OUTPUT_SS_SH)0;        // 出力データ
0801:     
0802:     // 位置座標
0803:     Out.Pos = Pos;
0804:     
0805:     // 位置ベクトル
0806:     Out.Position = Pos;
0807:     Out.Position.zw = 0;
0808:     
0809:     // テクスチャ座標
0810:     Out.Tex   = Tex0;
0811:     Out.Tex2.x= Tex0.x;
0812:     Out.Tex2.y= 1-Tex0.y;
0813: 
0814:     return Out;
0815: }
0816: 
0817: 
0818: // ------------------------------------------------------------
0819: // SH(0,0), SH(1,-1), SH(1,0), SH(1,1)
0820: // ------------------------------------------------------------
0821: float4 PS_SS_SH0 (VS_OUTPUT_SS_SH In) : COLOR0
0822: {
0823:     float4 N = In.Position;
0824:     float4 val;
0825:     
0826:     float l = dot(N,N);
0827:     if(1.0<l) N *= rsqrt(l);
0828:     N.z = sqrt(1-dot(N,N));
0829:     // サーフェス座標系からローカル座標系に変換
0830:     N = mul( N, mST );
0831:     
0832:     val.w = 1;
0833:     val.x = -N.x;
0834:     val.y =  N.y;
0835:     val.z = -N.z;
0836: 
0837:     return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ) * tex2D( SSSamp, In.Tex2 ));
0838: }
0839: 
0840: 
0841: 
0842: 
0843: // ------------------------------------------------------------
0844: // SH(2,-2), SH(2,-1), SH(2,0), SH(2,1)
0845: // ------------------------------------------------------------
0846: float4 PS_SS_SH1 (VS_OUTPUT_SS_SH In) : COLOR0
0847: {
0848:     float4 N = In.Position;
0849:     float4 val;
0850:     
0851:     float l = dot(N,N);
0852:     if(1.0<l) N *= rsqrt(l);
0853:     N.z = sqrt(1-dot(N,N));
0854:     // サーフェス座標系からローカル座標系に変換
0855:     N = mul( N, mST );
0856:     
0857:     val.x = N.x * N.x - N.z * N.z;
0858:     val.y = - N.y * N.x;
0859:     val.z =  (N.y * N.y - 1/3)/2;
0860:     val.w = - N.y * N.z;
0861: 
0862:     return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ) * tex2D( SSSamp, In.Tex2 ));
0863: }
0864: 
0865: 
0866: // ------------------------------------------------------------
0867: // SH(2,2), SH(3,-3), SH(3,-2), SH(3,-1)
0868: // ------------------------------------------------------------
0869: float4 PS_SS_SH2 (VS_OUTPUT_SS_SH In) : COLOR0
0870: {
0871:     float4 N = In.Position;
0872:     float4 val;
0873:     
0874:     float l = dot(N,N);
0875:     if(1.0<l) N *= rsqrt(l);
0876:     N.z = sqrt(1-dot(N,N));
0877:     // サーフェス座標系からローカル座標系に変換
0878:     N = mul( N, mST );
0879:     
0880:     val.x = 2 * N.x * N.z;
0881:     val.y = - N.z * (N.x * N.x - N.z * N.z/3);
0882:     val.z = 2 * N.x * N.y * N.z;
0883:     val.w = 0.5 * N.z * (0.2 - N.y * N.y);
0884: 
0885:     return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ) * tex2D( SSSamp, In.Tex2 ));
0886: }
0887: // ------------------------------------------------------------
0888: // SH(3,0), SH(3,1), SH(3,2), SH(3,3)
0889: // ------------------------------------------------------------
0890: float4 PS_SS_SH3 (VS_OUTPUT_SS_SH In) : COLOR0
0891: {
0892:     float4 N = In.Position;
0893:     float4 val;
0894:     
0895:     float l = dot(N,N);
0896:     if(1.0<l) N *= rsqrt(l);
0897:     N.z = sqrt(1-dot(N,N));
0898:     // サーフェス座標系からローカル座標系に変換
0899:     N = mul( N, mST );
0900:     
0901:     val.x = N.y * (N.y * N.y - 3/5) / 6;
0902:     val.y = 0.5 * N.x * (0.2 - N.y * N.y);
0903:     val.z = N.y * (N.x * N.x - N.z * N.z);
0904:     val.w = -N.x * (N.x * N.x/3 - N.z * N.z);
0905: 
0906:     return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ) * tex2D( SSSamp, In.Tex2 ));
0907: }
0908: 
0909: 
0910: 
0911: 
0912: 
0913: 
0914: // ------------------------------------------------------------
0915: // テクニック
0916: // ------------------------------------------------------------
0917: technique TShader
0918: {
0919:     pass P0 // Full Global Illuminations
0920:     {
0921:         VertexShader = compile vs_1_1 VS_ParabploidEnvmap();
0922:         PixelShader  = compile ps_2_0 PS_ParabploidEnvmap();
0923:     }
0924:     pass P1 // No environment mapping(環境マップなし)
0925:     {
0926:         VertexShader = compile vs_1_1 VS_ParabploidEnvmap();
0927:         PixelShader  = compile ps_2_0 PS_ParabploidEnvmapNoEnv();
0928:     }
0929:     pass P2 // No Global illumination(GIなし)
0930:     {
0931:         VertexShader = compile vs_1_1 VS_ParabploidEnvmap();
0932:         PixelShader  = compile ps_2_0 PS_ParabploidEnvmapNoGI();
0933:     }
0934:     
0935:     pass P3 // reduction(縮小)
0936:     {
0937:         VertexShader = compile vs_1_1 VS_Reduction();
0938:         PixelShader  = compile ps_2_0 PS_Reduction();
0939:     }
0940:     
0941:     pass P4 // Paraboloid transform(放物変換地形描画)
0942:     {
0943:         VertexShader = compile vs_1_1 VS_Parabploid();
0944:         PixelShader  = compile ps_1_1 PS();
0945:     }
0946:     pass P5 // Simple transform(地形描画)
0947:     {
0948:         VertexShader = compile vs_1_1 VS();
0949:         PixelShader  = compile ps_1_1 PS();
0950:     }
0951:     
0952:     pass P6
0953:     {
0954:         PixelShader = compile ps_2_0 PS_00();
0955:     }
0956:     pass P7
0957:     {
0958:         PixelShader = compile ps_2_0 PS_10();
0959:     }
0960:     pass P8
0961:     {
0962:         PixelShader = compile ps_2_0 PS_11();
0963:     }
0964:     pass P9
0965:     {
0966:         PixelShader = compile ps_2_0 PS_12();
0967:     }    
0968:     pass P10 // Height map and normal map(位置、法線マップ)
0969:     {
0970:         VertexShader = compile vs_1_1 VS_Map();
0971:         PixelShader  = compile ps_2_0 PS_Map();
0972:     }
0973:     pass P11
0974:     {
0975:         VertexShader = compile vs_1_1 VS_SH();
0976:         PixelShader  = compile ps_2_0 PS_SH0();
0977:     }
0978:     pass P12
0979:     {
0980:         VertexShader = compile vs_1_1 VS_SH();
0981:         PixelShader  = compile ps_2_0 PS_SH1();
0982:     }
0983:     pass P13
0984:     {
0985:         VertexShader = compile vs_1_1 VS_SH();
0986:         PixelShader  = compile ps_2_0 PS_SH2();
0987:     }
0988:     pass P14
0989:     {
0990:         VertexShader = compile vs_1_1 VS_SH();
0991:         PixelShader  = compile ps_2_0 PS_SH3();
0992:     }
0993:     pass P15 // ラディアンスの計算
0994:     {
0995:         VertexShader = compile vs_1_1 VS_Radiance();
0996:         PixelShader  = compile ps_2_0 PS_Radiance();
0997:     }
0998:     pass P16 // SS用ラディアンスの計算
0999:     {
1000:         VertexShader = compile vs_2_0 VS_SSRadiance();
1001:         PixelShader  = compile ps_2_0 PS_SSRadiance();
1002:         cullmode = none;
1003:     }
1004:     pass P17
1005:     {
1006:         VertexShader = compile vs_1_1 VS_SS_SH();
1007:         PixelShader  = compile ps_2_0 PS_SS_SH0();
1008:     }
1009:     pass P18
1010:     {
1011:         VertexShader = compile vs_1_1 VS_SS_SH();
1012:         PixelShader  = compile ps_2_0 PS_SS_SH1();
1013:     }
1014:     pass P19
1015:     {
1016:         VertexShader = compile vs_1_1 VS_SS_SH();
1017:         PixelShader  = compile ps_2_0 PS_SS_SH2();
1018:     }
1019:     pass P20
1020:     {
1021:         VertexShader = compile vs_1_1 VS_SS_SH();
1022:         PixelShader  = compile ps_2_0 PS_SS_SH3();
1023:     }
1024: }
1025: