// Box Shot Shader
// 
// Copyright Outerspace Software, all rights reserved

string description = "Use this effect with the picture layer in CUBE mode. The texture must be a strip containing the 6 sides of the box in the following order: front, right, back, left, top and bottom.";

float4x4	WorldViewProjection;
float4x4	World;
float4x4	ViewProjection;

float4		LightPos;
float4		LightPosModelSpace;
float4		EyePosModelSpace;

float4		AmbientCol;
float4		DiffuseCol;
float4		SpecularCol;
float		Power = 100;

//Tweakables
float4		ShadowColour = float4(0.01,0.01,0.01,1);
float		MirrorFadeOut = 30;

struct VS_INPUT{
	float4 position:	POSITION;
	float3 normal:		NORMAL;
	float3 diffuse:		COLOR;
	float2 tex:		TEXCOORD0;
};

struct VS_OUTPUT{
	float4 position:	POSITION;
	float4 diffuse:		COLOR;
	float2 tex:		TEXCOORD0;
};

float2 GetUV(float3 inNormal, float2 inUV){
	
	float2 uv=inUV;
	inNormal = normalize(inNormal);

	//front
	if(inNormal.z<-0.5){
		uv.x = uv.x*=0.1666;
	}
	//right
	if(inNormal.x>0.5){
		uv.x = 0.1666+uv.x*0.1666;
	}
	//back
	if(inNormal.z>0.5){
		uv.x = 0.3333+uv.x*0.1666;
	}
	//left
	if(inNormal.x<-0.5){
		uv.x = 0.5+uv.x*0.1666;
		uv.y = uv.y;
	}
	//top
	if(inNormal.y>0.5){
		uv.x = 0.8333-uv.x*0.1666;
		uv.y = 1-uv.y;
	}
	//bottom
	if(inNormal.y<-0.5){
		uv.x = 0.8333+uv.x*0.1666;
	}
	return uv;
}

float4 GetColour(float4 inPosition, float3 inNormal){
	
	float4 c;

	float3 NormalVector		= normalize(inNormal);
	float3 LightVector		= normalize(LightPosModelSpace - inPosition);
	float3 EyeVector		= normalize(EyePosModelSpace   - inPosition);
	float3 LightReflectionVector	= -reflect(LightVector,NormalVector);
	
	//ambient component
	c = AmbientCol;

	//diffuse component
	c += DiffuseCol * saturate(dot(NormalVector, LightVector));
	
	//specular component	
	c += SpecularCol * pow(saturate(dot(EyeVector, LightReflectionVector)),Power);
	
	c.w = DiffuseCol.w;
	return c;
}

// normal view
VS_OUTPUT VS0(VS_INPUT input){
	VS_OUTPUT output;      
	output.position = mul(input.position, WorldViewProjection);
	output.diffuse = GetColour(input.position, input.normal);
	
	float w=1;
	if(input.normal.x>0.5 && input.position.x<0) w=0;
	if(input.normal.x<-0.5 && input.position.x>0) w=0;
	if(input.normal.y>0.5 && input.position.y<0) w=0;
	if(input.normal.y<-0.5 && input.position.y>0) w=0;
	if(input.normal.z>0.5 && input.position.z<0) w=0;
	if(input.normal.z<-0.5 && input.position.z>0) w=0;

	output.diffuse.w = w * DiffuseCol.w;

	output.tex = GetUV(input.normal, input.tex);
	return output;
}

// mirror view
VS_OUTPUT VS1(VS_INPUT input){
	VS_OUTPUT output;    

	float4 pos=mul(input.position, World);  
	pos.y=-pos.y;

	float w = 1 + pos.y / MirrorFadeOut;
	if(w>1) w=1;
	if(w<0) w=0;

	pos=mul(pos, ViewProjection);	

	output.position = pos;
	output.diffuse = 0.6*GetColour(input.position, input.normal);

	if(input.normal.x>0.5 && input.position.x<0) w=0;
	if(input.normal.x<-0.5 && input.position.x>0) w=0;
	if(input.normal.y>0.5 && input.position.y<0) w=0;
	if(input.normal.y<-0.5 && input.position.y>0) w=0;
	if(input.normal.z>0.5 && input.position.z<0) w=0;
	if(input.normal.z<-0.5 && input.position.z>0) w=0;

	output.diffuse.w = w * DiffuseCol.w;

	output.tex = GetUV(input.normal, input.tex);
	return output;
}

// shadow view
VS_OUTPUT VS2(VS_INPUT input){
	VS_OUTPUT output;    

	float4 pos=mul(input.position, World);  
	
	pos.x -= (LightPos.x - pos.x) * ( pos.y / LightPos.y );
	pos.z -= (LightPos.z - pos.z) * ( pos.y / LightPos.y );	
	pos.y = 0;

	pos=mul(pos, ViewProjection);	

	output.position = pos;
	output.diffuse = ShadowColour;

	output.tex = float2(0,0);
	return output;
}

technique Shader
{
    pass P0
    {
	CullMode = CCW;

//	ALPHAARG1[0]=DIFFUSE;
//	ALPHAOP[0]=SELECTARG1;

	Alphablendenable	= TRUE;
	SRCBLEND		= SRCALPHA;
	DESTBLEND		= INVSRCALPHA;    

        VertexShader = compile vs_1_1 VS0();
        PixelShader  = NULL;
    }
    pass P1
    {
	CullMode = CW;

        VertexShader = compile vs_1_1 VS1();
        PixelShader  = NULL;
    }

    pass P2
    {
	CullMode = NONE;

	COLORARG1[0]=DIFFUSE;
	COLOROP[0]=SELECTARG1;

	Alphablendenable	=TRUE;
	SrcBlend		=ZERO;
	DestBlend		=INVSRCCOLOR;
	CullMode		=NONE;

	ZWriteEnable		=FALSE;

        VertexShader = compile vs_1_1 VS2();
        PixelShader  = NULL;
    }

}
