/*********************************************************************NVMH3****

Sky
******************************************************************************/
#include "..\mrt.fx"

//#define FixedPipe

float4x4 viewProj : ViewProjection;
float4x4 world : World;
float3 campos : CAMERAPOS;


float4 ColorStart : ColorStart;
float4 ColorMid : ColorMid;
float4 ColorEnd : ColorEnd;

float FinalColorModulate : FinalColorModulate;

float2 UVScale0 : UVScale0;
float2 UVScale1 : UVScale1;

float2 UVTranslate0 : UVTranslate0;
float2 UVTranslate1 : UVTranslate1;


float FresnelModulate : FresnelModulate = 1.0f;
float FresnelIndex : FresnelIndex = 0.5f;
float FresnelExponent : FresnelExponent = 0.5f;


texture MyDiffuseTexture : MyDiffuseTexture;
sampler DiffuseTextureSampler = sampler_state 
{
    texture = <MyDiffuseTexture>;
    AddressU  = WRAP;        
    AddressV  = WRAP;
    AddressW  = WRAP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};

struct vertexInput {
    float4 position				: POSITION;
    float3 normObj				: NORMAL;
    float2 texCoordDiffuse0		: TEXCOORD0;
};

struct vertexOutput {
    float4 hPosition		: POSITION;
    float2 texCoordDiffuse0	: TEXCOORD0;
    float2 texCoordDiffuse1	: TEXCOORD1;
    float2 texCoordDiffuse2	: TEXCOORD2;    
    float3 normWorld		: TEXCOORD3;
    float3 posWorld         : TEXCOORD4;
    float3 normObj			: TEXCOORD5;
};


vertexOutput VS_Transform(vertexInput IN) 
{
    float4 pos;
    vertexOutput OUT;
    
    pos = mul(IN.position, world);
    OUT.posWorld = pos;
    OUT.normWorld = mul(IN.normObj, world);    
    OUT.hPosition = mul( pos , viewProj);       
     
    OUT.texCoordDiffuse0 = IN.texCoordDiffuse0;
    OUT.texCoordDiffuse1 = (IN.texCoordDiffuse0 + UVTranslate0) * UVScale0;
    OUT.texCoordDiffuse2 = (IN.texCoordDiffuse0 + UVTranslate1) * UVScale1;
  
  	OUT.normObj = IN.normObj;
    return OUT;
}


// Fresnel effect
void DoFresnel( inout float3 inOutColor, in float3 posWorld, in float3 normalWorld )
{
    
    //float3 toCam = campos/10000 - posWorld/10000;  // floats out of range
    float3 toCam = campos - posWorld;  // floats out of range
    float nDotV = saturate( dot( normalize(normalWorld), normalize(toCam) ));
    
    float fresnel = FresnelIndex + (1.0f - FresnelIndex ) * pow( (1 - nDotV ), FresnelExponent);
    fresnel = saturate( fresnel );    

	// should be 2 techniques
	if( FresnelModulate < 0.0f )
    	inOutColor = lerp( inOutColor, inOutColor * (1-fresnel), -FresnelModulate );
   	else
   		inOutColor = lerp( inOutColor, inOutColor * fresnel, FresnelModulate );
   
}

//-----------------------------------
PS_OUTPUT PS_Textured( vertexOutput IN)
{    
    float4 diffuseTexture = tex2D( DiffuseTextureSampler, IN.texCoordDiffuse1);
 
    float4 colorSum;  
    colorSum = float4(1.0f, 1.0f, 1.0f, 1.0f);
    
    float whereWidth = 1.0f - (abs (IN.texCoordDiffuse0.y - 0.5f)) * 2.0f;
   
    float4 colorModulate;
	float midPoint = 0.5f;
    colorModulate = lerp( ColorStart, ColorMid, min(1, IN.texCoordDiffuse0.y/midPoint) );
 	colorModulate = lerp( colorModulate, ColorEnd, max(0, (IN.texCoordDiffuse0.y-midPoint)/(1.0f-midPoint)) );
 
   	colorSum *= diffuseTexture * colorModulate;
   	colorSum.xyz *= FinalColorModulate;

 	DoFresnel( colorSum.xyz, IN.posWorld, normalize(IN.normWorld) );
 	       
	PS_OUTPUT Out;
	SetPSOutput( Out, colorSum, float4( campos - IN.posWorld.xyz, 0) );
	return Out;
}

//-----------------------------------
PS_OUTPUT PS_TexturedModulate( vertexOutput IN)
{    
 
   float4 diffuseTexture = tex2D( DiffuseTextureSampler, IN.texCoordDiffuse1);
   float4 diffuseTexture2 = tex2D( DiffuseTextureSampler, IN.texCoordDiffuse2);
 
    float4 colorSum;  
    colorSum = float4(1.0f, 1.0f, 1.0f, 1.0f);
    
    float whereWidth = 1.0f - (abs (IN.texCoordDiffuse0.y - 0.5f)) * 2.0f;
   
    float4 colorModulate;
    float midPoint = 0.5f;
    colorModulate = lerp( ColorStart, ColorMid, min(1, IN.texCoordDiffuse0.y/midPoint) );
 	colorModulate = lerp( colorModulate, ColorEnd, max(0, (IN.texCoordDiffuse0.y-midPoint)/(1.0f-midPoint)) );
 
   	colorSum *= diffuseTexture * diffuseTexture2 * colorModulate;
   	colorSum.xyz *= FinalColorModulate;
    
    DoFresnel( colorSum.xyz, IN.posWorld, normalize(IN.normWorld) );

	PS_OUTPUT Out;
	SetPSOutput( Out, colorSum, float4( campos - IN.posWorld.xyz, 0) );
	return Out;
}


//-----------------------------------
PS_OUTPUT PS_UnTextured( vertexOutput IN)
{    
    
    float4 colorSum;  
    colorSum = float4(1.0f, 1.0f, 1.0f, 1.0f);
    
    float whereWidth = 1.0f - (abs (IN.texCoordDiffuse0.y - 0.5f)) * 2.0f;
   
    float4 colorModulate;
  	float midPoint = 0.5f;
    colorModulate = lerp( ColorStart, ColorMid, min(1, IN.texCoordDiffuse0.y/midPoint) );
 	colorModulate = lerp( colorModulate, ColorEnd, max(0, (IN.texCoordDiffuse0.y-midPoint)/(1.0f-midPoint)) );
 
   
   	//float midPoint = 0.5f;
    //colorModulate = lerp( ColorStart, ColorMid, min(1, IN.texCoordDiffuse0.y/midPoint) );
 	//colorModulate = lerp( colorModulate, ColorEnd, max(0, (IN.texCoordDiffuse0.y-midPoint)/(1.0f-midPoint)) );
  
   	colorSum *= (colorModulate);
   	colorSum.xyz *= FinalColorModulate;
    
    DoFresnel( colorSum.xyz, IN.posWorld, normalize(IN.normWorld) );

    
    PS_OUTPUT Out;
	SetPSOutput( Out, colorSum, float4( campos - IN.posWorld.xyz, 0) );
	return Out;
}



//-----------------------------------
technique textured
{
    pass p0 
    {	
    	VertexShader = compile vs_2_0 VS_Transform();
		PixelShader  = compile ps_2_0 PS_Textured();
    }
}

//-----------------------------------
technique texturedModulate
{
    pass p0 
    {	
    	VertexShader = compile vs_2_0 VS_Transform();
		PixelShader  = compile ps_2_0 PS_TexturedModulate();
    }
}


//-----------------------------------
technique untextured
{
    pass p0 
    {		
    	VertexShader = compile vs_2_0 VS_Transform();
		PixelShader  = compile ps_2_0 PS_UnTextured();
    }
}
