0001: // -------------------------------------------------------------
0002: // 放物変換によるツゥーン
0003: // 
0004: // Copyright (c) 2003 IMAGIRE Takashi. All rights reserved.
0005: // -------------------------------------------------------------
0006: 
0007: // -------------------------------------------------------------
0008: // グローバル変数
0009: // -------------------------------------------------------------
0010: float4x4 mWVP;
0011: float4 LightPos;
0012: float4 EyePos;
0013: float4 vColor;
0014: 
0015: // -------------------------------------------------------------
0016: // テクスチャ
0017: // -------------------------------------------------------------
0018: // 模様のテクスチャ
0019: texture DecaleTex;
0020: sampler DecaleSamp = sampler_state
0021: {
0022:     Texture = <DecaleTex>;
0023:     MinFilter = LINEAR;
0024:     MagFilter = LINEAR;
0025:     MipFilter = NONE;
0026: 
0027:     AddressU = Clamp;
0028:     AddressV = Clamp;
0029: };
0030: // -------------------------------------------------------------
0031: // ツゥーンのテクスチャ
0032: texture ToonTex;
0033: sampler ToonSamp = sampler_state
0034: {
0035:     Texture = <ToonTex>;
0036:     MinFilter = LINEAR;
0037:     MagFilter = LINEAR;
0038:     MipFilter = NONE;
0039: 
0040:     AddressU = Clamp;
0041:     AddressV = Clamp;
0042: };
0043: // -------------------------------------------------------------
0044: // アプリケーションから頂点シェーダに渡すデータ
0045: // -------------------------------------------------------------
0046: struct VS_INPUT
0047: {
0048:     float4 Pos          : POSITION;
0049:     float3 Normal       : NORMAL0;
0050:     float2 Tex          : TEXCOORD0;    // デカールテクスチャ座標
0051: };
0052: // -------------------------------------------------------------
0053: // 頂点シェーダからピクセルシェーダに渡すデータ
0054: // -------------------------------------------------------------
0055: struct VS_OUTPUT
0056: {
0057:     float4 Pos          : POSITION;
0058:     float2 Tex          : TEXCOORD0;    // デカールテクスチャ座標
0059:     float2 ToonCoord    : TEXCOORD1;    // トゥーン用
0060: };
0061: 
0062: // -------------------------------------------------------------
0063: // 座標変換
0064: // -------------------------------------------------------------
0065: float2 Q(float3 In, float3 B, float3 T, float3 N)
0066: {
0067:     float2 Out = (float2)0;
0068:     
0069:     // 表面座標系へ変換
0070:     float3 v;
0071:     v.x = dot(B,In);
0072:     v.y = dot(T,In);
0073:     v.z = dot(N,In);
0074: 
0075:     float pv = 7.0f/8.0f;
0076:     float ar = 1.0/(2.0*(1.000000001+v.z));
0077: 
0078:     Out.x = pv * ar * v.x + 0.5;
0079:     Out.y = pv * ar * v.y + 0.5;
0080: 
0081:     return Out;
0082: }
0083: // -------------------------------------------------------------
0084: // 頂点シェーダプログラム
0085: // -------------------------------------------------------------
0086: VS_OUTPUT VS(VS_INPUT In)
0087: {   
0088:     VS_OUTPUT Out = (VS_OUTPUT)0;            // 出力データ
0089:     
0090:     // 位置座標
0091:     Out.Pos = mul( In.Pos, mWVP );
0092:     
0093:     // 表面座標系の基底ベクトルを求める
0094:     float3 N = In.Normal;                   // 法線ベクトル
0095:     float3 B = float3(0,1,0);               // 従法線ベクトル
0096:     float3 T = normalize(cross(N,B));       // 接ベクトル
0097:     B = cross(T,N);
0098:     
0099:     // ベクトルをテクスチャ座標へ変換する
0100:     float3 L = normalize(LightPos-In.Pos.xyz);// ライトベクトル
0101:     Out.ToonCoord = Q(L, B,T,N);
0102:     
0103:     // デカールのテクスチャ座標
0104:     Out.Tex = In.Tex;
0105: 
0106:     return Out;
0107: }
0108: // -------------------------------------------------------------
0109: // ピクセルシェーダプログラム
0110: // -------------------------------------------------------------
0111: float4 PS(VS_OUTPUT In) : COLOR
0112: {   
0113:     float4 decale = tex2D( DecaleSamp, In.Tex );      // デカール
0114:     float  shade  = tex2D( ToonSamp,   In.ToonCoord );// ツゥーン
0115:     
0116:     return (0.5f*shade+0.5f) * decale;
0117: }
0118: // -------------------------------------------------------------
0119: // テクニック
0120: // -------------------------------------------------------------
0121: technique TShader
0122: {
0123:     pass P0
0124:     {
0125:         VertexShader = compile vs_1_1 VS();
0126:         PixelShader  = compile ps_1_1 PS();
0127:     }
0128: }
0129: 
0130: