Browse Source

Fixed crash in ShaderCompiler.
Split Common.hlsl into smaller hlsl include files.

Lasse Öörni 14 years ago
parent
commit
1d036b34ac

+ 2 - 2
CMakeLists.txt

@@ -90,13 +90,13 @@ macro (add_shader NAME)
     add_custom_command (
         OUTPUT ../../Bin/CoreData/Shaders/SM2/${NAME}.vs2
         COMMAND ../../Bin/ShaderCompiler ${NAME}.xml ../../Bin/CoreData/Shaders/SM2 SM2
-        DEPENDS ShaderCompiler Common.hlsl ${NAME}.hlsl ${NAME}.xml
+        DEPENDS ShaderCompiler Uniforms.hlsl Samplers.hlsl Transform.hlsl ScreenPos.hlsl Lighting.hlsl Fog.hlsl ${NAME}.hlsl ${NAME}.xml
     )
 
     add_custom_command (
         OUTPUT ../../Bin/CoreData/Shaders/SM3/${NAME}.vs3
         COMMAND ../../Bin/ShaderCompiler ${NAME}.xml ../../Bin/CoreData/Shaders/SM3 SM3
-        DEPENDS ShaderCompiler Common.hlsl ${NAME}.hlsl ${NAME}.xml
+        DEPENDS ShaderCompiler Uniforms.hlsl Samplers.hlsl Transform.hlsl ScreenPos.hlsl Lighting.hlsl Fog.hlsl ${NAME}.hlsl ${NAME}.xml
     )
 
     set (ALL_SHADERS ${ALL_SHADERS} ../../Bin/CoreData/Shaders/SM2/${NAME}.vs2 ../../Bin/CoreData/Shaders/SM3/${NAME}.vs3)

+ 2 - 0
Engine/Graphics/Shader.cpp

@@ -172,6 +172,8 @@ ShaderVariation* Shader::GetVariation(StringHash nameHash)
     // Create shader object now if not yet created. If fails, remove the variation
     if (!variation->GetGPUObject())
     {
+        LOGDEBUG("Creating variation " + variation->GetName() + " of shader " + GetName());
+        
         PROFILE(CreateShaderVariation);
         bool success = variation->Create();
         if (!success)

+ 14 - 20
Engine/IO/FileSystem.cpp

@@ -61,7 +61,7 @@ bool FileSystem::SetCurrentDir(const String& pathName)
         LOGERROR("Access denied to " + pathName);
         return false;
     }
-    if (SetCurrentDirectory(GetNativePath(pathName, true).CString()) == FALSE)
+    if (SetCurrentDirectory(GetNativePath(pathName).CString()) == FALSE)
     {
         LOGERROR("Failed to change directory to " + pathName);
         return false;
@@ -77,7 +77,7 @@ bool FileSystem::CreateDir(const String& pathName)
         return false;
     }
     
-    bool success = (CreateDirectory(GetNativePath(RemoveTrailingSlash(pathName), true).CString(), 0) == TRUE) ||
+    bool success = (CreateDirectory(GetNativePath(RemoveTrailingSlash(pathName)).CString(), 0) == TRUE) ||
         (GetLastError() == ERROR_ALREADY_EXISTS);
     if (success)
         LOGDEBUG("Created directory " + pathName);
@@ -102,7 +102,7 @@ int FileSystem::SystemRun(const String& fileName, const Vector<String>& argument
 {
     if (allowedPaths_.Empty())
     {
-        String fixedFileName = GetNativePath(fileName, true);
+        String fixedFileName = GetNativePath(fileName);
         
         PODVector<const char*> argPtrs;
         argPtrs.Push(fixedFileName.CString());
@@ -130,7 +130,7 @@ bool FileSystem::SystemOpen(const String& fileName, const String& mode)
         }
         
         bool success = (int)ShellExecute(0, !mode.Empty() ? (char*)mode.CString() : 0,
-            (char*)GetNativePath(fileName, true).CString(), 0, 0, SW_SHOW) > 32;
+            (char*)GetNativePath(fileName).CString(), 0, 0, SW_SHOW) > 32;
         if (!success)
             LOGERROR("Failed to open " + fileName + " externally");
         return success;
@@ -232,7 +232,7 @@ bool FileSystem::FileExists(const String& fileName)
     if (!CheckAccess(GetPath(fileName)))
         return false;
     
-    String fixedName = GetNativePath(RemoveTrailingSlash(fileName), true);
+    String fixedName = GetNativePath(RemoveTrailingSlash(fileName));
     DWORD attributes = GetFileAttributes(fixedName.CString());
     if ((attributes == INVALID_FILE_ATTRIBUTES) || (attributes & FILE_ATTRIBUTE_DIRECTORY))
         return false;
@@ -245,7 +245,7 @@ bool FileSystem::DirExists(const String& pathName)
     if (!CheckAccess(pathName))
         return false;
     
-    String fixedName = GetNativePath(RemoveTrailingSlash(pathName), true);
+    String fixedName = GetNativePath(RemoveTrailingSlash(pathName));
     DWORD attributes = GetFileAttributes(fixedName.CString());
     if ((attributes == INVALID_FILE_ATTRIBUTES) || (!(attributes & FILE_ATTRIBUTE_DIRECTORY)))
         return false;
@@ -300,7 +300,7 @@ void FileSystem::ScanDirInternal(Vector<String>& result, String path, const Stri
     const String& filter, unsigned flags, bool recursive)
 {
     path = AddTrailingSlash(path);
-    String pathAndFilter = GetNativePath(path + filter, true);
+    String pathAndFilter = GetNativePath(path + filter);
     String deltaPath;
     if (path.Length() > startPath.Length())
         deltaPath = path.Substring(startPath.Length());
@@ -424,19 +424,13 @@ String GetInternalPath(const String& pathName)
     return ret;
 }
 
-String GetNativePath(const String& pathName, bool forNativeApi)
+String GetNativePath(const String& pathName)
 {
-    // On MSVC, replace slash always with backslash. On MinGW only if going to do Win32 native calls
-#ifdef _MSC_VER
-    forNativeApi = true;
+#ifdef WIN32
+    String ret = pathName;
+    ret.Replace('/', '\\');
+    return ret;
+#else
+    return pathName;
 #endif
-    
-    if (forNativeApi)
-    {
-        String ret = pathName;
-        ret.Replace('/', '\\');
-        return ret;
-    }
-    else
-        return pathName;
 }

+ 1 - 1
Engine/IO/FileSystem.h

@@ -108,4 +108,4 @@ String GetParentPath(const String& pathName);
 /// Convert a path to internal format (use slashes)
 String GetInternalPath(const String& pathName);
 /// Convert a path to the format required by the operating system
-String GetNativePath(const String& pathName, bool forNativeApi = false);
+String GetNativePath(const String& pathName);

+ 5 - 3
SourceAssets/Shaders/Basic.hlsl

@@ -1,4 +1,6 @@
-#include "Common.hlsl"
+#include "Uniforms.hlsl"
+#include "Samplers.hlsl"
+#include "Transform.hlsl"
 
 void VS(float4 iPos : POSITION,
     #ifdef DIFFMAP
@@ -32,11 +34,11 @@ void PS(
     out float4 oColor : COLOR0)
 {
     float4 diffColor = cMatDiffColor;
-    
+
     #ifdef VERTEXCOLOR
         diffColor *= iColor;
     #endif
-    
+
     #if (!defined(DIFFMAP)) && (!defined(ALPHAMAP))
         oColor = diffColor;
     #endif

+ 0 - 326
SourceAssets/Shaders/Common.hlsl

@@ -1,326 +0,0 @@
-#pragma warning(disable:3571)
-
-// Vertex shader parameters
-uniform float3 cCameraPos : register(C0);
-uniform float3x3 cCameraRot : register(C1);
-uniform float4 cDepthMode : register(C4);
-uniform float2 cElapsedTime : register(C5);
-uniform float4 cFrustumSize : register(C6);
-uniform float4 cGBufferOffsets : register(C7);
-uniform float4x3 cModel : register(C8);
-uniform float4x4 cShadowProj : register(C11);
-uniform float4x4 cSpotProj : register(C15);
-uniform float4x4 cViewProj : register(C19);
-uniform float4 cUOffset : register(C23);
-uniform float4 cVOffset : register(C24);
-uniform float3 cViewRightVector : register(C25);
-uniform float3 cViewUpVector : register(C26);
-uniform float4x3 cSkinMatrices[64] : register(C27);
-
-// Pixel shader parameters
-uniform float3 cAmbientColor : register(C0);
-uniform float4 cAntiAliasWeights : register(C1);
-uniform float3 cCameraPosPS : register(C2);
-uniform float2 cElapsedTimePS : register(C3);
-uniform float4 cFogParams : register(C4);
-uniform float3 cFogColor : register(C5);
-uniform float4 cGBufferOffsetsPS : register(C6);
-uniform float4 cGBufferViewport : register(C7);
-uniform float cLightAtten : register(C8);
-uniform float4 cLightColor : register(C9);
-uniform float3 cLightDir : register(C10);
-uniform float3 cLightPos : register(C11);
-uniform float4 cLightSplits : register(C12);
-uniform float3x3 cLightVecRot: register(C13);
-uniform float4 cMatDiffColor : register(C16);
-uniform float3 cMatEmissiveColor : register(C17);
-uniform float2 cMatSpecProperties : register(C18);
-uniform float4 cSampleOffsets : register(C19);
-uniform float2 cShadowIntensity : register(C20);
-uniform float4x4 cShadowProjPS : register(C21);
-uniform float4x4 cSpotProjPS : register(C25);
-uniform float4x4 cViewProjPS : register(C25);
-
-// Material map samplers
-sampler2D sDiffMap : register(S0);
-samplerCUBE sDiffCubeMap : register(S0);
-sampler2D sNormalMap : register(S1);
-sampler2D sSpecMap : register(S2);
-sampler2D sDetailMap : register(S3);
-sampler2D sEnvMap : register(S4);
-samplerCUBE sEnvCubeMap : register(S4);
-sampler2D sEmissiveMap : register(S5);
-
-// Shadow and light shape samplers
-sampler2D sShadowMap : register(S5);
-sampler1D sLightRampMap : register(S6);
-sampler2D sLightSpotMap : register(S7);
-samplerCUBE sLightCubeMap : register(S7);
-
-// Rendertarget samplers
-sampler2D sDiffBuffer : register(S0);
-sampler2D sNormalBuffer : register(S1);
-sampler2D sDepthBuffer : register(S2);
-sampler2D sLightBuffer : register(S6);
-
-float4 Sample(sampler2D map, float2 texCoord)
-{
-    // Use tex2Dlod if available to avoid divergence and allow branching
-    #ifdef SM3
-        return tex2Dlod(map, float4(texCoord, 0.0, 0.0));
-    #else
-        return tex2D(map, texCoord);
-    #endif
-}
-
-float GetDepth(float4 clipPos)
-{
-    return dot(clipPos.zw, cDepthMode.zw);
-}
-
-float4 GetScreenPos(float4 clipPos)
-{
-    return float4(
-        clipPos.x * cGBufferOffsets.z + cGBufferOffsets.x * clipPos.w,
-        -clipPos.y * cGBufferOffsets.w + cGBufferOffsets.y * clipPos.w,
-        0.0,
-        clipPos.w);
-}
-
-float2 GetScreenPosPreDiv(float4 clipPos)
-{
-    return float2(
-        clipPos.x / clipPos.w * cGBufferOffsets.z + cGBufferOffsets.x,
-        -clipPos.y / clipPos.w * cGBufferOffsets.w + cGBufferOffsets.y);
-}
-
-float3 GetFarRay(float4 clipPos)
-{
-    float3 viewRay = float3(
-        clipPos.x / clipPos.w * cFrustumSize.x,
-        clipPos.y / clipPos.w * cFrustumSize.y,
-        cFrustumSize.z);
-
-    return mul(viewRay, cCameraRot);
-}
-
-float3 GetNearRay(float4 clipPos)
-{
-    float3 viewRay = float3(
-        clipPos.x / clipPos.w * cFrustumSize.x,
-        clipPos.y / clipPos.w * cFrustumSize.y,
-        0.0);
-    
-    return mul(viewRay, cCameraRot) * cDepthMode.z;
-}
-
-float GetIntensity(float3 color)
-{
-    return dot(color, float3(0.333, 0.333, 0.333));
-}
-
-float3 UnpackNormal(float4 normalInput)
-{
-    float3 normal;
-    normal.xy = normalInput.ag * 2.0 - 1.0;
-    normal.z = sqrt(1.0 - dot(normal.xy, normal.xy));
-    return normal;
-}
-
-float4 GetPosition(float4 iPos, out float4 oPos)
-{
-    float4 worldPos = float4(mul(iPos, cModel), 1.0);
-    oPos = mul(worldPos, cViewProj);
-    return worldPos;
-}
-
-float4 GetPositionBillboard(float4 iPos, float2 iSize, out float4 oPos)
-{
-    float4 worldPos = float4(iPos.xyz + iSize.x * cViewRightVector + iSize.y * cViewUpVector, 1.0);
-    oPos = mul(worldPos, cViewProj);
-    return worldPos;
-}
-
-float4 GetPositionSkinned(float4 iPos, float4 iBlendWeights, int4 iBlendIndices, out float4 oPos)
-{
-    float4x3 skinMatrix =
-        cSkinMatrices[iBlendIndices.x] * iBlendWeights.x +
-        cSkinMatrices[iBlendIndices.y] * iBlendWeights.y +
-        cSkinMatrices[iBlendIndices.z] * iBlendWeights.z +
-        cSkinMatrices[iBlendIndices.w] * iBlendWeights.w;
-    
-    float4 worldPos = float4(mul(iPos, skinMatrix), 1.0);
-    oPos = mul(worldPos, cViewProj);
-    return worldPos;
-}
-
-float4 GetPositionInstanced(float4 iPos, float4x3 iModel, out float4 oPos)
-{
-    float4 worldPos = float4(mul(iPos, iModel), 1.0);
-    oPos = mul(worldPos, cViewProj);
-    return worldPos;
-}
-
-float4 GetPositionNormal(float4 iPos, float3 iNormal, out float4 oPos, out float3 oNormal)
-{
-    float4 worldPos = float4(mul(iPos, cModel), 1.0);
-    oPos = mul(worldPos, cViewProj);
-    oNormal = normalize(mul(iNormal, (float3x3)cModel));
-    return worldPos;
-}
-
-float4 GetPositionNormalSkinned(float4 iPos, float3 iNormal, float4 iBlendWeights, int4 iBlendIndices, out float4 oPos, out float3 oNormal)
-{
-    float4x3 skinMatrix =
-        cSkinMatrices[iBlendIndices.x] * iBlendWeights.x +
-        cSkinMatrices[iBlendIndices.y] * iBlendWeights.y +
-        cSkinMatrices[iBlendIndices.z] * iBlendWeights.z +
-        cSkinMatrices[iBlendIndices.w] * iBlendWeights.w;
-
-    float4 worldPos = float4(mul(iPos, skinMatrix), 1.0);
-    oPos = mul(worldPos, cViewProj);
-    oNormal = normalize(mul(iNormal, (float3x3)skinMatrix));
-    return worldPos;
-}
-
-float4 GetPositionNormalInstanced(float4 iPos, float3 iNormal, float4x3 iModel, out float4 oPos, out float3 oNormal)
-{
-    float4 worldPos = float4(mul(iPos, iModel), 1.0);
-    oPos = mul(worldPos, cViewProj);
-    oNormal = normalize(mul(iNormal, (float3x3)iModel));
-    return worldPos;
-}
-
-float4 GetPositionNormalTangent(float4 iPos, float3 iNormal, float4 iTangent, out float4 oPos, out float3 oNormal, out float3 oTangent)
-{
-    float4 worldPos = float4(mul(iPos, cModel), 1.0);
-    oPos = mul(worldPos, cViewProj);
-    oNormal = normalize(mul(iNormal, (float3x3)cModel));
-    oTangent = normalize(mul(iTangent.xyz, (float3x3)cModel));
-    return worldPos;
-}
-
-float4 GetPositionNormalTangentSkinned(float4 iPos, float3 iNormal, float4 iTangent, float4 iBlendWeights, int4 iBlendIndices, out float4 oPos, out float3 oNormal, out float3 oTangent)
-{
-    float4x3 skinMatrix =
-        cSkinMatrices[iBlendIndices.x] * iBlendWeights.x +
-        cSkinMatrices[iBlendIndices.y] * iBlendWeights.y +
-        cSkinMatrices[iBlendIndices.z] * iBlendWeights.z +
-        cSkinMatrices[iBlendIndices.w] * iBlendWeights.w;
-
-    float4 worldPos = float4(mul(iPos, skinMatrix), 1.0);
-    oPos = mul(worldPos, cViewProj);
-    oNormal = normalize(mul(iNormal, (float3x3)skinMatrix));
-    oTangent = normalize(mul(iTangent.xyz, (float3x3)skinMatrix));
-    return worldPos;
-}
-
-float4 GetPositionNormalTangentInstanced(float4 iPos, float3 iNormal, float4 iTangent, float4x3 iModel, out float4 oPos, out float3 oNormal, out float3 oTangent)
-{
-    float4 worldPos = float4(mul(iPos, iModel), 1.0);
-    oPos = mul(worldPos, cViewProj);
-    oNormal = normalize(mul(iNormal, (float3x3)iModel));
-    oTangent = normalize(mul(iTangent.xyz, (float3x3)iModel));
-    return worldPos;
-}
-
-float2 GetTexCoord(float2 iTexCoord)
-{
-    return float2(dot(iTexCoord, cUOffset.xy) + cUOffset.w, dot(iTexCoord, cVOffset.xy) + cVOffset.w);
-};
-
-float GetDiffuseDir(float3 normal, out float3 lightDir)
-{
-    lightDir = cLightDir;
-    float NdotL = max(dot(normal, lightDir), 0.0);
-    return NdotL;
-}
-
-float GetDiffusePointOrSpot(float3 normal, float3 worldPos, out float3 lightDir, out float3 lightVec)
-{
-    lightVec = (cLightPos - worldPos) * cLightAtten.x;
-    float lightDist = length(lightVec);
-    lightDir = lightVec / lightDist;
-    float NdotL = max(dot(normal, lightDir), 0.0);
-    return NdotL * tex1D(sLightRampMap, lightDist).r;
-}
-
-float GetDiffuseDirVolumetric()
-{
-    return 1.0;
-}
-
-float GetDiffusePointOrSpotVolumetric(float3 worldPos, out float3 lightVec)
-{
-    lightVec = (cLightPos - worldPos) * cLightAtten.x;
-    float lightDist = length(lightVec);
-    return tex1D(sLightRampMap, lightDist).r;
-}
-
-float GetSplitFade(float depth)
-{
-    float nearFadeFactor = saturate((depth - cLightSplits.x) * cLightSplits.y);
-    float farFadeFactor = 1.0 - saturate((depth - cLightSplits.z) * cLightSplits.w);
-    return nearFadeFactor * farFadeFactor;
-}
-
-float GetSpecular(float3 normal, float3 worldPos, float3 lightDir, float specularPower)
-{
-    float3 eyeDir = normalize(-worldPos);
-    float3 halfDir = normalize(eyeDir + lightDir);
-    return pow(dot(normal, halfDir), specularPower);
-}
-
-float GetShadow(float4 shadowPos)
-{
-    // Take four samples and average them
-    float4 pcfValues = cShadowIntensity.x;
-    #ifdef SM3
-        float2 ofs = cSampleOffsets.xy;
-        float4 projShadowPos = float4(shadowPos.xyz / shadowPos.w, 0.0);
-        float4 inLight = float4(
-            tex2Dlod(sShadowMap, float4(projShadowPos.xy + float2(ofs.x, ofs.x), projShadowPos.zw)).r,
-            tex2Dlod(sShadowMap, float4(projShadowPos.xy + float2(ofs.y, ofs.x), projShadowPos.zw)).r,
-            tex2Dlod(sShadowMap, float4(projShadowPos.xy + float2(ofs.x, ofs.y), projShadowPos.zw)).r,
-            tex2Dlod(sShadowMap, float4(projShadowPos.xy + float2(ofs.y, ofs.y), projShadowPos.zw)).r
-        );
-        #ifdef HWSHADOW
-            return cShadowIntensity.y + dot(inLight, pcfValues);
-        #else
-            return cShadowIntensity.y + dot(inLight > projShadowPos.z, pcfValues);
-        #endif
-    #else
-        float2 projOfs = cSampleOffsets.xy * shadowPos.w;
-        float4 inLight = float4(
-            tex2Dproj(sShadowMap, float4(shadowPos.xy + float2(projOfs.x, projOfs.x), shadowPos.zw)).r,
-            tex2Dproj(sShadowMap, float4(shadowPos.xy + float2(projOfs.y, projOfs.x), shadowPos.zw)).r,
-            tex2Dproj(sShadowMap, float4(shadowPos.xy + float2(projOfs.x, projOfs.y), shadowPos.zw)).r,
-            tex2Dproj(sShadowMap, float4(shadowPos.xy + float2(projOfs.y, projOfs.y), shadowPos.zw)).r
-        );
-        #ifdef HWSHADOW
-            return cShadowIntensity.y + dot(inLight, pcfValues);
-        #else
-            return cShadowIntensity.y + dot((inLight * shadowPos.w) > shadowPos.z, pcfValues);
-        #endif
-    #endif
-}
-
-float3 GetFog(float3 color, float depth)
-{
-    return lerp(color, cFogColor, saturate((depth - cFogParams.x) * cFogParams.z));
-}
-
-float3 GetLitFog(float3 color, float depth)
-{
-    return color * saturate((cFogParams.y - depth) * cFogParams.z);
-}
-
-float GetFogFactor(float depth)
-{
-    return saturate((depth - cFogParams.x) * cFogParams.z);
-}
-
-float GetReverseFogFactor(float depth)
-{
-    return saturate((cFogParams.y - depth) * cFogParams.z);
-}

+ 5 - 1
SourceAssets/Shaders/Deferred/Ambient.hlsl

@@ -1,4 +1,8 @@
-#include "../Common.hlsl"
+#include "../Uniforms.hlsl"
+#include "../Samplers.hlsl"
+#include "../Transform.hlsl"
+#include "../ScreenPos.hlsl"
+#include "../Fog.hlsl"
 
 void VS(float4 iPos : POSITION,
     out float4 oPos : POSITION,

+ 7 - 4
SourceAssets/Shaders/Deferred/GBuffer.hlsl

@@ -1,4 +1,7 @@
-#include "../Common.hlsl"
+#include "../Uniforms.hlsl"
+#include "../Samplers.hlsl"
+#include "../Transform.hlsl"
+#include "../Fog.hlsl"
 
 void VS(float4 iPos : POSITION,
     float3 iNormal : NORMAL,
@@ -57,7 +60,7 @@ void VS(float4 iPos : POSITION,
     #ifdef VERTEXCOLOR
         oColor = iColor;
     #endif
-    
+
     oTexCoord = GetTexCoord(iTexCoord);
     oDepth = GetDepth(oPos);
 }
@@ -93,14 +96,14 @@ void PS(
     #ifdef VERTEXCOLOR
         diffColor *= iColor.rgb;
     #endif
-    
+
     #ifdef NORMALMAP
         float3x3 tbn = float3x3(iTangent, iBitangent, iNormal);
         float3 normal = normalize(mul(UnpackNormal(tex2D(sNormalMap, iTexCoord)), tbn));
     #else
         float3 normal = normalize(iNormal);
     #endif
-    
+
     #ifdef SPECMAP
         float specStrength = tex2D(sSpecMap, iTexCoord).r * cMatSpecProperties.x;
     #else

+ 2 - 1
SourceAssets/Shaders/Deferred/GBufferFill.hlsl

@@ -1,4 +1,5 @@
-#include "../Common.hlsl"
+#include "../Uniforms.hlsl"
+#include "../Transform.hlsl"
 
 void VS(float4 iPos : POSITION,
     out float4 oPos : POSITION)

+ 5 - 1
SourceAssets/Shaders/Deferred/Light.hlsl

@@ -1,4 +1,8 @@
-#include "../Common.hlsl"
+#include "../Uniforms.hlsl"
+#include "../Samplers.hlsl"
+#include "../Transform.hlsl"
+#include "../ScreenPos.hlsl"
+#include "../Lighting.hlsl"
 
 void VS(float4 iPos : POSITION,
     #ifdef DIRLIGHT

+ 19 - 0
SourceAssets/Shaders/Fog.hlsl

@@ -0,0 +1,19 @@
+float3 GetFog(float3 color, float depth)
+{
+    return lerp(color, cFogColor, saturate((depth - cFogParams.x) * cFogParams.z));
+}
+
+float3 GetLitFog(float3 color, float depth)
+{
+    return color * saturate((cFogParams.y - depth) * cFogParams.z);
+}
+
+float GetFogFactor(float depth)
+{
+    return saturate((depth - cFogParams.x) * cFogParams.z);
+}
+
+float GetReverseFogFactor(float depth)
+{
+    return saturate((cFogParams.y - depth) * cFogParams.z);
+}

+ 5 - 1
SourceAssets/Shaders/Forward.hlsl

@@ -1,4 +1,8 @@
-#include "Common.hlsl"
+#include "Uniforms.hlsl"
+#include "Samplers.hlsl"
+#include "Transform.hlsl"
+#include "Lighting.hlsl"
+#include "Fog.hlsl"
 
 void VS(float4 iPos : POSITION,
     float3 iNormal : NORMAL,

+ 75 - 0
SourceAssets/Shaders/Lighting.hlsl

@@ -0,0 +1,75 @@
+float GetDiffuseDir(float3 normal, out float3 lightDir)
+{
+    lightDir = cLightDir;
+    float NdotL = max(dot(normal, lightDir), 0.0);
+    return NdotL;
+}
+
+float GetDiffusePointOrSpot(float3 normal, float3 worldPos, out float3 lightDir, out float3 lightVec)
+{
+    lightVec = (cLightPos - worldPos) * cLightAtten.x;
+    float lightDist = length(lightVec);
+    lightDir = lightVec / lightDist;
+    float NdotL = max(dot(normal, lightDir), 0.0);
+    return NdotL * tex1D(sLightRampMap, lightDist).r;
+}
+
+float GetDiffuseDirVolumetric()
+{
+    return 1.0;
+}
+
+float GetDiffusePointOrSpotVolumetric(float3 worldPos, out float3 lightVec)
+{
+    lightVec = (cLightPos - worldPos) * cLightAtten.x;
+    float lightDist = length(lightVec);
+    return tex1D(sLightRampMap, lightDist).r;
+}
+
+float GetSplitFade(float depth)
+{
+    float nearFadeFactor = saturate((depth - cLightSplits.x) * cLightSplits.y);
+    float farFadeFactor = 1.0 - saturate((depth - cLightSplits.z) * cLightSplits.w);
+    return nearFadeFactor * farFadeFactor;
+}
+
+float GetSpecular(float3 normal, float3 worldPos, float3 lightDir, float specularPower)
+{
+    float3 eyeDir = normalize(-worldPos);
+    float3 halfDir = normalize(eyeDir + lightDir);
+    return pow(dot(normal, halfDir), specularPower);
+}
+
+float GetShadow(float4 shadowPos)
+{
+    // Take four samples and average them
+    float4 pcfValues = cShadowIntensity.x;
+    #ifdef SM3
+        float2 ofs = cSampleOffsets.xy;
+        float4 projShadowPos = float4(shadowPos.xyz / shadowPos.w, 0.0);
+        float4 inLight = float4(
+            tex2Dlod(sShadowMap, float4(projShadowPos.xy + float2(ofs.x, ofs.x), projShadowPos.zw)).r,
+            tex2Dlod(sShadowMap, float4(projShadowPos.xy + float2(ofs.y, ofs.x), projShadowPos.zw)).r,
+            tex2Dlod(sShadowMap, float4(projShadowPos.xy + float2(ofs.x, ofs.y), projShadowPos.zw)).r,
+            tex2Dlod(sShadowMap, float4(projShadowPos.xy + float2(ofs.y, ofs.y), projShadowPos.zw)).r
+        );
+        #ifdef HWSHADOW
+            return cShadowIntensity.y + dot(inLight, pcfValues);
+        #else
+            return cShadowIntensity.y + dot(inLight > projShadowPos.z, pcfValues);
+        #endif
+    #else
+        float2 projOfs = cSampleOffsets.xy * shadowPos.w;
+        float4 inLight = float4(
+            tex2Dproj(sShadowMap, float4(shadowPos.xy + float2(projOfs.x, projOfs.x), shadowPos.zw)).r,
+            tex2Dproj(sShadowMap, float4(shadowPos.xy + float2(projOfs.y, projOfs.x), shadowPos.zw)).r,
+            tex2Dproj(sShadowMap, float4(shadowPos.xy + float2(projOfs.x, projOfs.y), shadowPos.zw)).r,
+            tex2Dproj(sShadowMap, float4(shadowPos.xy + float2(projOfs.y, projOfs.y), shadowPos.zw)).r
+        );
+        #ifdef HWSHADOW
+            return cShadowIntensity.y + dot(inLight, pcfValues);
+        #else
+            return cShadowIntensity.y + dot((inLight * shadowPos.w) > shadowPos.z, pcfValues);
+        #endif
+    #endif
+}

+ 4 - 2
SourceAssets/Shaders/Prepass/GBuffer.hlsl

@@ -1,4 +1,6 @@
-#include "../Common.hlsl"
+#include "../Uniforms.hlsl"
+#include "../Samplers.hlsl"
+#include "../Transform.hlsl"
 
 void VS(float4 iPos : POSITION,
     float3 iNormal : NORMAL,
@@ -48,7 +50,7 @@ void VS(float4 iPos : POSITION,
 
     oTexCoord = GetTexCoord(iTexCoord);
     oDepth = GetDepth(oPos);
-    
+
     #ifdef NORMALMAP
         oBitangent = cross(oTangent, oNormal) * iTangent.w;
     #endif

+ 5 - 1
SourceAssets/Shaders/Prepass/Light.hlsl

@@ -1,4 +1,8 @@
-#include "../Common.hlsl"
+#include "../Uniforms.hlsl"
+#include "../Samplers.hlsl"
+#include "../Transform.hlsl"
+#include "../ScreenPos.hlsl"
+#include "../Lighting.hlsl"
 
 void VS(float4 iPos : POSITION,
     #ifdef DIRLIGHT

+ 5 - 1
SourceAssets/Shaders/Prepass/Material.hlsl

@@ -1,4 +1,8 @@
-#include "../Common.hlsl"
+#include "../Uniforms.hlsl"
+#include "../Samplers.hlsl"
+#include "../Transform.hlsl"
+#include "../ScreenPos.hlsl"
+#include "../Fog.hlsl"
 
 void VS(float4 iPos : POSITION,
     #ifdef SKINNED

+ 44 - 0
SourceAssets/Shaders/Samplers.hlsl

@@ -0,0 +1,44 @@
+// Material map samplers
+sampler2D sDiffMap : register(S0);
+samplerCUBE sDiffCubeMap : register(S0);
+sampler2D sNormalMap : register(S1);
+sampler2D sSpecMap : register(S2);
+sampler2D sDetailMap : register(S3);
+sampler2D sEnvMap : register(S4);
+samplerCUBE sEnvCubeMap : register(S4);
+sampler2D sEmissiveMap : register(S5);
+
+// Shadow and light shape samplers
+sampler2D sShadowMap : register(S5);
+sampler1D sLightRampMap : register(S6);
+sampler2D sLightSpotMap : register(S7);
+samplerCUBE sLightCubeMap : register(S7);
+
+// Rendertarget samplers
+sampler2D sDiffBuffer : register(S0);
+sampler2D sNormalBuffer : register(S1);
+sampler2D sDepthBuffer : register(S2);
+sampler2D sLightBuffer : register(S6);
+
+float4 Sample(sampler2D map, float2 texCoord)
+{
+    // Use tex2Dlod if available to avoid divergence and allow branching
+    #ifdef SM3
+        return tex2Dlod(map, float4(texCoord, 0.0, 0.0));
+    #else
+        return tex2D(map, texCoord);
+    #endif
+}
+
+float3 UnpackNormal(float4 normalInput)
+{
+    float3 normal;
+    normal.xy = normalInput.ag * 2.0 - 1.0;
+    normal.z = sqrt(1.0 - dot(normal.xy, normal.xy));
+    return normal;
+}
+
+float GetIntensity(float3 color)
+{
+    return dot(color, float3(0.333, 0.333, 0.333));
+}

+ 35 - 0
SourceAssets/Shaders/ScreenPos.hlsl

@@ -0,0 +1,35 @@
+float4 GetScreenPos(float4 clipPos)
+{
+    return float4(
+        clipPos.x * cGBufferOffsets.z + cGBufferOffsets.x * clipPos.w,
+        -clipPos.y * cGBufferOffsets.w + cGBufferOffsets.y * clipPos.w,
+        0.0,
+        clipPos.w);
+}
+
+float2 GetScreenPosPreDiv(float4 clipPos)
+{
+    return float2(
+        clipPos.x / clipPos.w * cGBufferOffsets.z + cGBufferOffsets.x,
+        -clipPos.y / clipPos.w * cGBufferOffsets.w + cGBufferOffsets.y);
+}
+
+float3 GetFarRay(float4 clipPos)
+{
+    float3 viewRay = float3(
+        clipPos.x / clipPos.w * cFrustumSize.x,
+        clipPos.y / clipPos.w * cFrustumSize.y,
+        cFrustumSize.z);
+
+    return mul(viewRay, cCameraRot);
+}
+
+float3 GetNearRay(float4 clipPos)
+{
+    float3 viewRay = float3(
+        clipPos.x / clipPos.w * cFrustumSize.x,
+        clipPos.y / clipPos.w * cFrustumSize.y,
+        0.0);
+
+    return mul(viewRay, cCameraRot) * cDepthMode.z;
+}

+ 3 - 1
SourceAssets/Shaders/Shadow.hlsl

@@ -1,4 +1,6 @@
-#include "Common.hlsl"
+#include "Uniforms.hlsl"
+#include "Samplers.hlsl"
+#include "Transform.hlsl"
 
 void VS(float4 iPos : POSITION,
     #ifdef SKINNED

+ 3 - 1
SourceAssets/Shaders/Skybox.hlsl

@@ -1,4 +1,6 @@
-#include "Common.hlsl"
+#include "Uniforms.hlsl"
+#include "Samplers.hlsl"
+#include "Transform.hlsl"
 
 void VS(float4 iPos : POSITION,
     out float4 oPos : POSITION,

+ 2 - 1
SourceAssets/Shaders/Stencil.hlsl

@@ -1,4 +1,5 @@
-#include "Common.hlsl"
+#include "Uniforms.hlsl"
+#include "Transform.hlsl"
 
 void VS(float4 iPos : POSITION,
     out float4 oPos : POSITION)

+ 4 - 1
SourceAssets/Shaders/TemporalAA.hlsl

@@ -1,4 +1,7 @@
-#include "Common.hlsl"
+#include "Uniforms.hlsl"
+#include "Samplers.hlsl"
+#include "Transform.hlsl"
+#include "ScreenPos.hlsl"
 
 void VS(float4 iPos : POSITION,
     out float4 oPos : POSITION,

+ 99 - 0
SourceAssets/Shaders/Transform.hlsl

@@ -0,0 +1,99 @@
+float4x3 GetSkinMatrix(float4 blendWeights, int4 blendIndices)
+{
+    return cSkinMatrices[blendIndices.x] * blendWeights.x +
+        cSkinMatrices[blendIndices.y] * blendWeights.y +
+        cSkinMatrices[blendIndices.z] * blendWeights.z +
+        cSkinMatrices[blendIndices.w] * blendWeights.w;
+}
+
+float2 GetTexCoord(float2 iTexCoord)
+{
+    return float2(dot(iTexCoord, cUOffset.xy) + cUOffset.w, dot(iTexCoord, cVOffset.xy) + cVOffset.w);
+};
+
+float GetDepth(float4 clipPos)
+{
+    return dot(clipPos.zw, cDepthMode.zw);
+}
+
+float4 GetPosition(float4 iPos, out float4 oPos)
+{
+    float4 worldPos = float4(mul(iPos, cModel), 1.0);
+    oPos = mul(worldPos, cViewProj);
+    return worldPos;
+}
+
+float4 GetPositionBillboard(float4 iPos, float2 iSize, out float4 oPos)
+{
+    float4 worldPos = float4(iPos.xyz + iSize.x * cViewRightVector + iSize.y * cViewUpVector, 1.0);
+    oPos = mul(worldPos, cViewProj);
+    return worldPos;
+}
+
+float4 GetPositionSkinned(float4 iPos, float4 iBlendWeights, int4 iBlendIndices, out float4 oPos)
+{
+    float4x3 skinMatrix = GetSkinMatrix(iBlendWeights, iBlendIndices);
+    float4 worldPos = float4(mul(iPos, skinMatrix), 1.0);
+    oPos = mul(worldPos, cViewProj);
+    return worldPos;
+}
+
+float4 GetPositionInstanced(float4 iPos, float4x3 iModel, out float4 oPos)
+{
+    float4 worldPos = float4(mul(iPos, iModel), 1.0);
+    oPos = mul(worldPos, cViewProj);
+    return worldPos;
+}
+
+float4 GetPositionNormal(float4 iPos, float3 iNormal, out float4 oPos, out float3 oNormal)
+{
+    float4 worldPos = float4(mul(iPos, cModel), 1.0);
+    oPos = mul(worldPos, cViewProj);
+    oNormal = normalize(mul(iNormal, (float3x3)cModel));
+    return worldPos;
+}
+
+float4 GetPositionNormalSkinned(float4 iPos, float3 iNormal, float4 iBlendWeights, int4 iBlendIndices, out float4 oPos, out float3 oNormal)
+{
+    float4x3 skinMatrix = GetSkinMatrix(iBlendWeights, iBlendIndices);
+    float4 worldPos = float4(mul(iPos, skinMatrix), 1.0);
+    oPos = mul(worldPos, cViewProj);
+    oNormal = normalize(mul(iNormal, (float3x3)skinMatrix));
+    return worldPos;
+}
+
+float4 GetPositionNormalInstanced(float4 iPos, float3 iNormal, float4x3 iModel, out float4 oPos, out float3 oNormal)
+{
+    float4 worldPos = float4(mul(iPos, iModel), 1.0);
+    oPos = mul(worldPos, cViewProj);
+    oNormal = normalize(mul(iNormal, (float3x3)iModel));
+    return worldPos;
+}
+
+float4 GetPositionNormalTangent(float4 iPos, float3 iNormal, float4 iTangent, out float4 oPos, out float3 oNormal, out float3 oTangent)
+{
+    float4 worldPos = float4(mul(iPos, cModel), 1.0);
+    oPos = mul(worldPos, cViewProj);
+    oNormal = normalize(mul(iNormal, (float3x3)cModel));
+    oTangent = normalize(mul(iTangent.xyz, (float3x3)cModel));
+    return worldPos;
+}
+
+float4 GetPositionNormalTangentSkinned(float4 iPos, float3 iNormal, float4 iTangent, float4 iBlendWeights, int4 iBlendIndices, out float4 oPos, out float3 oNormal, out float3 oTangent)
+{
+    float4x3 skinMatrix = GetSkinMatrix(iBlendWeights, iBlendIndices);
+    float4 worldPos = float4(mul(iPos, skinMatrix), 1.0);
+    oPos = mul(worldPos, cViewProj);
+    oNormal = normalize(mul(iNormal, (float3x3)skinMatrix));
+    oTangent = normalize(mul(iTangent.xyz, (float3x3)skinMatrix));
+    return worldPos;
+}
+
+float4 GetPositionNormalTangentInstanced(float4 iPos, float3 iNormal, float4 iTangent, float4x3 iModel, out float4 oPos, out float3 oNormal, out float3 oTangent)
+{
+    float4 worldPos = float4(mul(iPos, iModel), 1.0);
+    oPos = mul(worldPos, cViewProj);
+    oNormal = normalize(mul(iNormal, (float3x3)iModel));
+    oTangent = normalize(mul(iTangent.xyz, (float3x3)iModel));
+    return worldPos;
+}

+ 40 - 0
SourceAssets/Shaders/Uniforms.hlsl

@@ -0,0 +1,40 @@
+// Vertex shader parameters
+uniform float3 cCameraPos : register(C0);
+uniform float3x3 cCameraRot : register(C1);
+uniform float4 cDepthMode : register(C4);
+uniform float2 cElapsedTime : register(C5);
+uniform float4 cFrustumSize : register(C6);
+uniform float4 cGBufferOffsets : register(C7);
+uniform float4x3 cModel : register(C8);
+uniform float4x4 cShadowProj : register(C11);
+uniform float4x4 cSpotProj : register(C15);
+uniform float4x4 cViewProj : register(C19);
+uniform float4 cUOffset : register(C23);
+uniform float4 cVOffset : register(C24);
+uniform float3 cViewRightVector : register(C25);
+uniform float3 cViewUpVector : register(C26);
+uniform float4x3 cSkinMatrices[64] : register(C27);
+
+// Pixel shader parameters
+uniform float3 cAmbientColor : register(C0);
+uniform float4 cAntiAliasWeights : register(C1);
+uniform float3 cCameraPosPS : register(C2);
+uniform float2 cElapsedTimePS : register(C3);
+uniform float4 cFogParams : register(C4);
+uniform float3 cFogColor : register(C5);
+uniform float4 cGBufferOffsetsPS : register(C6);
+uniform float4 cGBufferViewport : register(C7);
+uniform float cLightAtten : register(C8);
+uniform float4 cLightColor : register(C9);
+uniform float3 cLightDir : register(C10);
+uniform float3 cLightPos : register(C11);
+uniform float4 cLightSplits : register(C12);
+uniform float3x3 cLightVecRot: register(C13);
+uniform float4 cMatDiffColor : register(C16);
+uniform float3 cMatEmissiveColor : register(C17);
+uniform float2 cMatSpecProperties : register(C18);
+uniform float4 cSampleOffsets : register(C19);
+uniform float2 cShadowIntensity : register(C20);
+uniform float4x4 cShadowProjPS : register(C21);
+uniform float4x4 cSpotProjPS : register(C25);
+uniform float4x4 cViewProjPS : register(C25);

+ 33 - 31
Tools/ShaderCompiler/ShaderCompiler.cpp

@@ -668,42 +668,44 @@ void Compile(CompiledVariation* variation)
         compileFailed_ = true;
     }
     else
-        CopyStrippedCode(variation->byteCode_, shaderCode->GetBufferPointer(), shaderCode->GetBufferSize());
-    
-    // Parse the constant table for constants and texture units
-    D3DXCONSTANTTABLE_DESC desc;
-    constantTable->GetDesc(&desc);
-    for (unsigned i = 0; i < desc.Constants; ++i)
     {
-        D3DXHANDLE handle = constantTable->GetConstant(NULL, i);
-        D3DXCONSTANT_DESC constantDesc;
-        unsigned numElements = 1;
-        constantTable->GetConstantDesc(handle, &constantDesc, &numElements);
-        
-        String name(constantDesc.Name);
-        unsigned index = constantDesc.RegisterIndex;
-        
-        // Check if the parameter is a constant or a texture sampler
-        bool isSampler = (name[0] == 's');
-        name = name.Substring(1);
-        
-        MutexLock lock(globalParamMutex_);
+        CopyStrippedCode(variation->byteCode_, shaderCode->GetBufferPointer(), shaderCode->GetBufferSize());
         
-        if (isSampler)
+        // Parse the constant table for constants and texture units
+        D3DXCONSTANTTABLE_DESC desc;
+        constantTable->GetDesc(&desc);
+        for (unsigned i = 0; i < desc.Constants; ++i)
         {
-            // Skip if it's a G-buffer sampler
-            if (name.Find("Buffer") == String::NPOS)
+            D3DXHANDLE handle = constantTable->GetConstant(NULL, i);
+            D3DXCONSTANT_DESC constantDesc;
+            unsigned numElements = 1;
+            constantTable->GetConstantDesc(handle, &constantDesc, &numElements);
+            
+            String name(constantDesc.Name);
+            unsigned index = constantDesc.RegisterIndex;
+            
+            // Check if the parameter is a constant or a texture sampler
+            bool isSampler = (name[0] == 's');
+            name = name.Substring(1);
+            
+            MutexLock lock(globalParamMutex_);
+            
+            if (isSampler)
             {
-                Parameter newTextureUnit(name, index);
-                variation->textureUnits_.Insert(newTextureUnit);
-                textureUnits_.Insert(newTextureUnit);
+                // Skip if it's a G-buffer sampler
+                if (name.Find("Buffer") == String::NPOS)
+                {
+                    Parameter newTextureUnit(name, index);
+                    variation->textureUnits_.Insert(newTextureUnit);
+                    textureUnits_.Insert(newTextureUnit);
+                }
+            }
+            else
+            {
+                Parameter newParam(name, index);
+                variation->constants_.Insert(newParam);
+                constants_.Insert(newParam);
             }
-        }
-        else
-        {
-            Parameter newParam(name, index);
-            variation->constants_.Insert(newParam);
-            constants_.Insert(newParam);
         }
     }