0001: // -------------------------------------------------------------
0002: // HSV変換
0003: // 
0004: // Copyright (c) 2003 IMAGIRE Takashi. All rights reserved.
0005: // -------------------------------------------------------------
0006: 
0007: // -------------------------------------------------------------
0008: // グローバル変数
0009: // -------------------------------------------------------------
0010: float4x4 mWVP;
0011: float4 LightPos;
0012: float fShift;
0013: 
0014: // -------------------------------------------------------------
0015: // テクスチャ
0016: // -------------------------------------------------------------
0017: // 模様のテクスチャ
0018: texture DecaleTex;
0019: sampler DecaleSamp = sampler_state
0020: {
0021:     Texture = <DecaleTex>;
0022:     MinFilter = LINEAR;
0023:     MagFilter = LINEAR;
0024:     MipFilter = NONE;
0025: 
0026:     AddressU = Clamp;
0027:     AddressV = Clamp;
0028: };
0029: // -------------------------------------------------------------
0030: // アプリケーションから頂点シェーダに渡すデータ
0031: // -------------------------------------------------------------
0032: struct VS_INPUT
0033: {
0034:     float4 Pos          : POSITION;
0035:     float3 Normal       : NORMAL0;
0036:     float2 Tex          : TEXCOORD0;    // デカールテクスチャ座標
0037: };
0038: // -------------------------------------------------------------
0039: // 頂点シェーダからピクセルシェーダに渡すデータ
0040: // -------------------------------------------------------------
0041: struct VS_OUTPUT
0042: {
0043:     float4 Pos          : POSITION;
0044:     float2 Tex          : TEXCOORD0;    // デカールテクスチャ座標
0045:     float  LN           : TEXCOORD1;    // dot(L,N)
0046: };
0047: 
0048: // -------------------------------------------------------------
0049: // 頂点シェーダプログラム
0050: // -------------------------------------------------------------
0051: VS_OUTPUT VS(VS_INPUT In)
0052: {   
0053:     VS_OUTPUT Out = (VS_OUTPUT)0;            // 出力データ
0054:     
0055:     // 位置座標
0056:     Out.Pos = mul( In.Pos, mWVP );
0057:     
0058:     // 表面座標系の基底ベクトルを求める
0059:     float3 N = In.Normal;                   // 法線ベクトル
0060:     
0061:     // ベクトルをテクスチャ座標へ変換する
0062:     float3 L = normalize(LightPos-In.Pos.xyz);// ライトベクトル
0063:     Out.LN = dot(N,L);
0064:     
0065:     // デカールのテクスチャ座標
0066:     Out.Tex = In.Tex;
0067: 
0068:     return Out;
0069: }
0070: // -------------------------------------------------------------
0071: // ピクセルシェーダプログラム
0072: // -------------------------------------------------------------
0073: float4 PS(VS_OUTPUT In) : COLOR
0074: {   
0075: //    const float NO_HUE = -1;
0076:     float4 ret = (float4)0;
0077:     float4 decale = tex2D( DecaleSamp, In.Tex );      // デカール
0078:     float3 rgb = decale.xyz;    // 元になる色
0079:     float3 hsv;
0080:     
0081:     // RGB 2 HSV
0082:     float max = max(rgb.r, max(rgb.g, rgb.b));
0083:     float min = min(rgb.r, min(rgb.g, rgb.b));
0084:     float delta = max - min;
0085: 
0086:     hsv.z = max; // v
0087:     if (max != 0.0){
0088:         hsv.y = delta / max;//s
0089:     }else{
0090:         hsv.y = 0.0;//s
0091:     }
0092:     
0093: //  if (hsv.y == 0.0) {
0094: //      hsv.x = NO_HUE; // h
0095: //  } else {
0096:       if ( rgb.r == max ){
0097:           hsv.x =     (rgb.g - rgb.b) / delta;// h
0098:       }else if (rgb.g == max){
0099:           hsv.x = 2 + (rgb.b - rgb.r) / delta;// h
0100:       }else{
0101:           hsv.x = 4 + (rgb.r - rgb.g) / delta;// h
0102:       }
0103:       hsv.x /= 6.0;
0104:       if (hsv.x < 0) hsv.x += 1.0;
0105: //  }
0106:     
0107:     hsv.x += fShift;                                // 色相補正
0108:     if (1.0 <= hsv.x) hsv.x -= 1.0;
0109:     
0110:     // HSV 2 RGB
0111:     if ( hsv.y == 0 ){ /* Grayscale */
0112:         ret.r = ret.g = ret.b = hsv.z;// v
0113:     } else {
0114:         if (1.0 <= hsv.x) hsv.x -= 1.0;
0115:         hsv.x *= 6.0;
0116:         float i = floor (hsv.x);
0117:         float f = hsv.x - i;
0118:         float aa = hsv.z * (1 - hsv.y);
0119:         float bb = hsv.z * (1 - (hsv.y * f));
0120:         float cc = hsv.z * (1 - (hsv.y * (1 - f)));
0121:         if( i < 1 ){
0122:             ret.r = hsv.z; ret.g = cc;    ret.b = aa;
0123:         }else if( i < 2 ){
0124:             ret.r = bb;    ret.g = hsv.z; ret.b = aa;
0125:         }else if( i < 3 ){
0126:             ret.r = aa;    ret.g = hsv.z; ret.b = cc;
0127:         }else if( i < 4 ){
0128:             ret.r = aa;    ret.g = bb;    ret.b = hsv.z;
0129:         }else if( i < 5 ){
0130:             ret.r = cc;    ret.g = aa;    ret.b = hsv.z;
0131:         }else{
0132:             ret.r = hsv.z; ret.g = aa;    ret.b = bb;
0133:         }
0134:     }
0135:     
0136:     return (0.5f*In.LN + 0.5f) * ret;
0137: }
0138: // -------------------------------------------------------------
0139: // テクニック
0140: // -------------------------------------------------------------
0141: technique TShader
0142: {
0143:     pass P0
0144:     {
0145:         VertexShader = compile vs_1_1 VS();
0146:         PixelShader  = compile ps_2_0 PS();
0147:     }
0148: }
0149: 
0150: