//Effect to render a poygon with texturing but masked to red

matrix matWorldViewProj;	//The World*View*Projection tranformation matrix
matrix matWorld;			//The World tranformation matrix
matrix matView;
matrix matTangentSpace;		//Transforms light vectors from world space to tangent space for normalmapping

texture texDiffuseMap;		//The diffuse colour texture map
texture texNormalMap;		//The normal texture map
texture texToonMap;			//The toon texture map
texture texAttenMap;		//The light attenuation texture map

vector	vtxLight0Pos;
vector	vtxLight0NMCorrectedPos;
vector	vtxLight0Colour;
vector	vtxLight0Atten;

vector	vtxLight1Pos;
vector	vtxLight1NMCorrectedPos;
vector	vtxLight1Colour;
vector	vtxLight1Atten;

vector	vtxLight2Pos;
vector	vtxLight2NMCorrectedPos;
vector	vtxLight2Colour;
vector	vtxLight2Atten;

vector	vtxLight3Pos;
vector	vtxLight3NMCorrectedPos;
vector	vtxLight3Colour;
vector	vtxLight3Atten;

vector	vtxLight4Pos;
vector	vtxLight4NMCorrectedPos;
vector	vtxLight4Colour;
vector	vtxLight4Atten;

vector	vtxLight5Pos;
vector	vtxLight5NMCorrectedPos;
vector	vtxLight5Colour;
vector	vtxLight5Atten;

vector vtxGlobalLightColour;

VertexShader VS11ForPS14 = 
	decl
	{
		stream 0;
		float v0[3];	//Vertex Position
		d3dcolor v1[1]; //Vertex Colour
		float v2[2];	//Vertex UV1 for diffuse map
		float v3[2];	//Vertex UV2 for normal map
	}
	asm
	{
		vs.1.1							//Version 1.1 Vertex Shader
		m4x4	oPos, v0, c0			//Transform vertex to projection space and place in position register
		mov		oD0, v1					//Move vertex colour into colour register
		mov		oT0.xy, v2				//Move texture UV1 into output texture register
		mov		oT1.xy, v3				//Move texture UV2 into output texture register
		
		//Calculate vertex position in world space, place into r4
		mov		r4, v0
		m4x4	r4, v0, c4				//Vertex position transformed to world space
		
		//Form per vertex light attenuation space info for the first light
		sub		r0.xyz, r4, c12			//Form light vector to vertex in object space
		mul		r1.xy, r0.xy, c13.xx	//multiply screen space light vector by light attenuation
		add		r1.xy, r1.xy, c16.yy	//add 0.5 to bring range to 0..1 from -0.5..0.5
		max		r1.xy, r1.xy, c16.ww	//clamp to ensure in 0..1 range
		min		oT2.xy, r1.xy, c16.xx	//clamp to ensure in 0..1 range
		
		//Form per vertex tangent space lighting info for the first light 
		//normalize light vector and place in output texture register oT3
		sub		r0.xyz, c12, r4			//Form light vector from vertex in object space
		dp3		r1.x, r0.xyz, r0.xyz	//length for normalize
		rsq		r1.w, r1.x				// 1/sqrt(length) for normalize
		mul		r0.xyz, r0.xyz, r1.w	// mul for normalize
		m3x3	r0, r0, c8				//tangent space transform for light vector
		mul		r0.xyz, r0.xyz, c16.yyy	//bias   *0.5
		add		oT3.xyz, r0.xyz, c16.yyy//bias   +0.5
		
		//Form per vertex light attenuation space info for the second light
		sub		r0.xyz, r4, c14			//Form light vector to vertex in object space
		mul		r1.xy, r0.xy, c15.xx	//multiply screen space light vector by light attenuation
		add		r1.xy, r1.xy, c16.yy	//add 0.5 to bring range to 0..1 from -0.5..0.5
		max		r1.xy, r1.xy, c16.ww	//clamp to ensure in 0..1 range
		min		oT4.xy, r1.xy, c16.xx	//clamp to ensure in 0..1 range
		
		//Form per vertex tangent space lighting info for the second light 
		//normalize light vector and place in output texture register oT3
		sub		r0.xyz, c14, r4			//Form light vector to vertex in object space
		dp3		r1.x, r0.xyz, r0.xyz	//length for normalize
		rsq		r1.w, r1.x				// 1/sqrt(length) for normalize
		mul		r0.xyz, r0.xyz, r1.w	// mul for normalize
		m3x3	r0, r0, c8				//tangent space transform for light vector
		mul		r0.xyz, r0.xyz, c16.yyy	//bias   *0.5
		add		oT5.xyz, r0.xyz, c16.yyy//bias   +0.5
	};
	
PixelShader PS14_GL =
	asm
	{
	//form normal mapped lighting information for two lights in one pass
		ps.1.4					//Version 1.4 Pixel Shader
		texld r1, t1			//load normal map texture into r1
		texld r2, t2			//load atten for first light into r2
		texld r3, t4			//load atten for second light into r3
		texcrd r4.xyz, t3		//load light vector for first light into r4
		texcrd r5.xyz, t5		//load light vector for second light into r5
		
		dp3_sat r4, r1_bx2, r4_bx2	//Calculate the dotprod of the normal and light vector for the first light and store in r4
		dp3_sat r5, r1_bx2, r5_bx2	//Calculate the dotprod of the normal and light vector for the second light and store in r5

		mov r1.x, r1.a			//move mask for first light into r1.x for use in the next phase
		mul r2, r2, c1			//compute atten*light for first light and place in r2
		mul r3, r3, c2			//compute atten*light for second light and place in r3
		
		phase					//Shift to phase 2, erases alpha channels in all r[N] temporary registers
		texld r0, t0			//load diffuse map texture into r0
		texld r4, r4			//load toon texture at dotprod location for first light
		texld r5, r5			//load toon texture at dotprod location for second light
		
		mad r2.xyz, r2, r4, c3	//compute (atten*light)*toon(dotprod) for first light + global_light
		mad r2.xyz, r3, r5, r2	//compute (atten*light)*toon(dotprod) for second light + (first light + global_light)
		
		mul r1, r1.xxxx, r0		//compute mask*diffuse
		
		mul r2.xyz, r1, r2 		//compute (mask*diffuse)*((atten*light)*toon(dotprod) for first and second light + global_light)
		+mov r2.w, r1.w
		mul r0, r2, v0.wwww		// * modulate
	};
	
PixelShader PS14 =
	asm
	{
	//form normal mapped lighting information for two lights in one pass
		ps.1.4					//Version 1.4 Pixel Shader
		texld r1, t1			//load normal map texture into r1
		texld r2, t2			//load atten for first light into r2
		texld r3, t4			//load atten for second light into r3
		texcrd r4.xyz, t3		//load light vector for first light into r4
		texcrd r5.xyz, t5		//load light vector for second light into r5
		
		dp3_sat r4, r1_bx2, r4_bx2	//Calculate the dotprod of the normal and light vector for the first light and store in r4
		dp3_sat r5, r1_bx2, r5_bx2	//Calculate the dotprod of the normal and light vector for the second light and store in r5

		mov r1.x, r1.a			//move mask for first light into r1.x for use in the next phase
		mul r2, r2, c1			//compute atten*light for first light and place in r2
		mul r3, r3, c2			//compute atten*light for second light and place in r3
		
		phase					//Shift to phase 2, erases alpha channels in all r[N] temporary registers
		texld r0, t0			//load diffuse map texture into r0
		texld r4, r4			//load toon texture at dotprod location for first light
		texld r5, r5			//load toon texture at dotprod location for second light
		
		mul r2.xyz, r2, r4		//compute (atten*light)*toon(dotprod) for first light
		mad r2.xyz, r3, r5, r2	//compute (atten*light)*toon(dotprod) for second light + first light
		
		mul r1, r1.xxxx, r0		//compute mask*diffuse
		
		mul r2.xyz, r1, r2 		//compute (mask*diffuse)*((atten*light)*toon(dotprod) for first and second light + global_light)
		+mov r2.w, r1.w
		mul r0, r2, v0.wwww		// * modulate
	};
	
VertexShader VS11ForPS13 =
	decl
	{
		stream 0;
		float v0[3];	//Vertex Position
		d3dcolor v1[1]; //Vertex Colour
		float v2[2];	//Vertex UV1 for diffuse map
		float v3[2];	//Vertex UV2 for normal map
	}
	asm
	{
		vs.1.1							//Version 1.1 Vertex Shader
		m4x4	oPos, v0, c0			//Transform vertex to projection space and place in position register
		mov		oD0, v1					//Move vertex colour into colour register
		mov		oT0.xy, v2				//Move texture UV1 into output texture register
		mov		oT1.xy, v3				//Move texture UV2 into output texture register
		
		//Calculate vertex position in world space, place into r4
		mov		r4, v0
		m4x4	r4, v0, c14				//Vertex position transformed to world space
		
		//Form per vertex light attenuation space info for the first light
		sub		r0.xyz, r4, c4			//Form light vector to vertex in object space
		mul		r1.xy, r0.xy, c6.xx		//multiply screen space light vector by light attenuation
		add		r1.xy, r1.xy, c7.yy		//add 0.5 to bring range to 0..1 from -0.5..0.5
		max		r1.xy, r1.xy, c7.ww		//clamp to ensure in 0..1 range
		min		oT2.xy, r1.xy, c7.xx
		
		//Form per vertex tangent space lighting info for the first light 
		//normalize light vector and place in output texture register oT3
		sub		r0.xyz, c4, r4			//Form light vector
		
		dp3		r1.x, r0.xyz, r0.xyz	//length for normalize
		rsq		r1.w, r1.x				//sqrt for normalize
		mul		r0.xyz, r0.xyz, r1.w	//mul for normalize
		
		m3x3	r0, r0, c8				//tangent space transform for light vector
		
		mul		r0.xyz, r0.xyz, c7.yyy		//bias
		add		r0.xyz, r0.xyz, c7.yyy
		
		mov oT3, r0
		
	};
	
PixelShader PS13_GL = 
	asm
	{
		ps.1.3
		tex t0							//load diffuse map texture
		tex t1							//load normal map texture
		tex t2							//Load Attenuation factor
		texcoord t3						//Load Lightdirection
		
		dp3_d2_sat r0.xyz, t1_bx2, t3_bx2	//Compute NdL and place in r0 (NdL = Normal dot Light) per component div 2 and saturate
		add_sat r0.xyz, r0, c0.w		//add 0.5 per component to r0 and saturate
		mul r0.xyz, r0, c1				//Compute LightColour * NdL
		
		mad r1.xyz, t2, r0, c2			//Compute Atten * (LightColour * NdL) + global_light and place in r1
		mul r0, t1.w, t0				//Compute Mask * Diffuse and place in r0
		mul r1.xyz, r0, r1				//Compute (Mask * Diffuse) * (Atten * LightColour * NdL + global_light) and place in r1
		+mov r1.w, r0.w
		
		mul r0, r1, v0.wwww				//modulate output colour by vertex colour
	};
	
PixelShader PS13 = 
	asm
	{
		ps.1.3
		tex t0							//load diffuse map texture
		tex t1							//load normal map texture
		tex t2							//Load Attenuation factor
		texcoord t3						//Load Lightdirection
		
		dp3_d2_sat r0.xyz, t1_bx2, t3_bx2	//Compute NdL and place in r0 (NdL = Normal dot Light) per component div 2 and saturate
		add_sat r0.xyz, r0, c0.w		//add 0.5 per component to r0 and saturate
		mul r0.xyz, r0, c1				//Compute LightColour * NdL
		
		mul r1.xyz, t2, r0				//Compute Atten * (LightColour * NdL) and place in r1
		mul r0, t1.w, t0				//Compute Mask * Diffuse and place in r0
		mul r1.xyz, r0, r1				//Compute (Mask * Diffuse) * (Atten * LightColour * NdL + global_light) and place in r1
		+mov r1.w, r0.w
		
		mul r0, r1, v0.wwww				//modulate output colour by vertex colour
	};

//First technique is for PS14 has full lighting
technique VS1_1__PS_1_4
{
	pass Light0_GlobalLight
	{
		//Load matrices
		VertexShaderConstant[0] = <matWorldViewProj>;			//World*View*Projection transformation
		VertexShaderConstant[4] = <matWorld>;
		VertexShaderConstant[8] = <matTangentSpace>;			//Tangent space transform for light vector
		//Load vectors
		VertexShaderConstant[12] = <vtxLight0Pos>;				//Light 0's position in object space
		VertexShaderConstant[13] = <vtxLight0Atten>;			//Light 0's attenuation parameters
		VertexShaderConstant[14] = <vtxLight1Pos>;				//Light 1's position in object space
		VertexShaderConstant[15] = <vtxLight1Atten>;			//Light 1's attenuation parameters
		//Load constants
		VertexShaderConstant[16] = (1, 0.5, 0.25, 0);			//Constants
		
		
		PixelShaderConstant[0] = (1, 0.5, 0.25, 0);				//Constants
		PixelShaderConstant[1] = <vtxLight0Colour>;				//Light 0's colour
		PixelShaderConstant[2] = <vtxLight1Colour>;				//Light 1's colour
		PixelShaderConstant[3] = <vtxGlobalLightColour>;		//Global light colour
		
		// textures
		//Diffuse Map
		Texture[0] = <texDiffuseMap>;
		MipFilter[0] = LINEAR;
		MinFilter[0] = LINEAR;
		MagFilter[0] = LINEAR;
		AddressU[0] = CLAMP;
		AddressV[0] = CLAMP;
		//Normal map
		Texture[1] = <texNormalMap>;
		MipFilter[1] = LINEAR;
		MinFilter[1] = LINEAR;
		MagFilter[1] = LINEAR;
		AddressU[1] = CLAMP;
		AddressV[1] = CLAMP;
		//Light Attenuation map for first light
		Texture[2] = <texAttenMap>;
		MipFilter[2] = LINEAR;
		MinFilter[2] = LINEAR;
		MagFilter[2] = LINEAR;
		AddressU[2] = CLAMP;
		AddressV[2] = CLAMP;
		//Light Attenuation map for second light
		Texture[3] = <texAttenMap>;
		MipFilter[3] = LINEAR;
		MinFilter[3] = LINEAR;
		MagFilter[3] = LINEAR;
		AddressU[3] = CLAMP;
		AddressV[3] = CLAMP;
		//Toon map for first light
		Texture[4] = <texToonMap>;
		MipFilter[4] = LINEAR;
		MinFilter[4] = LINEAR;
		MagFilter[4] = LINEAR;
		AddressU[4] = CLAMP;
		AddressV[4] = CLAMP;
		//Toon map for second light
		Texture[5] = <texToonMap>;
		MipFilter[5] = NONE;
		MinFilter[5] = POINT;
		MagFilter[5] = POINT;
		AddressU[5] = CLAMP;
		AddressV[5] = CLAMP;
		
		//DestBlend	= ZERO;
		
		VertexShader = <VS11ForPS14>;
		PixelShader = <PS14_GL>;
	}
	pass Light1
	{
		//Load matrices
		//Load matrices
		VertexShaderConstant[0] = <matWorldViewProj>;			//World*View*Projection transformation
		VertexShaderConstant[4] = <matWorld>;
		VertexShaderConstant[8] = <matTangentSpace>;			//Tangent space transform for light vector
		//Load vectors
		VertexShaderConstant[12] = <vtxLight2Pos>;				//Light 0's position in object space
		VertexShaderConstant[13] = <vtxLight2Atten>;			//Light 0's attenuation parameters
		VertexShaderConstant[14] = <vtxLight3Pos>;				//Light 1's position in object space
		VertexShaderConstant[15] = <vtxLight3Atten>;			//Light 1's attenuation parameters
		//Load constants
		VertexShaderConstant[16] = (1, 0.5, 0.25, 0);			//Constants
		
		
		PixelShaderConstant[0] = (1, 0.5, 0.25, 0);				//Constants
		PixelShaderConstant[1] = <vtxLight2Colour>;				//Light 0's colour
		PixelShaderConstant[2] = <vtxLight3Colour>;				//Light 1's colour
		
		//BlendOp          = ADD;
        SrcBlend         = ONE;
        DestBlend        = ONE;
		
		VertexShader = <VS11ForPS14>;
		PixelShader = <PS14>;
	}
	pass Light2
	{
		//Load matrices
		VertexShaderConstant[0] = <matWorldViewProj>;			//World*View*Projection transformation
		VertexShaderConstant[4] = <matWorld>;
		VertexShaderConstant[8] = <matTangentSpace>;			//Tangent space transform for light vector
		//Load vectors
		VertexShaderConstant[12] = <vtxLight4Pos>;				//Light 0's position in object space
		VertexShaderConstant[13] = <vtxLight4Atten>;			//Light 0's attenuation parameters
		VertexShaderConstant[14] = <vtxLight5Pos>;				//Light 1's position in object space
		VertexShaderConstant[15] = <vtxLight5Atten>;			//Light 1's attenuation parameters
		//Load constants
		VertexShaderConstant[16] = (1, 0.5, 0.25, 0);			//Constants
		
		
		PixelShaderConstant[0] = (1, 0.5, 0.25, 0);				//Constants
		PixelShaderConstant[1] = <vtxLight4Colour>;				//Light 0's colour
		PixelShaderConstant[2] = <vtxLight5Colour>;				//Light 1's colour
		
		VertexShader = <VS11ForPS14>;
		PixelShader = <PS14>;
	}
}

//Second technique is for PS1.3, has limited lighting
technique VS1_0_PS_1_3
{
	pass P1
	{
		//Load matrices
		VertexShaderConstant[0] = <matWorldViewProj>;			//World*View*Projection transformation
		VertexShaderConstant[4] = <vtxLight0Pos>;				//Light 0's position in object space
		VertexShaderConstant[6] = <vtxLight0Atten>;				//Light 0's attenuation parameters
		VertexShaderConstant[7] = (1, 0.5, 0.25, 0);			//Constants
		VertexShaderConstant[8] = <matTangentSpace>;			//Tangent space transform for light vector
		VertexShaderConstant[13] = (1,1,1,1);
		VertexShaderConstant[14] = <matWorld>;
		
		PixelShaderConstant[0] = (1, 0, 0.25, 0.5);				//Constants
		PixelShaderConstant[1] = <vtxLight0Colour>;				//Light 0's colour
		PixelShaderConstant[2] = <vtxGlobalLightColour>;		//Global Light colour

		
		// textures
		//Diffuse Map
		Texture[0] = <texDiffuseMap>;
		MipFilter[0] = LINEAR;
		MinFilter[0] = LINEAR;
		MagFilter[0] = LINEAR;
		AddressU[0] = CLAMP;
		AddressV[0] = CLAMP;
		//Normal map
		Texture[1] = <texNormalMap>;
		MipFilter[1] = LINEAR;
		MinFilter[1] = LINEAR;
		MagFilter[1] = LINEAR;
		AddressU[1] = CLAMP;
		AddressV[1] = CLAMP;
		//Light Attenuation map for first light
		Texture[2] = <texAttenMap>;
		MipFilter[2] = LINEAR;
		MinFilter[2] = LINEAR;
		MagFilter[2] = LINEAR;
		AddressU[2] = CLAMP;
		AddressV[2] = CLAMP;
		
		VertexShader = <VS11ForPS13>;
		PixelShader = <PS13_GL>;
	}
	
	pass P2
	{
		VertexShaderConstant[0] = <matWorldViewProj>;			//World*View*Projection transformation
		VertexShaderConstant[4] = <vtxLight1Pos>;				//Light 1's position in object space
		VertexShaderConstant[5] = <vtxLight1NMCorrectedPos>;	//Light 1's position corrected for NM
		VertexShaderConstant[6] = <vtxLight1Atten>;				//Light 1's attenuation parameters
		VertexShaderConstant[7] = (1, 0.5, 0.25, 0);			//Constants
		
		PixelShaderConstant[0] = (1, 0, 0.25, 0.5);				//Constants
		PixelShaderConstant[1] = <vtxLight1Colour>;				//Light 1's colour
		
		//BlendOp          = ADD;
        SrcBlend         = ONE;
        DestBlend        = ONE;
		
		VertexShader = <VS11ForPS13>;
		PixelShader = <PS13>;
	}
	
	pass P3
	{
		VertexShaderConstant[0] = <matWorldViewProj>;			//World*View*Projection transformation
		VertexShaderConstant[4] = <vtxLight2Pos>;				//Light 2's position in object space
		VertexShaderConstant[5] = <vtxLight2NMCorrectedPos>;	//Light 2's position corrected for NM
		VertexShaderConstant[6] = <vtxLight2Atten>;				//Light 2's attenuation parameters
		VertexShaderConstant[7] = (1, 0.5, 0.25, 0);			//Constants
		
		PixelShaderConstant[0] = (1, 0, 0.25, 0.5);				//Constants
		PixelShaderConstant[1] = <vtxLight2Colour>;				//Light 2's colour
		
		VertexShader = <VS11ForPS13>;
		PixelShader = <PS13>;
	}
	
	pass P4
	{
		VertexShaderConstant[0] = <matWorldViewProj>;			//World*View*Projection transformation
		VertexShaderConstant[4] = <vtxLight3Pos>;				//Light 3's position in object space
		VertexShaderConstant[5] = <vtxLight3NMCorrectedPos>;	//Light 3's position corrected for NM
		VertexShaderConstant[6] = <vtxLight3Atten>;				//Light 3's attenuation parameters
		VertexShaderConstant[7] = (1, 0.5, 0.25, 0);			//Constants
		
		PixelShaderConstant[0] = (1, 0, 0.25, 0.5);				//Constants
		PixelShaderConstant[1] = <vtxLight3Colour>;				//Light 3's colour
		
		VertexShader = <VS11ForPS13>;
		PixelShader = <PS13>;
	}
	
	pass P5
	{
		VertexShaderConstant[0] = <matWorldViewProj>;			//World*View*Projection transformation
		VertexShaderConstant[4] = <vtxLight4Pos>;				//Light 4's position in object space
		VertexShaderConstant[5] = <vtxLight4NMCorrectedPos>;	//Light 4's position corrected for NM
		VertexShaderConstant[6] = <vtxLight4Atten>;				//Light 4's attenuation parameters
		VertexShaderConstant[7] = (1, 0.5, 0.25, 0);			//Constants
		
		PixelShaderConstant[0] = (1, 0, 0.25, 0.5);				//Constants
		PixelShaderConstant[1] = <vtxLight4Colour>;				//Light 4's colour
		
		VertexShader = <VS11ForPS13>;
		PixelShader = <PS13>;
	}
	
	pass P6
	{
		VertexShaderConstant[0] = <matWorldViewProj>;			//World*View*Projection transformation
		VertexShaderConstant[4] = <vtxLight5Pos>;				//Light 5's position in object space
		VertexShaderConstant[5] = <vtxLight5NMCorrectedPos>;	//Light 5's position corrected for NM
		VertexShaderConstant[6] = <vtxLight5Atten>;				//Light 5's attenuation parameters
		VertexShaderConstant[7] = (1, 0.5, 0.25, 0);			//Constants
		
		PixelShaderConstant[0] = (1, 0, 0.25, 0.5);				//Constants
		PixelShaderConstant[1] = <vtxLight5Colour>;				//Light 5's colour
		
		VertexShader = <VS11ForPS13>;
		PixelShader = <PS13>;
	}
}

//Last technique is for no pixel shader support, and ergo, no lighting
technique TNoShader
{
    pass P0
    {
        LightEnable[0] = FALSE;
        Lighting       = FALSE;
        SpecularEnable = FALSE;
        
        PixelShader = NULL;
        VertexShader = XYZ | Diffuse | Tex2;
        
        // textures
        Texture[0] = <texDiffuseMap>;
        MipFilter[0] = LINEAR;
		MinFilter[0] = LINEAR;
		MagFilter[0] = LINEAR;
		AddressU[0] = CLAMP;
		AddressV[0] = CLAMP;
        
        // texture stages
        ColorOp[0]   = MODULATE;
        ColorArg1[0] = TEXTURE;
        ColorArg2[0] = DIFFUSE;
        AlphaOp[0]   = MODULATE;
        AlphaArg1[0] = TEXTURE;
        AlphaArg2[0] = DIFFUSE;

        ColorOp[1]   = DISABLE;
        AlphaOp[1]   = DISABLE;
    }
}