//--------------------------------------------------------------------
// Toon Pixel Shading with Wireframe style outline
// Author: Ben Smith
// Date  : November 30th, 2005
//--------------------------------------------------------------------

#include "Effects/StdFunctions.fx"

//--------------------------------------------------------------------
// Global Variables
//--------------------------------------------------------------------
float4x4 World         : WORLD;
float4x4 WorldViewProj : WORLDVIEWPROJ;

//--------------------------------------------------------------------
// Extra Texture
//--------------------------------------------------------------------
texture  texToon : EXTTEXTURE
<
  int TextureID = 29;
>;

//--------------------------------------------------------------------
// Vertex Shader Output Structure
//--------------------------------------------------------------------
struct VS_OUTPUT
{
    float4 position    : POSITION;  //Vertex position on screen
    float2 toonCoords  : TEXCOORD0; //Vertex toon texture coordinates
    float2 texCoords   : TEXCOORD1; //Vertex texture coordinates
    float4 baseColor   : COLOR; //Base color of material
};

//--------------------------------------------------------------------
// Vertex Shader that computes screen position, and texture coordinates.
//--------------------------------------------------------------------
VS_OUTPUT VSRenderScene( float4 worldPos : POSITION,
			 float3 normal : NORMAL0,
			 float2 texCoords: TEXCOORD0 )
{
    VS_OUTPUT Output;
    
    //Vectors
    float3 nNormal = normalize(mul(normal,World));
    
    //Calculate screen position of vertex
    float3 nWNormal = normalize(normal) / 5.0f;
    worldPos.xyz -= nWNormal/7.0f;
    Output.position = mul(worldPos,WorldViewProj);
    
    float  diffuseI = max(0,dot(nNormal,-LightDir));
    
    //Set U,V toon coordinates
    Output.toonCoords.x = min(.99,diffuseI);
    Output.toonCoords.y = 0;
    
    //Set U,V texture coordinates
    Output.texCoords = texCoords;
    
    Output.baseColor = float4(mEmissive,1);
    
    return Output;
}

VS_OUTPUT VSRenderNormal( float4 worldPos : POSITION,
			 float3 normal : NORMAL0,
			 float2 texCoords: TEXCOORD0 )
{
	VS_OUTPUT Output = (VS_OUTPUT)0;
    
	//Calculate screen position of vertex
    Output.position = mul(worldPos,WorldViewProj);
    
    return Output;
}

sampler Toon = sampler_state
{
    Texture = (texToon);
    AddressU = Clamp;
    AddressV = Clamp;
	MinFilter = Anisotropic;
	MagFilter = Anisotropic;
	MipFilter = Linear;
};

sampler Sampler = sampler_state
{
    Texture = (Tex);
	MinFilter = Anisotropic;
	MagFilter = Anisotropic;
	MipFilter = Linear;
};

//--------------------------------------------------------------------
// Pixel Shader Output Structure
//--------------------------------------------------------------------
struct PS_OUTPUT
{
    float4 color : COLOR;     //Pixel's final color
};

//--------------------------------------------------------------------
// Pixel Shader that computes pixel color based on vertex color and
// texture.
//--------------------------------------------------------------------
PS_OUTPUT PSRenderScene( VS_OUTPUT Input, uniform bool hasTexture )
{
    PS_OUTPUT Output;
    if (hasTexture)
		Output.color = tex2D(Toon, Input.toonCoords) * tex2D(Sampler, Input.texCoords) * Input.baseColor;
	else
		Output.color = tex2D(Toon, Input.toonCoords) * Input.baseColor;
	Output.color.a = mAlpha;
    
    return Output;
}

PS_OUTPUT PSRenderBlack( VS_OUTPUT Input )
{
    PS_OUTPUT Output;
    Output.color = float4(0,0,0,mAlpha);
    
    return Output;
}

//--------------------------------------------------------------------------------------
// Medium Requirement Scene Rendering
//-------------------------------------- ------------------------------------------------
technique RenderScene
{
    pass ToonRender
    {
		//Clockwise culling for RHW
		CULLMODE = CW;
		
		ZENABLE = true;
		ZWRITEENABLE = true;

        VertexShader = compile vs_1_1 VSRenderScene();
        PixelShader  = compile ps_2_0 PSRenderScene(true);
    }
    
    pass Outline
    {
		CULLMODE = CCW;
		VertexShader = compile vs_1_1 VSRenderNormal();
        PixelShader  = compile ps_2_0 PSRenderBlack();
    }
}

technique RenderScene_NoTexture
{
    pass ToonRender
    {
		//Clockwise culling for RHW
		CULLMODE = CW;
		
		ZENABLE = true;
		ZWRITEENABLE = true;

        VertexShader = compile vs_1_1 VSRenderScene();
        PixelShader  = compile ps_2_0 PSRenderScene(false);
    }
    
    pass Outline
    {
		CULLMODE = CCW;
		VertexShader = compile vs_1_1 VSRenderNormal();
        PixelShader  = compile ps_2_0 PSRenderBlack();
    }
}








