
// Expand a range-compressed vector (used with surfaceNormal maps)
float3 expand(float3 v)
{
	return v * 2 - 1;
}
float3 compress(float3 v)
{
	return ( v + 1 ) / 2;
}

float3 decodeNormal(float2 enc)
{
	float2 fenc = enc * 2 - 1;
	float3 n = float3( 0.f, 0.f, -( dot( fenc, fenc ) * 2 - 1 ) );
	n.xy = normalize( fenc ) * sqrt( 1 - n.z * n.z );
	return n;
}

float decodeDepth(float2 enc)
{
	return dot( enc, float2( 1.f, 1.f / 255.f ) );
}

// This program is exactly the same as the specular-only VP.
void deferredPointLight_vp(
                                	in float4 position : POSITION,
			                out float4 oPos    : POSITION,
			                out float4 oDir    : TEXCOORD0,
			                uniform float4x4 worldViewProj,
			                uniform float4x4 worldView,
			                uniform float farDist )
{
   	oPos = mul( worldViewProj, position );
   	oDir = mul( worldView, position );
   	//oDir.w = oDir.z;
   	oDir.xyz *= abs(farDist) / abs(oDir.z);
}

void deferredPointLight_fp(	out float4 color : COLOR0,
				float2 screenPos : SV_POSITION,
				float3 dir : TEXCOORD0,
				//uniform sampler2D depthMap : register(s0),
				//uniform sampler2D normalMap : register(s1),
				//uniform sampler2D diffuseMap : register(s2),
				//uniform sampler2D specularMap : register(s3),
				uniform sampler2D depthAndNormalMap : register(s0),
				uniform sampler2D diffuseMap : register(s1),
				uniform sampler2D specularMap : register(s2),
				
				uniform float4 lightDiffuse,
				uniform float4 lightSpecular,
				uniform float4 lightAttenuation,
				uniform float3 lightPos,
				uniform float4 viewPortSize,
				uniform float4x4 invView)
{
	float2 uv = ( screenPos.xy + 0.5f ) * viewPortSize.zw;
	float4 diffuse = tex2D( diffuseMap, uv );
	//float4 surfaceNormal = tex2D( normalMap, uv );
	float4 depthAndNormal = tex2D( depthAndNormalMap, uv );
	float4 surfaceNormal = float4( depthAndNormal.zw, 0.f, 0.f );
	
	surfaceNormal.xyz = decodeNormal( surfaceNormal.xy );
	float4 specular = tex2D( specularMap, uv );
		
	//float3 pixelPos = dir * tex2D( depthMap, uv ).x;
	float depth = decodeDepth( depthAndNormal.xy );
	float3 pixelPos = dir * depth;
	
	float3 lightVec = lightPos - pixelPos.xyz;
	float3 viewVec = normalize( -dir );
	float lightDistance = length( lightVec );
	float3 normLightVec = lightVec / lightDistance;
	
	float lightFactor = 1 / ( lightAttenuation.x + lightDistance * lightAttenuation.y + ( lightDistance * lightDistance ) * lightAttenuation.z );
	
	float diffusePower = max( 0, dot( normLightVec, surfaceNormal.xyz ) );
	float3 halfAngle = ( viewVec + normLightVec ) / 2;
	
	// Expand specular exponent
	float specExp = specular.w * 256;
	float specularPower = pow( max( 0, dot( halfAngle, surfaceNormal.xyz ) ), specExp );
	
	color.xyz = lightFactor * ( ( lightDiffuse.xyz * diffusePower * diffuse.xyz ) + ( lightSpecular.xyz * specularPower * specular.xyz ) );
	color.w = 1.f;
	//color.xyz = mul( invView, float4( pixelPos,1.f ) ) * 0.1;
	//color.xyz = normLightVec.xyz;
	//color.xyz = lightDistance * 0.1;
}
