#include "scattering.h"

float4x4	worldviewproj; 
float4x4	viewproj; 
float4x4	worldMatrix;
float4		lightDir;
float4		camPos;

float4		ambient;
float4		specular;
float		SpecularPower;


texture2D		diffuseTexture;
texture2D		multiplierTexture;
texture2D		additiveTexture;


sampler2D diffuseMap = sampler_state
{
    Texture		= (diffuseTexture);
    AddressU	= WRAP;
    AddressV	= WRAP;       
	MinFilter	= ANISOTROPIC;
	MagFilter	= ANISOTROPIC;
	MipFilter	= ANISOTROPIC;
    MIPMAPLODBIAS	= -2.0f;
    MAXMIPLEVEL		= 0;
    MAXANISOTROPY	= 2.0f;
};

sampler2D multiplierMap = sampler_state
{
    Texture		= (multiplierTexture);
    AddressU	= WRAP;
    AddressV	= WRAP;       
	MinFilter	= LINEAR;
	MagFilter	= LINEAR;
	MipFilter	= NONE;
    MIPMAPLODBIAS	= -1.0f;
    MAXMIPLEVEL		= 0;
    MAXANISOTROPY	= 1;
};

sampler2D additiveMap = sampler_state
{
    Texture		= (additiveTexture);
    AddressU	= WRAP;
    AddressV	= WRAP;       
	MinFilter	= LINEAR;
	MagFilter	= LINEAR;
	MipFilter	= NONE;
    MIPMAPLODBIAS	= -1.0f;
    MAXMIPLEVEL		= 0;
    MAXANISOTROPY	= 1;
};

struct VS_OUT
{
	float4	pos		:	POSITION;
	float3	N		:	TEXCOORD0;	
	float2	uv0		:	TEXCOORD1;
	float2	uv1		:	TEXCOORD2;
	float2	uv2		:	TEXCOORD3;
	float4	vpos	:	TEXCOORD4;
	float	depth	:	TEXCOORD5;
};

VS_OUT VShader(
	float3	pos		:	POSITION	: register(v0),
	float3	N		:	NORMAL		: register(v1),		
	float2	uv0		:	TEXCOORD0	: register(v2),		//<- Diffuse 
	float2	uv1		:	TEXCOORD1	: register(v3),		//<- Multiply
	float2	uv2		:	TEXCOORD2	: register(v4)		//<- Add
	)
{
	VS_OUT Out	= (VS_OUT)0;
	
	Out.pos		= mul(float4(pos, 1), worldviewproj);	
	Out.N = normalize(mul(N, (float3x4)worldMatrix));
	Out.uv0	= uv0;	
	Out.uv1	= uv1;
	Out.uv2	= uv2;	
	Out.vpos = mul(float4(pos, 1), worldMatrix);
	Out.depth = Out.pos.z;
					
    return Out;
}

VS_OUT VShaderInstanced(
	float3	pos		:	POSITION	: register(v0),
	float3	N		:	NORMAL		: register(v1),		
	float2	uv0		:	TEXCOORD0	: register(v2),		//<- Diffuse 
	float2	uv1		:	TEXCOORD1	: register(v3),		//<- Multiply
	float2	uv2		:	TEXCOORD2	: register(v4),		//<- Add
	float4 row1			: TEXCOORD3,
	float4 row2			: TEXCOORD4,
	float4 row3			: TEXCOORD5,
	float4 row4			: TEXCOORD6)
{
	VS_OUT Out	= (VS_OUT)0;
	
	float4x4 mWorld = float4x4(row1, row2, row3, row4);
	Out.vpos = mul(mWorld, float4(pos, 1));
	Out.pos = mul(Out.vpos, viewproj);
	Out.N = normalize(mul((float3x4)mWorld, N));
	Out.uv0	= uv0;
	Out.uv1	= uv1;
	Out.uv2	= uv2;
	Out.depth = Out.pos.z;

    return Out;
}

float4 PShader(
	float3	N		:	TEXCOORD0	: register(v0),
	float2	uv0		:	TEXCOORD1	: register(v1),
	float2	uv1		:	TEXCOORD2	: register(v2),
	float2	uv2		:	TEXCOORD3	: register(v3),
	float4	vpos	:	TEXCOORD4	: register(v4),
	float	depth	:	TEXCOORD5	: register(v5)
	) : COLOR
{	
	float4 color	=   tex2D(diffuseMap,		uv0.xy);
	float4 multiplier =	tex2D(multiplierMap,	uv1.xy);
	float4 additive =	tex2D(additiveMap,		uv2.xy);

	color *= multiplier;
	color += additive;

	float  diff		=	max(0 , dot(N,lightDir.xyz));		
	color.xyz		*= (ambient + diff);
	
	//color = Scattering(vpos.xyz, camPos.xyz, lightDir.xyz, color);

	return color;
}


technique Default
{
    pass Pass0
    {    
		FillMode = SOLID;
		Lighting	= FALSE;
		Clipping	= FALSE;
		CullMode	= NONE;
		
		FogEnable	= FALSE;
		FogColor	= 0x00000000;
		FogDensity	= 1.0f;
		FogEnd		= 10000.0f;
		FogStart	= 50.0f;
				
		//Pixel Pipe Render States
		AlphaBlendEnable	= FALSE;
		AlphaRef			= 0x50;
		AlphaTestEnable		= FALSE;
		AlphaFunc			= GREATER;	
					
		ZEnable				= TRUE;
		ZWriteEnable		= TRUE;
		ZFunc				= LESSEQUAL;

		SrcBlend			= SRCALPHA;
		DestBlend			= INVSRCALPHA;
		
		VertexShader = compile vs_2_0 VShader();
		PixelShader  = compile ps_2_0 PShader();	
    }
}

technique Transparent
{
    pass Pass0
    {    
		FillMode = SOLID;

		Lighting	= FALSE;
		Clipping	= FALSE;
		CullMode	= NONE;

		FogEnable	= FALSE;
		FogColor	= 0x00000000;
		FogDensity	= 1.0f;
		FogEnd		= 10000.0f;
		FogStart	= 50.0f;

		AlphaBlendEnable	= TRUE;
		AlphaRef			= 100;
		AlphaTestEnable		= FALSE;		
		AlphaFunc			= GREATER;

		ZEnable				= TRUE;
		ZWriteEnable		= FALSE;
		ZFunc				= LESSEQUAL;

		SrcBlend			= SRCALPHA;
		DestBlend			= INVSRCALPHA;  

		VertexShader = compile vs_2_0 VShader();
		PixelShader  = compile ps_2_0 PShader();
    }

	pass Pass1
    {    
		FillMode	= SOLID;

		Lighting	= FALSE;
		Clipping	= FALSE;
		CullMode	= NONE;

		FogEnable	= FALSE;
		FogColor	= 0x00000000;
		FogDensity	= 1.0f;
		FogEnd		= 10000.0f;
		FogStart	= 50.0f;

		AlphaBlendEnable	= FALSE;
		AlphaRef			= 200;
		AlphaTestEnable		= TRUE;		
		AlphaFunc			= GREATEREQUAL;	

		ZEnable				= TRUE;
		ZWriteEnable		= TRUE;
		ZFunc				= LESSEQUAL;

		SrcBlend			= SRCALPHA;
		DestBlend			= INVSRCALPHA;  

		VertexShader = compile vs_2_0 VShader();
		PixelShader  = compile ps_2_0 PShader();
    }   
}

technique DefaultInstanced
{
    pass Pass0
    {    
		FillMode = SOLID;
		Lighting	= FALSE;
		Clipping	= FALSE;
		CullMode	= NONE;
		
		FogEnable	= FALSE;
		FogColor	= 0x00000000;
		FogDensity	= 1.0f;
		FogEnd		= 10000.0f;
		FogStart	= 50.0f;
				
		//Pixel Pipe Render States
		AlphaBlendEnable	= FALSE;
		AlphaRef			= 0x50;
		AlphaTestEnable		= FALSE;
		AlphaFunc			= GREATER;	
					
		ZEnable				= TRUE;
		ZWriteEnable		= TRUE;
		ZFunc				= LESSEQUAL;

		SrcBlend			= SRCALPHA;
		DestBlend			= INVSRCALPHA;
		
		VertexShader = compile vs_2_0 VShaderInstanced();
		PixelShader  = compile ps_2_0 PShader();	
    }
}

technique TransparentInstanced
{
    pass Pass0
    {    
		FillMode = SOLID;

		Lighting	= FALSE;
		Clipping	= FALSE;
		CullMode	= NONE;

		FogEnable	= FALSE;
		FogColor	= 0x00000000;
		FogDensity	= 1.0f;
		FogEnd		= 10000.0f;
		FogStart	= 50.0f;

		AlphaBlendEnable	= TRUE;
		AlphaRef			= 100;
		AlphaTestEnable		= FALSE;		
		AlphaFunc			= GREATER;

		ZEnable				= TRUE;
		ZWriteEnable		= FALSE;
		ZFunc				= LESSEQUAL;

		SrcBlend			= SRCALPHA;
		DestBlend			= INVSRCALPHA;  

		VertexShader = compile vs_2_0 VShaderInstanced();
		PixelShader  = compile ps_2_0 PShader();
    }

	pass Pass1
    {    
		FillMode	= SOLID;

		Lighting	= FALSE;
		Clipping	= FALSE;
		CullMode	= NONE;

		FogEnable	= FALSE;
		FogColor	= 0x00000000;
		FogDensity	= 1.0f;
		FogEnd		= 10000.0f;
		FogStart	= 50.0f;

		AlphaBlendEnable	= FALSE;
		AlphaRef			= 200;
		AlphaTestEnable		= TRUE;		
		AlphaFunc			= GREATEREQUAL;	

		ZEnable				= TRUE;
		ZWriteEnable		= TRUE;
		ZFunc				= LESSEQUAL;

		SrcBlend			= SRCALPHA;
		DestBlend			= INVSRCALPHA;  

		VertexShader = compile vs_2_0 VShaderInstanced();
		PixelShader  = compile ps_2_0 PShader();
    }   
}
