////////////////////////////////////////////////////////////////////////////////////////////////////
// skydome.fx
////////////////////////////////////////////////////////////////////////////////////////////////////



// Transforms
////////////////////////////////////////////////////////////////////////////////////////////////////
float4x4 matWorldViewProj;
float4x4 matWorldView;
vector sunDir;
vector SUN_COLOR; // [r, g, b, intensity]
vector BETA_DASH_1;
vector BETA_DASH_2;
vector BETA_1_PLUS_2;
vector ONE_OVER_BETA_1_PLUS_2;
vector HG; // [1-g^2, 1+g, 2g]


// Vertex shaders
////////////////////////////////////////////////////////////////////////////////////////////////////
void vs(
		in float3 iPos : POSITION0,
		
		out float4 oPos	: POSITION,
		out float3 oCol	: COLOR0 )                                               
{
	// calc view direction
	vector viewDir = {normalize(iPos), 1};

	// calc theta - scattering angle between sun direction and view direction
	float cT = dot(viewDir, sunDir);
	float p1T = 1 + (cT * cT); // Phase1(theta)

	// calc distance s
	vector pos = mul(iPos.xyz, matWorldView);
	float s = pos.z;

	// calc extinction E1
	float3 E1 = exp(BETA_1_PLUS_2.xyz * (-s));

	// total extinction E - not used in sky
//	float3 TERRAIN_REFLECTANCE = float3(0.138f, 0.113f, 0.08f); // Taken from soil's reflectance spectrum data.
//	float3 E = E1 * (0.1f * TERRAIN_REFLECTANCE);

	// Phase2(theta) = (1-g^2)/(1+g-2g*cos(theta))^(3/2)
	// theta is 180 - actual theta (this corrects for sign)
	// HG = [1-g^2, 1+g, 2g]
	float p2T = HG.x * pow(rsqrt(HG.y + (HG.z * cT)), 3); // Phase2(theta)

	// Inscattering I = (Beta'_1 * Phase_1(theta) + Beta'_2 * Phase_2(theta)) * 
	//        [1-exp(-Beta_1*s).exp(-Beta_2*s)] / (Beta_1 + Beta_2)
	float3 I = ((BETA_DASH_1.xyz * p1T) + (BETA_DASH_2.xyz * p2T)) * (1.0f - E1) * ONE_OVER_BETA_1_PLUS_2.xyz;

	// Scale with Sun color & intensity
	I = I * SUN_COLOR.xyz * SUN_COLOR.w;

	// output the inscattering
	oCol.rgb = I.rgb;

	// transform and project pos
	//oPos = mul(iPos, matWorldViewProj);
	oPos = mul( float4( iPos.xyz, 1.0 ), matWorldViewProj );
	oPos.z = oPos.w;
}



// Pixel shaders
////////////////////////////////////////////////////////////////////////////////////////////////////
float4 ps( in float3 iCol : COLOR0 ) : COLOR
{
		return float4( iCol.rgb, 1.0 );
}



// Techniques
////////////////////////////////////////////////////////////////////////////////////////////////////
technique main
{
   pass p0
   {
		AlphaBlendEnable = false;
        VertexShader = compile vs_3_0 vs();
        PixelShader = compile ps_3_0 ps();
   }
}
