//--------------------------------------------------------------------------
//
// WHALE ENGINE 1.0
// LGM GAMES
// DIRECT X9c
// SHADER v2.0
//          
//--------------------------------------------------------------------------
/*
texture TextureDifuse;            
texture TextureLightMap;                 
texture TextureNormalMap;
texture TextureCubeMap;                 
texture TextureShadowMap;
*/
float4	 g_fScale;
float    g_fTime;                    // App's time in seconds
float4x4 g_mWorld;                    // World matrix for object
float4x4 g_mWorldViewProjection;    // World * View * Projection matrix
float4x4 g_mShadowProjection;
vector   CameraPosition;
vector   g_LightAmbient =  {1.0f, 1.0f, 1.0f, 1.0f};
float4   UV; //Umin, Umax, Vmin, Vmax
vector   ExtraVector = { 0.5f, 0.5f, 0.5f, 0.5f }; 

//--------------------------------------------------------------------------
// Globals
//--------------------------------------------------------------------------
// The per-color weighting to be used for luminance calculations in RGB order.
static const float3 LUMINANCE_VECTOR  = float3(0.2125f, 0.7154f, 0.0721f);

// The per-color weighting to be used for blue shift under low light.
static const float3 BLUE_SHIFT_VECTOR = float3(1.05f, 0.97f, 1.27f); 
static const float BLUR_FACTOR = 0.1f;

bool bUseBlueShift = true;

float4		tcLumOffsets[2];			// The offsets used by GreyScaleDownSample()
float4		tcDSOffsets[5];				// The offsets used by DownSample()

float gDeltaTime;
float Exposure = 1.0;
float BlurFactor = 0.8;//0.5f;

static const float  GAMA = 0.75f;

static const float  MIDDLE_GRAY = 0.3;///0.35f;
static const float  LUM_WHITE = 1.6;//1.3f;

static const float  MIDDLE_GRAY_BLOOM = 0.25f;
static const float  LUM_WHITE_BLOOM = 1.6f;

texture Noise;    // noise map
texture Diffuse;    // difuse map
texture Glow;       // glow map
texture Refraction; // refraction map
texture Star;       // star texture
texture Tone;       // tone map

vector FrameBufferColor = float4(1.0f, 1.0f, 1.0f, 1.0f);

matrix ViewProjMatrix;

//--------------------------------------------------------------------------
// Vertex shader
//--------------------------------------------------------------------------
struct VS_INPUT
{
 float4 Position : POSITION;
 float2 TextureUV : TEXCOORD0;
};
//--------------------------------------------------------------------------
struct VS_OUTPUT
{
 float4 Position : POSITION;
 float2 TextureUV : TEXCOORD0;
 float2 TextureUVRefr : TEXCOORD0;
};
//--------------------------------------------------------------------------
VS_OUTPUT VShade(VS_INPUT input)
{
 // zero out members of output
 VS_OUTPUT output;
 
 // transform to view space and project
 output.Position  = mul(input.Position, ViewProjMatrix);
 
 output.TextureUV = input.TextureUV;
 output.TextureUVRefr = input.TextureUV+float2(1,1)*g_fTime*2.0f;
 
 return output;
}
//--------------------------------------------------------------------------



//--------------------------------------------------------------------------
// Pixel shader
//--------------------------------------------------------------------------
uniform sampler   BaseTex: register(s0) = 
sampler_state 
{
 texture = <Diffuse>;
 MinFilter = Linear;
 MagFilter = Linear;
 MipFilter = Linear;

 AddressU = Mirror; 
 AddressV = Mirror; 
 AddressW = Mirror; 
};
//--------------------------------------------------------------------------
uniform sampler   GlowTex = 
sampler_state 
{
 texture = <Glow>;
 MinFilter = Linear;
 MagFilter = Linear;
 MipFilter = Linear;

 AddressU = Clamp; 
 AddressV = Clamp; 
 AddressW = Clamp; 
};
//--------------------------------------------------------------------------
uniform sampler   StarTex = 
sampler_state 
{
 texture = <Star>;
 MinFilter = Linear;
 MagFilter = Linear;
 MipFilter = Linear;

 AddressU = Clamp; 
 AddressV = Clamp; 
 AddressW = Clamp; 
};
//--------------------------------------------------------------------------
uniform sampler   RefractionTex = 
sampler_state 
{
 texture = <Refraction>;
 MinFilter = Linear;
 MagFilter = Linear;
 MipFilter = Point;

 AddressU = Clamp; 
 AddressV = Clamp; 
 AddressW = Clamp; 
};


uniform sampler   NoiseTex = 
sampler_state 
{
 texture = <Noise>;
 MinFilter = Linear;
 MagFilter = Linear;
 MipFilter = Linear;

 AddressU = Mirror; 
 AddressV = Mirror; 
 AddressW = Mirror; 
};

//--------------------------------------------------------------------------
uniform sampler   ToneTex: register(s1) = 
sampler_state 
{
 texture = <Tone>;
 MinFilter = Point;
 MagFilter = Point;
 MipFilter = Point;

 AddressU = Clamp; 
 AddressV = Clamp; 
 AddressW = Clamp; 
};
//--------------------------------------------------------------------------
struct PS_OUTPUT
{
 vector diffuse : COLOR0;
};
//--------------------------------------------------------------------------
half luminance(half3 c)
{
 return dot(c, float3(0.3, 0.59, 0.11));
}
//--------------------------------------------------------------------------
float vignette(const float2 win_bias)
{
	// convert window coord to [-1, 1] range
	float2 wpos = 2*(win_bias - (float2)(0.5, 0.5)); 

	// calculate distance from origin
	float r = length(wpos.xy);
	r = 1.0 - smoothstep(0.8, 1.5, r);
	
	return  r;
}

//--------------------------------------------------------------------------
PS_OUTPUT Bloom(float2 Tex0 : TEXCOORD0)
{
 PS_OUTPUT output;

 float dof = 1*g_fTime;
 float3 n1 = tex2D(NoiseTex, 10*float2(Tex0.x+dof, Tex0.y-dof));
 float3 n2 = tex2D(NoiseTex, 10*float2(Tex0.x-dof, Tex0.y+dof));
 
 float4 c3 = tex2D(RefractionTex, Tex0);
 //float4 Dif = tex2D(BaseTex, Tex0);
 float offset = ((n1.r+n2.r)*0.5f-0.5f)*(c3.r+c3.g+c3.b)*0.03f;
 float2 NewCor = float2(Tex0.x+offset, Tex0.y+offset);
 half4 c1 = tex2D(BaseTex, NewCor);
 //c1 = max(Dif, c1);
 half4 c2 = tex2D(GlowTex, NewCor);
 
  output.diffuse = c1+c2;//
 //output.diffuse = (c1*0.8f)+(c2*0.65f);
 //output.diffuse *= FrameBufferColor;
 /*
 float v = vignette(NewCor.xy); 
 //output.diffuse = lerp(luminance(output.diffuse.rgb), output.diffuse, saturate(v-0.2));
 output.diffuse.a = lerp(BLUR_FACTOR, 0.8f, saturate(v-0.2));
  */
 return output;
}
//--------------------------------------------------------------------------
PS_OUTPUT Normal(float2 Tex0 : TEXCOORD0)
{
 PS_OUTPUT output;

 float4 c3 = tex2D(RefractionTex, Tex0);
 float offset = ((c3.r+c3.g+c3.b)*0.02f);
 //offset = 0.01*cos(Tex0.y*16)*sin(g_fTime*6)*cos(Tex0.x*24);
 float2 NewCor = float2(Tex0.x+offset, Tex0.y+offset);
 //float3 test = tex2D(RefractionTex, NewCor);
 //offset *= (test.r+test.g+test.b);

 //NewCor = /*Tex0;//*/float2(Tex0.x+offset, Tex0.y+offset);
 //if (test.r+test.g+test.b == 0) NewCor = float2(Tex0.x, Tex0.y);
 half4 c1 = tex2D(BaseTex, NewCor);
 half4 c2 = tex2D(GlowTex, NewCor);
 
 output.diffuse = (c1*1.0)+(c2*0.55);
 //output.diffuse = (c1*0.8)+(c2*0.55);
 //output.diffuse *= Exposure;
 //output.diffuse *= FrameBufferColor;
 
 //float v = vignette(NewCor.xy); 
 //output.diffuse = lerp(luminance(output.diffuse.rgb), output.diffuse, saturate(v-0.2));
 output.diffuse.a = 1.0f;//lerp(BLUR_FACTOR, 0.8f, saturate(v-0.2));
 
 return output;
}


//------------------------------------------------------------------
float4 Simply( in float2 t : TEXCOORD0 ) : COLOR0
{
		return tex2D(BaseTex, t)*FrameBufferColor;
}
//------------------------------------------------------------------


//--------------------------------------------------------------------------

technique RenderScreen
{ 
 pass p0
 {      
  VertexShader = NULL;

  PixelShader = compile ps_2_0 Bloom();
 }
 pass p1
 {      
  VertexShader = NULL;

  PixelShader = compile ps_2_0 Normal();
 }
 pass p2
 {      
  VertexShader = NULL;

  PixelShader = compile ps_2_0 Simply();
 } 
}
//--------------------------------------------------------
