//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------
TextureCube posTex : register( t0 );
TextureCube buffTex : register( t1 );

SamplerState samLinear : register( s0 );
SamplerState samPoint : register( s1 );

cbuffer cbChangesOnRenderTarget : register( b0 )
{
    float4 lightWorldPos;
	float4 dimensions; //y is 1/x
};

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

Just tu have it here too

RT	 View Side				Up Vector
0	( 1.0f, 0.0f, 0.0f)   ( 0.0f, 1.0f, 0.0f)
1	(-1.0f, 0.0f, 0.0f)   ( 0.0f, 1.0f, 0.0f)
2	( 0.0f, 1.0f, 0.0f)   ( 0.0f, 0.0f,-1.0f)
3	( 0.0f,-1.0f, 0.0f)   ( 0.0f, 0.0f, 1.0f)
4	( 0.0f, 0.0f, 1.0f)   ( 0.0f, 1.0f, 0.0f)
5	( 0.0f, 0.0f,-1.0f)   ( 0.0f, 1.0f, 0.0f)


static const float3 cubeTexCoords[8] = {
	//FRONT SIDE
	float3( 1.0f,  1.0f, -1.0f),
    float3(-1.0f,  1.0f, -1.0f),
    float3( 1.0f, -1.0f, -1.0f),
    float3(-1.0f, -1.0f, -1.0f),
	//BACK SIDE
	float3( 1.0f,  1.0f,  1.0f),
    float3(-1.0f,  1.0f,  1.0f),
    float3( 1.0f, -1.0f,  1.0f),
    float3(-1.0f, -1.0f,  1.0f)
};

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

#define FILTER_WIDTH 4

//--------------------------------------------------------------------------------------
// Point Light
//--------------------------------------------------------------------------------------

struct VS_INPUT
{
    float2 Pos : POSITION;
    float3 Tex : TEXCOORD0;
	float3 Side : TEXCOORD1;
	float3 Up : TEXCOORD2;
	uint   Rt  : BLENDINDICES0;
};

struct VS_OUTPUT
{
    float4 Pos : SV_POSITION;
    float3 Tex : TEXCOORD0;
	float3 Side : TEXCOORD1;
	float3 Up : TEXCOORD2;
	uint   Rt  : TEXCOORD3;
};

struct PS_INPUT
{
    float4 Pos : SV_POSITION;
    float3 Tex : TEXCOORD0;
	float3 Side : TEXCOORD1;
	float3 Up : TEXCOORD2;
	uint Rt    : SV_RenderTargetArrayIndex;
};

//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
VS_OUTPUT VS( VS_INPUT input )
{
    VS_OUTPUT output = (VS_OUTPUT)0;
    output.Pos.xy = input.Pos;
	output.Pos.zw = float2(0.0f,1.0f);
    output.Tex = input.Tex;
	output.Side = input.Side;
	output.Up = input.Up;
	output.Rt = input.Rt;
    
    return output;
}

//--------------------------------------------------------------------------------------
// Geometry Shader
//--------------------------------------------------------------------------------------

[maxvertexcount(3)]
void GS( triangle VS_OUTPUT input[3], inout TriangleStream<PS_INPUT> outstream )
{
	PS_INPUT output;

	for(uint v=0; v<3; v++) {
		output.Pos = input[v].Pos;
		output.Tex = input[v].Tex;
		output.Side = input[v].Side;
		output.Up = input[v].Up;
		output.Rt = input[v].Rt;
		outstream.Append( output );
	}
	outstream.RestartStrip();
}


//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float2 FirstPS( PS_INPUT input) : SV_TARGET
{
	float2 depth = (float2)0.0f;
	for(int i=-FILTER_WIDTH; i<=FILTER_WIDTH; i++) {
		float4 pos = posTex.Sample( samPoint, input.Tex + input.Side * dimensions.y  * (float)i ); //HORIZONTAL //TODO OFFSET
		float d =  length( lightWorldPos.xyz - pos.xyz);
		depth.x += d;
		depth.y += d*d;
	}
	depth /= FILTER_WIDTH*2+1;
	return depth;
	//float4 pos = posTex.Sample( samPoint, input.Tex ); //HORIZONTAL //TODO OFFSET
	//return length( lightWorldPos.xyz - pos.xyz) / 10.0f;
}

float2 SecondPS( PS_INPUT input) : SV_TARGET
{
	float2 depth = (float2) 0.0f;
	for(int i=-FILTER_WIDTH; i<=FILTER_WIDTH; i++) {
		float2 s = buffTex.Sample( samPoint, input.Tex + input.Up * dimensions.y * (float)i ); //VERTICAL //TODO OFFSET
		depth+=s;
	}
	depth /= FILTER_WIDTH*2+1;
	return depth;
	//return buffTex.Sample( samPoint, input.Tex );
}