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

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


float4x4 viewProj : ViewProjection;
float4x4 world : World;
float3 campos : CAMERAPOS;
float4x4 view : View;
float4x4 proj : Projection;

float FinalColorModulate : FinalColorModulate;

float4 MidColor : MidColor;

float WhereSpline : WhereSpline;

float2 UVTranslation0 : UVTranslation0;
float2 UVTranslation1 : UVTranslation1;

float2 UVScale0 : UVScale0;
float2 UVScale1 : UVScale1;

float2 QuadDimensions : QuadDimensions;

float centerX = 0.5f;    
float centerY = 0.5f;

    


float4 UpperColor : UpperColor;
float4 LowerColor : LowerColor;
float  GradientAngle : GradientAngle;
float  GradientExponent : GradientExponent;
float4 DistanceFogColor : DistanceFogColor;
float	DistanceFogEnd : DistanceFogEnd;






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 pos0					: TEXCOORD0;
    float3 pos2					: TEXCOORD1;
    float3 pos3					: TEXCOORD2;
    float2 rotations			: TEXCOORD3;
};

struct vertexOutput {
    float4 hPosition		: POSITION;
    float2 texCoordDiffuse	: TEXCOORD0;
    float2 texCoordDiffuse2	: TEXCOORD1;
    float2 texCoordDiffuse3	: TEXCOORD2;
    float3 posWorld         : TEXCOORD3;
};

struct vertexOutputFog {
    float4 hPosition		: POSITION;
    float2 texCoordDiffuse	: TEXCOORD0;
    float2 texCoordDiffuse2	: TEXCOORD1;
    float2 texCoordDiffuse3	: TEXCOORD2;
    float3 posWorld         : TEXCOORD3;
    float  fogAmount         : TEXCOORD4;
};

float xOffset[6] = { -1, -1, 1, 1, -1, 1 };
float yOffset[6] = { -1, 1, 1, -1, -1, 1 };

float2 UVs[6] = { float2(0,1), float2(0,0), float2(1,0), float2(1,1), float2(0,1), float2(1,0) };



void ApplyShading(float inX, float inY, float fogAmount, inout float4 colorOut )
{
	float fWhereY = (inY - centerY)*cos(GradientAngle) + (inX-centerX)*sin( GradientAngle );
   	fWhereY += centerY;
   	float4 shadeColor = lerp( UpperColor, LowerColor, fWhereY );
   	
   	colorOut *= pow(shadeColor, GradientExponent);   	
   	
   	colorOut = lerp( colorOut, float4( DistanceFogColor.xyz, colorOut.a*DistanceFogColor.a ), fogAmount );
}
  
vertexOutput VS_Transform(vertexInput IN) 
{
    float4 pos;
    vertexOutput OUT;
    
    float4 centerPos; // = float4( IN.position.xyz, 1 );    
    
    // Spline
    float3 a =   -IN.pos0 + 3*IN.position.xyz - 3*IN.pos2 + IN.pos3;
    float3 b =  2*IN.pos0 - 5*IN.position.xyz + 4*IN.pos2 - IN.pos3;
    float3 c =   -IN.pos0                     + IN.pos2;
    float3 d =            2*IN.position.xyz;

    // Evaluate the equation at u, where:
    //    f(u) = 0.5 * ( au^3 + bu^2 + cu + d )
    float3 newPos =  0.5f * ( ( ( a * WhereSpline + b ) * WhereSpline + c ) * WhereSpline + d );    
    
    centerPos.xyz = newPos;
    centerPos.w = 1;
    
    pos = mul(centerPos, world);    
    OUT.posWorld = pos; //note: thjs is not accurate
    
    // Billboard and rotate in viewSpace
    float4 posView = mul( pos , view );  
   
    float2 offset; 
    offset.x = xOffset[IN.position.w] * QuadDimensions.x; //* IN.texCoordDiffuse.x;
    offset.y = yOffset[IN.position.w] * QuadDimensions.y; //* IN.texCoordDiffuse.x;
    
    //rotate
    float fTheta;    
    fTheta = lerp( IN.rotations.x, IN.rotations.y, WhereSpline );
    
    float2 offsetRotated;
    offsetRotated.x = offset.x * cos(fTheta) - offset.y * sin(fTheta);
    offsetRotated.y = offset.y * cos(fTheta) + offset.x * sin(fTheta);
    
    posView.xy += offsetRotated;
 
    OUT.hPosition = mul( posView , proj);
      
    OUT.texCoordDiffuse = UVs[IN.position.w];
    OUT.texCoordDiffuse2 = (UVs[IN.position.w] + UVTranslation0 )* UVScale0 ;
    OUT.texCoordDiffuse3 = (UVs[IN.position.w] + UVTranslation1 )* UVScale1 ;
    
    return OUT;
}


vertexOutputFog VS_TransformShaded(vertexInput IN) 
{
    float4 pos;
    vertexOutputFog OUT;
    
    float4 centerPos; // = float4( IN.position.xyz, 1 );    
    
    // Spline
    float3 a =   -IN.pos0 + 3*IN.position.xyz - 3*IN.pos2 + IN.pos3;
    float3 b =  2*IN.pos0 - 5*IN.position.xyz + 4*IN.pos2 - IN.pos3;
    float3 c =   -IN.pos0                     + IN.pos2;
    float3 d =            2*IN.position.xyz;

    // Evaluate the equation at u, where:
    //    f(u) = 0.5 * ( au^3 + bu^2 + cu + d )
    float3 newPos =  0.5f * ( ( ( a * WhereSpline + b ) * WhereSpline + c ) * WhereSpline + d );    
    
    centerPos.xyz = newPos;
    centerPos.w = 1;
    
    pos = mul(centerPos, world);    
    OUT.posWorld = pos; //note: thjs is not accurate
    
    // Billboard and rotate in viewSpace
    float4 posView = mul( pos , view );  
   
    float2 offset; 
    offset.x = xOffset[IN.position.w] * QuadDimensions.x; //* IN.texCoordDiffuse.x;
    offset.y = yOffset[IN.position.w] * QuadDimensions.y; //* IN.texCoordDiffuse.x;
    
    //rotate
    float fTheta;    
    fTheta = lerp( IN.rotations.x, IN.rotations.y, WhereSpline );
    
    float2 offsetRotated;
    offsetRotated.x = offset.x * cos(fTheta) - offset.y * sin(fTheta);
    offsetRotated.y = offset.y * cos(fTheta) + offset.x * sin(fTheta);
    
    posView.xy += offsetRotated;
 
    OUT.hPosition = mul( posView , proj);
      
    OUT.texCoordDiffuse = UVs[IN.position.w];
    OUT.texCoordDiffuse2 = (UVs[IN.position.w] + UVTranslation0 )* UVScale0 ;
    OUT.texCoordDiffuse3 = (UVs[IN.position.w] + UVTranslation1 )* UVScale1 ;
    
    // Calculate fogging
    OUT.fogAmount = saturate( length(campos - pos) / DistanceFogEnd );
    return OUT;
}



//-----------------------------------
PS_OUTPUT PS_UnTextured( vertexOutput IN)
{        
   	float4 outColor = float4( MidColor.xyz, 1 );
   	
 	
    float2 toCenter = float2(centerX,centerY) - IN.texCoordDiffuse;
    
    float where = length( toCenter );
      
    where = where / length( float2(0.5,0.5) ) ; //0.7071068f; 
    where = saturate( 1.0f - where );
  
   	outColor.xyz *= FinalColorModulate;
   	outColor.a *= MidColor.a * where;	
   	
   	//outColor = float4( 1, 1, 1, 1 );
   	
   	PS_OUTPUT Out;
	SetPSOutput( Out, outColor, float4( 1, 1, 1, 1 ));
	return Out;
}



//-----------------------------------
PS_OUTPUT PS_Textured( vertexOutput IN)
{           

 	float4 diffuseTexture = tex2D( DiffuseTextureSampler, IN.texCoordDiffuse2 );
 	float4 diffuseTexture2 = tex2D( DiffuseTextureSampler, IN.texCoordDiffuse3 );
   
	diffuseTexture *= diffuseTexture2;
	
   	float4 outColor = diffuseTexture * float4( MidColor.xyz, 1 );
   	
 	float centerX = 0.5f;    
    float centerY = 0.5f;
    
    float2 toCenter = float2(centerX,centerY) - IN.texCoordDiffuse;
    
    float where = length( toCenter );
      
    where = where / length( float2(0.5,0.5) ) ; //0.7071068f; 
    where = saturate( 1.0f - where );
  
   	outColor.xyz *= FinalColorModulate;   	
   	outColor.a *= MidColor.a * where;	
   	
   	PS_OUTPUT Out;
	SetPSOutput( Out, outColor, float4( 1, 1, 1, 1 ));
	return Out;
}


//-----------------------------------
PS_OUTPUT PS_UnTexturedShaded( vertexOutputFog IN)
{        
   	float4 outColor = float4( MidColor.xyz, 1 );
   	
 	float centerX = 0.5f;    
    float centerY = 0.5f;
    
    float2 toCenter = float2(centerX,centerY) - IN.texCoordDiffuse;
    
    float where = length( toCenter );
      
    where = where / length( float2(0.5,0.5) ) ; //0.7071068f; 
    where = saturate( 1.0f - where );
  
   	outColor.xyz *= FinalColorModulate;
  	outColor.a *= MidColor.a * where;	
   	
   	// Apply shading -> rotate about center
   	ApplyShading( IN.texCoordDiffuse.x, IN.texCoordDiffuse.y, IN.fogAmount, outColor );
   	
   	PS_OUTPUT Out;
	SetPSOutput( Out, outColor, float4( 1, 1, 1, 1 ));
	return Out;
}


PS_OUTPUT PS_TexturedShaded( vertexOutputFog IN)
{           

 	float4 diffuseTexture = tex2D( DiffuseTextureSampler, IN.texCoordDiffuse2 );
 	float4 diffuseTexture2 = tex2D( DiffuseTextureSampler, IN.texCoordDiffuse3 );
   
	diffuseTexture *= diffuseTexture2;
	
   	float4 outColor = diffuseTexture * float4( MidColor.xyz, 1 );
   	
 	float centerX = 0.5f;    
    float centerY = 0.5f;
    
    float2 toCenter = float2(centerX,centerY) - IN.texCoordDiffuse;
    
    float where = length( toCenter );
      
    where = where / length( float2(0.5,0.5) ) ; //0.7071068f; 
    where = saturate( 1.0f - where );
  
   	outColor.xyz *= FinalColorModulate;   	
   	outColor.a *= MidColor.a * where;	
   	
   	//outColor.a = 1.0f;
   	
   	// Apply shading -> rotate about center
   	ApplyShading( IN.texCoordDiffuse.x, IN.texCoordDiffuse.y, IN.fogAmount, outColor );
   	
   	PS_OUTPUT Out;
	SetPSOutput( Out, outColor, float4( 1, 1, 1, 1 ));
	return Out;
}




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


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


//-----------------------------------
technique untexturedShaded
{
    pass p0 
    {	
    	VertexShader = compile vs_2_0 VS_TransformShaded();
		PixelShader  = compile ps_2_0 PS_UnTexturedShaded();
    }
}


//-----------------------------------
technique texturedShaded
{
    pass p0 
    {	
    	VertexShader = compile vs_2_0 VS_TransformShaded();
		PixelShader  = compile ps_2_0 PS_TexturedShaded();
    }
}
