//-----------------------------------------------------------------------------
// ps14_Bump.sha
// 
// Diffuse bump mapping, but the light space position is used to look up 
// a 1D texture map which describes the light intensity falloff function 
//
//    Chris Brennan - ATI Research, Inc. - 2001
//-----------------------------------------------------------------------------

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
texture tPointFalloff;  // Point light falloff function based on distance^2

DWord cAmbient = 0x40404040;

//--------------------------------------------------------------
// Diffuse bump mapping with per pixel falloff
//--------------------------------------------------------------
vertexshader vTexTLightWLight = 
	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

		;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  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
        mul  oT2, r1, c33.x          ; Light Space Position
	};

pixelshader ps14_Dot3_DiffuseFalloff = asm
{
    ps.1.4
    def c0, 1.0f,1.0f,1.0f,1.0f
    texld  r1, t0      ; Normal
    texld  r2, t3      ; Cubic Normalized Tangent Space Light Direction
    texcrd r3.rgb, t2  ; World Space Light Direction. Unit length is the light's range.

    dp3_sat r1.rgb, r1_bx2, r2_bx2  ; N.L
    dp3     r2.rgb, r3, r3          ; (Light Space Distance)^2

    phase

    texld  r0, t0  ; Base
    texld  r3, r2  ; Light Falloff Function 

    mul_x2    r4.rgb, r1, r3     ; falloff * (N.L)
    add       r4.rgb, r4, c7     ; += ambient
    mul       r0.rgb, r0, r4     ; base * (ambient + (falloff*N.L))

    +mov   r0.a, r3.a
};

String ps14_Dot3_DiffuseFalloff_desc = "PS 1.4 - Bumped Diffuse Lighting with per pixel intensity falloff";

technique ps14_Dot3_DiffuseFalloff  // 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 = <vTexTLightWLight>;	

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

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

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

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

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

//--------------------------------------------------------------
// Diffuse bump mapping with per vertex falloff
//--------------------------------------------------------------
vertexshader vTexLight = 
	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

		;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  oT1.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 ps14_Dot3_Diff = asm
{
    ps.1.4
    texld r0, t0
    texld r1, t0
    texld r2, t1
    dp3_sat r3.rgb, r1_bx2, r2_bx2 ; N.L
    mul_x2  r3.rgb, r3, v0         ; Attenuation
    add     r3.rgb, r3, c7         ; Ambient
    mul     r0.rgb, r3, r0         ; *= Base
};

String ps14_Dot3_Diffuse_desc = "PS 1.4 - Bumped Diffuse Lighting";

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

        vertexshader = <vTexLight>;	

        // 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 = <ps14_Dot3_Diff>;
    }
}

