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

Support for 2 directional lights and 1 point.

******************************************************************************/


float4x4 worldViewProj : WorldViewProjection;
float4x4 viewProj : ViewProjection;
float4x4 world : World;



#include "..\mrt_none.fx"

float ColorModulate : ColorModulate;


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



texture DepthTexture : DepthTexture;
sampler DepthTextureSampler = sampler_state 
{
    texture = <DepthTexture>;
    AddressU  = WRAP;        
    AddressV  = WRAP;
    AddressW  = WRAP;
    MIPFILTER = POINT;
    MINFILTER = POINT;
    MAGFILTER = POINT;
};

float DepthSpriteFadeDistance : DepthSpriteFadeDistance;

struct DirectionalLight
{
    float3 Direction    : DIRECTION;
    float3 Diffuse      : DIFFUSE;
    float3 Specular     : SPECULAR;
};

struct PointLight
{
    float4 Position_Att0     : POSITION_ATT0;
    float4 Diffuse_Att1      : DIFFUSE_ATT1;
    float4 Specular_Att2     : SPECULAR_ATT2;
};

struct Material
{
    float4 Diffuse_Opacity  : DIFFUSE_OPACITY;
    float4 Specular_Power : SPECULAR_POWER;
    float3 Ambient  : AMBIENT;
    float3 Emissive : EMISSIVE;
};

DirectionalLight    dirLights[3]    : DIRLIGHT;
PointLight          pointLights[3]  : POINTLIGHT;
Material            matSettings     : MATERIAL;

float3 ambientLevel : AMBIENT = {0.2, 0.2, 0.2};
float3 campos : CAMERAPOS;

struct vertexInput {
    float4 position				: POSITION;
    float4 diffuse				: COLOR0;
    float2 texCoordDiffuse		: TEXCOORD0;
};

struct vertexOutput {
    float4 hPosition		: POSITION;
    float2 texCoordDiffuse	: TEXCOORD0;
    float4 diffColor		: COLOR0;
};

struct vertexOutputDepth {
    float4 hPosition		: POSITION;
    float2 texCoordDiffuse	: TEXCOORD0;
    float4 diffColor		: COLOR0;
    float4 screenPos		: TEXCOORD1;
    float4 posWorld		 	: TEXCOORD2;
};

float4 VS_PointLightSetup(float3 pos, float a0, float a1, float a2, float3 vertPosWorld)
{
    float3 lightVec = pos - vertPosWorld;
    float lightVecDSq = dot(lightVec, lightVec);
    float lightVecD = sqrt(lightVecDSq);
    float att = a0 + a1 * lightVecD + a2 * lightVecDSq;
    att = 1 / att;
    return float4(lightVec, att);
}

vertexOutput VS_Shared(float4 pos, float2 uv, float4 vertDiffuse)
{
    vertexOutput OUT;

    OUT.texCoordDiffuse = uv;
    OUT.hPosition = mul( pos , viewProj);
    OUT.diffColor = vertDiffuse;
    return OUT;
}

vertexOutput VS_Transform(vertexInput IN) 
{
    float4 pos;
    
    pos = mul(IN.position, world);
    return VS_Shared(pos, IN.texCoordDiffuse, IN.diffuse);
}


//-----------------------------------
PS_OUTPUT PS_Textured( vertexOutput IN)
{
    float4 diffuseTexture = tex2D( DiffuseTextureSampler, IN.texCoordDiffuse );
  
    float4 colorSum;
    
    colorSum = diffuseTexture * IN.diffColor;
    colorSum.xyz += matSettings.Ambient * ambientLevel * diffuseTexture;
    colorSum.xyz += ambientLevel * diffuseTexture;
    colorSum.xyz *= ColorModulate;
  
	PS_OUTPUT Out;
	SetPSOutput( Out, colorSum, float4( 0,0,0,  0.3f /*MRT_FORCE_BLOOM + hot*/ ) );
    return Out;
}


vertexOutputDepth VS_TransformDepthSprites(vertexInput IN) 
{
    float4 pos;
    vertexOutputDepth output;
    
    pos = mul(IN.position, world);
    
    output.texCoordDiffuse = IN.texCoordDiffuse;
    output.hPosition = mul( pos , viewProj);
    output.diffColor = IN.diffuse;
  	output.screenPos = mul( pos , viewProj);
    output.posWorld = mul( pos, world );
    return output; 
}


//-----------------------------------
PS_OUTPUT PS_TexturedDepthSprites( vertexOutputDepth IN)
{
    float4 diffuseTexture = tex2D( DiffuseTextureSampler, IN.texCoordDiffuse );
  
    float4 colorSum;
    
    colorSum = diffuseTexture * IN.diffColor;
    colorSum.xyz += matSettings.Ambient * ambientLevel * diffuseTexture;
    colorSum.xyz += ambientLevel * diffuseTexture;

    colorSum.xyz *= ColorModulate;
  
    float2 screenUV = (IN.screenPos.xy / (2*IN.screenPos.w) ) + 0.5f;
    screenUV.y = 1.0f - screenUV.y;
	
    float4 cameraToBackground = tex2D( DepthTextureSampler, screenUV );
    float3 cameraToPixel = campos - IN.posWorld.xyz;
	
	// modulate by distance
	PS_OUTPUT Out;
	//colorSum.rgb = 1.0f - saturate( length( cameraToBackground - cameraToPixel ) / 200.0f );
	
	colorSum.a *= saturate( length( cameraToBackground - cameraToPixel ) / DepthSpriteFadeDistance );
	
	SetPSOutput( Out, colorSum, float4( 0,0,0,  0.3f /*MRT_FORCE_BLOOM + hot*/ ) );
    return Out;
}


//-----------------------------------
#ifndef FixedPipe
technique textured
{
    pass p0 
    {
   		VertexShader = compile vs_1_1 VS_Transform();
		PixelShader  = compile ps_2_0 PS_Textured();   
    }
}
technique depthSprites
{
    pass p0 
    {
   		VertexShader = compile vs_1_1 VS_TransformDepthSprites();
		PixelShader  = compile ps_2_0 PS_TexturedDepthSprites();
    }
}
#else
technique textured
{
    pass p0 
    {		
		VertexShader = compile vs_1_1 VS_Transform();
		PixelShader  = 0;
		
		ColorOp[0] = Modulate; ColorArg1[0] = Texture; ColorArg2[0] = Diffuse;
		AlphaOp[0] = Modulate; AlphaArg1[0] = Texture; AlphaArg2[0] = Diffuse;
		SpecularEnable = false;
		Sampler[0] = <DiffuseTextureSampler>;
		
		ColorOp[1] = Disable;
		AlphaOp[1] = Disable;
    }
}
technique depthSprites
{
    pass p0 
    {		
		VertexShader = compile vs_1_1 VS_Transform();
		PixelShader  = 0;
		
		ColorOp[0] = Modulate; ColorArg1[0] = Texture; ColorArg2[0] = Diffuse;
		AlphaOp[0] = Modulate; AlphaArg1[0] = Texture; AlphaArg2[0] = Diffuse;
		SpecularEnable = false;
		Sampler[0] = <DiffuseTextureSampler>;
		
		ColorOp[1] = Disable;
		AlphaOp[1] = Disable;
    }
}
#endif
