
// You may modify this to move more data from the vertex shader to the pixel shader.
// It needs at least the position to work.
struct VS_to_PS {
	float4 Pos : SV_POSITION;
	float4 Color : COLOR;
	float4 Pos_WorldSpace : TEXCOORD1;
	float4 Pos_CameraSpace : TEXCOORD2;
	float3 Normal_WorldSpace : TEXCOORD3;
};

//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
VS_to_PS VS( VS_structure input ) {
	VS_to_PS output = (VS_to_PS)0;
	
	// Convert vertice positions from object space to world space
	output.Pos_WorldSpace = mul( input.Pos, ObjectToWorld );
	// Convert vertice positions from world space to camera space
	output.Pos_CameraSpace = mul( output.Pos_WorldSpace, WorldToCamera );
	// Convert vertice positions from camera space to 2D projection
	output.Pos = mul( output.Pos_CameraSpace, CameraToImage );
	
	// Give the vertex color multiplied with the instance color to the pixel shader
	output.Color = lerp(input.Color * InstanceColor, float4(0.0f,0.0f,1.0f,1.0f), input.Selected);
	
	// Transform normals to camera space
	output.Normal_WorldSpace = mul(input.Normal,(float3x3)ObjectToWorld);
	
	return output;
}

#define ObjectXAxis float3(ObjectToWorld._11,ObjectToWorld._12,ObjectToWorld._13)
#define ObjectYAxis float3(ObjectToWorld._21,ObjectToWorld._22,ObjectToWorld._23)
#define ObjectZAxis float3(ObjectToWorld._31,ObjectToWorld._32,ObjectToWorld._33)
#define ObjectOrigin float3(ObjectToWorld._41,ObjectToWorld._42,ObjectToWorld._43)

//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( VS_to_PS input) : SV_Target {
	// If the camera has a world space cutting plane, clip on the negative side.
	UseCuttingPlane(input.Pos_WorldSpace)
	
	// Get the vertex color
	float4 Color = input.Color;
	
	float3 CameraToPixel = input.Pos_WorldSpace.xyz - CameraPos_WorldSpace;
	float3 CameraDir = normalize(CameraToPixel);
	float CenterLength = 1.0f / length(float2(dot(normalize(ObjectXAxis),CameraDir),dot(normalize(ObjectYAxis),CameraDir)));
	float3 NormalizedZAxis = normalize(ObjectZAxis);
	float3 ProjectedCameraDir = normalize(CameraDir - (NormalizedZAxis * dot(CameraDir,NormalizedZAxis)));
	float SideIntensity = abs(dot(normalize(input.Normal_WorldSpace),ProjectedCameraDir));
	float Intensity = CenterLength * SideIntensity;
	
	// Fade alpha based on intensity
	Color.a = saturate(Color.a * Intensity);
	
	// Show the final color with fog on R,G,B channels
	return float4((lerp(Color,FogColor,saturate(length(input.Pos_CameraSpace) / FogDistance) * MaxFogIntensity)).xyz,Color.a);
}
