diff --git a/GiantsTools.sln b/GiantsTools.sln
index 46b6da4..25cd403 100644
--- a/GiantsTools.sln
+++ b/GiantsTools.sln
@@ -13,32 +13,88 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Giants.Launcher", "Giants.L
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Giants.WebApi.Clients", "Giants.WebApi.Clients\Giants.WebApi.Clients.csproj", "{D4C21170-82D4-4D1F-81EC-036835AC1238}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Shaders", "Shaders\Shaders.vcxproj", "{9A0AF60B-3C3B-45B7-B5E1-4C9997A68EBB}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0CD61424-4E74-4A48-A726-729FEA32C50C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0CD61424-4E74-4A48-A726-729FEA32C50C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0CD61424-4E74-4A48-A726-729FEA32C50C}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {0CD61424-4E74-4A48-A726-729FEA32C50C}.Debug|x64.Build.0 = Debug|Any CPU
+ {0CD61424-4E74-4A48-A726-729FEA32C50C}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0CD61424-4E74-4A48-A726-729FEA32C50C}.Debug|x86.Build.0 = Debug|Any CPU
{0CD61424-4E74-4A48-A726-729FEA32C50C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0CD61424-4E74-4A48-A726-729FEA32C50C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0CD61424-4E74-4A48-A726-729FEA32C50C}.Release|x64.ActiveCfg = Release|Any CPU
+ {0CD61424-4E74-4A48-A726-729FEA32C50C}.Release|x64.Build.0 = Release|Any CPU
+ {0CD61424-4E74-4A48-A726-729FEA32C50C}.Release|x86.ActiveCfg = Release|Any CPU
+ {0CD61424-4E74-4A48-A726-729FEA32C50C}.Release|x86.Build.0 = Release|Any CPU
{D426FE47-231B-41F0-AC78-293D12EF66A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D426FE47-231B-41F0-AC78-293D12EF66A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D426FE47-231B-41F0-AC78-293D12EF66A0}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D426FE47-231B-41F0-AC78-293D12EF66A0}.Debug|x64.Build.0 = Debug|Any CPU
+ {D426FE47-231B-41F0-AC78-293D12EF66A0}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D426FE47-231B-41F0-AC78-293D12EF66A0}.Debug|x86.Build.0 = Debug|Any CPU
{D426FE47-231B-41F0-AC78-293D12EF66A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D426FE47-231B-41F0-AC78-293D12EF66A0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D426FE47-231B-41F0-AC78-293D12EF66A0}.Release|x64.ActiveCfg = Release|Any CPU
+ {D426FE47-231B-41F0-AC78-293D12EF66A0}.Release|x64.Build.0 = Release|Any CPU
+ {D426FE47-231B-41F0-AC78-293D12EF66A0}.Release|x86.ActiveCfg = Release|Any CPU
+ {D426FE47-231B-41F0-AC78-293D12EF66A0}.Release|x86.Build.0 = Release|Any CPU
{9A284C34-8F4B-4E20-B74B-1A0AF04EDBD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9A284C34-8F4B-4E20-B74B-1A0AF04EDBD1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9A284C34-8F4B-4E20-B74B-1A0AF04EDBD1}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {9A284C34-8F4B-4E20-B74B-1A0AF04EDBD1}.Debug|x64.Build.0 = Debug|Any CPU
+ {9A284C34-8F4B-4E20-B74B-1A0AF04EDBD1}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9A284C34-8F4B-4E20-B74B-1A0AF04EDBD1}.Debug|x86.Build.0 = Debug|Any CPU
{9A284C34-8F4B-4E20-B74B-1A0AF04EDBD1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9A284C34-8F4B-4E20-B74B-1A0AF04EDBD1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9A284C34-8F4B-4E20-B74B-1A0AF04EDBD1}.Release|x64.ActiveCfg = Release|Any CPU
+ {9A284C34-8F4B-4E20-B74B-1A0AF04EDBD1}.Release|x64.Build.0 = Release|Any CPU
+ {9A284C34-8F4B-4E20-B74B-1A0AF04EDBD1}.Release|x86.ActiveCfg = Release|Any CPU
+ {9A284C34-8F4B-4E20-B74B-1A0AF04EDBD1}.Release|x86.Build.0 = Release|Any CPU
{612FD606-F072-4A04-9054-65BC592E9D3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{612FD606-F072-4A04-9054-65BC592E9D3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {612FD606-F072-4A04-9054-65BC592E9D3E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {612FD606-F072-4A04-9054-65BC592E9D3E}.Debug|x64.Build.0 = Debug|Any CPU
+ {612FD606-F072-4A04-9054-65BC592E9D3E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {612FD606-F072-4A04-9054-65BC592E9D3E}.Debug|x86.Build.0 = Debug|Any CPU
{612FD606-F072-4A04-9054-65BC592E9D3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{612FD606-F072-4A04-9054-65BC592E9D3E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {612FD606-F072-4A04-9054-65BC592E9D3E}.Release|x64.ActiveCfg = Release|Any CPU
+ {612FD606-F072-4A04-9054-65BC592E9D3E}.Release|x64.Build.0 = Release|Any CPU
+ {612FD606-F072-4A04-9054-65BC592E9D3E}.Release|x86.ActiveCfg = Release|Any CPU
+ {612FD606-F072-4A04-9054-65BC592E9D3E}.Release|x86.Build.0 = Release|Any CPU
{D4C21170-82D4-4D1F-81EC-036835AC1238}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D4C21170-82D4-4D1F-81EC-036835AC1238}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D4C21170-82D4-4D1F-81EC-036835AC1238}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D4C21170-82D4-4D1F-81EC-036835AC1238}.Debug|x64.Build.0 = Debug|Any CPU
+ {D4C21170-82D4-4D1F-81EC-036835AC1238}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D4C21170-82D4-4D1F-81EC-036835AC1238}.Debug|x86.Build.0 = Debug|Any CPU
{D4C21170-82D4-4D1F-81EC-036835AC1238}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D4C21170-82D4-4D1F-81EC-036835AC1238}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D4C21170-82D4-4D1F-81EC-036835AC1238}.Release|x64.ActiveCfg = Release|Any CPU
+ {D4C21170-82D4-4D1F-81EC-036835AC1238}.Release|x64.Build.0 = Release|Any CPU
+ {D4C21170-82D4-4D1F-81EC-036835AC1238}.Release|x86.ActiveCfg = Release|Any CPU
+ {D4C21170-82D4-4D1F-81EC-036835AC1238}.Release|x86.Build.0 = Release|Any CPU
+ {9A0AF60B-3C3B-45B7-B5E1-4C9997A68EBB}.Debug|Any CPU.ActiveCfg = Debug|Win32
+ {9A0AF60B-3C3B-45B7-B5E1-4C9997A68EBB}.Debug|x64.ActiveCfg = Debug|x64
+ {9A0AF60B-3C3B-45B7-B5E1-4C9997A68EBB}.Debug|x64.Build.0 = Debug|x64
+ {9A0AF60B-3C3B-45B7-B5E1-4C9997A68EBB}.Debug|x86.ActiveCfg = Debug|Win32
+ {9A0AF60B-3C3B-45B7-B5E1-4C9997A68EBB}.Debug|x86.Build.0 = Debug|Win32
+ {9A0AF60B-3C3B-45B7-B5E1-4C9997A68EBB}.Release|Any CPU.ActiveCfg = Release|Win32
+ {9A0AF60B-3C3B-45B7-B5E1-4C9997A68EBB}.Release|x64.ActiveCfg = Release|x64
+ {9A0AF60B-3C3B-45B7-B5E1-4C9997A68EBB}.Release|x64.Build.0 = Release|x64
+ {9A0AF60B-3C3B-45B7-B5E1-4C9997A68EBB}.Release|x86.ActiveCfg = Release|Win32
+ {9A0AF60B-3C3B-45B7-B5E1-4C9997A68EBB}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Shaders/Shaders.sln b/Shaders/Shaders.sln
new file mode 100644
index 0000000..02bd688
--- /dev/null
+++ b/Shaders/Shaders.sln
@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26228.4
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Shaders", "Shaders.vcxproj", "{9A0AF60B-3C3B-45B7-B5E1-4C9997A68EBB}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {9A0AF60B-3C3B-45B7-B5E1-4C9997A68EBB}.Debug|x64.ActiveCfg = Debug|x64
+ {9A0AF60B-3C3B-45B7-B5E1-4C9997A68EBB}.Debug|x64.Build.0 = Debug|x64
+ {9A0AF60B-3C3B-45B7-B5E1-4C9997A68EBB}.Debug|x86.ActiveCfg = Debug|Win32
+ {9A0AF60B-3C3B-45B7-B5E1-4C9997A68EBB}.Debug|x86.Build.0 = Debug|Win32
+ {9A0AF60B-3C3B-45B7-B5E1-4C9997A68EBB}.Release|x64.ActiveCfg = Release|x64
+ {9A0AF60B-3C3B-45B7-B5E1-4C9997A68EBB}.Release|x64.Build.0 = Release|x64
+ {9A0AF60B-3C3B-45B7-B5E1-4C9997A68EBB}.Release|x86.ActiveCfg = Release|Win32
+ {9A0AF60B-3C3B-45B7-B5E1-4C9997A68EBB}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Shaders/Shaders.vcxproj b/Shaders/Shaders.vcxproj
new file mode 100644
index 0000000..b343fb5
--- /dev/null
+++ b/Shaders/Shaders.vcxproj
@@ -0,0 +1,94 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 15.0
+ {9A0AF60B-3C3B-45B7-B5E1-4C9997A68EBB}
+
+
+
+ Application
+ true
+ v142
+
+
+ Application
+ false
+ v142
+
+
+ Application
+ true
+ v142
+
+
+ Application
+ false
+ v142
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Effect
+ 2.0
+
+
+
+
+
+ Effect
+ 2.0
+
+
+
+
+
+
+ /Gec %(AdditionalOptions)
+ /Gec %(AdditionalOptions)
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Shaders/fx.rules b/Shaders/fx.rules
new file mode 100644
index 0000000..ff44326
--- /dev/null
+++ b/Shaders/fx.rules
@@ -0,0 +1,268 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Shaders/fx/LandBump.fx b/Shaders/fx/LandBump.fx
new file mode 100644
index 0000000..b76ef1f
--- /dev/null
+++ b/Shaders/fx/LandBump.fx
@@ -0,0 +1,376 @@
+//--------------------------------------------------------------------------------------
+// LandBump.fx
+
+// Land bumpmapping and lighting shader.
+//--------------------------------------------------------------------------------------
+
+#define MAX_LIGHTS 4
+
+float4x4 g_mWorldViewProjection : WorldViewProjection;
+float4x4 g_World : World;
+
+float4x4 g_TexGenTransform0 : TexGenTransform0;
+float4x4 g_TexGenTransform1 : TexGenTransform1;
+float4x4 g_ShoreGen : TexGenTransform2;
+
+float4 g_LightDiffuseColors[MAX_LIGHTS] : EffectLightColors;
+float3 g_LightPositions[MAX_LIGHTS] : EffectLightPositions;
+float g_LightRangeSquared[MAX_LIGHTS] : EffectLightRanges;
+
+float4 g_TextureFactor : TextureFactor;
+int g_NumLights = 0;
+
+//////////////////////////////////////////////////////
+//The sizes of the various terrain UV Coordinates
+float detailScale = 1;
+float diffuseScale = 5;
+float globalScale;
+float detailMapStrength = 1;
+
+float3 sunlightVector = float3(.5,.5,.8);
+
+//The Colour (and brightness) of the Sunlight
+float3 lightColour = float3(2,2,2);
+//The colour (and birghtness) of the ambient light
+float3 ambientColour = float3(.1,.1,.1);
+
+
+texture g_LandTexture;
+texture g_LandBumpTexture;
+texture g_ShoreTexture;
+texture g_LandDetailTexture;
+
+//--------------------------------------------------------------------------------------
+// Texture samplers
+//--------------------------------------------------------------------------------------
+sampler g_LandTextureSampler =
+sampler_state
+{
+ Texture = ;
+ MipFilter = LINEAR;
+ MinFilter = LINEAR;
+ MagFilter = LINEAR;
+};
+
+sampler g_LandBumpTextureSampler =
+sampler_state
+{
+ Texture = ;
+ MipFilter = LINEAR;
+ MinFilter = LINEAR;
+ MagFilter = LINEAR;
+};
+
+sampler g_LandDetailTextureSampler =
+sampler_state
+{
+ Texture = ;
+ MipFilter = LINEAR;
+ MinFilter = LINEAR;
+ MagFilter = LINEAR;
+};
+
+sampler g_ShoreTextureSampler =
+sampler_state
+{
+ Texture = ;
+ MipFilter = LINEAR;
+ MinFilter = LINEAR;
+ MagFilter = LINEAR;
+};
+
+//--------------------------------------------------------------------------------------
+// Vertex shader output structure
+//--------------------------------------------------------------------------------------
+struct VS_OUTPUT_BUMP
+{
+ float4 Position : POSITION;
+ float4 LandBumpDiffuse : COLOR1;
+ float4 LandDiffuse : COLOR0;
+ float2 LandBumpTextureUV : TEXCOORD0;
+ float2 LandTextureUV : TEXCOORD1;
+ float3 WorldPos : TEXCOORD2;
+ float3 Normal : TEXCOORD3;
+ float3 ShoreTextureUV : TEXCOORD4;
+};
+
+float4 bx2(float4 x)
+{
+ return float4(2.0f * x.xyzw - 1.0f);
+}
+
+
+VS_OUTPUT_BUMP LandBumpVS( float4 vPos : POSITION,
+ float3 vNormal : NORMAL,
+ float4 vDiffuse : COLOR0,
+ float4 vDiffuse2 : COLOR1)
+{
+ VS_OUTPUT_BUMP Output;
+
+ // Transform the position from object space to homogeneous projection space
+ Output.Position = mul(vPos, g_mWorldViewProjection);
+
+ Output.LandBumpDiffuse = vDiffuse2 * .5f;
+ Output.LandBumpDiffuse.a = 1.0f;
+
+ //Output.LandDiffuse
+ Output.LandDiffuse.rgb = vDiffuse;
+ Output.LandDiffuse.a = 1.0f;
+
+ Output.WorldPos = mul(vPos, g_World);
+
+ // Set dynamically generated tex coords
+ Output.LandBumpTextureUV = mul(vPos, g_TexGenTransform0);
+ Output.LandTextureUV = mul(vPos, g_TexGenTransform1);
+ Output.ShoreTextureUV = mul(vPos, g_ShoreGen);
+
+ // Transform the normal from object space to world space
+ Output.Normal = normalize(mul(vNormal, (float3x3)g_World)); // normal (world space)
+
+ return Output;
+}
+
+float4 LandBumpPS(VS_OUTPUT_BUMP input) : COLOR0
+{
+ float4 normal = bx2(tex2D(g_LandBumpTextureSampler, input.LandBumpTextureUV));
+ float4 normalcol = bx2(input.LandDiffuse);
+
+ float3 normalMap;
+ normalMap = saturate((float4)dot((float3)normal, (float3)normalcol)).xyz;
+#ifdef MIX_4X
+ float3 texel = tex2D(g_LandTextureSampler, input.LandTextureUV).rgb * tex2D(g_LandTextureSampler, input.LandTextureUV * -0.25).rgb * 4;
+ float3 finalColor = 2.0 * (normalMap * (texel) + input.LandBumpDiffuse);
+#else
+ float3 finalColor = 2.0 * (normalMap * (tex2D(g_LandTextureSampler, input.LandTextureUV)) + input.LandBumpDiffuse);
+ //finalColor *= tex2D(g_ShoreTextureSampler, input.ShoreTextureUV);
+#endif
+
+ //finalColor = (g_TextureFactor * (1 - input.LandDiffuse)) + finalColor;
+
+ for (int i = 0; i < MAX_LIGHTS; i++)
+ {
+ // Get light direction for this fragment
+ float3 lightDir = normalize(input.WorldPos - g_LightPositions[i]); // per pixel diffuse lighting
+
+ // Note: Non-uniform scaling not supported
+ float diffuseLighting = saturate(dot(input.Normal, -lightDir));
+
+ // Introduce fall-off of light intensity
+ diffuseLighting *= (g_LightRangeSquared[i] / dot(g_LightPositions[i] - input.WorldPos, g_LightPositions[i] - input.WorldPos));
+
+ float4 diffuseColor = diffuseLighting * g_LightDiffuseColors[i];
+
+ finalColor += diffuseColor;
+ }
+
+ return float4(finalColor, 1);
+}
+
+technique LandBump
+{
+ pass P0
+ {
+ VertexShader = compile vs_2_0 LandBumpVS();
+ PixelShader = compile ps_2_0 LandBumpPS();
+ }
+}
+
+VS_OUTPUT_BUMP LandNormalVS( float4 vPos : POSITION,
+ float3 vNormal : NORMAL,
+ float4 vDiffuse : COLOR0,
+ float4 vDiffuse2 : COLOR1)
+{
+ VS_OUTPUT_BUMP Output;
+
+ // Transform the position from object space to homogeneous projection space
+ Output.Position = mul(vPos, g_mWorldViewProjection);
+
+ Output.LandBumpDiffuse = vDiffuse2 * .5f;
+ Output.LandBumpDiffuse.a = 1.0f;
+
+ //Output.LandDiffuse
+ Output.LandDiffuse.rgb = vDiffuse;
+ Output.LandDiffuse.a = 1.0f;
+
+ Output.WorldPos = mul(vPos, g_World);
+
+ // Set dynamically generated tex coords
+ Output.LandBumpTextureUV = mul(vPos, g_TexGenTransform0);
+ Output.LandTextureUV = mul(vPos, g_TexGenTransform1);
+ Output.ShoreTextureUV = mul(vPos, g_ShoreGen);
+
+ // Transform the normal from object space to world space
+ Output.Normal = normalize(mul(vNormal, (float3x3)g_World)); // normal (world space)
+
+ return Output;
+}
+
+float4 LandNormalPS(VS_OUTPUT_BUMP input) : COLOR0
+{
+ float4 Output;
+ //Get Global Normal from the full terrain normal map
+ float3 Normal = tex2D(g_LandBumpTextureSampler, input.LandTextureUV);
+ Normal[0] -= .5;
+ Normal[1] -= .5;
+ Normal[2] -= .5;
+ Normal = normalize(Normal);
+
+
+ //{
+ //
+ // //Get Detail Normal from the detail map
+ // float3 detailNormalMap = (tex2D(g_LandDetailTextureSampler, input.LandTextureUV*100/detailScale));
+ // detailNormalMap[0] -= .5;
+ // detailNormalMap[1] -= .5;
+ // detailNormalMap[2] -= .5;
+ // //Multiply Detail Normal by detailMapStrength
+ // detailNormalMap[0] = mul(detailNormalMap[0], detailMapStrength);
+ // detailNormalMap[1] = mul(detailNormalMap[1], detailMapStrength);
+ //
+ // //Normalize detail Normal
+ // detailNormalMap = normalize(detailNormalMap);
+ //
+ // if(false)
+ // {
+ // //Generate the Tangent Basis for the Detail Normal Map.
+ // float3x3 tangentBasis;
+ //
+ // tangentBasis[0] = cross(Normal, float3(1,0,0));
+ // tangentBasis[1] = cross(Normal, tangentBasis[0]);
+ // tangentBasis[2] = Normal;
+ //
+ // detailNormalMap = detailNormalMap, detailMapStrength;
+ //
+ // Normal = mul(detailNormalMap, tangentBasis);
+ // Normal = normalize(Normal);
+ // }
+ // else
+ // {
+ // Normal = normalize(Normal*2+detailNormalMap*detailMapStrength);
+ // }
+ //}
+
+ float3 sv = normalize(sunlightVector);
+ float3 lightLevel;
+ lightLevel[0] = max(dot(Normal, sv), 0)*lightColour[0]*2;//+ambientColour[0];
+ lightLevel[1] = max(dot(Normal, sv), 0)*lightColour[1]*2;//+ambientColour[1];
+ lightLevel[2] = max(dot(Normal, sv), 0)*lightColour[2]*2;//+ambientColour[2];
+
+ return float4(tex2D(g_LandTextureSampler, input.LandTextureUV) * lightLevel, 1) + input.LandBumpDiffuse;
+
+
+
+ float4 normal = bx2(tex2D(g_LandBumpTextureSampler, input.LandBumpTextureUV));
+ float4 normalcol = bx2(input.LandDiffuse);
+
+ float3 normalMap;
+ normalMap = saturate((float4)dot((float3)normal, (float3)normalcol)).xyz;
+#ifdef MIX_4X
+ float3 texel = tex2D(g_LandTextureSampler, input.LandTextureUV).rgb * tex2D(g_LandTextureSampler, input.LandTextureUV * -0.25).rgb * 4;
+ float3 finalColor = 2.0 * (normalMap * (texel) + input.LandBumpDiffuse);
+#else
+ float3 finalColor = 2.0 * (normalMap * (tex2D(g_LandTextureSampler, input.LandTextureUV)) + input.LandBumpDiffuse);
+ //finalColor *= tex2D(g_ShoreTextureSampler, input.ShoreTextureUV);
+#endif
+
+ //finalColor = (g_TextureFactor * (1 - input.LandDiffuse)) + finalColor;
+
+ for (int i = 0; i < MAX_LIGHTS; i++)
+ {
+ // Get light direction for this fragment
+ float3 lightDir = normalize(input.WorldPos - g_LightPositions[i]); // per pixel diffuse lighting
+
+ // Note: Non-uniform scaling not supported
+ float diffuseLighting = saturate(dot(input.Normal, -lightDir));
+
+ // Introduce fall-off of light intensity
+ diffuseLighting *= (g_LightRangeSquared[i] / dot(g_LightPositions[i] - input.WorldPos, g_LightPositions[i] - input.WorldPos));
+
+ float4 diffuseColor = diffuseLighting * g_LightDiffuseColors[i];
+
+ finalColor += diffuseColor;
+ }
+
+ return float4(finalColor, 1);
+}
+
+technique LandNormal
+{
+ pass P0
+ {
+ VertexShader = compile vs_2_0 LandNormalVS();
+ PixelShader = compile ps_2_0 LandNormalPS();
+ }
+}
+
+//--------------------------------------------------------------------------------------
+// Vertex shader output structure
+//--------------------------------------------------------------------------------------
+struct VS_OUTPUT
+{
+ float4 Position : POSITION;
+ float4 Diffuse : COLOR0;
+ float2 TextureUV : TEXCOORD0;
+ float3 Normal : TEXCOORD1;
+ float3 WorldPos : TEXCOORD2;
+};
+
+VS_OUTPUT LandscapeVS( float4 vPos : POSITION,
+ float3 vNormal : NORMAL,
+ float4 vDiffuse : COLOR0)
+{
+ VS_OUTPUT Output;
+
+ // Transform the position from object space to homogeneous projection space
+ Output.Position = mul(vPos, g_mWorldViewProjection);
+
+ // Transform the normal from object space to world space
+ Output.Normal = normalize(mul(vNormal, (float3x3)g_World)); // normal (world space)
+
+ Output.Diffuse.rgb = vDiffuse;
+ Output.Diffuse.a = 1.0f;
+
+ Output.WorldPos = mul(vPos, g_World);
+
+ // Set dynamically generated tex coords
+ Output.TextureUV = mul(vPos, g_TexGenTransform0);
+
+ return Output;
+}
+
+float4 LandscapePS(VS_OUTPUT input) : COLOR0
+{
+ float4 finalColor = 0;
+
+ for (int i = 0; i < MAX_LIGHTS; i++)
+ {
+ // Get light direction for this fragment
+ float3 lightDir = normalize(input.WorldPos - g_LightPositions[i]); // per pixel diffuse lighting
+
+ // Note: Non-uniform scaling not supported
+ float diffuseLighting = saturate(dot(input.Normal, -lightDir));
+
+ // Introduce fall-off of light intensity
+ diffuseLighting *= (g_LightRangeSquared[i] / dot(g_LightPositions[i] - input.WorldPos, g_LightPositions[i] - input.WorldPos));
+
+ float4 diffuseColor = diffuseLighting * g_LightDiffuseColors[i];
+
+ finalColor += diffuseColor;
+ }
+
+#ifdef MIX_4X
+ float3 texel = tex2D(g_LandTextureSampler, input.TextureUV).rgb * tex2D(g_LandTextureSampler, input.TextureUV * -0.25).rgb * 4;
+#else
+ float3 texel = tex2D(g_LandTextureSampler, input.TextureUV);
+#endif
+ return float4(saturate((texel.xyz + input.Diffuse) + (finalColor)), 1.0f);
+}
+
+technique Landscape
+{
+ pass P0
+ {
+ VertexShader = compile vs_2_0 LandscapeVS();
+ PixelShader = compile ps_2_0 LandscapePS();
+ }
+}
\ No newline at end of file
diff --git a/Shaders/fx/Ocean.fx b/Shaders/fx/Ocean.fx
new file mode 100644
index 0000000..8e9f2b9
--- /dev/null
+++ b/Shaders/fx/Ocean.fx
@@ -0,0 +1,147 @@
+//--------------------------------------------------------------------------------------
+// Water.fx
+
+// Ocean water reflection shader.
+//--------------------------------------------------------------------------------------
+
+/* Original asm code:
+ ps_1_1
+ tex t0
+ tex t1
+ lrp r0, -v0.w, t0, t1 // lrp = linear interpolate
+*/
+
+struct PS_INPUT
+{
+ float4 color : COLOR0;
+ float4 texCoord0 : TEXCOORD0;
+ float4 texCoord1 : TEXCOORD1;
+};
+
+sampler s0, s1;
+
+float4 MainPS(const PS_INPUT input) : COLOR0
+{
+ // Interpolate linearly between Environment Texture, seabed, and inverted alpha of current pixel
+ return lerp(tex2D(s1, input.texCoord1), tex2D(s0, input.texCoord0), 1-input.color.a);
+}
+
+// C45: {0.00333, 0, 0, 0}
+// C44:
+// C27: {0, 1.0, 0.5, 0.25}
+// C26: {minfog, maxfog, 1.0f / (maxfog - minfog), 1.0}
+
+float4 const44 : register(c44);
+matrix matWorld : WorldViewProjectionTranspose : register(c2);
+float4 fog : register (c26);
+texture tex0;
+texture tex1;
+
+struct VS_OUTPUT
+{
+ float4 pos : POSITION;
+ float4 texCoord1 : TEXCOORD1;
+ //float4 texCoord0 : TEXCOORD0;
+ //float4 color : COLOR0;
+ //float fog : FOG;
+};
+
+struct VS_INPUT
+{
+ float4 pos : POSITION;
+};
+
+VS_OUTPUT MainVS(const VS_INPUT input)
+{
+ float4 const27 = {0.0f, 1.0f, 0.5f, 0.75f};
+ VS_OUTPUT output;
+
+ output.pos = mul(input.pos, matWorld);
+
+ // add r0, v0, -c44
+ float4 r0 = input.pos + -const44;
+
+ // mov r0.z, -r0.z
+ r0.z = -r0.z;
+
+ // dp3 r0.w, r0, r0
+ r0.w = dot(r0.xyz, r0.xyz);
+
+ // rsq r0.w, r0.w
+ r0.w = rsqrt(r0.w);
+
+
+ // mul oT1.x, -r0, r0.w
+ // mul oT1.y, r0, r0.w
+ // mul oT1.z, r0, r0.w
+ // mov oT1.w, c27.y
+ output.texCoord1.x = -r0 * r0.w;
+ output.texCoord1.y = r0 * r0.w;
+ output.texCoord1.z = r0 * r0.w;
+ output.texCoord1.w = const27.y;
+
+ return output;
+}
+
+technique t0
+{
+ pass p0
+ {
+ Texture[0] = ; // Seabed texture
+ Texture[1] = ; // Environment texture
+
+ // All of these constants are set by the game engine before drawing the shader
+ // Each constant register (c# in the asm code) has 4 floating point values
+
+ // World view matrix
+ VertexShaderConstant[2] = ;
+ VertexShaderConstant[3] = ;
+ VertexShaderConstant[4] = ;
+ VertexShaderConstant[5] = ;
+
+ VertexShaderConstant[26] = ; // This constant is calculated from the current fog min/max values
+ VertexShaderConstant[27] = {0.0f, 1.0f, 0.5f, 0.75f}; // I don't know what this does but it doesn't change
+ VertexShaderConstant[44] = ; // I don't know what this is
+ VertexShaderConstant[45] = {0.00033333333f, 0, 0, 0}; // I don't know what this does but it doesn't change
+#if 1 // 1 to use asm shader
+ VertexShader =
+ asm
+ {
+ vs_1_1
+ dcl_position v0
+ dcl_texcoord v2
+
+ /* Places the dot product of the world view matrix and v0 in the output register oPos */
+ dp4 oPos.x, v0, c2
+ dp4 oPos.y, v0, c3
+ dp4 oPos.z, v0, c4
+ dp4 oPos.w, v0, c5
+
+ // this is some kind of vector normalization or transform
+ add r0, v0, -c44
+ mov r0.z, -r0.z
+ dp3 r0.w, r0, r0
+ rsq r0.w, r0.w
+
+ /* Output register for texture 1 (environment texture) is modified by register 0 */
+ mul oT1.x, -r0, r0.w
+ mul oT1.y, r0, r0.w
+ mul oT1.z, r0, r0.w
+ mov oT1.w, c27.y
+
+ rcp r0.w, r0.w
+ mul r0.w, r0.w, c45.x
+ max r0.x, r0.w, c27.x
+ min oD0.w, r0.w, c27.y
+ mov oT0, v2
+ dp4 r0.z, v0, c5
+ add r0.x, -r0.z, c26.y
+ mul oFog, r0.x, c26.z
+ };
+#else
+ VertexShader = compile vs_1_1 MainVS();
+#endif
+
+ PixelShader = compile ps_1_3 MainPS(); // effect will not work > ps 1.3
+ }
+}
diff --git a/Shaders/fx/Sky.fx b/Shaders/fx/Sky.fx
new file mode 100644
index 0000000..951c61b
--- /dev/null
+++ b/Shaders/fx/Sky.fx
@@ -0,0 +1,61 @@
+//--------------------------------------------------------------------------------------
+// Sky.fx
+
+// Experimental sky shader. Does nothing currently.
+//--------------------------------------------------------------------------------------
+
+float4x4 g_mWorldViewProjection : WorldViewProjection;
+float4x4 g_World : World;
+float4x4 g_View : View;
+float4x4 g_Projection : Projection;
+float intensityThreshold = 1.f;
+float colorMultiplier = 1.f;
+texture g_SkyTexture;
+
+sampler g_SkyTextureSampler =
+sampler_state
+{
+ Texture = ;
+ MipFilter = LINEAR;
+ MinFilter = LINEAR;
+ MagFilter = LINEAR;
+};
+void RenderSceneVS(
+ float3 iPosition : POSITION,
+ float2 iTexCoord0 : TEXCOORD0,
+
+ out float4 oPosition : POSITION,
+ out float4 oColor0 : COLOR0,
+ out float2 oTexCoord0 : TEXCOORD0 )
+{
+ oPosition = mul(iPosition, g_mWorldViewProjection);
+ //oPosition = mul(iPosition, g_World);
+ //oPosition = mul(oPosition, g_View);
+ //oPosition = mul(oPosition, g_Projection);
+ oColor0 = float4(1, 1, 1, 1);
+ oTexCoord0 = iTexCoord0;
+}
+
+float4 RenderScenePS(
+ float4 iColor : COLOR,
+ float2 iTexCoord0 : TEXCOORD0) : COLOR0
+{
+ //return float4(1, 1, 1, 1);
+ return tex2D(g_SkyTextureSampler, iTexCoord0);
+ //oColor0 = tex2D(TextureDiffuse0Sampler, iTexCoord0);
+ //float intensity = dot(oColor0.rgb, float3(0.3, 0.59, 0.11));
+ //float p = smoothstep(intensityThreshold, 1.f, intensity);
+ //oColor0 = oColor0 * p * colorMultiplier;
+}
+
+technique RenderWithPixelShader
+{
+ pass Pass0
+ {
+ VertexShader = compile vs_1_1 RenderSceneVS();
+ PixelShader = compile ps_2_0 RenderScenePS();
+ ZEnable = FALSE;
+ ZWriteEnable = FALSE;
+ }
+}
+
diff --git a/Shaders/fx/Water.fx b/Shaders/fx/Water.fx
new file mode 100644
index 0000000..4eb501d
--- /dev/null
+++ b/Shaders/fx/Water.fx
@@ -0,0 +1,62 @@
+//--------------------------------------------------------------------------------------
+// Water.fx
+
+// Very basic shader that implements D3DTOP_ADDSMOOTH functionality in HLSL, replicating
+// the original fixed-function water rendering behavior.
+//--------------------------------------------------------------------------------------
+
+float4x4 g_WorldViewProjection : WorldViewProjection;
+float4 g_TextureFactor : TextureFactor;
+//float4 g_Fog : Fog;
+
+texture2D g_WaterTexture;
+sampler2D g_WaterTextureSampler =
+sampler_state
+{
+ Texture = ;
+};
+
+struct VS_OUTPUT
+{
+ float4 Position : POSITION; // vertex position
+ float2 TextureUV : TEXCOORD0; // vertex texture coords
+ float4 Color : COLOR0;
+ //float Fog : FOG;
+};
+
+VS_OUTPUT RenderSceneVS(float4 inPos : POSITION,
+ float4 inDiffuse : COLOR0,
+ float4 inTextureUV : TEXCOORD0)
+{
+ VS_OUTPUT Output;
+
+ Output.Position = mul(inPos, g_WorldViewProjection);
+ Output.TextureUV = inTextureUV;
+ Output.Color = inDiffuse;
+
+ // Don't think this is right, but we can use FFP fog unless this is compiled for SM 3.0
+ //float4 r0;
+ //r0.z = inPos.z * g_WorldViewProjection[3];
+ //r0.x = -r0.z + g_Fog.y;
+ //Output.Fog.x = r0.x * g_Fog.z;
+
+ return Output;
+}
+
+float4 RenderScenePS(VS_OUTPUT input) : COLOR0
+{
+ float4 texel = tex2D(g_WaterTextureSampler, input.TextureUV);
+ float4 result = saturate(texel + (1 - texel) * g_TextureFactor); // equivalent to saturate((texel + g_TextureFactor) - (texel * g_TextureFactor));
+ result.a = input.Color.a * g_TextureFactor.a;
+
+ return result;
+}
+
+technique RenderScene
+{
+ pass P0
+ {
+ VertexShader = compile vs_2_0 RenderSceneVS();
+ PixelShader = compile ps_2_0 RenderScenePS();
+ }
+}
\ No newline at end of file
diff --git a/Shaders/fxo/.gitkeep b/Shaders/fxo/.gitkeep
new file mode 100644
index 0000000..e69de29