//-----------------------------------------------------------------------------
// ps11_CubeBump.sha: VSpec cubic environment bump mapping
//-----------------------------------------------------------------------------
matrix mW;      // World matrix
matrix mWVP;    // World*View*Projection matrix
matrix mWrt;    // Inverse Transpose World Rotation matrix
matrix mWVt;    // Inverse Transpose World*View matrix
vector pOV;     // Object space viewer position
vector pWL;
vector pOL;
vector cLgt;
vector cnst;
vector cHlf;

texture tBase;
texture tGloss;
texture tCube;
texture tDiffuseCube;
texture tNormal;

DWord dwCubeMipFilter = 2; // None = 0, Point = 1, Linear = 2

//--------------------------------------------------------------
// Pixel Shader 1.0 - 1.1 Section
//--------------------------------------------------------------
// Cubic bump mapping
vertexshader vTangent123 = 
	decl
	{
		stream 0;
		float    v0[3];  // Position
		D3DCOLOR v3;     // Normal
		float    v7[2];  // Tex coord 0
		D3DCOLOR v8;     // Binormal
		D3DCOLOR v9;     // Tangent
	}
	asm
	{
        ; Sample vertex shader which outputs a 3x3 orthogonal transform which takes you from world space to 
        ; tangent space.  The result is stored in output tex coords 1,2,and 3
        ; Also, stored in the w component of these vectors is a per vertex normalized view vector
        ; which can be used for the texm3x3vspec  pixel shader operation.
        ;
        ; This sample expects the incoming vertex data to be set up as follows:
        ;
        ; v0     - Vertex Position
        ; v3	 - Vertex Normal
        ; v7	 - Vertex 2D Bumpmap Texture Coords
        ; v8	 - Vertex Tangent (normalized assumed to be positive v direction for tangent space)
        ; v9   - vertex binormal
        ; This sample expects the constant store to be set up in the following manner:
        ;
        ; c16..c19 - Composite World-View-Projection Matrix
        ; c20..c23   - Env Transform Matrix  (object to world or view coord transform (depends on type of env mapping you want to do) )

        ; c28      - ModelSpace Camera Position
        ; c31      - WorldSpace Light Position
        ; c32      - ModelSpace Light Position
        ; c95      - 0, .5, 1, 2

        vs.1.0

        ;derive per vertex eye vector using camera position   
        add		r8, c28, -v0	;view direction
        dp3		r11.x, r8, r8	;magnitude
        rsq		r11.y, r11.x	;normalize
        mul		r8, r8, r11.y	;normalized direction vector 

        m3x3	   r2, r8, c20	;transform reflection vector from object space to env space

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

        ; upper 3x3 of world matrix by upper tangent space transposed
        dp3		r9.x, c20, r7
        dp3		r9.y, c20, r8
        dp3		r9.z, c20, r3

        dp3		r10.x, c21, r7
        dp3		r10.y, c21, r8
        dp3		r10.z, c21, r3

        dp3		r11.x, c22, r7
        dp3		r11.y, c22, r8
        dp3		r11.z, c22, r3


        ;pack normalized view vector in 
        mov     r9.w, r2.x
        mov     r10.w, r2.y
        mov     r11.w, r2.z


        ; OutPos = ObjSpacePos * Composite World-View-Projection Matrix
        m4x4   oPos, v0, c16

        mov oT0.xy, v7		;passthrough texcoord 0 for bump map addressing
        mov oT1.xyzw, r9	;3x3 tangent space to world space transform
        mov oT2.xyzw, r10	;
        mov oT3.xyzw, r11	;
    };

pixelshader ps11_BumpVSpec = asm
{
    ps.1.1

    tex t0                  ; Define t0 as a standard 3-vector.
    texm3x3pad t1, t0_bx2   ; Perform first row of matrix multiply.
    texm3x3pad t2, t0_bx2   ; Perform second row of matrix multiply.
    texm3x3vspec t3, t0_bx2 ; Perform third row of matrix multiply, 
					        ; do reflection calculation
                            ; using eye ray, and sample texture 3
                            ; specular map.
    mov r0, t3
};

String ps11_CubicBumpReflect_desc = "PS 1.1 - Cubic Environment Bumped Reflections";

technique ps11_CubicBumpReflect
{
    pass P0 
    {
        VertexShaderConstant[12] = <mW>;    // World
        VertexShaderConstant[16] = <mWVP>;  // World*View*Proj Matrix
        VertexShaderConstant[20] = <mWrt>;  // World Rotation Inv Transpose
        VertexShaderConstant[28] = <pOV>;   // Object space Viewer position
        VertexShaderConstant[31] = <pWL>;   // World space light position
        VertexShaderConstant[32] = <pOL>;   // Object space Light position
        VertexShaderConstant[33] = <cLgt>;
        VertexShaderConstant[95] = <cnst>;
        VertexShader = <vTangent123>;

        Texture[0]   = <tNormal>;
        MagFilter[0] = Linear;
        MinFilter[0] = Linear;
        MipFilter[0] = Linear;

        Texture[3]   = <tCube>;
	    AddressU[3]  = Clamp;
	    AddressV[3]  = Clamp;
        MagFilter[3] = Linear;
        MinFilter[3] = Linear;
        MipFilter[3] = <dwCubeMipFilter>;

        PixelShader  = <ps11_BumpVSpec>;
    }
}


pixelshader ps11_BumpCubeDiff = asm
{
    ps.1.1

    tex t0                  ; Define t0 as a standard 3-vector.
    texm3x3pad t1, t0_bx2   ; Perform first row of matrix multiply.
    texm3x3pad t2, t0_bx2   ; Perform second row of matrix multiply.
    texm3x3tex t3, t0_bx2   ; Perform third row of matrix multiply, 
					        ; sample texture 3 diffuse map.
    mov_x2 r0, t3
};

String ps11_CubicBumpDiffuse_desc = "PS 1.1 - Bumped Cubic Environment Diffuse Lighting";

technique ps11_CubicBumpDiffuse
{
    pass P0 
    {
        VertexShaderConstant[12] = <mW>;    // World
        VertexShaderConstant[16] = <mWVP>;  // World*View*Proj Matrix
        VertexShaderConstant[20] = <mWrt>;  // World Rotation Inv Transpose
        VertexShaderConstant[28] = <pOV>;   // Object space Viewer position
        VertexShaderConstant[31] = <pWL>;   // World space light position
        VertexShaderConstant[32] = <pOL>;   // Object space Light position
        VertexShaderConstant[33] = <cLgt>;
        VertexShaderConstant[95] = <cnst>;
        VertexShader = <vTangent123>;

        Texture[0]   = <tNormal>;
        MagFilter[0] = Linear;
        MinFilter[0] = Linear;
        MipFilter[0] = Linear;

        Texture[3]   = <tDiffuseCube>;
	    AddressU[3]  = Clamp;
	    AddressV[3]  = Clamp;
        MagFilter[3] = Linear;
        MinFilter[3] = Linear;
        MipFilter[3] = <dwCubeMipFilter>;

        PixelShader  = <ps11_BumpCubeDiff>;
    }
}


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
	{
        vs.1.0

        m4x4   oPos, v0, c16
        mov oT0, v7		;passthrough texcoord 0 for bump map addressing
        mov oT1, v7		;passthrough texcoord 0 for bump map addressing
    };

pixelshader ps11_GlossABaseRGB = asm
{
    ps.1.1

    tex t0            ; Base texture
    tex t1            ; Gloss texture
    mov r0.a, t1.b    ; hack to get monochrome gloss map
    mov r0.rgb, t0
};

String ps11_Base_desc = "PS 1.1 - Base + Gloss to Seed Framebuffer";

technique ps11_Base
{
    pass Base 
    {
        VertexShaderConstant[16] = <mWVP>;  // World*View*Proj Matrix
        VertexShader = <vBase>;

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

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

        PixelShader  = <ps11_GlossABaseRGB>;
    }
}

String ps11_3Pass_CubicBump_desc = "PS 1.1 - 3 Pass Cubic Bump Reflections and Diffuse";

technique ps11_3Pass_CubicBump
{
    pass Base 
    {
        VertexShaderConstant[16] = <mWVP>;  // World*View*Proj Matrix
        VertexShader = <vBase>;

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

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

        PixelShader  = <ps11_GlossABaseRGB>;

        ZFunc            = Always;
    }

    pass Diffuse 
    {
        VertexShaderConstant[12] = <mW>;    // World
        VertexShaderConstant[16] = <mWVP>;  // World*View*Proj Matrix
        VertexShaderConstant[20] = <mWrt>;  // World Rotation Inv Transpose
        VertexShaderConstant[28] = <pOV>;   // Object space Viewer position
        VertexShaderConstant[31] = <pWL>;   // World space light position
        VertexShaderConstant[32] = <pOL>;   // Object space Light position
        VertexShaderConstant[33] = <cLgt>;
        VertexShaderConstant[95] = <cnst>;
        VertexShader = <vTangent123>;

        Texture[0]   = <tNormal>;
        MagFilter[0] = Linear;
        MinFilter[0] = Linear;
        MipFilter[0] = Linear;

        Texture[3]   = <tDiffuseCube>;
	    AddressU[3]  = Clamp;
	    AddressV[3]  = Clamp;
        MagFilter[3] = Linear;
        MinFilter[3] = Linear;
        MipFilter[3] = <dwCubeMipFilter>;

        PixelShader  = <ps11_BumpCubeDiff>;

	    // Destination Blend
        AlphaBlendEnable = True;
        SrcBlend         = DestColor;
        DestBlend        = Zero;
        ColorWriteEnable = 0x7;  // Mask alpha
    }

    pass Specular 
    {
        VertexShaderConstant[12] = <mW>;    // World
        VertexShaderConstant[16] = <mWVP>;  // World*View*Proj Matrix
        VertexShaderConstant[20] = <mWrt>;  // World Rotation Inv Transpose
        VertexShaderConstant[28] = <pOV>;   // Object space Viewer position
        VertexShaderConstant[31] = <pWL>;   // World space light position
        VertexShaderConstant[32] = <pOL>;   // Object space Light position
        VertexShaderConstant[33] = <cLgt>;
        VertexShaderConstant[95] = <cnst>;
        VertexShader = <vTangent123>;

        Texture[0]   = <tNormal>;
        MagFilter[0] = Linear;
        MinFilter[0] = Linear;
        MipFilter[0] = Linear;

        Texture[3]   = <tCube>;
	    AddressU[3]  = Clamp;
	    AddressV[3]  = Clamp;
        MagFilter[3] = Linear;
        MinFilter[3] = Linear;
        MipFilter[3] = <dwCubeMipFilter>;

        PixelShader  = <ps11_BumpVSpec>;

	    // Destination Blend
        AlphaBlendEnable = True;
        SrcBlend         = DestAlpha;
        DestBlend        = One;
    }
}

