// parameters ------------------------------------------
float4x4 g_mWorld		: WORLD;
float4x4 g_mView		: VIEW;
float4x4 g_mProjection	: PROJECTION;

float4x4 g_mViewInverse	: VIEWINVERSE;



float3		g_vColor;
texture2D 	g_tDiffuseMap;
texture2D 	g_tOcclusionMap;
textureCUBE	g_tEnvironmentMap;
	
	
// input structs ---------------------------------------
sampler2D g_sOcclusionSampler = 
sampler_state
{
	Texture = <g_tOcclusionMap>;
	MinFilter = anisotropic;
	MagFilter = linear;
	MipFilter = linear;
	AddressU = wrap;
	AddressV = wrap;
};

sampler2D g_sDiffuseSampler = 
sampler_state
{
	Texture = <g_tDiffuseMap>;
	MinFilter = anisotropic;
	MagFilter = linear;
	MipFilter = linear;
	AddressU = wrap;
	AddressV = wrap;
};

samplerCUBE g_sEnvironmentSampler = 
sampler_state
{
	Texture = <g_tEnvironmentMap>;
	MinFilter = anisotropic;
	MagFilter = linear;
	MipFilter = linear;
	AddressU = clamp;
	AddressV = clamp;
};


struct {
	float3 vNormal   : NORMAL0;
} E42_REQUIRE_INPUTSTREAMS;

struct VS_INPUT
{
	float3	vPositionOS	: POSITION0;
	float3	vNormalOS	: NORMAL0;
	float2	vTexcoord0	: TEXCOORD0;
	float2	vTexcoord1	: TEXCOORD1;
};

struct VS_OUTPUT
{
	float4	vPositionPS	: POSITION0;
	float2	vTexcoord0	: TEXCOORD0_centroid;
	float2	vTexcoord1	: TEXCOORD1_centroid;
	float3	vNormalWS	: TEXCOORD2;
	float4	vPositionWS	: TEXCOORD3;
};

// shaders ---------------------------------------------
VS_OUTPUT
vsMain(VS_INPUT i)
{
	// preshader->
	float4x4 mWorldView = mul(g_mWorld, g_mView);
	float4x4 mWorldViewProjection = mul(mWorldView, g_mProjection);
	// <-preshader


	VS_OUTPUT o;
	
	o.vPositionPS = mul(float4(i.vPositionOS, 1), mWorldViewProjection);

	o.vTexcoord0 = i.vTexcoord0;
	o.vTexcoord1 = i.vTexcoord1;

	o.vNormalWS = mul(float4(i.vNormalOS, 0), g_mWorld);
	o.vPositionWS = mul(float4(i.vPositionOS, 1), g_mWorld);

	return o;
}


float 
CalcFresnel(float3 vNormal, float3 vEyeVec)
{
	return pow(dot(vNormal, vEyeVec) + 1, -6);
}


float4
psMain(VS_OUTPUT i) : COLOR0
{
	// preshader->
	float3 vViewerPosWS = g_mViewInverse[3].xyz;
	// <-preshader
	
	float3 vEyeVecWS = normalize(vViewerPosWS - i.vPositionWS);

	float3 vNormalWS = i.vNormalWS;
	
	// fix backfacing normals
	if (dot(vNormalWS, vEyeVecWS) < 0)
	{
		float3 vTmp = cross(vNormalWS, vEyeVecWS);
		vNormalWS = cross(vTmp, vEyeVecWS);
	}
	vNormalWS = normalize(vNormalWS);
	
	float3 vReflectWS = -reflect(vEyeVecWS, vNormalWS);
	

	float fFresnellFactor = CalcFresnel(vNormalWS, vEyeVecWS);
	

	// reflection color
	float3 vReflectionColor = texCUBE(g_sEnvironmentSampler, vReflectWS);

	// surface color
	float3 vColor = g_vColor * tex2D(g_sDiffuseSampler, i.vTexcoord0);

	float3 vRefractionColor = vColor * tex2D(g_sOcclusionSampler, i.vTexcoord1);
	
	float4 o;
	o.rgb = lerp(vRefractionColor, vReflectionColor, fFresnellFactor);
	o.a = 1;
	
	return o;
}


// techniques ------------------------------------------
technique _staticmesh
{
	pass p0
	{
		cullmode = cw;

		VertexShader = compile vs_1_1 vsMain();
		PixelShader = compile ps_2_0 psMain();

		AlphaBlendEnable = false;
		AlphaTestEnable = false;
		
		ZEnable = true;
		ZFunc = less;
		ZWriteEnable = true;
	}
}
// -----------------------------------------------------
