//-----------------------------------------------------------------------------
// ChestWood.sha
// 
// Basic diffuse shader used on chest and keep and all the fallbacks.
//-----------------------------------------------------------------------------

matrix  mWVP;
matrix  mW;
vector  pWL;
vector  pOL;
vector  cLgt;
vector  cnst;

texture tBase;       // Base texture
texture tNormal;     // Normal Map
texture tNormalizer; // Cubic Normalizer map

DWord cAmbient = 0x40404040;

//--------------------------------------------------------------
// PS1.0 - 1.1 Section
//--------------------------------------------------------------
vertexshader vBaseNormLightDiff = 
	decl
	{
		stream 0;
		float    v0[3];  // Position
		D3DCOLOR v3;     // Normal
		float    v7[2];  // Tex coord 0
		D3DCOLOR v8;     // Binormal
		D3DCOLOR v9;     // Tangent
	}
	asm
	{
        ; Constants:
        ; 16..19 - Composite World-View-Projection Matrix
        ; 24..27 - World Matrix
        ; 31     - World Space Light Position
        ; 32     - Object Space Light Position
        ; 33     - {1/light range, light range, 1/attenuation2, attenuation2}
        ; 94     - ambient color
        ; 95     - {0.0, 0.5, 1.0, 2.0}

		vs.1.0
		
		m4x4 oPos, v0, c16
	    mov  oT0.xy, v7.xy   ; Base Texture
		mov  oT1.xy, v7.xy   ; Normal Map

		;r9 = tangent U vector = normal cross tangent V vector
        mad  r3, v3, c95.wwwz, -c95.zzzx ; Normal = (v3*2.0)-1.0
        mad  r9, v8, c95.wwwz, -c95.zzzx ; TangentU = (v8*2.0)-1.0
        mad  r8, v9, c95.wwwz, -c95.zzzx ; TangentV = (v9*2.0)-1.0

		;r5 = tangent space light vector 
		sub  r1, c32, v0     ; Object space light direction
		dp3  r5.x, r9, r1
		dp3  r5.y, r8, r1
		dp3  r5.z, r3, r1
		mov  oT2.xyz, r5.xyz ; Tangent Space Light vector

        ; attenuation = (1/attenuation2)/D^2
		m4x4 r0, v0, c24             ; World Space Position
		sub  r1, r0, c31             ; World Space Light direction
		dp3  r11.x, r1, r1           ; Distance^2
		rcp  r2.x, r11.x             ; recip = 1/D^2
        mul  r2.y, r2.x, c33.z       ; *= 1/attenuation2
		mul  oD0, r2.y, c95.y
	};

pixelshader ps10_Dot3_Diff = asm
{
    ps.1.0
    tex t0
    tex t1
    tex t2
    mov     r0.a, v0
    mov     r0.rgb, t2_bx2
    dp3_sat r0.rgb, t1_bx2, r0
    mul_x2  r0.rgb, r0, v0
    add     r0.rgb, r0, c7
    mul     r0.rgb, r0, t0
};

String ps10_Dot3_Diffuse_desc = "PS 1.0 - Diffuse Bump Mapping";

technique ps10_Dot3_Diffuse  // Dot3 diffuse bump mapping
{
    pass P0
    {
        VertexShaderConstant[16] = <mWVP>;
        VertexShaderConstant[24] = <mW>;
        VertexShaderConstant[31] = <pWL>;
        VertexShaderConstant[32] = <pOL>;
        VertexShaderConstant[33] = <cLgt>;
        VertexShaderConstant[95] = <cnst>;

        vertexshader = <vBaseNormLightDiff>;	

        // Texture 0
	    Texture[0]       = <tBase>;
	    AddressU[0]      = Wrap;
	    AddressV[0]      = Wrap;
	    MinFilter[0]     = Linear;
	    MagFilter[0]     = Linear;
	    MipFilter[0]     = Linear;

        // Texture 1
        Texture[1]       = <tNormal>;
        AddressU[1]      = Wrap;
        AddressV[1]      = Wrap;
        MinFilter[1]     = Linear;
        MagFilter[1]     = Linear;
        MipFilter[1]     = Linear;

        // Texture 2
	    Texture[2]   = <tNormalizer>;
	    AddressU[2]  = Clamp;
	    AddressV[2]  = Clamp;
	    MinFilter[2] = Linear;
	    MagFilter[2] = Linear;
	    MipFilter[2] = Point;

        PixelShaderConstant[7] = <cAmbient>;
        PixelShader = <ps10_Dot3_Diff>;
    }
}

//--------------------------------------------------------------
// Specular
//--------------------------------------------------------------
vertexshader vBaseNormLightViewDiff = 
	decl
	{
		stream 0;
		float    v0[3];  // Position
		D3DCOLOR v3;     // Normal
		float    v7[2];  // Tex coord 0
		D3DCOLOR v8;     // Binormal
		D3DCOLOR v9;     // Tangent
	}
	asm
	{
        ; Constants:
        ; 16..19 - Composite World-View-Projection Matrix
        ; 24..27 - World Matrix
        ; 31     - World Space Light Position
        ; 32     - Object Space Light Position
        ; 33     - {1/light range, light range, 1/attenuation2, attenuation2}
        ; 34     - Object Space Viewer Position
        ; 95     - {0.0, 0.5, 1.0, 2.0}

		vs.1.0
		
		m4x4 oPos, v0, c16
	    mov  oT0.xy, v7.xy   ; Base Texture
		mov  oT1.xy, v7.xy   ; Normal Map

		;r9 = tangent U vector = normal cross tangent V vector
        mad  r3, v3, c95.wwwz, -c95.zzzx ; Normal = (v3*2.0)-1.0
        mad  r9, v8, c95.wwwz, -c95.zzzx ; TangentU = (v8*2.0)-1.0
        mad  r8, v9, c95.wwwz, -c95.zzzx ; TangentV = (v9*2.0)-1.0

		;r5 = tangent space light vector 
		sub  r1, c32, v0     ; Object space light direction
		dp3  r5.x, r9, r1
		dp3  r5.y, r8, r1
		dp3  r5.z, r3, r1
		mov  oT2.xyz, r5.xyz ; Tangent Space Light vector

		;r5 = tangent space halfangle vector 
		sub  r2, c34, v0     ; Object space viewer direction
		dp3  r5.x, r9, r2
		dp3  r5.y, r8, r2
		dp3  r5.z, r3, r2
		mov  oT3.xyz, r5.xyz ; Tangent Space Light vector

        ; attenuation = (1/attenuation2)/D^2
		m4x4 r0, v0, c24             ; World Space Position
		sub  r1, r0, c31             ; World Space Light direction
		dp3  r11.x, r1, r1           ; Distance^2
		rcp  r2.x, r11.x             ; recip = 1/D^2
        mul  r2.y, r2.x, c33.z       ; *= 1/attenuation2
		mul  oD0, r2.y, c95.y        ; *= .5
	};

pixelshader ps10_Diff_Spec = asm
{
    ps.1.0
    tex t0
    tex t1
    tex t2
    tex t3
    mov         r1, t2_bx2     ; vLight
    add_d2      r0, t3_bx2, r1 ; vHalfAngle
    dp3_sat     r0, t1_bx2, r0 ; vN.vH
    dp3_sat     r1.rgb, t1_bx2, r1 ; vN.vL
   +mul         r1.a, r0, r0       ; ^2
    mul         r1.rgb, r1, v0     ; Attenuation
   +mul         r1.a, r1, r1       ; ^4
    add         r1.rgb, r1, c7     ; Ambient
   +mul_d2      r1.a, r1, r1       ; ^16
    mul         r0.rgb, r1, t0     ; Base*(Diff*attenuation + ambient)
    mad_x2      r0.rgb, r1.a, v0, r0     ; (spec * Attenuation) + last stage
};

vector pOV;

String ps10_Diff_Spec_desc = "PS 1.0 - Diffuse and Specular Bump Mapping";

technique ps10_Diff_Spec  // Dot3 diffuse bump mapping
{
    pass P0
    {
        VertexShaderConstant[16] = <mWVP>;
        VertexShaderConstant[24] = <mW>;
        VertexShaderConstant[31] = <pWL>;
        VertexShaderConstant[32] = <pOL>;
        VertexShaderConstant[33] = <cLgt>;
        VertexShaderConstant[34] = <pOV>;
        VertexShaderConstant[95] = <cnst>;

        vertexshader = <vBaseNormLightViewDiff>;	

        // Texture 0
	    Texture[0]       = <tBase>;
	    AddressU[0]      = Wrap;
	    AddressV[0]      = Wrap;
	    MinFilter[0]     = Linear;
	    MagFilter[0]     = Linear;
	    MipFilter[0]     = Linear;

        // Texture 1
        Texture[1]       = <tNormal>;
        AddressU[1]      = Wrap;
        AddressV[1]      = Wrap;
        MinFilter[1]     = Linear;
        MagFilter[1]     = Linear;
        MipFilter[1]     = Linear;

        // Texture 2
	    Texture[2]   = <tNormalizer>;
	    AddressU[2]  = Clamp;
	    AddressV[2]  = Clamp;
	    MinFilter[2] = Linear;
	    MagFilter[2] = Linear;
	    MipFilter[2] = Point;

        // Texture 3
	    Texture[3]   = <tNormalizer>;
	    AddressU[3]  = Clamp;
	    AddressV[3]  = Clamp;
	    MinFilter[3] = Linear;
	    MagFilter[3] = Linear;
	    MipFilter[3] = Point;


        PixelShaderConstant[7] = <cAmbient>;
        PixelShader = <ps10_Diff_Spec>;
    }
}

//--------------------------------------------------------------
// Fixed function pixel pipe
//--------------------------------------------------------------
vertexshader vLightNormBase = 
	decl
	{
		stream 0;
		float    v0[3];  // Position
		D3DCOLOR v3;     // Normal
		float    v7[2];  // Tex coord 0
		D3DCOLOR v8;     // Binormal
		D3DCOLOR v9;     // Tangent
	}
	asm
	{
        ; Constants:
        ; 16..19 - Composite World-View-Projection Matrix
        ; 24..27 - World Matrix
        ; 31     - World Space Light Position
        ; 32     - Object Space Light Position
        ; 33     - {1/light range, light range, 1/attenuation2, attenuation2}
        ; 95     - {0.0, 0.5, 1.0, 2.0}

		vs.1.0
		
		m4x4 oPos, v0, c16
		;r9 = tangent U vector = normal cross tangent V vector
        mad  r3, v3, c95.wwwz, -c95.zzzx ; Normal = (v3*2.0)-1.0
        mad  r9, v8, c95.wwwz, -c95.zzzx ; TangentU = (v8*2.0)-1.0
        mad  r8, v9, c95.wwwz, -c95.zzzx ; TangentV = (v9*2.0)-1.0

		;r5 = tangent space light vector 
		sub  r1, c32, v0     ; Object space light direction
		dp3  r5.x, r9, r1
		dp3  r5.y, r8, r1
		dp3  r5.z, r3, r1
		mov  oT0.xyz, r5.xyz ; Tangent Space Light vector

        ; attenuation = (1/attenuation2)/D^2
		m4x4 r0, v0, c24             ; World Space Position
		sub  r1, r0, c31             ; World Space Light direction
		dp3  r11.x, r1, r1           ; Distance^2
		rcp  r2.x, r11.x             ; recip = 1/D^2
		mul  oD0, r2.x, c33.z        ; *= 1/attenuation2

		mov  oT1.xy, v7.xy   ; Normal Map
	    mov  oT2.xy, v7.xy   ; Base Texture
	};

String Fixed_Dot3_Diffuse_desc = "Diffuse Bump Mapping";

technique Fixed_Dot3_Diffuse  // Dot3 diffuse bump mapping
{
    pass P0
    {
        VertexShaderConstant[16] = <mWVP>;
        VertexShaderConstant[24] = <mW>;
        VertexShaderConstant[31] = <pWL>;
        VertexShaderConstant[32] = <pOL>;
        VertexShaderConstant[33] = <cLgt>;
        VertexShaderConstant[95] = <cnst>;

        vertexshader = <vLightNormBase>;	

        // Stage 0
	    Texture[0]   = <tNormalizer>;
	    AddressU[0]  = Clamp;
	    AddressV[0]  = Clamp;
	    MinFilter[0] = Linear;
	    MagFilter[0] = Linear;
	    MipFilter[0] = Point;
        ColorOp[0]   = SelectArg1;
        ColorArg1[0] = Texture;
        AlphaOp[0]   = SelectArg1;
        AlphaArg1[0] = Diffuse;

        // Stage 1
        Texture[1]       = <tNormal>;
        AddressU[1]      = Wrap;
        AddressV[1]      = Wrap;
        MinFilter[1]     = Linear;
        MagFilter[1]     = Linear;
        MipFilter[1]     = Linear;
        ColorOp[1]       = DotProduct3;
        ColorArg1[1]     = Current;
        ColorArg2[1]     = Texture;
        AlphaOp[1]       = SelectArg1;
        AlphaArg1[1]     = Diffuse;

        // Stage 2
	    Texture[2]       = <tBase>;
	    AddressU[2]      = Wrap;
	    AddressV[2]      = Wrap;
	    MinFilter[2]     = Linear;
	    MagFilter[2]     = Linear;
	    MipFilter[2]     = Linear;
        ColorOp[2]       = Modulate;
        ColorArg1[2]     = Current;
        ColorArg2[2]     = Texture;
        AlphaOp[2]       = SelectArg1;
        AlphaArg1[2]     = Diffuse;

	    // Destination Blend
        AlphaBlendEnable = True;
        SrcBlend         = SrcAlpha;
        DestBlend        = Zero;
    }
}

vertexshader vBase = 
	decl
	{
		stream 0;
		float    v0[3];  // Position
		D3DCOLOR v3;     // Normal
		float    v7[2];  // Tex coord 0
		D3DCOLOR v8;     // Binormal
		D3DCOLOR v9;     // Tangent
	}
	asm
	{
        ; Constants:
        ; 16..19 - Composite World-View-Projection Matrix
        ; 24..27 - World Matrix
        ; 31     - World Space Light Position
        ; 32     - Object Space Light Position
        ; 33     - {1/light range, light range, 1/attenuation2, attenuation2}
        ; 95     - {0.0, 0.5, 1.0, 2.0}

		vs.1.0
		
		m4x4 oPos, v0, c16
	    mov  oT0.xy, v7.xy   ; Base Texture

        ; Light
        mad  r3, v3, c95.wwwz, -c95.zzzx ; Normal = (v3*2.0)-1.0
        sub  r0, v0, c32     ; Object space light direction
		dp3  r11.x, r0, r0   ; length^2
		rsq  r11.y, r11.x    ; 1/length
		mul  r0, r0, r11.y   ; normalized
        dp3  r4, r3, -r0     ; N.L
        max  r4, r4, c95.x   ; Saturate 0-1

        ; attenuation = (1/attenuation2)/D^2
		m4x4 r0, v0, c24             ; World Space Position
		sub  r1, r0, c31             ; World Space Light direction
		dp3  r11.x, r1, r1           ; Distance^2
		rcp  r2.x, r11.x             ; recip = 1/D^2
		mul  r4.w, r2.x, c33.z       ; *= 1/attenuation2
        mad  oD0, r4, r4.w, c94
	};


String Fixed_Textured_desc = "Diffuse Texture Mapping";

technique Fixed_Textured
{
    pass P0
    {
        VertexShaderConstant[16] = <mWVP>;
        VertexShaderConstant[24] = <mW>;
        VertexShaderConstant[31] = <pWL>;
        VertexShaderConstant[32] = <pOL>;
        VertexShaderConstant[33] = <cLgt>;
        VertexShaderConstant[94] = <cAmbient>;
        VertexShaderConstant[95] = <cnst>;

        vertexshader = <vBase>;	

        // Stage 0
	    Texture[0]       = <tBase>;
	    AddressU[0]      = Wrap;
	    AddressV[0]      = Wrap;
	    MinFilter[0]     = Linear;
	    MagFilter[0]     = Linear;
	    MipFilter[0]     = Linear;
        ColorOp[0]       = Modulate;
        ColorArg1[0]     = Diffuse;
        ColorArg2[0]     = Texture;
        AlphaOp[0]       = SelectArg1;
        AlphaArg1[0]     = Diffuse;
    }
}

String Fixed_Gouraud_desc = "Gouraud Shading";

technique Fixed_Gouraud  // Diffuse Texture Mapping
{
    pass P0
    {
        VertexShaderConstant[16] = <mWVP>;
        VertexShaderConstant[24] = <mW>;
        VertexShaderConstant[31] = <pWL>;
        VertexShaderConstant[32] = <pOL>;
        VertexShaderConstant[33] = <cLgt>;
        VertexShaderConstant[94] = <cAmbient>;
        VertexShaderConstant[95] = <cnst>;

        vertexshader = <vBase>;	

        // Stage 0
        Texture[0]       = Null;
        ColorOp[0]       = SelectArg1;
        ColorArg1[0]     = Diffuse;
        AlphaOp[0]       = SelectArg1;
        AlphaArg1[0]     = Diffuse;

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