0001:
0002:
0003:
0004:
0005:
0006:
0007:
0008:
0009:
0010: float4x4 mWVP;
0011: float4x4 mWV;
0012: float4x4 mST;
0013: static const int L_MAX = 3;
0014: float4 vSH[((L_MAX+1)*(L_MAX+1)+3)/4];
0015:
0016:
0017:
0018:
0019: texture SrcTex;
0020: sampler SrcSamp = sampler_state
0021: {
0022: Texture = <SrcTex>;
0023: MinFilter = LINEAR;
0024: MagFilter = LINEAR;
0025: MipFilter = NONE;
0026:
0027: AddressU = Clamp;
0028: AddressV = Clamp;
0029: };
0030:
0031:
0032: texture PrtTex0;
0033: sampler PrtSamp0 = sampler_state
0034: {
0035: Texture = <PrtTex0>;
0036: MinFilter = LINEAR;
0037: MagFilter = LINEAR;
0038: MipFilter = NONE;
0039:
0040: AddressU = Clamp;
0041: AddressV = Clamp;
0042: };
0043: texture PrtTex1;
0044: sampler PrtSamp1 = sampler_state
0045: {
0046: Texture = <PrtTex1>;
0047: MinFilter = LINEAR;
0048: MagFilter = LINEAR;
0049: MipFilter = NONE;
0050:
0051: AddressU = Clamp;
0052: AddressV = Clamp;
0053: };
0054: texture PrtTex2;
0055: sampler PrtSamp2 = sampler_state
0056: {
0057: Texture = <PrtTex2>;
0058: MinFilter = LINEAR;
0059: MagFilter = LINEAR;
0060: MipFilter = NONE;
0061:
0062: AddressU = Clamp;
0063: AddressV = Clamp;
0064: };
0065: texture PrtTex3;
0066: sampler PrtSamp3 = sampler_state
0067: {
0068: Texture = <PrtTex3>;
0069: MinFilter = LINEAR;
0070: MagFilter = LINEAR;
0071: MipFilter = NONE;
0072:
0073: AddressU = Clamp;
0074: AddressV = Clamp;
0075: };
0076:
0077:
0078:
0079: struct VS_OUTPUT
0080: {
0081: float4 Pos : POSITION;
0082: float4 Color : COLOR0;
0083: float2 Tex0 : TEXCOORD0;
0084: };
0085:
0086:
0087:
0088:
0089: VS_OUTPUT VS (
0090: float4 Pos : POSITION
0091: ,float4 Normal : NORMAL
0092: ,float4 Tex0 : TEXCOORD0
0093: ){
0094: VS_OUTPUT Out = (VS_OUTPUT)0;
0095:
0096:
0097: Out.Pos = mul( Pos, mWVP );
0098:
0099:
0100: Out.Tex0 = Tex0;
0101:
0102: return Out;
0103: }
0104:
0105:
0106:
0107:
0108:
0109:
0110: float GetPRT(float2 Tex)
0111: {
0112: return dot(2.0*tex2D( PrtSamp0, Tex )-1.0, vSH[0])
0113: + dot(2.0*tex2D( PrtSamp1, Tex )-1.0, vSH[1])
0114: + dot(2.0*tex2D( PrtSamp2, Tex )-1.0, vSH[2])
0115: + dot(2.0*tex2D( PrtSamp3, Tex )-1.0, vSH[3])
0116: ;
0117: }
0118:
0119:
0120:
0121:
0122: float4 PS (VS_OUTPUT In) : COLOR
0123: {
0124: float4 Out;
0125:
0126:
0127: Out = tex2D( SrcSamp, In.Tex0 ) * GetPRT(In.Tex0);
0128:
0129: return Out;
0130: }
0131:
0132:
0133:
0134: float4 PS_NoTex (VS_OUTPUT In) : COLOR
0135: {
0136: float4 Out;
0137:
0138:
0139: Out = GetPRT(In.Tex0);
0140:
0141: return Out;
0142: }
0143:
0144:
0145:
0146: float4 PS_NoGI (VS_OUTPUT In) : COLOR
0147: {
0148: float4 Out;
0149:
0150:
0151: Out = tex2D( SrcSamp, In.Tex0 );
0152:
0153: return Out;
0154: }
0155:
0156:
0157:
0158:
0159:
0160:
0161:
0162: struct VS_OUTPUT_MAP
0163: {
0164: float4 Pos : POSITION;
0165: float4 Position : TEXCOORD0;
0166: float4 Normal : TEXCOORD1;
0167: };
0168: struct PS_OUTPUT_MAP
0169: {
0170: float4 Position : COLOR0;
0171: float4 Normal : COLOR1;
0172: };
0173:
0174:
0175:
0176:
0177: VS_OUTPUT_MAP VS_Map (
0178: float4 Pos : POSITION
0179: , float4 Normal : NORMAL
0180: , float4 Tex0 : TEXCOORD0
0181: ){
0182: float MAP_SIZE = 256;
0183: VS_OUTPUT_MAP Out = (VS_OUTPUT_MAP)0;
0184:
0185: float4 pos = mul( Pos, mWVP );
0186:
0187:
0188: Out.Pos.x = 2.0 * (Tex0.x*(MAP_SIZE+1)/MAP_SIZE - 1/MAP_SIZE) - 1.0;
0189: Out.Pos.y = -2.0 * (Tex0.y*(MAP_SIZE+1)/MAP_SIZE - 1/MAP_SIZE) + 1.0;
0190: Out.Pos.z = 0.5;
0191: Out.Pos.w = 1;
0192:
0193:
0194: Out.Position = Pos;
0195: Out.Normal = Normal;
0196:
0197: return Out;
0198: }
0199:
0200:
0201:
0202:
0203:
0204: PS_OUTPUT_MAP PS_Map (VS_OUTPUT_MAP In)
0205: {
0206: PS_OUTPUT_MAP Out;
0207:
0208: Out.Position = In.Position;
0209: Out.Normal = In.Normal;
0210:
0211: return Out;
0212: }
0213:
0214:
0215:
0216:
0217:
0218:
0219: struct VS_OUTPUT_RADIANCE
0220: {
0221: float4 Pos : POSITION;
0222: float4 Color : COLOR0;
0223: };
0224:
0225:
0226:
0227:
0228: VS_OUTPUT_RADIANCE VS_Radiance (
0229: float4 Pos : POSITION
0230: ,float4 Normal : NORMAL
0231: ,float4 Tex0 : TEXCOORD0
0232: ){
0233: VS_OUTPUT_RADIANCE Out = (VS_OUTPUT_RADIANCE)0;
0234:
0235: float4 pos = mul( Pos, mWV );
0236:
0237:
0238: float rlen = rsqrt(dot(pos.xyz, pos.xyz));
0239: pos *= rlen;
0240: Out.Pos = pos;
0241:
0242: if(pos.z<0){
0243: Out.Pos.w = 0;
0244: }else{
0245: Out.Pos.w = 1;
0246: }
0247:
0248: Out.Color = 0.5;
0249:
0250: return Out;
0251: }
0252:
0253:
0254:
0255: float4 PS_Radiance (VS_OUTPUT_RADIANCE In) : COLOR
0256: {
0257: return In.Color;
0258: }
0259:
0260:
0261:
0262:
0263:
0264:
0265:
0266:
0267:
0268:
0269:
0270:
0271:
0272: float MAP_WIDTH;
0273: float MAP_HEIGHT;
0274:
0275:
0276:
0277:
0278: texture ReductionMap;
0279: sampler ReductionSamp = sampler_state
0280: {
0281: Texture = <ReductionMap>;
0282: MinFilter = LINEAR;
0283: MagFilter = LINEAR;
0284: MipFilter = NONE;
0285:
0286: AddressU = Clamp;
0287: AddressV = Clamp;
0288: };
0289:
0290:
0291:
0292: struct VS_OUTPUT_REDUCTION
0293: {
0294: float4 Pos : POSITION;
0295: float2 Tex0 : TEXCOORD0;
0296: float2 Tex1 : TEXCOORD1;
0297: float2 Tex2 : TEXCOORD2;
0298: float2 Tex3 : TEXCOORD3;
0299: float2 Tex4 : TEXCOORD4;
0300: float2 Tex5 : TEXCOORD5;
0301: float2 Tex6 : TEXCOORD6;
0302: float2 Tex7 : TEXCOORD7;
0303: };
0304:
0305:
0306:
0307:
0308: VS_OUTPUT_REDUCTION VS_Reduction (
0309: float4 Pos : POSITION
0310: ,float4 Tex : TEXCOORD0
0311: ){
0312: VS_OUTPUT_REDUCTION Out = (VS_OUTPUT_REDUCTION)0;
0313:
0314:
0315: Out.Pos = Pos;
0316:
0317: Out.Tex0 = Tex + float2(3.0f/MAP_WIDTH, 1.0f/MAP_HEIGHT);
0318: Out.Tex1 = Tex + float2(3.0f/MAP_WIDTH, 3.0f/MAP_HEIGHT);
0319: Out.Tex2 = Tex + float2(3.0f/MAP_WIDTH, 5.0f/MAP_HEIGHT);
0320: Out.Tex3 = Tex + float2(3.0f/MAP_WIDTH, 7.0f/MAP_HEIGHT);
0321: Out.Tex4 = Tex + float2(1.0f/MAP_WIDTH, 1.0f/MAP_HEIGHT);
0322: Out.Tex5 = Tex + float2(1.0f/MAP_WIDTH, 3.0f/MAP_HEIGHT);
0323: Out.Tex6 = Tex + float2(1.0f/MAP_WIDTH, 5.0f/MAP_HEIGHT);
0324: Out.Tex7 = Tex + float2(1.0f/MAP_WIDTH, 7.0f/MAP_HEIGHT);
0325:
0326: return Out;
0327: }
0328:
0329:
0330:
0331:
0332: float4 PS_Reduction ( VS_OUTPUT_REDUCTION In ) : COLOR0
0333: {
0334: float4 t0 = tex2D(ReductionSamp, In.Tex0);
0335: float4 t1 = tex2D(ReductionSamp, In.Tex1);
0336: float4 t2 = tex2D(ReductionSamp, In.Tex2);
0337: float4 t3 = tex2D(ReductionSamp, In.Tex3);
0338:
0339: float4 t4 = tex2D(ReductionSamp, In.Tex4);
0340: float4 t5 = tex2D(ReductionSamp, In.Tex5);
0341: float4 t6 = tex2D(ReductionSamp, In.Tex6);
0342: float4 t7 = tex2D(ReductionSamp, In.Tex7);
0343:
0344: float4 t8 = tex2D(ReductionSamp, In.Tex0 + float2(+4.0f/MAP_WIDTH, 0));
0345: float4 t9 = tex2D(ReductionSamp, In.Tex1 + float2(+4.0f/MAP_WIDTH, 0));
0346: float4 ta = tex2D(ReductionSamp, In.Tex2 + float2(+4.0f/MAP_WIDTH, 0));
0347: float4 tb = tex2D(ReductionSamp, In.Tex3 + float2(+4.0f/MAP_WIDTH, 0));
0348:
0349: float4 tc = tex2D(ReductionSamp, In.Tex4 + float2(+4.0f/MAP_WIDTH, 0));
0350: float4 td = tex2D(ReductionSamp, In.Tex5 + float2(+4.0f/MAP_WIDTH, 0));
0351: float4 te = tex2D(ReductionSamp, In.Tex6 + float2(+4.0f/MAP_WIDTH, 0));
0352: float4 tf = tex2D(ReductionSamp, In.Tex7 + float2(+4.0f/MAP_WIDTH, 0));
0353:
0354: return ((t0+t1+t2+t3)
0355: +(t4+t5+t6+t7)
0356: +(t8+t9+ta+tb)
0357: +(tc+td+te+tf))/16;
0358: }
0359:
0360:
0361:
0362:
0363:
0364:
0365:
0366:
0367: struct VS_OUTPUT_SH
0368: {
0369: float4 Pos : POSITION;
0370: float4 Tex : TEXCOORD0;
0371: float4 Position : TEXCOORD1;
0372: };
0373:
0374:
0375:
0376:
0377:
0378:
0379: VS_OUTPUT_SH VS_SH (
0380: float4 Pos : POSITION
0381: , float4 Tex0 : TEXCOORD0
0382: ){
0383: VS_OUTPUT_SH Out = (VS_OUTPUT_SH)0;
0384:
0385:
0386: Out.Pos = Pos;
0387:
0388:
0389: Out.Position = Pos;
0390: Out.Position.zw = 0;
0391:
0392:
0393: Out.Tex = Tex0;
0394:
0395: return Out;
0396: }
0397:
0398:
0399:
0400:
0401:
0402: float4 PS_SH0 (VS_OUTPUT_SH In) : COLOR0
0403: {
0404: return 0.5+0.5*tex2D( SrcSamp, In.Tex );
0405: }
0406:
0407:
0408:
0409:
0410:
0411: float4 PS_SH10 (VS_OUTPUT_SH In) : COLOR0
0412: {
0413: float4 N = In.Position;
0414:
0415: float l = dot(N,N);
0416: if(1.0<l) N *= rsqrt(l);
0417: N.z = sqrt(1-dot(N,N));
0418:
0419: N = mul( N, mST );
0420:
0421: float val = -N.z;
0422:
0423: return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ));
0424: }
0425:
0426:
0427:
0428:
0429:
0430: float4 PS_SH11 (VS_OUTPUT_SH In) : COLOR0
0431: {
0432: float4 N = In.Position;
0433:
0434: float l = dot(N,N);
0435: if(1.0<l) N *= rsqrt(l);
0436: N.z = sqrt(1-dot(N,N));
0437:
0438: N = mul( N, mST );
0439:
0440: float val = N.y;
0441:
0442: return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ));
0443: }
0444:
0445:
0446:
0447:
0448:
0449: float4 PS_SH12 (VS_OUTPUT_SH In) : COLOR0
0450: {
0451: float4 N = In.Position;
0452:
0453: float l = dot(N,N);
0454: if(1.0<l) N *= rsqrt(l);
0455: N.z = sqrt(1-dot(N,N));
0456:
0457: N = mul( N, mST );
0458:
0459: float val = -N.x;
0460:
0461: return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ));
0462: }
0463:
0464:
0465:
0466:
0467:
0468: float4 PS_SH20 (VS_OUTPUT_SH In) : COLOR0
0469: {
0470: float4 N = In.Position;
0471:
0472: float l = dot(N,N);
0473: if(1.0<l) N *= rsqrt(l);
0474: N.z = sqrt(1-dot(N,N));
0475:
0476: N = mul( N, mST );
0477:
0478: float val = 2 * N.x * N.z;
0479:
0480: return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ));
0481: }
0482:
0483:
0484:
0485:
0486:
0487: float4 PS_SH21 (VS_OUTPUT_SH In) : COLOR0
0488: {
0489: float4 N = In.Position;
0490:
0491: float l = dot(N,N);
0492: if(1.0<l) N *= rsqrt(l);
0493: N.z = sqrt(1-dot(N,N));
0494:
0495: N = mul( N, mST );
0496:
0497: float val = -N.y * N.z;
0498:
0499: return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ));
0500: }
0501:
0502:
0503:
0504:
0505:
0506: float4 PS_SH22 (VS_OUTPUT_SH In) : COLOR0
0507: {
0508: float4 N = In.Position;
0509:
0510: float l = dot(N,N);
0511: if(1.0<l) N *= rsqrt(l);
0512: N.z = sqrt(1-dot(N,N));
0513:
0514: N = mul( N, mST );
0515:
0516: float val = (N.y * N.y - 1/3)/2;
0517:
0518: return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ));
0519: }
0520:
0521:
0522:
0523:
0524:
0525: float4 PS_SH23 (VS_OUTPUT_SH In) : COLOR0
0526: {
0527: float4 N = In.Position;
0528:
0529: float l = dot(N,N);
0530: if(1.0<l) N *= rsqrt(l);
0531: N.z = sqrt(1-dot(N,N));
0532:
0533: N = mul( N, mST );
0534:
0535: float val = - N.y * N.x;
0536:
0537: return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ));
0538: }
0539:
0540:
0541:
0542:
0543:
0544: float4 PS_SH24 (VS_OUTPUT_SH In) : COLOR0
0545: {
0546: float4 N = In.Position;
0547:
0548: float l = dot(N,N);
0549: if(1.0<l) N *= rsqrt(l);
0550: N.z = sqrt(1-dot(N,N));
0551:
0552: N = mul( N, mST );
0553:
0554: float val = N.x * N.x - N.z * N.z;
0555:
0556: return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ));
0557: }
0558:
0559:
0560:
0561:
0562: float4 PS_SH30 (VS_OUTPUT_SH In) : COLOR0
0563: {
0564: float4 N = In.Position;
0565:
0566: float l = dot(N,N);
0567: if(1.0<l) N *= rsqrt(l);
0568: N.z = sqrt(1-dot(N,N));
0569:
0570: N = mul( N, mST );
0571:
0572: float val = - N.z * (N.x * N.x - N.z * N.z/3);
0573:
0574: return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ));
0575: }
0576:
0577:
0578:
0579: float4 PS_SH31 (VS_OUTPUT_SH In) : COLOR0
0580: {
0581: float4 N = In.Position;
0582:
0583: float l = dot(N,N);
0584: if(1.0<l) N *= rsqrt(l);
0585: N.z = sqrt(1-dot(N,N));
0586:
0587: N = mul( N, mST );
0588:
0589: float val = 2 * N.x * N.y * N.z;
0590:
0591: return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ));
0592: }
0593:
0594:
0595:
0596: float4 PS_SH32 (VS_OUTPUT_SH In) : COLOR0
0597: {
0598: float4 N = In.Position;
0599:
0600: float l = dot(N,N);
0601: if(1.0<l) N *= rsqrt(l);
0602: N.z = sqrt(1-dot(N,N));
0603:
0604: N = mul( N, mST );
0605:
0606: float val = 0.5 * N.z * (0.2 - N.y * N.y);
0607:
0608: return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ));
0609: }
0610:
0611:
0612:
0613: float4 PS_SH33 (VS_OUTPUT_SH In) : COLOR0
0614: {
0615: float4 N = In.Position;
0616:
0617: float l = dot(N,N);
0618: if(1.0<l) N *= rsqrt(l);
0619: N.z = sqrt(1-dot(N,N));
0620:
0621: N = mul( N, mST );
0622:
0623: float val = N.y * (N.y * N.y - 9/15) / 6;
0624:
0625: return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ));
0626: }
0627:
0628:
0629:
0630: float4 PS_SH34 (VS_OUTPUT_SH In) : COLOR0
0631: {
0632: float4 N = In.Position;
0633:
0634: float l = dot(N,N);
0635: if(1.0<l) N *= rsqrt(l);
0636: N.z = sqrt(1-dot(N,N));
0637:
0638: N = mul( N, mST );
0639:
0640: float val = 0.5 * N.x * (0.2 - N.y * N.y);
0641:
0642: return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ));
0643: }
0644:
0645:
0646:
0647: float4 PS_SH35 (VS_OUTPUT_SH In) : COLOR0
0648: {
0649: float4 N = In.Position;
0650:
0651: float l = dot(N,N);
0652: if(1.0<l) N *= rsqrt(l);
0653: N.z = sqrt(1-dot(N,N));
0654:
0655: N = mul( N, mST );
0656:
0657: float val = N.y * (N.x * N.x - N.z * N.z);
0658:
0659: return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ));
0660: }
0661:
0662:
0663:
0664: float4 PS_SH36 (VS_OUTPUT_SH In) : COLOR0
0665: {
0666: float4 N = In.Position;
0667:
0668: float l = dot(N,N);
0669: if(1.0<l) N *= rsqrt(l);
0670: N.z = sqrt(1-dot(N,N));
0671:
0672: N = mul( N, mST );
0673:
0674: float val = -N.x * (N.x * N.x/3 - N.z * N.z);
0675:
0676: return 0.5+0.5 * (val * tex2D( SrcSamp, In.Tex ));
0677: }
0678:
0679:
0680:
0681:
0682:
0683: technique TShader
0684: {
0685: pass P0
0686: {
0687: VertexShader = compile vs_1_1 VS_Map();
0688: PixelShader = compile ps_2_0 PS_Map();
0689: }
0690: pass P1
0691: {
0692: VertexShader = compile vs_1_1 VS_Radiance();
0693: PixelShader = compile ps_2_0 PS_Radiance();
0694: }
0695: pass P2
0696: {
0697: VertexShader = compile vs_1_1 VS_Reduction();
0698: PixelShader = compile ps_2_0 PS_Reduction();
0699: }
0700: pass P3
0701: {
0702: VertexShader = compile vs_1_1 VS();
0703: PixelShader = compile ps_2_0 PS_NoTex();
0704: }
0705: pass P4
0706: {
0707: VertexShader = compile vs_1_1 VS();
0708: PixelShader = compile ps_2_0 PS_NoGI();
0709: }
0710: pass P5
0711: {
0712: VertexShader = compile vs_1_1 VS();
0713: PixelShader = compile ps_2_0 PS();
0714: }
0715: }
0716: technique TSphericalHarmonics
0717: {
0718: pass P0
0719: {
0720: VertexShader = compile vs_1_1 VS_SH();
0721: PixelShader = compile ps_2_0 PS_SH0();
0722: }
0723: pass P1
0724: {
0725: VertexShader = compile vs_1_1 VS_SH();
0726: PixelShader = compile ps_2_0 PS_SH10();
0727: }
0728: pass P2
0729: {
0730: VertexShader = compile vs_1_1 VS_SH();
0731: PixelShader = compile ps_2_0 PS_SH11();
0732: }
0733: pass P3
0734: {
0735: VertexShader = compile vs_1_1 VS_SH();
0736: PixelShader = compile ps_2_0 PS_SH12();
0737: }
0738: pass P4
0739: {
0740: VertexShader = compile vs_1_1 VS_SH();
0741: PixelShader = compile ps_2_0 PS_SH20();
0742: }
0743: pass P5
0744: {
0745: VertexShader = compile vs_1_1 VS_SH();
0746: PixelShader = compile ps_2_0 PS_SH21();
0747: }
0748: pass P6
0749: {
0750: VertexShader = compile vs_1_1 VS_SH();
0751: PixelShader = compile ps_2_0 PS_SH22();
0752: }
0753: pass P7
0754: {
0755: VertexShader = compile vs_1_1 VS_SH();
0756: PixelShader = compile ps_2_0 PS_SH23();
0757: }
0758: pass P8
0759: {
0760: VertexShader = compile vs_1_1 VS_SH();
0761: PixelShader = compile ps_2_0 PS_SH24();
0762: }
0763: pass P9
0764: {
0765: VertexShader = compile vs_1_1 VS_SH();
0766: PixelShader = compile ps_2_0 PS_SH30();
0767: }
0768: pass P10
0769: {
0770: VertexShader = compile vs_1_1 VS_SH();
0771: PixelShader = compile ps_2_0 PS_SH31();
0772: }
0773: pass P11
0774: {
0775: VertexShader = compile vs_1_1 VS_SH();
0776: PixelShader = compile ps_2_0 PS_SH32();
0777: }
0778: pass P12
0779: {
0780: VertexShader = compile vs_1_1 VS_SH();
0781: PixelShader = compile ps_2_0 PS_SH33();
0782: }
0783: pass P13
0784: {
0785: VertexShader = compile vs_1_1 VS_SH();
0786: PixelShader = compile ps_2_0 PS_SH34();
0787: }
0788: pass P14
0789: {
0790: VertexShader = compile vs_1_1 VS_SH();
0791: PixelShader = compile ps_2_0 PS_SH35();
0792: }
0793: pass P15
0794: {
0795: VertexShader = compile vs_1_1 VS_SH();
0796: PixelShader = compile ps_2_0 PS_SH36();
0797: }
0798: }