0001: // ------------------------------------------------------------
0002: // PR
0003: // 
0004: // Copyright (c) 2003 IMAGIRE Takashi. All rights reserved.
0005: // ------------------------------------------------------------
0006: 
0007: // ------------------------------------------------------------
0008: // グローバル変数
0009: // ------------------------------------------------------------
0010: float4x4 mWVP;
0011: 
0012: // ------------------------------------------------------------
0013: // テクスチャ
0014: // ------------------------------------------------------------
0015: texture SrcTex;
0016: sampler SrcSamp = sampler_state
0017: {
0018:     Texture = <SrcTex>;
0019:     MinFilter = LINEAR;
0020:     MagFilter = LINEAR;
0021:     MipFilter = NONE;
0022: 
0023:     AddressU = Clamp;
0024:     AddressV = Clamp;
0025: };
0026: // ------------------------------------------------------------
0027: texture RadianceTex;
0028: sampler RadianceSamp = sampler_state
0029: {
0030:     Texture = <RadianceTex>;
0031:     MinFilter = LINEAR;
0032:     MagFilter = LINEAR;
0033:     MipFilter = NONE;
0034: 
0035:     AddressU = Clamp;
0036:     AddressV = Clamp;
0037: };
0038: // ------------------------------------------------------------
0039: // 頂点シェーダからピクセルシェーダに渡すデータ
0040: // ------------------------------------------------------------
0041: struct VS_OUTPUT
0042: {
0043:     float4 Pos          : POSITION;
0044:     float4 Color        : COLOR0;
0045:     float2 Tex0         : TEXCOORD0;
0046: };
0047: 
0048: // ------------------------------------------------------------
0049: // 照明計算なし頂点シェーダプログラム
0050: // ------------------------------------------------------------
0051: VS_OUTPUT VS (
0052:       float4 Pos    : POSITION           // モデルの頂点
0053:      ,float4 Normal : NORMAL             // 法線ベクトル
0054:      ,float4 Tex0   : TEXCOORD0          // テクスチャ座標
0055: ){
0056:     VS_OUTPUT Out = (VS_OUTPUT)0;        // 出力データ
0057:     
0058:     // 位置座標
0059:     Out.Pos = mul( Pos, mWVP );
0060:     
0061:     Out.Tex0 = Tex0;
0062:     
0063:     return Out;
0064: }
0065: // ------------------------------------------------------------
0066: // 全部込みピクセルシェーダプログラム
0067: // ------------------------------------------------------------
0068: float4 PS (VS_OUTPUT In) : COLOR
0069: {
0070:     float4 Out;
0071:     
0072:     // 色
0073:     Out = tex2D( SrcSamp, In.Tex0 ) * tex2D( RadianceSamp, In.Tex0 );
0074:     
0075:     return Out;
0076: }
0077: // ------------------------------------------------------------
0078: // テクスチャなし
0079: // ------------------------------------------------------------
0080: float4 PS_NoTex (VS_OUTPUT In) : COLOR
0081: {
0082:     float4 Out;
0083:     
0084:     // 色
0085:     Out = tex2D( RadianceSamp, In.Tex0 );
0086:     
0087:     return Out;
0088: }
0089: // ------------------------------------------------------------
0090: // 照明計算なしピクセルシェーダプログラム
0091: // ------------------------------------------------------------
0092: float4 PS_NoGI (VS_OUTPUT In) : COLOR
0093: {
0094:     float4 Out;
0095:     
0096:     // 色
0097:     Out = tex2D( SrcSamp, In.Tex0 );
0098:     
0099:     return Out;
0100: }
0101: 
0102: 
0103: // ------------------------------------------------------------
0104: // ------------------------------------------------------------
0105: // 位置、法線マップの作成
0106: // ------------------------------------------------------------
0107: // ------------------------------------------------------------
0108: struct VS_OUTPUT_MAP
0109: {
0110:     float4 Pos          : POSITION;
0111:     float4 Position     : TEXCOORD0;
0112:     float4 Normal       : TEXCOORD1;
0113: };
0114: struct PS_OUTPUT_MAP
0115: {
0116:     float4 Position     : COLOR0;
0117:     float4 Normal       : COLOR1;
0118: };
0119: 
0120: // ------------------------------------------------------------
0121: // 頂点シェーダ
0122: // ------------------------------------------------------------
0123: VS_OUTPUT_MAP VS_Map (
0124:       float4 Pos    : POSITION           // モデルの頂点
0125:     , float4 Normal : NORMAL             // 法線ベクトル
0126:     , float4 Tex0   : TEXCOORD0          // テクスチャ座標
0127: ){
0128:     float MAP_SIZE = 256;
0129:     VS_OUTPUT_MAP Out = (VS_OUTPUT_MAP)0;        // 出力データ
0130:     
0131:     float4 pos = mul( Pos, mWVP );
0132:     
0133:     // 位置座標
0134:     Out.Pos.x =  2.0 * (Tex0.x*(MAP_SIZE+1)/MAP_SIZE - 1/MAP_SIZE) - 1.0;
0135:     Out.Pos.y = -2.0 * (Tex0.y*(MAP_SIZE+1)/MAP_SIZE - 1/MAP_SIZE) + 1.0;
0136:     Out.Pos.z = 0.5;
0137:     Out.Pos.w = 1;
0138:     
0139:     // 色
0140:     Out.Position = Pos;
0141:     Out.Normal   = Normal;
0142: 
0143:     return Out;
0144: }
0145: 
0146: 
0147: // ------------------------------------------------------------
0148: // ピクセルシェーダ
0149: // ------------------------------------------------------------
0150: PS_OUTPUT_MAP PS_Map (VS_OUTPUT_MAP In)
0151: {
0152:     PS_OUTPUT_MAP Out;
0153:     
0154:     Out.Position = In.Position;
0155:     Out.Normal   = In.Normal;
0156: 
0157:     return Out;
0158: }
0159: 
0160: // ------------------------------------------------------------
0161: // ------------------------------------------------------------
0162: // ラディアンスの計算
0163: // ------------------------------------------------------------
0164: // ------------------------------------------------------------
0165: struct VS_OUTPUT_RADIANCE
0166: {
0167:     float4 Pos          : POSITION;
0168:     float4 Color        : COLOR0;
0169:     float4 Depth        : TEXCOORD0;
0170: };
0171: 
0172: // ------------------------------------------------------------
0173: // 頂点シェーダプログラム
0174: // ------------------------------------------------------------
0175: VS_OUTPUT_RADIANCE VS_Radiance (
0176:       float4 Pos    : POSITION           // モデルの頂点
0177:      ,float4 Normal : NORMAL             // 法線ベクトル
0178:      ,float4 Tex0   : TEXCOORD0          // テクスチャ座標
0179: ){
0180:     VS_OUTPUT_RADIANCE Out = (VS_OUTPUT_RADIANCE)0;        // 出力データ
0181:     
0182:     float4 pos = mul( Pos, mWVP );
0183:     
0184:     // 位置座標
0185:     float rlen = rsqrt(dot(pos.xyz, pos.xyz));
0186:     pos *= rlen;
0187:     Out.Pos = pos;
0188:     Out.Pos.w = 1;
0189:     
0190:     Out.Color = 0;
0191:     
0192:     Out.Depth = pos.z;
0193:     
0194:     return Out;
0195: }
0196: // ------------------------------------------------------------
0197: // ピクセルシェーダプログラム
0198: // ------------------------------------------------------------
0199: float4 PS_Radiance (VS_OUTPUT_RADIANCE In) : COLOR
0200: {
0201:     // (深度を見て)裏面を消去する
0202:     clip(In.Depth);
0203:     
0204:     return In.Color;
0205: }
0206: 
0207: 
0208: 
0209: 
0210: // ------------------------------------------------------------
0211: // ------------------------------------------------------------
0212: // 遮蔽マップの作成
0213: // ------------------------------------------------------------
0214: // ------------------------------------------------------------
0215: 
0216: // ------------------------------------------------------------
0217: // グローバル変数
0218: // ------------------------------------------------------------
0219: float MAP_WIDTH;
0220: float MAP_HEIGHT;
0221: 
0222: // ------------------------------------------------------------
0223: // テクスチャ
0224: // ------------------------------------------------------------
0225: texture ReductionMap;
0226: sampler ReductionSamp = sampler_state
0227: {
0228:     Texture = <ReductionMap>;
0229:     MinFilter = LINEAR;
0230:     MagFilter = LINEAR;
0231:     MipFilter = NONE;
0232: 
0233:     AddressU = Clamp;
0234:     AddressV = Clamp;
0235: };
0236: // ------------------------------------------------------------
0237: // 頂点シェーダからピクセルシェーダに渡すデータ
0238: // ------------------------------------------------------------
0239: struct VS_OUTPUT_REDUCTION
0240: {
0241:     float4 Pos          : POSITION;
0242:     float2 Tex0         : TEXCOORD0;
0243:     float2 Tex1         : TEXCOORD1;
0244:     float2 Tex2         : TEXCOORD2;
0245:     float2 Tex3         : TEXCOORD3;
0246:     float2 Tex4         : TEXCOORD4;
0247:     float2 Tex5         : TEXCOORD5;
0248:     float2 Tex6         : TEXCOORD6;
0249:     float2 Tex7         : TEXCOORD7;
0250: };
0251: 
0252: // ------------------------------------------------------------
0253: // 頂点シェーダプログラム
0254: // ------------------------------------------------------------
0255: VS_OUTPUT_REDUCTION VS_Reduction (
0256:       float4 Pos    : POSITION           // モデルの頂点
0257:      ,float4 Tex    : TEXCOORD0          // テクスチャ座標
0258: ){
0259:     VS_OUTPUT_REDUCTION Out = (VS_OUTPUT_REDUCTION)0;        // 出力データ
0260:     
0261:     // 位置座標
0262:     Out.Pos = Pos;
0263:     
0264:     Out.Tex0 = Tex + float2(3.0f/MAP_WIDTH, 1.0f/MAP_HEIGHT);
0265:     Out.Tex1 = Tex + float2(3.0f/MAP_WIDTH, 3.0f/MAP_HEIGHT);
0266:     Out.Tex2 = Tex + float2(3.0f/MAP_WIDTH, 5.0f/MAP_HEIGHT);
0267:     Out.Tex3 = Tex + float2(3.0f/MAP_WIDTH, 7.0f/MAP_HEIGHT);
0268:     Out.Tex4 = Tex + float2(1.0f/MAP_WIDTH, 1.0f/MAP_HEIGHT);
0269:     Out.Tex5 = Tex + float2(1.0f/MAP_WIDTH, 3.0f/MAP_HEIGHT);
0270:     Out.Tex6 = Tex + float2(1.0f/MAP_WIDTH, 5.0f/MAP_HEIGHT);
0271:     Out.Tex7 = Tex + float2(1.0f/MAP_WIDTH, 7.0f/MAP_HEIGHT);
0272:     
0273:     return Out;
0274: }
0275: 
0276: // ------------------------------------------------------------
0277: // ピクセルシェーダプログラム
0278: // ------------------------------------------------------------
0279: float4 PS_Reduction ( VS_OUTPUT_REDUCTION In ) : COLOR0
0280: {
0281:     float4 t0 = tex2D(ReductionSamp, In.Tex0);
0282:     float4 t1 = tex2D(ReductionSamp, In.Tex1);
0283:     float4 t2 = tex2D(ReductionSamp, In.Tex2);
0284:     float4 t3 = tex2D(ReductionSamp, In.Tex3);
0285:     
0286:     float4 t4 = tex2D(ReductionSamp, In.Tex4);
0287:     float4 t5 = tex2D(ReductionSamp, In.Tex5);
0288:     float4 t6 = tex2D(ReductionSamp, In.Tex6);
0289:     float4 t7 = tex2D(ReductionSamp, In.Tex7);
0290:     
0291:     float4 t8 = tex2D(ReductionSamp, In.Tex0 + float2(+4.0f/MAP_WIDTH, 0));
0292:     float4 t9 = tex2D(ReductionSamp, In.Tex1 + float2(+4.0f/MAP_WIDTH, 0));
0293:     float4 ta = tex2D(ReductionSamp, In.Tex2 + float2(+4.0f/MAP_WIDTH, 0));
0294:     float4 tb = tex2D(ReductionSamp, In.Tex3 + float2(+4.0f/MAP_WIDTH, 0));
0295:     
0296:     float4 tc = tex2D(ReductionSamp, In.Tex4 + float2(+4.0f/MAP_WIDTH, 0));
0297:     float4 td = tex2D(ReductionSamp, In.Tex5 + float2(+4.0f/MAP_WIDTH, 0));
0298:     float4 te = tex2D(ReductionSamp, In.Tex6 + float2(+4.0f/MAP_WIDTH, 0));
0299:     float4 tf = tex2D(ReductionSamp, In.Tex7 + float2(+4.0f/MAP_WIDTH, 0));
0300:     
0301:     return ((t0+t1+t2+t3)
0302:            +(t4+t5+t6+t7)
0303:            +(t8+t9+ta+tb)
0304:            +(tc+td+te+tf))/16;
0305: }
0306: 
0307: 
0308: 
0309: 
0310: // ------------------------------------------------------------
0311: // アルファ成分で色成分を割る
0312: // ------------------------------------------------------------
0313: float4 PS_Div ( float4 Tex0 : TEXCOORD0 ) : COLOR0
0314: {
0315:     float4 samp = tex2D(SrcSamp, Tex0);
0316:     
0317:     if(samp.w != 0) samp /= samp.w;
0318:     
0319:     return samp;
0320: }
0321: 
0322: 
0323: 
0324: 
0325: // ------------------------------------------------------------
0326: // テクニック
0327: // ------------------------------------------------------------
0328: technique TShader
0329: {
0330:     pass P0 // 位置、法線マップ
0331:     {
0332:         VertexShader = compile vs_1_1 VS_Map();
0333:         PixelShader  = compile ps_2_0 PS_Map();
0334:     }
0335:     pass P1 // ラディアンスの計算
0336:     {
0337:         VertexShader = compile vs_1_1 VS_Radiance();
0338:         PixelShader  = compile ps_2_0 PS_Radiance();
0339:     }
0340:     pass P2 // 縮小
0341:     {
0342:         VertexShader = compile vs_1_1 VS_Reduction();
0343:         PixelShader  = compile ps_2_0 PS_Reduction();
0344:     }
0345:     pass P3 // アルファ成分で色成分を割る
0346:     {
0347:         PixelShader  = compile ps_2_0 PS_Div();
0348:     }
0349:     pass P4 // テクスチャなし
0350:     {
0351:         VertexShader = compile vs_1_1 VS();
0352:         PixelShader  = compile ps_2_0 PS_NoTex();
0353:     }
0354:     pass P5// GIなし
0355:     {
0356:         VertexShader = compile vs_1_1 VS();
0357:         PixelShader  = compile ps_2_0 PS_NoGI();
0358:     }
0359:     pass P6
0360:     {
0361:         VertexShader = compile vs_1_1 VS();
0362:         PixelShader  = compile ps_2_0 PS();
0363:     }
0364: }
0365: