/*
---------------------------------------------------------------------------
Open Asset Import Library (ASSIMP)
---------------------------------------------------------------------------

Copyright (c) 2006-2008, ASSIMP Development Team

All rights reserved.

Redistribution and use of this software in source and binary forms, 
with or without modification, are permitted provided that the following 
conditions are met:

* Redistributions of source code must retain the above
  copyright notice, this list of conditions and the
  following disclaimer.

* Redistributions in binary form must reproduce the above
  copyright notice, this list of conditions and the
  following disclaimer in the documentation and/or other
  materials provided with the distribution.

* Neither the name of the ASSIMP team, nor the names of its
  contributors may be used to endorse or promote products
  derived from this software without specific prior
  written permission of the ASSIMP Development Team.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/

#include "stdafx.h"
#include "assimp_view.h"


namespace AssimpView {

std::string g_szNormalsShader = std::string(

	// World * View * Projection matrix\n"
	// NOTE: Assume that the material uses a WorldViewProjection matrix\n"
	"float4x4 WorldViewProjection	: WORLDVIEWPROJECTION;\n"
	"float4 OUTPUT_COLOR;\n"
	

	// ----------------------------------------------------------------------------\n"
	// Vertex shader input structure\n"
	// ----------------------------------------------------------------------------\n"
	"struct VS_INPUT\n"
		"{\n"
		"// Position\n"
		"float3 Position : POSITION;\n"
		"};\n"


	// ----------------------------------------------------------------------------\n"
	// Vertex shader output structure\n"
	// ----------------------------------------------------------------------------\n"
	"struct VS_OUTPUT\n"
		"{\n"
		"// Position\n"
		"float4 Position : POSITION;\n"
		"};\n"

	// ----------------------------------------------------------------------------\n"
	// Vertex shader\n"
	// ----------------------------------------------------------------------------\n"
	"VS_OUTPUT RenderNormalsVS(VS_INPUT IN)\n"
		"{\n"
		"// Initialize the output structure with zero\n"
		"VS_OUTPUT Out = (VS_OUTPUT)0;\n"

		"// Multiply with the WorldViewProjection matrix\n"
		"Out.Position = mul(float4(IN.Position,1.0f),WorldViewProjection);\n"

		"return Out;\n"
		"}\n"


	// ----------------------------------------------------------------------------\n"
	// Pixel shader\n"
	// ----------------------------------------------------------------------------\n"
	"float4 RenderNormalsPS() : COLOR\n"
		"{\n"
		"return OUTPUT_COLOR;\n"
		"}\n"


	// ----------------------------------------------------------------------------\n"
	// Technique for the normal rendering effect (ps_2_0)\n"
	// ----------------------------------------------------------------------------\n"
	"technique RenderNormals\n"
		"{\n"
		"pass p0\n"
		"{\n"
		"CullMode=none;\n"
		"PixelShader = compile ps_2_0 RenderNormalsPS();\n"
		"VertexShader = compile vs_2_0 RenderNormalsVS();\n"
		"}\n"
		"};\n"
	);

std::string g_szSkyboxShader = std::string(

	// ----------------------------------------------------------------------------\n"
	// Sampler and texture for the skybox\n"
	// ----------------------------------------------------------------------------\n"
	"textureCUBE lw_tex_envmap;\n"
	"samplerCUBE EnvironmentMapSampler = sampler_state\n"
	"{\n"
	"Texture = (lw_tex_envmap);\n"
	"AddressU = CLAMP;\n"
	"AddressV = CLAMP;\n"
	"AddressW = CLAMP;\n"

	"MAGFILTER = linear;\n"
	"MINFILTER = linear;\n"
	"};\n"

	// World * View * Projection matrix\n"
	// NOTE: Assume that the material uses a WorldViewProjection matrix\n"
	"float4x4 WorldViewProjection	: WORLDVIEWPROJECTION;\n"
	

	// ----------------------------------------------------------------------------\n"
	// Vertex shader input structure\n"
	// ----------------------------------------------------------------------------\n"
	"struct VS_INPUT\n"
		"{\n"
		// Position\n"
		"float3 Position : POSITION;\n"

		// 3D-Texture coordinate\n"
		"float3 Texture0 : TEXCOORD0;\n"
		"};\n"


	// ----------------------------------------------------------------------------\n"
	// Vertex shader output structure\n"
	// ----------------------------------------------------------------------------\n"
	"struct VS_OUTPUT\n"
		"{\n"
		// Position\n"
		"float4 Position : POSITION;\n"

		// 3D-Texture coordinate\n"
		"float3 Texture0 : TEXCOORD0;\n"
		"};\n"

	// ----------------------------------------------------------------------------\n"
	// Vertex shader\n"
	// ----------------------------------------------------------------------------\n"
	"VS_OUTPUT RenderSkyBoxVS(VS_INPUT IN)\n"
		"{\n"
		// Initialize the output structure with zero\n"
		"VS_OUTPUT Out = (VS_OUTPUT)0;\n"

		// Multiply with the WorldViewProjection matrix\n"
		"Out.Position = mul(float4(IN.Position,1.0f),WorldViewProjection);\n"

		// Set z to w to ensure z becomes 1.0 after the division through\n"
		// w occurs\n"
		"Out.Position.z = Out.Position.w;\n"
	
		// Simply pass through texture coordinates\n"
		"Out.Texture0 = IN.Texture0;\n"

		"return Out;\n"
		"}\n"


	// ----------------------------------------------------------------------------\n"
	// Pixel shader\n"
	// ----------------------------------------------------------------------------\n"
	"float4 RenderSkyBoxPS(float3 Texture0 : TEXCOORD0) : COLOR\n"
		"{\n"
		// Lookup the skybox texture\n"
		"return texCUBE(EnvironmentMapSampler,Texture0) ;\n"
		"}\n"


	// ----------------------------------------------------------------------------\n"
	// Technique for the skybox shader (ps_2_0)\n"
	// ----------------------------------------------------------------------------\n"
	"technique RenderSkyBox\n"
		"{\n"
		"pass p0\n"
		"{\n"
		"ZWriteEnable = FALSE;\n"
		"FogEnable = FALSE;\n"
		"CullMode = NONE;\n"

		"PixelShader = compile ps_2_0 RenderSkyBoxPS();\n"
		"VertexShader = compile vs_2_0 RenderSkyBoxVS();\n"
		"}\n"
		"};\n"

	"texture TEXTURE_2D;\n"
		"sampler TEXTURE_SAMPLER = sampler_state\n"
			"{\n"
			"Texture = (TEXTURE_2D);\n"
			"};\n"


	// ----------------------------------------------------------------------------\n"
	"struct VS_OUTPUT2\n"
		"{\n"
		"// Position\n"
		"float4 _Position : POSITION;\n"

		"// Texture coordinate\n"
		"float2 _TexCoord0 : TEXCOORD0;\n"
		"};\n"


	// ----------------------------------------------------------------------------\n"
	"VS_OUTPUT2 RenderImageVS(float4 INPosition : POSITION,\n"
		"float2 INTexCoord0 : TEXCOORD0 )\n"
		"{\n"
		// Initialize the output structure with zero\n"
		"VS_OUTPUT2 Out = (VS_OUTPUT2)0;\n"

		"Out._Position.xy = INPosition.xy;\n"
		"Out._Position.z = Out._Position.w = 1.0f;\n"

		"Out._TexCoord0 = INTexCoord0;\n"

		"return Out;\n"
		"}\n"

	// ----------------------------------------------------------------------------\n"
	"float4 RenderImagePS(float2 IN : TEXCOORD0) : COLOR\n"
		"{\n"
		"return tex2D(TEXTURE_SAMPLER,IN);\n"
		"}\n"


	// ----------------------------------------------------------------------------\n"
	// Technique for the background image shader (ps_2_0)\n"
	// ----------------------------------------------------------------------------\n"
	"technique RenderImage2D\n"
		"{\n"
		"pass p0\n"
			"{\n"
			"ZWriteEnable = FALSE;\n"
			"FogEnable = FALSE;\n"
			"CullMode = NONE;\n"
	
			"PixelShader = compile ps_2_0 RenderImagePS();\n"
			"VertexShader = compile vs_2_0 RenderImageVS();\n"
			"}\n"
		"};\n"
		);

std::string g_szDefaultShader = std::string(

	// World * View * Projection matrix\n"
	// NOTE: Assume that the material uses a WorldViewProjection matrix\n"
	"float4x4 WorldViewProjection	: WORLDVIEWPROJECTION;\n"
	"float4x4 World					: WORLD;\n"
	"float4x3 WorldInverseTranspose	: WORLDINVERSETRANSPOSE;\n"


	// light colors\n"
	"float3 afLightColor[5];\n"

	// light direction \n"
	"float3 afLightDir[5];\n"

	// position of the camera in worldspace\n"
	"float3 vCameraPos : CAMERAPOSITION;\n"


	// ----------------------------------------------------------------------------\n"
	// Vertex shader input structure\n"
	// ----------------------------------------------------------------------------\n"
	"struct VS_INPUT\n"
		"{\n"
		"// Position\n"
		"float3 Position : POSITION;\n"
		"float3 Normal : NORMAL;\n"
		"};\n"


	// ----------------------------------------------------------------------------\n"
	// Vertex shader output structure\n"
	// ----------------------------------------------------------------------------\n"
	"struct VS_OUTPUT\n"
		"{\n"
		// Position\n"
		"float4 Position : POSITION;\n"

		"float3 ViewDir : TEXCOORD0;\n"
		"float3 Normal : TEXCOORD1;\n"
		"};\n"

	// ----------------------------------------------------------------------------\n"
	// Vertex shader\n"
	// ----------------------------------------------------------------------------\n"
	"VS_OUTPUT DefaultVShader(VS_INPUT IN)\n"
		"{\n"
		// Initialize the output structure with zero\n"
		"VS_OUTPUT Out = (VS_OUTPUT)0;\n"

		// Multiply with the WorldViewProjection matrix\n"
		"Out.Position = mul(float4(IN.Position,1.0f),WorldViewProjection);\n"
		"float3 WorldPos = mul(float4(IN.Position,1.0f),World);\n"
		"Out.ViewDir = vCameraPos - WorldPos;\n"
		"Out.Normal = mul(IN.Normal,WorldInverseTranspose);\n"

		"return Out;\n"
		"}\n"


	// ----------------------------------------------------------------------------\n"
	// Pixel shader\n"
	// ----------------------------------------------------------------------------\n"
	"float4 DefaultPShaderSpecular_D1(VS_OUTPUT IN) : COLOR\n"
		"{\n"
		"float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"

		"float3 Normal = normalize(IN.Normal);\n"
		"float3 ViewDir = normalize(IN.ViewDir);\n"

		"{\n"
			"float L1 = dot(Normal,afLightDir[0]) * 0.5f + 0.5f;\n"
			"float3 Reflect = reflect (Normal,afLightDir[0]);\n"
			"float fHalfLambert = L1*L1;\n"
			"OUT.rgb += afLightColor[0] * (fHalfLambert +\n"
				"saturate(fHalfLambert * 4.0f) * pow(dot(Reflect,ViewDir),9));\n"
		"}\n"
		"return OUT;\n"
		"}\n"
	// ----------------------------------------------------------------------------\n"
		"float4 DefaultPShaderSpecular_D2(VS_OUTPUT IN) : COLOR\n"
		"{\n"
		"float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"

		"float3 Normal = normalize(IN.Normal);\n"
		"float3 ViewDir = normalize(IN.ViewDir);\n"

		"{\n"
			"float L1 = dot(Normal,afLightDir[0]) * 0.5f + 0.5f;\n"
			"float3 Reflect = reflect (ViewDir,Normal);\n"
			"float fHalfLambert = L1*L1;\n"
			"OUT.rgb += afLightColor[0] * (fHalfLambert +\n"
			"saturate(fHalfLambert * 4.0f) * pow(dot(Reflect,afLightDir[0]),9));\n"
		"}\n"
		"{\n"
			"float L1 = dot(Normal,afLightDir[1]) * 0.5f + 0.5f;\n"
			"float3 Reflect = reflect (ViewDir,Normal);\n"
			"float fHalfLambert = L1*L1;\n"
			"OUT.rgb += afLightColor[1] * (fHalfLambert +\n"
			"saturate(fHalfLambert * 4.0f) * pow(dot(Reflect,afLightDir[1]),9));\n"
		"}\n"
		"return OUT;\n"
		"}\n"
	// ----------------------------------------------------------------------------\n"
	"float4 DefaultPShaderSpecular_PS20_D1(VS_OUTPUT IN) : COLOR\n"
		"{\n"
		"float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"

		"float3 Normal = normalize(IN.Normal);\n"
		"float3 ViewDir = normalize(IN.ViewDir);\n"

		"{\n"
			"float L1 = dot(Normal,afLightDir[0]);\n"
			"float3 Reflect = reflect (Normal,afLightDir[0]);\n"
			"OUT.rgb += afLightColor[0] * ((L1) +\n"
			"pow(dot(Reflect,ViewDir),9));\n"
		"}\n"

		"return OUT;\n"
		"}\n"
	// ----------------------------------------------------------------------------\n"
	"float4 DefaultPShaderSpecular_PS20_D2(VS_OUTPUT IN) : COLOR\n"
		"{\n"
		"float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"

		"float3 Normal = normalize(IN.Normal);\n"
		"float3 ViewDir = normalize(IN.ViewDir);\n"

		"{\n"
			"float L1 = dot(Normal,afLightDir[0]);\n"
			"float3 Reflect = reflect (Normal,afLightDir[0]);\n"
			"OUT.rgb += afLightColor[0] * ((L1) +\n"
			"pow(dot(Reflect,ViewDir),9));\n"
		"}\n"
		"{\n"
			"float L1 = dot(Normal,afLightDir[1]);\n"
			"float3 Reflect = reflect (Normal,afLightDir[1]);\n"
			"OUT.rgb += afLightColor[1] * ((L1) +\n"
			"pow(dot(Reflect,ViewDir),9));\n"
		"}\n"
		"return OUT;\n"
		"}\n"


	// ----------------------------------------------------------------------------\n"
	// Technique for the default effect\n"
	// ----------------------------------------------------------------------------\n"
	"technique DefaultFXSpecular_D1\n"
		"{\n"
		"pass p0\n"
			"{\n"
			"CullMode=none;\n"
			"PixelShader = compile ps_3_0 DefaultPShaderSpecular_D1();\n"
			"VertexShader = compile vs_3_0 DefaultVShader();\n"
			"}\n"
		"};\n"
	"technique DefaultFXSpecular_D2\n"
		"{\n"
		"pass p0\n"
			"{\n"
			"CullMode=none;\n"
			"PixelShader = compile ps_3_0 DefaultPShaderSpecular_D2();\n"
			"VertexShader = compile vs_3_0 DefaultVShader();\n"
			"}\n"
		"};\n"


	// ----------------------------------------------------------------------------\n"
	// Technique for the default effect (ps_2_0)\n"
	// ----------------------------------------------------------------------------\n"
	"technique DefaultFXSpecular_PS20_D1\n"
		"{\n"
		"pass p0\n"
		"{\n"
		"CullMode=none;\n"
		"PixelShader = compile ps_2_0 DefaultPShaderSpecular_PS20_D1();\n"
		"VertexShader = compile vs_2_0 DefaultVShader();\n"
		"}\n"
		"};\n"
	"technique DefaultFXSpecular_PS20_D2\n"
		"{\n"
		"pass p0\n"
		"{\n"
		"CullMode=none;\n"
		"PixelShader = compile ps_2_0 DefaultPShaderSpecular_PS20_D2();\n"
		"VertexShader = compile vs_2_0 DefaultVShader();\n"
		"}\n"
		"};\n"
		);


std::string g_szMaterialShader = std::string(

	// World * View * Projection matrix\n"
	// NOTE: Assume that the material uses a WorldViewProjection matrix\n"
	"float4x4 WorldViewProjection	: WORLDVIEWPROJECTION;\n"
	"float4x4 World					: WORLD;\n"
	"float4x3 WorldInverseTranspose	: WORLDINVERSETRANSPOSE;\n"

	"#ifndef AV_DISABLESSS\n"
	"float4x3 ViewProj;\n"
	"float4x3 InvViewProj;\n"
	"#endif\n"

	"float4 DIFFUSE_COLOR;\n"
	"float4 SPECULAR_COLOR;\n"
	"float4 AMBIENT_COLOR;\n"
	"float4 EMISSIVE_COLOR;\n"

	"#ifdef AV_SPECULAR_COMPONENT\n"
	"float SPECULARITY;\n"
	"float SPECULAR_STRENGTH;\n"
	"#endif\n"
	"#ifdef AV_OPACITY\n"
	"float TRANSPARENCY;\n"
	"#endif\n"

	// light colors (diffuse and specular)\n"
	"float4 afLightColor[5];\n"
	"float4 afLightColorAmbient[5];\n"

	// light direction \n"
	"float3 afLightDir[5];\n"

	// position of the camera in worldspace\n"
	"float3 vCameraPos : CAMERAPOSITION;\n"

	"#ifdef AV_DIFFUSE_TEXTURE\n"
		"texture DIFFUSE_TEXTURE;\n"
		"sampler DIFFUSE_SAMPLER\n"
		"{\n"
		"Texture = <DIFFUSE_TEXTURE>;\n"
		"MinFilter=LINEAR;\n"
		"MagFilter=LINEAR;\n"
		"MipFilter=LINEAR;\n"
		"};\n"
	"#endif // AV_DIFFUSE_TEXTUR\n"

	"#ifdef AV_SPECULAR_TEXTURE\n"
		"texture SPECULAR_TEXTURE;\n"
		"sampler SPECULAR_SAMPLER\n"
		"{\n"
		"Texture = <SPECULAR_TEXTURE>;\n"
		"MinFilter=LINEAR;\n"
		"MagFilter=LINEAR;\n"
		"MipFilter=LINEAR;\n"
		"};\n"
	"#endif // AV_SPECULAR_TEXTUR\n"

	"#ifdef AV_AMBIENT_TEXTURE\n"
		"texture AMBIENT_TEXTURE;\n"
		"sampler AMBIENT_SAMPLER\n"
		"{\n"
		"Texture = <AMBIENT_TEXTURE>;\n"
		"MinFilter=LINEAR;\n"
		"MagFilter=LINEAR;\n"
		"MipFilter=LINEAR;\n"
		"};\n"
	"#endif // AV_AMBIENT_TEXTUR\n"

	"#ifdef AV_OPACITY_TEXTURE\n"
		"texture OPACITY_TEXTURE;\n"
		"sampler OPACITY_SAMPLER\n"
		"{\n"
		"Texture = <OPACITY_TEXTURE>;\n"
		"MinFilter=LINEAR;\n"
		"MagFilter=LINEAR;\n"
		"MipFilter=LINEAR;\n"
		"};\n"
	"#endif // AV_OPACITY_TEXTURE\n"

	"#ifdef AV_EMISSIVE_TEXTURE\n"
		"texture EMISSIVE_TEXTURE;\n"
		"sampler EMISSIVE_SAMPLER\n"
		"{\n"
		"Texture = <EMISSIVE_TEXTURE>;\n"
		"MinFilter=LINEAR;\n"
		"MagFilter=LINEAR;\n"
		"MipFilter=LINEAR;\n"
		"};\n"
	"#endif // AV_EMISSIVE_TEXTUR\n"

	"#ifdef AV_NORMAL_TEXTURE\n"
		"texture NORMAL_TEXTURE;\n"
		"sampler NORMAL_SAMPLER\n"
		"{\n"
		"Texture = <NORMAL_TEXTURE>;\n"
		"MinFilter=LINEAR;\n"
		"MagFilter=LINEAR;\n"
		"MipFilter=LINEAR;\n"
		"};\n"
	"#endif // AV_NORMAL_TEXTURE\n"

	"#ifdef AV_SKYBOX_LOOKUP\n"
		"textureCUBE lw_tex_envmap;\n"
		"samplerCUBE EnvironmentMapSampler = sampler_state\n"
		"{\n"
		"Texture = (lw_tex_envmap);\n"
		"AddressU = CLAMP;\n"
		"AddressV = CLAMP;\n"
		"AddressW = CLAMP;\n"

		"MAGFILTER = linear;\n"
		"MINFILTER = linear;\n"
		"};\n"
	"#endif // AV_SKYBOX_LOOKUP\n"

	// ----------------------------------------------------------------------------\n"
	// Vertex shader input structure\n"
	// ----------------------------------------------------------------------------\n"
	"struct VS_INPUT\n"
		"{\n"
		// Position\n"
		"float3 Position : POSITION;\n"
		"float3 Normal : NORMAL;\n"

		// NOTE: Tangents and bitangents are passed to the shader
		// in every case, even if not required. This saves a few lines 
		// of code ...

		"float3 Tangent   : TEXCOORD0;\n"
		"float3 Bitangent : TEXCOORD1;\n"
		"float2 TexCoord0 : TEXCOORD2;\n"
		"};\n"


	// ----------------------------------------------------------------------------\n"
	// Vertex shader output structure\n"
	// ----------------------------------------------------------------------------\n"
	"struct VS_OUTPUT\n"
		"{\n"
		// Position\n"
		"float4 Position : POSITION;\n"

		"float3 ViewDir : TEXCOORD0;\n"

		"#ifndef AV_NORMAL_TEXTURE\n"
		"float3 Normal  : TEXCOORD1;\n"
		"#endif\n"

		"float2 TexCoord0 : TEXCOORD2;\n"

		"#ifdef AV_NORMAL_TEXTURE\n"

		"float3 Light0 : TEXCOORD3;\n"
		"float3 Light1 : TEXCOORD4;\n"

		"#endif\n"
		"};\n"


	// ----------------------------------------------------------------------------\n"
	// Selective SuperSampling in screenspace for reflection lookups\n"
	// ----------------------------------------------------------------------------\n"
	"#ifndef AV_SKYBOX_LOOKUP\n"
	"#define AV_DISABLESSS\n"
	"#endif\n"
	"#ifndef AV_DISABLESSS\n"
	"float3 GetSSSCubeMap(float3 Reflect)\n"
		"{\n"
		// compute the reflection vector in screen space\n"
		"float3 ScreenReflect = mul(Reflect,ViewProj);\n"

		// compute the gradients of the reflection vector\n"
		"float3 fDX = ddx(ScreenReflect);\n"
		"float3 fDY = ddy(ScreenReflect);\n"

		// take the center step and calculate gradients for it\n"
		"float3 fColor = texCUBE(EnvironmentMapSampler,Reflect).rgb;\n"

		// Take 10 samples around the center step \n"
		"fColor += texCUBEgrad(EnvironmentMapSampler,mul( ScreenReflect + (0.4f * 2.0 / 3.5) * fDX + (0.4f * 2.0 / 3.5) * fDY, InvViewProj),fDX,fDY).rgb;\n"
		"fColor += texCUBEgrad(EnvironmentMapSampler,mul( ScreenReflect + (0.4f * 3.0 / 3.5) * fDX + (0.4f *-1.0 / 3.5) * fDY, InvViewProj),fDX,fDY).rgb;\n"
		"fColor += texCUBEgrad(EnvironmentMapSampler,mul( ScreenReflect + (0.4f * 1.0 / 3.5) * fDX + (0.4f *-3.0 / 3.5) * fDY, InvViewProj),fDX,fDY).rgb;\n"
		"fColor += texCUBEgrad(EnvironmentMapSampler,mul( ScreenReflect + (0.4f *-2.0 / 3.5) * fDX + (0.4f *-2.0 / 3.5) * fDY, InvViewProj),fDX,fDY).rgb;\n"
		"fColor += texCUBEgrad(EnvironmentMapSampler,mul( ScreenReflect + (0.4f *-3.0 / 3.5) * fDX + (0.4f * 1.0 / 3.5) * fDY, InvViewProj),fDX,fDY).rgb;\n"
		"fColor += texCUBEgrad(EnvironmentMapSampler,mul( ScreenReflect + (0.4f *-1.0 / 3.5) * fDX + (0.4f * 3.0 / 3.5) * fDY, InvViewProj),fDX,fDY).rgb;\n"
		"fColor /= 7;\n"
		"return fColor;\n"
		"}\n"
	"#else\n"
		"#define GetSSSCubeMap(_refl) (texCUBElod(EnvironmentMapSampler,float4(_refl,0.0f)).rgb) \n"
	"#endif\n"

	// bugfix: if normal mapping is active we have the reflection
	// vector in tangent, not in world space. Would need the inverse
	// of the TSM matrix in the pixel shader (or world space tangent mapping)
	// Simply disable realtime reflection for normal mapping.
	"#ifdef AV_NORMAL_TEXTURE\n"
	"#undef GetSSSCubeMap\n"
	"#define GetSSSCubeMap(_refl) (float3(1.0f,1.0f,1.0f))\n"
	"#endif\n"


	// ----------------------------------------------------------------------------\n"
	// Vertex shader\n"
	// ----------------------------------------------------------------------------\n"
	"VS_OUTPUT MaterialVShader_D1(VS_INPUT IN)\n"
		"{\n"
		// Initialize the output structure with zero\n"
		"VS_OUTPUT Out = (VS_OUTPUT)0;\n"

		// Multiply with the WorldViewProjection matrix\n"
		"Out.Position = mul(float4(IN.Position,1.0f),WorldViewProjection);\n"
		"float3 WorldPos = mul(float4(IN.Position,1.0f),World);\n"
		"Out.TexCoord0 = IN.TexCoord0;\n"

		"#ifndef AV_NORMAL_TEXTURE\n"
		"Out.ViewDir = vCameraPos - WorldPos;\n"
		"Out.Normal = mul(IN.Normal,WorldInverseTranspose);\n"
		"#endif\n"
		
		"#ifdef AV_NORMAL_TEXTURE\n"
		"float3x3 TBNMatrix = float3x3(IN.Tangent, IN.Bitangent, IN.Normal);\n"
		"float3x3 WTTS      = mul(TBNMatrix, (float3x3)WorldInverseTranspose);\n"
		"Out.Light0         = normalize(mul(WTTS, afLightDir[0] ));\n"
		"Out.ViewDir = normalize(mul(WTTS, (vCameraPos - WorldPos)));\n"
		"#endif\n"
		"return Out;\n"
		"}\n"
	"// ----------------------------------------------------------------------------\n"
	"VS_OUTPUT MaterialVShader_D2(VS_INPUT IN)\n"
		"{\n"
		// Initialize the output structure with zero\n"
		"VS_OUTPUT Out = (VS_OUTPUT)0;\n"

		// Multiply with the WorldViewProjection matrix\n"
		"Out.Position = mul(float4(IN.Position,1.0f),WorldViewProjection);\n"
		"float3 WorldPos = mul(float4(IN.Position,1.0f),World);\n"
		"Out.TexCoord0 = IN.TexCoord0;\n"

		"#ifndef AV_NORMAL_TEXTURE\n"
		"Out.ViewDir = vCameraPos - WorldPos;\n"
		"Out.Normal = mul(IN.Normal,WorldInverseTranspose);\n"
		"#endif\n"

		"#ifdef AV_NORMAL_TEXTURE\n"
		"float3x3 TBNMatrix = float3x3(IN.Tangent, IN.Bitangent, IN.Normal);\n"
		"float3x3 WTTS      = mul(TBNMatrix, (float3x3)WorldInverseTranspose);\n"
		"Out.Light0         = normalize(mul(WTTS, afLightDir[0] ));\n"
		"Out.Light1         = normalize(mul(WTTS, afLightDir[1] ));\n"
		"Out.ViewDir = normalize(mul(WTTS, (vCameraPos - WorldPos)));\n"
		"#endif\n"
		"return Out;\n"
		"}\n"


	// ----------------------------------------------------------------------------\n"
	// Pixel shader\n"
	// ----------------------------------------------------------------------------\n"
	"float4 MaterialPShaderSpecular_D1(VS_OUTPUT IN) : COLOR\n"
		"{\n"
		"float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"

		"#ifdef AV_NORMAL_TEXTURE\n"
		"float3 IN_Light0 = normalize(IN.Light0);\n"
		"float3 Normal  =  normalize(2.0f * tex2D(NORMAL_SAMPLER, IN.TexCoord0).rgb - 1.0f);\n"
		"#else\n"
		"float3 Normal = normalize(IN.Normal);\n"
		"#endif \n"
		"float3 ViewDir = normalize(IN.ViewDir);\n"
		"#ifdef AV_SPECULAR_COMPONENT\n"
			"float3 Reflect = -normalize(reflect (ViewDir,Normal));\n"
		"#endif // !AV_SPECULAR_COMPONENT\n"

		"{\n"
		"#ifdef AV_NORMAL_TEXTURE\n"
			"float L1 =  dot(Normal,IN_Light0) * 0.5f + 0.5f;\n"
			"#define AV_LIGHT_0 IN_Light0\n"
			// would need to convert the reflection vector into world space ....
			// simply let it ...
		"#else\n"
			"float L1 = dot(Normal,afLightDir[0]) * 0.5f + 0.5f;\n"
			"#define AV_LIGHT_0 afLightDir[0]\n"
		"#endif\n"
			"float fHalfLambert = L1*L1;\n"
		"#ifdef AV_DIFFUSE_TEXTURE\n"
			"OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * fHalfLambert +\n"
		"#else\n"
			"OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * fHalfLambert +\n"
		"#endif // !AV_DIFFUSE_TEXTURE\n"

		"#ifdef AV_SPECULAR_COMPONENT\n"
			"#ifndef AV_SKYBOX_LOOKUP\n"
				"#ifdef AV_SPECULAR_TEXTURE\n"
					"SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
				"#else\n"
					"SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
				"#endif // !AV_SPECULAR_TEXTURE\n"
			"#else\n"
				"#ifdef AV_SPECULAR_TEXTURE\n"
					"SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * GetSSSCubeMap(Reflect) * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
				"#else\n"
					"SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * GetSSSCubeMap(Reflect) * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
				"#endif // !AV_SPECULAR_TEXTURE\n"
			"#endif // !AV_SKYBOX_LOOKUP\n"
		"#endif // !AV_SPECULAR_COMPONENT\n"

		"#ifdef AV_AMBIENT_TEXTURE\n"
			"AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb * tex2D(AMBIENT_SAMPLER,IN.TexCoord0).rgb +\n"
		"#else\n"
			"AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb + \n"
		"#endif // !AV_AMBIENT_TEXTURE\n"
     		"#ifdef AV_EMISSIVE_TEXTURE\n"
			"EMISSIVE_COLOR.rgb * tex2D(EMISSIVE_SAMPLER,IN.TexCoord0).rgb;\n"
		"#else \n"
			"EMISSIVE_COLOR.rgb;\n"
		"#endif // !AV_EMISSIVE_TEXTURE\n"
		"}\n"
		"#ifdef AV_OPACITY\n"
		"OUT.a = TRANSPARENCY;\n"
		"#endif\n"
		"#ifdef AV_OPACITY_TEXTURE\n"
		"OUT.a *= tex2D(OPACITY_SAMPLER,IN.TexCoord0). AV_OPACITY_TEXTURE_REGISTER_MASK;\n"
		"#endif\n"
		"return OUT;\n"

		"#undef AV_LIGHT_0\n"
		"}\n"
	// ----------------------------------------------------------------------------\n"
	"float4 MaterialPShaderSpecular_D2(VS_OUTPUT IN) : COLOR\n"
		"{\n"
		"float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"

		"#ifdef AV_NORMAL_TEXTURE\n"
		"float3 IN_Light0 = normalize(IN.Light0);\n"
		"float3 IN_Light1 = normalize(IN.Light1);\n"
		"float3 Normal  =  normalize(2.0f * tex2D(NORMAL_SAMPLER, IN.TexCoord0).rgb - 1.0f);\n"
		"#else\n"
		"float3 Normal = normalize(IN.Normal);\n"
		"#endif \n"
		"float3 ViewDir = normalize(IN.ViewDir);\n"
		"#ifdef AV_SPECULAR_COMPONENT\n"
			"float3 Reflect = -normalize(reflect (ViewDir,Normal));\n"
		"#endif // !AV_SPECULAR_COMPONENT\n"

		"{\n"
		
		"#ifdef AV_NORMAL_TEXTURE\n"
			"float L1 = dot(Normal,IN_Light0) * 0.5f + 0.5f;\n"
			"#define AV_LIGHT_0 IN_Light0\n"
		"#else\n"
			"float L1 = dot(Normal,afLightDir[0]) * 0.5f + 0.5f;\n"
			"#define AV_LIGHT_0 afLightDir[0]\n"
		"#endif\n"
			"float fHalfLambert = L1*L1;\n"
			
		"#ifdef AV_DIFFUSE_TEXTURE\n"
			"OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * fHalfLambert +\n"
		"#else\n"
			"OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * fHalfLambert +\n"
		"#endif // !AV_DIFFUSE_TEXTURE\n"

		"#ifdef AV_SPECULAR_COMPONENT\n"
			"#ifndef AV_SKYBOX_LOOKUP\n"
				"#ifdef AV_SPECULAR_TEXTURE\n"
					"SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
				"#else\n"
					"SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
				"#endif // !AV_SPECULAR_TEXTURE\n"
			"#else\n"
				"#ifdef AV_SPECULAR_TEXTURE\n"
					"SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * GetSSSCubeMap(Reflect) * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
				"#else\n"
					"SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * GetSSSCubeMap(Reflect) * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
				"#endif // !AV_SPECULAR_TEXTURE\n"
			"#endif // !AV_SKYBOX_LOOKUP\n"
		"#endif // !AV_SPECULAR_COMPONENT\n"
		"#ifdef AV_AMBIENT_TEXTURE\n"
			"AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb * tex2D(AMBIENT_SAMPLER,IN.TexCoord0).rgb + \n"
		"#else\n"
			"AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb + \n"
		"#endif // !AV_AMBIENT_TEXTURE\n"
		"#ifdef AV_EMISSIVE_TEXTURE\n"
			"EMISSIVE_COLOR.rgb * tex2D(EMISSIVE_SAMPLER,IN.TexCoord0).rgb;\n"
		"#else \n"
			"EMISSIVE_COLOR.rgb;\n"
		"#endif // !AV_EMISSIVE_TEXTURE\n"
		"}\n"
		"{\n"
		"#ifdef AV_NORMAL_TEXTURE\n"
			"float L1 = dot(Normal,IN_Light1) * 0.5f + 0.5f;\n"
			"#define AV_LIGHT_1 IN_Light1\n"
		"#else\n"
			"float L1 = dot(Normal,afLightDir[1]) * 0.5f + 0.5f;\n"
			"#define AV_LIGHT_1 afLightDir[1]\n"
		"#endif\n"
			"float fHalfLambert = L1*L1;\n"
		"#ifdef AV_DIFFUSE_TEXTURE\n"
			"OUT.rgb += afLightColor[1].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * fHalfLambert +\n"
		"#else\n"
			"OUT.rgb += afLightColor[1].rgb * DIFFUSE_COLOR.rgb * fHalfLambert +\n"
		"#endif // !AV_DIFFUSE_TEXTURE\n"

		"#ifdef AV_SPECULAR_COMPONENT\n"
			"#ifndef AV_SKYBOX_LOOKUP\n"
				"#ifdef AV_SPECULAR_TEXTURE\n"
					"SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_1),SPECULARITY)) + \n"
				"#else\n"
					"SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_1),SPECULARITY)) + \n"
				"#endif // !AV_SPECULAR_TEXTURE\n"
			"#else\n"
				"#ifdef AV_SPECULAR_TEXTURE\n"
					"SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * GetSSSCubeMap(Reflect) * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_1),SPECULARITY)) + \n"
				"#else\n"
					"SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * GetSSSCubeMap(Reflect) * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_1),SPECULARITY)) + \n"
				"#endif // !AV_SPECULAR_TEXTURE\n"
			"#endif // !AV_SKYBOX_LOOKUP\n"
		"#endif // !AV_SPECULAR_COMPONENT\n"
		"#ifdef AV_AMBIENT_TEXTURE\n"
			"AMBIENT_COLOR.rgb * afLightColorAmbient[1].rgb * tex2D(AMBIENT_SAMPLER,IN.TexCoord0).rgb + \n"
		"#else\n"
			"AMBIENT_COLOR.rgb * afLightColorAmbient[1].rgb + \n"
		"#endif // !AV_AMBIENT_TEXTURE\n"
		"#ifdef AV_EMISSIVE_TEXTURE\n"
			"EMISSIVE_COLOR.rgb * tex2D(EMISSIVE_SAMPLER,IN.TexCoord0).rgb;\n"
		"#else \n"
			"EMISSIVE_COLOR.rgb;\n"
		"#endif // !AV_EMISSIVE_TEXTURE\n"
		"}\n"
		"#ifdef AV_OPACITY\n"
		"OUT.a = TRANSPARENCY;\n"
		"#endif\n"
		"#ifdef AV_OPACITY_TEXTURE\n"
		"OUT.a *= tex2D(OPACITY_SAMPLER,IN.TexCoord0). AV_OPACITY_TEXTURE_REGISTER_MASK;\n"
		"#endif\n"
		"return OUT;\n"

		"#undef AV_LIGHT_0\n"
		"#undef AV_LIGHT_1\n"
		"}\n"
	// ----------------------------------------------------------------------------\n"
	"float4 MaterialPShaderSpecular_PS20_D1(VS_OUTPUT IN) : COLOR\n"
		"{\n"
		"float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"

		"#ifdef AV_NORMAL_TEXTURE\n"
		"float3 IN_Light0 = normalize(IN.Light0);\n"
		"float3 Normal  =  normalize(2.0f * tex2D(NORMAL_SAMPLER, IN.TexCoord0).rgb - 1.0f);\n"
		"#else\n"
		"float3 Normal = normalize(IN.Normal);\n"
		"#endif \n"
		"float3 ViewDir = normalize(IN.ViewDir);\n"

		"{\n"
		"#ifdef AV_NORMAL_TEXTURE\n"
		"float L1 = dot(Normal,IN_Light0) * 0.5f + 0.5f;\n"
		"float3 Reflect = reflect (Normal,IN_Light0);\n"
		"#else\n"
		"float L1 = dot(Normal,afLightDir[0]) * 0.5f + 0.5f;\n"
		"float3 Reflect = reflect (Normal,afLightDir[0]);\n"
		"#endif\n"
		"#ifdef AV_DIFFUSE_TEXTURE\n"
			"OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * L1 +\n"
		"#else\n"
			"OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * L1 +\n"
		"#endif // !AV_DIFFUSE_TEXTURE\n"

		"#ifdef AV_SPECULAR_COMPONENT\n"
		"#ifdef AV_SPECULAR_TEXTURE\n"
			"SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
		"#else\n"
			"SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
		"#endif // !AV_SPECULAR_TEXTURE\n"
		"#endif // !AV_SPECULAR_COMPONENT\n"
		"#ifdef AV_AMBIENT_TEXTURE\n"
			"AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb * tex2D(AMBIENT_SAMPLER,IN.TexCoord0).rgb +\n"
		"#else\n"
			"AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb +\n"
		"#endif // !AV_AMBIENT_TEXTURE\n"
		"#ifdef AV_EMISSIVE_TEXTURE\n"
			"EMISSIVE_COLOR.rgb * tex2D(EMISSIVE_SAMPLER,IN.TexCoord0).rgb;\n"
		"#else \n"
			"EMISSIVE_COLOR.rgb;\n"
		"#endif // !AV_EMISSIVE_TEXTURE\n"
		"}\n"

		"#ifdef AV_OPACITY\n"
		"OUT.a = TRANSPARENCY;\n"
		"#endif\n"
		"#ifdef AV_OPACITY_TEXTURE\n"
		"OUT.a *= tex2D(OPACITY_SAMPLER,IN.TexCoord0). AV_OPACITY_TEXTURE_REGISTER_MASK;\n"
		"#endif\n"
		"return OUT;\n"
		"}\n"
	// ----------------------------------------------------------------------------\n"
	"float4 MaterialPShaderSpecular_PS20_D2(VS_OUTPUT IN) : COLOR\n"
		"{\n"
		"float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"

		"#ifdef AV_NORMAL_TEXTURE\n"
		"float3 IN_Light0 = normalize(IN.Light0);\n"
		"float3 IN_Light1 = normalize(IN.Light1);\n"
		"float3 Normal  =  normalize(2.0f * tex2D(NORMAL_SAMPLER, IN.TexCoord0) - 1.0f);\n"
		"#else\n"
		"float3 Normal = normalize(IN.Normal);\n"
		"#endif \n"
		"float3 ViewDir = normalize(IN.ViewDir);\n"

		"{\n"
		"#ifdef AV_NORMAL_TEXTURE\n"
		"float L1 = dot(Normal,IN_Light0) * 0.5f + 0.5f;\n"
		"float3 Reflect = reflect (Normal,IN_Light0);\n"
		"#else\n"
		"float L1 = dot(Normal,afLightDir[0]) * 0.5f + 0.5f;\n"
		"float3 Reflect = reflect (Normal,afLightDir[0]);\n"
		"#endif\n"
		"#ifdef AV_DIFFUSE_TEXTURE\n"
			"OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * L1 +\n"
		"#else\n"
			"OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * L1 +\n"
		"#endif // !AV_DIFFUSE_TEXTURE\n"

		"#ifdef AV_SPECULAR_COMPONENT\n"
		"#ifdef AV_SPECULAR_TEXTURE\n"
			"SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
		"#else\n"
			"SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
		"#endif // !AV_SPECULAR_TEXTURE\n"
		"#endif // !AV_SPECULAR_COMPONENT\n"
		"#ifdef AV_AMBIENT_TEXTURE\n"
			"AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb * tex2D(AMBIENT_SAMPLER,IN.TexCoord0).rgb +\n"
		"#else\n"
			"AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb +\n"
		"#endif // !AV_AMBIENT_TEXTURE\n"
		"#ifdef AV_EMISSIVE_TEXTURE\n"
			"EMISSIVE_COLOR.rgb * tex2D(EMISSIVE_SAMPLER,IN.TexCoord0).rgb;\n"
		"#else \n"
			"EMISSIVE_COLOR.rgb;\n"
		"#endif // !AV_EMISSIVE_TEXTURE\n"
		"}\n"
		"{\n"
		"#ifdef AV_NORMAL_TEXTURE\n"
		"float L1 = dot(Normal,IN_Light1) * 0.5f + 0.5f;\n"
		"float3 Reflect = reflect (Normal,IN_Light1);\n"
		"#else\n"
		"float L1 = dot(Normal,afLightDir[1]) * 0.5f + 0.5f;\n"
		"float3 Reflect = reflect (Normal,afLightDir[1]);\n"
		"#endif\n"
		"#ifdef AV_DIFFUSE_TEXTURE\n"
			"OUT.rgb += afLightColor[1].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * L1 +\n"
		"#else\n"
			"OUT.rgb += afLightColor[1].rgb * DIFFUSE_COLOR.rgb * L1 +\n"
		"#endif // !AV_DIFFUSE_TEXTURE\n"

		"#ifdef AV_SPECULAR_COMPONENT\n"
		"#ifdef AV_SPECULAR_TEXTURE\n"
			"SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
		"#else\n"
			"SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
		"#endif // !AV_SPECULAR_TEXTURE\n"
		"#endif // !AV_SPECULAR_COMPONENT\n"
		"#ifdef AV_AMBIENT_TEXTURE\n"
			"AMBIENT_COLOR.rgb * afLightColorAmbient[1].rgb * tex2D(AMBIENT_SAMPLER,IN.TexCoord0).rgb +\n"
		"#else\n"
			"AMBIENT_COLOR.rgb * afLightColorAmbient[1].rgb + \n"
		"#endif // !AV_AMBIENT_TEXTURE\n"
		"#ifdef AV_EMISSIVE_TEXTURE\n"
			"EMISSIVE_COLOR.rgb * tex2D(EMISSIVE_SAMPLER,IN.TexCoord0).rgb;\n"
		"#else \n"
			"EMISSIVE_COLOR.rgb;\n"
		"#endif // !AV_EMISSIVE_TEXTURE\n"
		"}\n"

		"#ifdef AV_OPACITY\n"
		"OUT.a = TRANSPARENCY;\n"
		"#endif\n"
		"#ifdef AV_OPACITY_TEXTURE\n"
		"OUT.a *= tex2D(OPACITY_SAMPLER,IN.TexCoord0). AV_OPACITY_TEXTURE_REGISTER_MASK;\n"
		"#endif\n"
		"return OUT;\n"
		"}\n"


	// ----------------------------------------------------------------------------\n"
	// Technique for the material effect\n"
	// ----------------------------------------------------------------------------\n"
	"technique MaterialFXSpecular_D1\n"
		"{\n"
		"pass p0\n"
			"{\n"
			"CullMode=none;\n"

			"#ifdef AV_OPACITY_TEXTURE\n"
			"AlphaBlendEnable=TRUE;"
			"SrcBlend = srcalpha;\n"
			"DestBlend = invsrcalpha;\n"
			"#else\n"
			"#ifdef AV_OPACITY\n"
			"AlphaBlendEnable=TRUE;"
			"SrcBlend = srcalpha;\n"
			"DestBlend = invsrcalpha;\n"
			"#endif \n"
			"#endif\n"

			"PixelShader = compile ps_3_0 MaterialPShaderSpecular_D1();\n"
			"VertexShader = compile vs_3_0 MaterialVShader_D1();\n"
			"}\n"
		"};\n"
	"technique MaterialFXSpecular_D2\n"
		"{\n"
		"pass p0\n"
			"{\n"
			"CullMode=none;\n"

			"#ifdef AV_OPACITY_TEXTURE\n"
			"AlphaBlendEnable=TRUE;"
			"SrcBlend = srcalpha;\n"
			"DestBlend = invsrcalpha;\n"
			"#else\n"
			"#ifdef AV_OPACITY\n"
			"AlphaBlendEnable=TRUE;"
			"SrcBlend = srcalpha;\n"
			"DestBlend = invsrcalpha;\n"
			"#endif \n"
			"#endif\n"

			"PixelShader = compile ps_3_0 MaterialPShaderSpecular_D2();\n"
			"VertexShader = compile vs_3_0 MaterialVShader_D2();\n"
			"}\n"
		"};\n"


	// ----------------------------------------------------------------------------\n"
	// Technique for the material effect (ps_2_0)\n"
	// ----------------------------------------------------------------------------\n"
	"technique MaterialFXSpecular_PS20_D1\n"
		"{\n"
		"pass p0\n"
		"{\n"
		"CullMode=none;\n"

		"#ifdef AV_OPACITY_TEXTURE\n"
		"AlphaBlendEnable=TRUE;"
		"SrcBlend = srcalpha;\n"
		"DestBlend = invsrcalpha;\n"
		"#else\n"
		"#ifdef AV_OPACITY\n"
		"AlphaBlendEnable=TRUE;"
		"SrcBlend = srcalpha;\n"
		"DestBlend = invsrcalpha;\n"
		"#endif \n"
		"#endif\n"

		"PixelShader = compile ps_2_0 MaterialPShaderSpecular_PS20_D1();\n"
		"VertexShader = compile vs_2_0 MaterialVShader_D1();\n"
		"}\n"
		"};\n"
	"technique MaterialFXSpecular_PS20_D2\n"
		"{\n"
		"pass p0\n"
		"{\n"
		"CullMode=none;\n"

		"#ifdef AV_OPACITY_TEXTURE\n"
		"AlphaBlendEnable=TRUE;"
		"SrcBlend = srcalpha;\n"
		"DestBlend = invsrcalpha;\n"
		"#else\n"
		"#ifdef AV_OPACITY\n"
		"AlphaBlendEnable=TRUE;"
		"SrcBlend = srcalpha;\n"
		"DestBlend = invsrcalpha;\n"
		"#endif \n"
		"#endif\n"

		"PixelShader = compile ps_2_0 MaterialPShaderSpecular_PS20_D2();\n"
		"VertexShader = compile vs_2_0 MaterialVShader_D2();\n"
		"}\n"
		"};\n"
		);

std::string g_szPassThroughShader = std::string(
		"texture TEXTURE_2D;\n"
		"sampler TEXTURE_SAMPLER = sampler_state\n"
			"{\n"
			"Texture = (TEXTURE_2D);\n"
			"};\n"


		// ----------------------------------------------------------------------------\n"
		"struct VS_OUTPUT\n"
			"{\n"
			"// Position\n"
			"float4 _Position : POSITION;\n"

			"// Texture coordinate\n"
			"float2 _TexCoord0 : TEXCOORD0;\n"
			"};\n"


		// ----------------------------------------------------------------------------\n"
		"VS_OUTPUT DefaultVShader(float4 INPosition : POSITION,\n"
			"float2 INTexCoord0 : TEXCOORD0 )\n"
			"{\n"
			"// Initialize the output structure with zero\n"
			"VS_OUTPUT Out = (VS_OUTPUT)0;\n"

			"Out._Position = INPosition;\n"
			"Out._TexCoord0 = INTexCoord0;\n"

			"return Out;\n"
			"}\n"

		// simply lookup a texture
		// ----------------------------------------------------------------------------\n"
		"float4 PassThrough_PS(float2 IN : TEXCOORD0) : COLOR\n"
		"{\n"
		"return tex2D(TEXTURE_SAMPLER,IN);\n"
		"}\n"

		// visualize the alpha channel (in black) -> use a
		// ----------------------------------------------------------------------------\n"
		"float4 PassThroughAlphaA_PS(float2 IN : TEXCOORD0) : COLOR\n"
		"{\n"
		"return float4(0.0f,0.0f,0.0f,tex2D(TEXTURE_SAMPLER,IN).a);\n"
		"}\n"

		// visualize the alpha channel (in black) -> use r
		// ----------------------------------------------------------------------------\n"
		"float4 PassThroughAlphaR_PS(float2 IN : TEXCOORD0) : COLOR\n"
		"{\n"
		"return float4(0.0f,0.0f,0.0f,tex2D(TEXTURE_SAMPLER,IN).r);\n"
		"}\n"

		// ----------------------------------------------------------------------------\n"
		// Simple pass-through technique\n"
		// ----------------------------------------------------------------------------\n"
		"technique PassThrough\n"
		"{\n"
			"pass p0\n"
			"{\n"
				"FillMode=Solid;\n"
				"ZEnable = FALSE;\n"
				"CullMode = none;\n"
				"AlphaBlendEnable = TRUE;\n"
				"SrcBlend =srcalpha;\n"
				"DestBlend =invsrcalpha;\n"
				"PixelShader = compile ps_2_0 PassThrough_PS();\n"
				"VertexShader = compile vs_2_0 DefaultVShader();\n"
			"}\n"
		"};\n"

		// ----------------------------------------------------------------------------\n"
		// Pass-through technique which visualizes the texture's alpha channel
		// ----------------------------------------------------------------------------\n"
		"technique PassThroughAlphaFromA\n"
		"{\n"
			"pass p0\n"
			"{\n"
				"FillMode=Solid;\n"
				"ZEnable = FALSE;\n"
				"CullMode = none;\n"
				"AlphaBlendEnable = TRUE;\n"
				"SrcBlend =srcalpha;\n"
				"DestBlend =invsrcalpha;\n"
				"PixelShader = compile ps_2_0 PassThroughAlphaA_PS();\n"
				"VertexShader = compile vs_2_0 DefaultVShader();\n"
			"}\n"
		"};\n"

		// ----------------------------------------------------------------------------\n"
		// Pass-through technique which visualizes the texture's red channel
		// ----------------------------------------------------------------------------\n"
		"technique PassThroughAlphaFromR\n"
		"{\n"
			"pass p0\n"
			"{\n"
				"FillMode=Solid;\n"
				"ZEnable = FALSE;\n"
				"CullMode = none;\n"
				"AlphaBlendEnable = TRUE;\n"
				"SrcBlend =srcalpha;\n"
				"DestBlend =invsrcalpha;\n"
				"PixelShader = compile ps_2_0 PassThroughAlphaR_PS();\n"
				"VertexShader = compile vs_2_0 DefaultVShader();\n"
			"}\n"
		"};\n"
		);

std::string g_szCheckerBackgroundShader = std::string(

		// the two colors used to draw the checker pattern
		"float3 COLOR_ONE = float3(0.4f,0.4f,0.4f);\n"
		"float3 COLOR_TWO = float3(0.6f,0.6f,0.6f);\n"

		// size of a square in both x and y direction
		"float SQUARE_SIZE = 10.0f;\n"

		// ----------------------------------------------------------------------------\n"
		"struct VS_OUTPUT\n"
			"{\n"
			"// Position\n"
			"float4 _Position : POSITION;\n"	
			"};\n"


		// ----------------------------------------------------------------------------\n"
		"VS_OUTPUT DefaultVShader(float4 INPosition : POSITION,\n"
			"float2 INTexCoord0 : TEXCOORD0 )\n"
			"{\n"
			"// Initialize the output structure with zero\n"
			"VS_OUTPUT Out = (VS_OUTPUT)0;\n"

			"Out._Position = INPosition;\n"

			"return Out;\n"
			"}\n"


		// ----------------------------------------------------------------------------\n"
		"float4 MakePattern_PS(float2 IN : VPOS) : COLOR\n"
		"{\n"
		"float2 fDiv = IN / SQUARE_SIZE;\n"
		"float3 fColor = COLOR_ONE;\n"
		"if (0 == round(fmod(round(fDiv.x),2)))\n"
			"{\n"
			"if (0 == round(fmod(round(fDiv.y),2))) fColor = COLOR_TWO;\n"
			"}\n"
		"else if (0 != round(fmod(round(fDiv.y),2)))fColor = COLOR_TWO;\n"
		"return float4(fColor,1.0f);"
		"}\n"
	

		// ----------------------------------------------------------------------------\n"
		// Shader to generate a pattern\n"
		// ----------------------------------------------------------------------------\n"
		"technique MakePattern\n"
		"{\n"
		"pass p0\n"
		"{\n"
		"FillMode=Solid;\n"
		"ZEnable = FALSE;\n"
		"CullMode = none;\n"
		"PixelShader = compile ps_3_0 MakePattern_PS();\n"
		"VertexShader = compile vs_3_0 DefaultVShader();\n"
		"}\n"
		"};\n"
		);
	};