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

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

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

float FinalColorModulate : FinalColorModulate;

float4 InnerColor : InnerColor;
float4 MidColor : MidColor;
float4 OuterColor : OuterColor;

float InnerOpacity : InnerOpacity;
float MidOpacity : MidOpacity;
float OuterOpacity : OuterOpacity;

float ColorMidpoint : ColorMidpoint;
float OpacityMidpoint : OpacityMidpoint;

// Circular gradient
float CircularGradientStart : CircularGradientStart;
float CircularGradientMid1 : CircularGradientMid1;
float CircularGradientMid2 : CircularGradientMid2;
float CircularGradientEnd : CircularGradientEnd;

float TextureBlend : TextureBlend;
float2 UVScales: UVScales;
float2 UVTransforms : UVTransforms;

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

struct vertexInput{
    float4 position				: POSITION;
    float3 normal				: NORMAL;
    float2 texCoordDiffuse		: TEXCOORD0;
};

struct vertexOutput {
    float4 hPosition		: POSITION;
    float3 posObj           : TEXCOORD0;
    float3 normalObj        : TEXCOORD1;
    float2 texCoordDiffuse	: TEXCOORD2;
};

vertexOutput VS_Transform(vertexInput IN) 
{
    float4 pos;
    vertexOutput OUT;
    
    pos = mul(IN.position, world);
    OUT.posObj = IN.position;
    OUT.normalObj =  IN.normal;    
    OUT.hPosition = mul( pos , viewProj);       
     
    OUT.texCoordDiffuse = IN.texCoordDiffuse;
    return OUT;
}


//-----------------------------------
PS_OUTPUT PS_Untextured( vertexOutput IN)
{    
    float3 color;
    float opacity;
    float4 outColor;
    // The halo geometry has inner vertices with normal.y at -1
    //   and outer vertices with normal.y at +1
	float where = (IN.normalObj.y + 1.0f) / 2.0f;
    color = lerp( InnerColor, MidColor, min(1, where/ColorMidpoint) );
    color = lerp( color, OuterColor, max(0, (where-ColorMidpoint)/(1.0f-ColorMidpoint)) );
        
    opacity = lerp( InnerOpacity, MidOpacity, min(1, where/OpacityMidpoint) );
    opacity = lerp( opacity, OuterOpacity, max(0, (where-OpacityMidpoint)/(1.0f-OpacityMidpoint)) );
  
    
  	outColor = float4( color, opacity );
	outColor *= FinalColorModulate;
	
	PS_OUTPUT Out;	
	
	SetPSOutput( Out, outColor, float4( 0,0,0,0 ) );
	return Out;
}



//-----------------------------------
PS_OUTPUT PS_UntexturedCircularGradient( vertexOutput IN)
{    
  float4 outColor;
 
    float3 color;
    float opacity;
     // The halo geometry has inner vertices with normal.y at -1
    //   and outer vertices with normal.y at +1
	float where = (IN.normalObj.y + 1.0f) / 2.0f;

    color = lerp( InnerColor, MidColor, min(1, where/ColorMidpoint) );
    color = lerp( color, OuterColor, max(0, (where-ColorMidpoint)/(1.0f-ColorMidpoint)) );
        
    opacity = lerp( InnerOpacity, MidOpacity, min(1, where/OpacityMidpoint) );
    opacity = lerp( opacity, OuterOpacity, max(0, (where-OpacityMidpoint)/(1.0f-OpacityMidpoint)) );
  
  	outColor = float4( color, opacity );
	
	// Find out where in the circle we are
	float3 toPixel = normalize( IN.posObj );
	float angle = acos( toPixel.x );
	
	float angleScale = angle / 3.14159265358979;	
	// bring into [0..1] over entire sphere
	angleScale = angleScale / 2.0f;
	if( toPixel.y < 0.0f )
	    angleScale = (0.5f + (0.5f - angleScale));
	
    float StartOpacity = 0.0f;
    float MidOpacity1 = 1.0f;
    float MidOpacity2 = 1.0f;
    float EndOpacity = 0.0f;
    
    float opacityModifier = 1.0f;
    float whereGradient;
    
    angleScale -= CircularGradientStart;
    if( angleScale < 0.0f )
        angleScale = 1.0f + angleScale;

    if( angleScale < CircularGradientMid1 )
    {
      whereGradient = angleScale / CircularGradientMid1;
      opacityModifier = lerp( StartOpacity, MidOpacity1, whereGradient );
    }
    else
    if( (angleScale > CircularGradientMid1) && (angleScale < CircularGradientMid2) )
    {
      whereGradient = ( angleScale - CircularGradientMid1) / (CircularGradientMid2 - CircularGradientMid1);
      opacityModifier = lerp( MidOpacity1, MidOpacity2, whereGradient );
    }
    else
    if( (angleScale > CircularGradientMid2) && (angleScale < CircularGradientEnd) )
    {
      whereGradient = ( angleScale - CircularGradientMid2) / (CircularGradientEnd - CircularGradientMid2);
      opacityModifier = lerp( MidOpacity2, EndOpacity, whereGradient );
    }
    else
    {
    	whereGradient = ( angleScale - CircularGradientEnd) / CircularGradientEnd;      
        opacityModifier = lerp( EndOpacity, StartOpacity, whereGradient );    
    }    
	
	outColor *= FinalColorModulate * opacityModifier;
	
	PS_OUTPUT Out;	
	SetPSOutput( Out, outColor, float4( 0,0,0,0 ) );
	return Out;
}

//-----------------------------------
PS_OUTPUT PS_Textured( vertexOutput IN)
{    
    float3 color;
    float opacity;
    float4 outColor;

#ifdef PerVertexPreference
	float4 noise1 = tex2D( NoiseTextureSampler, (IN.texCoordDiffuse + float2( UVTransforms.x, 0)) * float2(UVScales.x, 1) );
  
  	//outColor = noise1 * lerp( MidColor, OuterColor, 0.5f );
	
	float where = (IN.normalObj.y + 1.0f) / 2.0f;    
  	//outColor.a = where * 0.4f;
  	
  	color = lerp( InnerColor, MidColor, min(1, where/ColorMidpoint) );
    color = lerp( color, OuterColor, max(0, (where-ColorMidpoint)/(1.0f-ColorMidpoint)) );
        
    opacity = lerp( InnerOpacity, MidOpacity, min(1, where/OpacityMidpoint) );
    opacity = lerp( opacity, OuterOpacity, max(0, (where-OpacityMidpoint)/(1.0f-OpacityMidpoint)) );
  
  	outColor = float4( noise1.xyz * color, opacity );
	

#else
    float4 noise1 = tex2D( NoiseTextureSampler, (IN.texCoordDiffuse + float2( UVTransforms.x, 0)) * float2(UVScales.x, 1) );
    float4 noise2 = tex2D( NoiseTextureSampler, (IN.texCoordDiffuse + float2( UVTransforms.y, 0)) * float2(UVScales.y, 1) );
    
    // The halo geometry has inner vertices with normal.y at -1
    //   and outer vertices with normal.y at +1
	float where = (IN.normalObj.y + 1.0f) / 2.0f;    
    color = lerp( InnerColor, MidColor, min(1, where/ColorMidpoint) );
    color = lerp( color, OuterColor, max(0, (where-ColorMidpoint)/(1.0f-ColorMidpoint)) );
        
    opacity = lerp( InnerOpacity, MidOpacity, min(1, where/OpacityMidpoint) );
    opacity = lerp( opacity, OuterOpacity, max(0, (where-OpacityMidpoint)/(1.0f-OpacityMidpoint)) );
      
  	outColor = float4( color, opacity );
	outColor *= FinalColorModulate;
	
	outColor = lerp( outColor, (noise1 * noise2) * outColor,  TextureBlend );	
#endif
	
	PS_OUTPUT Out;	
	SetPSOutput( Out, outColor, float4( 0,0,0,0 ) );
	return Out;
}






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


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


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