Browse Source

Added initial light pre-pass shaders.

Lasse Öörni 14 years ago
parent
commit
c20e0ada86

+ 1 - 1
CMakeLists.txt

@@ -107,7 +107,7 @@ else()
         add_custom_command (
         add_custom_command (
             OUTPUT ../../Bin/CoreData/Shaders/SM2/${NAME}.vs2
             OUTPUT ../../Bin/CoreData/Shaders/SM2/${NAME}.vs2
             COMMAND ../../Bin/ShaderCompiler ${NAME}.xml ../../Bin/CoreData/Shaders/SM2 SM2
             COMMAND ../../Bin/ShaderCompiler ${NAME}.xml ../../Bin/CoreData/Shaders/SM2 SM2
-            DEPENDS ShaderCompiler Uniforms.hlsl Samplers.hlsl Transform.hlsl Lighting.hlsl Fog.hlsl ${NAME}.hlsl ${NAME}.xml
+            DEPENDS ShaderCompiler Uniforms.hlsl Samplers.hlsl Transform.hlsl Lighting.hlsl ScreenPos.hlsl Fog.hlsl ${NAME}.hlsl ${NAME}.xml
         )
         )
             
             
         add_custom_command (
         add_custom_command (

+ 5 - 0
Engine/Graphics/GraphicsDefs.cpp

@@ -29,6 +29,8 @@
 StringHash VSP_CAMERAPOS("CameraPos");
 StringHash VSP_CAMERAPOS("CameraPos");
 StringHash VSP_CAMERAROT("CameraRot");
 StringHash VSP_CAMERAROT("CameraRot");
 StringHash VSP_DEPTHMODE("DepthMode");
 StringHash VSP_DEPTHMODE("DepthMode");
+StringHash VSP_FRUSTUMSIZE("FrustumSize");
+StringHash VSP_GBUFFEROFFSETS("GBufferOffsets");
 StringHash VSP_LIGHTDIR("LightDir");
 StringHash VSP_LIGHTDIR("LightDir");
 StringHash VSP_LIGHTPOS("LightPos");
 StringHash VSP_LIGHTPOS("LightPos");
 StringHash VSP_LIGHTVECROT("LightVecRot");
 StringHash VSP_LIGHTVECROT("LightVecRot");
@@ -48,6 +50,8 @@ StringHash PSP_AMBIENTENDCOLOR("AmbientEndColor");
 StringHash PSP_FOGCOLOR("FogColor");
 StringHash PSP_FOGCOLOR("FogColor");
 StringHash PSP_FOGPARAMS("FogParams");
 StringHash PSP_FOGPARAMS("FogParams");
 StringHash PSP_LIGHTCOLOR("LightColor");
 StringHash PSP_LIGHTCOLOR("LightColor");
+StringHash PSP_LIGHTDIR("LightDirPS");
+StringHash PSP_LIGHTPOS("LightPosPS");
 StringHash PSP_MATDIFFCOLOR("MatDiffColor");
 StringHash PSP_MATDIFFCOLOR("MatDiffColor");
 StringHash PSP_MATEMISSIVECOLOR("MatEmissiveColor");
 StringHash PSP_MATEMISSIVECOLOR("MatEmissiveColor");
 StringHash PSP_MATSPECPROPERTIES("MatSpecProperties");
 StringHash PSP_MATSPECPROPERTIES("MatSpecProperties");
@@ -56,3 +60,4 @@ StringHash PSP_SHADOWCUBEADJUST("ShadowCubeAdjust");
 StringHash PSP_SHADOWDEPTHFADE("ShadowDepthFade");
 StringHash PSP_SHADOWDEPTHFADE("ShadowDepthFade");
 StringHash PSP_SHADOWINTENSITY("ShadowIntensity");
 StringHash PSP_SHADOWINTENSITY("ShadowIntensity");
 StringHash PSP_SHADOWSPLITS("ShadowSplits");
 StringHash PSP_SHADOWSPLITS("ShadowSplits");
+StringHash PSP_SHADOWPROJ("ShadowProjPS");

+ 5 - 0
Engine/Graphics/GraphicsDefs.h

@@ -199,6 +199,8 @@ enum ShaderType
 extern StringHash VSP_CAMERAPOS;
 extern StringHash VSP_CAMERAPOS;
 extern StringHash VSP_CAMERAROT;
 extern StringHash VSP_CAMERAROT;
 extern StringHash VSP_DEPTHMODE;
 extern StringHash VSP_DEPTHMODE;
+extern StringHash VSP_FRUSTUMSIZE;
+extern StringHash VSP_GBUFFEROFFSETS;
 extern StringHash VSP_LIGHTDIR;
 extern StringHash VSP_LIGHTDIR;
 extern StringHash VSP_LIGHTPOS;
 extern StringHash VSP_LIGHTPOS;
 extern StringHash VSP_LIGHTVECROT;
 extern StringHash VSP_LIGHTVECROT;
@@ -218,6 +220,8 @@ extern StringHash PSP_AMBIENTENDCOLOR;
 extern StringHash PSP_FOGCOLOR;
 extern StringHash PSP_FOGCOLOR;
 extern StringHash PSP_FOGPARAMS;
 extern StringHash PSP_FOGPARAMS;
 extern StringHash PSP_LIGHTCOLOR;
 extern StringHash PSP_LIGHTCOLOR;
+extern StringHash PSP_LIGHTDIR;
+extern StringHash PSP_LIGHTPOS;
 extern StringHash PSP_MATDIFFCOLOR;
 extern StringHash PSP_MATDIFFCOLOR;
 extern StringHash PSP_MATEMISSIVECOLOR;
 extern StringHash PSP_MATEMISSIVECOLOR;
 extern StringHash PSP_MATSPECPROPERTIES;
 extern StringHash PSP_MATSPECPROPERTIES;
@@ -226,6 +230,7 @@ extern StringHash PSP_SHADOWCUBEADJUST;
 extern StringHash PSP_SHADOWDEPTHFADE;
 extern StringHash PSP_SHADOWDEPTHFADE;
 extern StringHash PSP_SHADOWINTENSITY;
 extern StringHash PSP_SHADOWINTENSITY;
 extern StringHash PSP_SHADOWSPLITS;
 extern StringHash PSP_SHADOWSPLITS;
+extern StringHash PSP_SHADOWPROJ;
 
 
 /// Texture units.
 /// Texture units.
 enum TextureUnit
 enum TextureUnit

+ 3 - 0
SourceAssets/HLSLShaders/CMakeLists.txt

@@ -3,6 +3,9 @@ set (ALL_SHADERS)
 add_shader (Ambient)
 add_shader (Ambient)
 add_shader (Basic)
 add_shader (Basic)
 add_shader (BlinnPhong)
 add_shader (BlinnPhong)
+add_shader (GBuffer)
+add_shader (LightVolume)
+add_shader (Material)
 add_shader (Shadow)
 add_shader (Shadow)
 add_shader (Stencil)
 add_shader (Stencil)
 add_shader (Unlit)
 add_shader (Unlit)

+ 94 - 0
SourceAssets/HLSLShaders/GBuffer.hlsl

@@ -0,0 +1,94 @@
+#include "Uniforms.hlsl"
+#include "Samplers.hlsl"
+#include "Transform.hlsl"
+#include "Fog.hlsl"
+
+void VS(float4 iPos : POSITION,
+    float3 iNormal : NORMAL,
+    #ifdef NORMALMAP
+        float4 iTangent : TANGENT0,
+    #endif
+    float2 iTexCoord : TEXCOORD0,
+    #ifdef SKINNED
+        float4 iBlendWeights : BLENDWEIGHT,
+        int4 iBlendIndices : BLENDINDICES,
+    #endif
+    #ifdef INSTANCED
+        float4x3 iModelInstance : TEXCOORD2,
+    #endif
+    out float2 oTexCoord : TEXCOORD0,
+    #ifndef HWDEPTH
+        out float oDepth : TEXCOORD1,
+    #endif
+    out float3 oNormal : TEXCOORD2,
+    #ifdef NORMALMAP
+        out float3 oTangent : TEXCOORD3,
+        out float3 oBitangent : TEXCOORD4,
+    #endif
+    out float4 oPos : POSITION)
+{
+    float4x3 modelMatrix = iModelMatrix;
+    float3 worldPos = GetWorldPos(modelMatrix);
+    oPos = GetClipPos(worldPos);
+
+    oNormal = GetWorldNormal(modelMatrix);
+    #ifdef NORMALMAP
+        oTangent = GetWorldTangent(modelMatrix);
+        oBitangent = cross(oTangent, oNormal) * iTangent.w;
+    #endif
+
+    oTexCoord = GetTexCoord(iTexCoord);
+    #ifndef HWDEPTH
+        oDepth = GetDepth(oPos);
+    #endif
+}
+
+void PS(
+    float2 iTexCoord : TEXCOORD0,
+    #ifndef HWDEPTH
+        float iDepth : TEXCOORD1,
+    #endif
+    #ifdef NORMALMAP
+        float3 iNormal : TEXCOORD2,
+        float3 iTangent : TEXCOORD3,
+        float3 iBitangent : TEXCOORD4,
+    #else
+        float3 iNormal : TEXCOORD2,
+    #endif
+    #if !defined(HWDEPTH) && !defined(FALLBACK)
+        out float4 oDepth : COLOR0,
+        out float4 oNormal : COLOR1)
+    #else
+        out float4 oNormal : COLOR0)
+    #endif
+{
+    #ifdef ALPHAMASK
+        float4 diffInput = tex2D(sDiffMap, iTexCoord);
+        if (diffInput.a < 0.5)
+            discard;
+    #endif
+
+    #ifdef NORMALMAP
+        float3x3 tbn = float3x3(iTangent, iBitangent, iNormal);
+        float3 normal = normalize(mul(DecodeNormal(tex2D(sNormalMap, iTexCoord)), tbn));
+    #else
+        float3 normal = normalize(iNormal);
+    #endif
+
+    #ifdef FALLBACK
+        // Fallback mode uses 15-bit linear depth
+        oNormal = PackNormalDepth(normal, iDepth.x);
+    #else
+        #ifdef SPECMAP
+            float specStrength = tex2D(sSpecMap, iTexCoord).r * cMatSpecProperties.x;
+        #else
+            float specStrength = cMatSpecProperties.x;
+        #endif
+        float specPower = cMatSpecProperties.y / 255.0;
+
+        oNormal = float4(normal * 0.5 + 0.5, specPower);
+        #ifndef HWDEPTH
+            oDepth = iDepth;
+        #endif
+    #endif
+}

+ 16 - 0
SourceAssets/HLSLShaders/GBuffer.xml

@@ -0,0 +1,16 @@
+<shaders>
+    <shader name="GBuffer" type="vs">
+        <option name="Normal" define="NORMALMAP" />
+        <option name="HW" define="HWDEPTH" />
+        <variation name="" />
+        <variation name="Skinned" define="SKINNED" />
+        <variation name="Instanced" define="INSTANCED" />
+    </shader>
+    <shader name="GBuffer" type="ps">
+        <option name="Normal" define="NORMALMAP" />
+        <option name="Spec" define="SPECMAP" />
+        <option name="Mask" define="ALPHAMASK" include="Diff" />
+        <option name="HW" define="HWDEPTH" exclude="FB" />
+        <option name="FB" define="FALLBACK" exclude="HW" />
+    </shader>
+</shaders>

+ 162 - 0
SourceAssets/HLSLShaders/LightVolume.hlsl

@@ -0,0 +1,162 @@
+#include "Uniforms.hlsl"
+#include "Samplers.hlsl"
+#include "Transform.hlsl"
+#include "ScreenPos.hlsl"
+#include "Lighting.hlsl"
+
+void VS(float4 iPos : POSITION,
+    #ifdef DIRLIGHT
+        out float2 oScreenPos : TEXCOORD0,
+    #else
+        out float4 oScreenPos : TEXCOORD0,
+    #endif
+    out float3 oFarRay : TEXCOORD1,
+    #ifdef ORTHO
+        out float3 oNearRay : TEXCOORD2,
+    #endif
+    out float4 oPos : POSITION)
+{
+    float4x3 modelMatrix = iModelMatrix;
+    float3 worldPos = GetWorldPos(modelMatrix);
+    oPos = GetClipPos(worldPos);
+    #ifdef DIRLIGHT
+        oScreenPos = GetScreenPosPreDiv(oPos);
+        oFarRay = GetFarRay(oPos);
+        #ifdef ORTHO
+            oNearRay = GetNearRay(oPos);
+        #endif
+    #else
+        oScreenPos = GetScreenPos(oPos);
+        oFarRay = GetFarRay(oPos) * oPos.w;
+        #ifdef ORTHO
+            oNearRay = GetNearRay(oPos) * oPos.w;
+        #endif
+    #endif
+}
+
+void PS(
+    #ifdef DIRLIGHT
+        float2 iScreenPos : TEXCOORD0,
+    #else
+        float4 iScreenPos : TEXCOORD0,
+    #endif
+    float3 iFarRay : TEXCOORD1,
+    #ifdef ORTHO
+        float3 iNearRay : TEXCOORD2,
+    #endif
+    out float4 oColor : COLOR0)
+{
+    // If rendering a directional light quad, optimize out the w divide
+    #ifndef FALLBACK
+        #ifdef DIRLIGHT
+            #ifdef ORTHO
+                float depth = Sample(sDepthBuffer, iScreenPos).r;
+                float3 worldPos = lerp(iNearRay, iFarRay, depth);
+            #else
+                #ifdef LINEAR
+                    float depth = Sample(sDepthBuffer, iScreenPos).r;
+                #else
+                    float depth = ReconstructDepth(Sample(sDepthBuffer, iScreenPos).r);
+                #endif
+                float3 worldPos = iFarRay * depth;
+            #endif
+            float4 normalInput = Sample(sNormalBuffer, iScreenPos);
+        #else
+            #ifdef ORTHO
+                float depth = tex2Dproj(sDepthBuffer, iScreenPos).r;
+                float3 worldPos = lerp(iNearRay, iFarRay, depth) / iScreenPos.w;
+            #else
+                #ifdef LINEAR
+                    float depth = tex2Dproj(sDepthBuffer, iScreenPos).r;
+                #else
+                    float depth = ReconstructDepth(tex2Dproj(sDepthBuffer, iScreenPos).r);
+                #endif
+                float3 worldPos = iFarRay * depth / iScreenPos.w;
+            #endif
+            float4 normalInput = tex2Dproj(sNormalBuffer, iScreenPos);
+        #endif
+
+        // With specular, normalization greatly improves stability of reflections,
+        // considering input is only 8 bits per axis
+        #ifdef SPECULAR
+            float3 normal = normalize(normalInput.rgb * 2.0 - 1.0);
+        #else
+            float3 normal = normalInput.rgb * 2.0 - 1.0;
+        #endif
+    #else
+        float3 normal;
+        float depth;
+        #ifdef DIRLIGHT
+            UnpackNormalDepth(Sample(sNormalBuffer, iScreenPos), normal, depth);
+            #ifdef ORTHO
+                float3 worldPos = lerp(iNearRay, iFarRay, depth);
+            #else
+                float3 worldPos = iFarRay * depth;
+            #endif
+        #else
+            UnpackNormalDepth(tex2Dproj(sNormalBuffer, iScreenPos), normal, depth);
+            #ifdef ORTHO
+                float3 worldPos = lerp(iNearRay, iFarRay, depth) / iScreenPos.w;
+            #else
+                float3 worldPos = iFarRay * depth / iScreenPos.w;
+            #endif
+        #endif
+    #endif
+
+    float3 lightColor;
+    float3 lightDir;
+    float diff;
+
+    // Accumulate light at half intensity to allow 2x "overburn"
+    #ifdef DIRLIGHT
+        lightDir = cLightDirPS;
+        diff = 0.5 * GetDiffuseDir(normal, lightDir);
+    #else
+        float3 lightVec = (cLightPosPS.xyz - worldPos) * cLightPosPS.w;
+        diff = 0.5 * GetDiffusePointOrSpot(normal, lightVec, lightDir);
+    #endif
+
+    #ifdef SHADOW
+        #if defined(DIRLIGHT)
+            #ifdef SM3
+                float4x4 shadowMatrix = GetDirShadowMatrix(depth);
+                float4 shadowPos = mul(float4(worldPos, 1.0), shadowMatrix);
+            #else
+                // PS2.0 runs out of instructions while choosing cascade per pixel. Render cascade per pass instead
+                float4x4 shadowMatrix = float4x4(cShadowProjPS[0], cShadowProjPS[1], cShadowProjPS[2], cShadowProjPS[3]);
+                float4 shadowPos = mul(float4(worldPos, 1.0), shadowMatrix);
+                // No light outside cascade limits
+                if (depth < cShadowSplits.x || depth >= cShadowSplits.y)
+                    diff = 0.0;
+            #endif
+            diff *= saturate(GetShadow(shadowPos) + GetShadowFade(depth));
+        #elif defined(SPOTLIGHT)
+            float4x4 shadowMatrix = float4x4(cShadowProjPS[0], cShadowProjPS[1], cShadowProjPS[2], cShadowProjPS[3]);
+            float4 shadowPos = mul(float4(worldPos, 1.0), shadowMatrix);
+            diff *= GetShadow(shadowPos);
+        #else
+            float3 shadowPos = worldPos - cLightPosPS.xyz;
+            diff *= GetCubeShadow(shadowPos);
+        #endif
+    #endif
+
+    #ifdef SPOTLIGHT
+        float4x4 spotMatrix = float4x4(cShadowProjPS[4], cShadowProjPS[5], cShadowProjPS[6], cShadowProjPS[7]);
+        float4 spotPos = mul(float4(worldPos, 1.0), spotMatrix);
+        lightColor = spotPos.w > 0.0 ? tex2Dproj(sLightSpotMap, spotPos).rgb * cLightColor.rgb : 0.0;
+    #else
+        #ifdef CUBEMASK
+            float3x3 lightVecRot = float3x3(cShadowProjPS[0].xyz, cShadowProjPS[1].xyz, cShadowProjPS[2].xyz);
+            lightColor = texCUBE(sLightCubeMap, mul(lightVec, lightVecRot)).rgb * cLightColor.rgb;
+        #else
+            lightColor = cLightColor.rgb;
+        #endif
+    #endif
+
+    #ifdef SPECULAR
+        float spec = lightColor.g * GetSpecular(normal, worldPos, lightDir, normalInput.a * 255.0);
+        oColor = diff * float4(lightColor, spec * cLightColor.a);
+    #else
+        oColor = diff * float4(lightColor, 0.0);
+    #endif
+}

+ 23 - 0
SourceAssets/HLSLShaders/LightVolume.xml

@@ -0,0 +1,23 @@
+<shaders>
+    <shader name="LightVolume" type="vs">
+        <option name="Ortho" define="ORTHO" />
+        <option name="Dir" define="DIRLIGHT" />
+    </shader>
+    <shader name="LightVolume" type="ps">
+        <option name="Linear" define="LINEAR" exclude="Ortho" />
+        <option name="Ortho" define="ORTHO" exclude="Linear" />
+        <variation name="Dir" define="DIRLIGHT" />
+        <variation name="Spot" define="SPOTLIGHT" />
+        <variation name="Point" define="POINTLIGHT" />
+        <option name="Mask" define="CUBEMASK" require="POINTLIGHT" />
+        <option name="Shadow" define="SHADOW" />
+        <option name="Spec" define="SPECULAR" />
+        <option name="HW" define="HWSHADOW" require="SHADOW" />
+        <option name="FB" define="FALLBACK">
+            <exclude name="Linear" />
+            <exclude name="Shadow" />
+            <exclude name="Spec" />
+            <exclude name="HW" />
+        </option>
+    </shader>
+</shaders>

+ 16 - 0
SourceAssets/HLSLShaders/Lighting.hlsl

@@ -155,5 +155,21 @@ float4 GetDirShadowPos(const float4 iShadowPos[4], float depth)
         return iShadowPos[2];
         return iShadowPos[2];
     else
     else
         return iShadowPos[3];
         return iShadowPos[3];
+}   
+
+float4x4 GetDirShadowMatrix(float depth)
+{
+    float4x4 shadowMatrix;
+
+    if (depth < cShadowSplits.x)
+        shadowMatrix = float4x4(cShadowProjPS[0], cShadowProjPS[1], cShadowProjPS[2], cShadowProjPS[3]);
+    else if (depth < cShadowSplits.y)
+        shadowMatrix = float4x4(cShadowProjPS[4], cShadowProjPS[5], cShadowProjPS[6], cShadowProjPS[7]);
+    else if (depth < cShadowSplits.z)
+        shadowMatrix = float4x4(cShadowProjPS[8], cShadowProjPS[9], cShadowProjPS[10], cShadowProjPS[11]);
+    else
+        shadowMatrix = float4x4(cShadowProjPS[12], cShadowProjPS[13], cShadowProjPS[14], cShadowProjPS[15]);
+
+    return shadowMatrix;
 }
 }
 
 

+ 80 - 0
SourceAssets/HLSLShaders/Material.hlsl

@@ -0,0 +1,80 @@
+#pragma warning(disable:3557)
+
+#include "Uniforms.hlsl"
+#include "Samplers.hlsl"
+#include "Transform.hlsl"
+#include "ScreenPos.hlsl"
+#include "Fog.hlsl"
+#include "Lighting.hlsl"
+
+void VS(float4 iPos : POSITION,   
+    #ifdef NUMVERTEXLIGHTS
+        float3 iNormal : NORMAL,
+    #endif
+    #ifdef SKINNED
+        float4 iBlendWeights : BLENDWEIGHT,
+        int4 iBlendIndices : BLENDINDICES,
+    #endif
+    #ifdef INSTANCED
+        float4x3 iModelInstance : TEXCOORD2,
+    #endif
+    float2 iTexCoord : TEXCOORD0,
+    out float4 oTexCoord : TEXCOORD0,
+    out float3 oVertexLighting : TEXCOORD1,
+    out float4 oScreenPos : TEXCOORD2,
+    #ifdef VERTEXCOLOR
+        out float4 oColor : COLOR0,
+    #endif
+    out float4 oPos : POSITION)
+{
+    float4x3 modelMatrix = iModelMatrix;
+    float3 worldPos = GetWorldPos(modelMatrix);
+    oPos = GetClipPos(worldPos);
+
+    oTexCoord = float4(GetTexCoord(iTexCoord), GetZonePos(worldPos), GetDepth(oPos));
+    oScreenPos = GetScreenPos(oPos);
+    oVertexLighting = 0.0;
+
+    #ifdef NUMVERTEXLIGHTS
+    float3 normal = GetWorldNormal(modelMatrix);
+    for (int i = 0; i < NUMVERTEXLIGHTS; ++i)
+        oVertexLighting += GetVertexLight(i, worldPos, normal) * cVertexLights[i * 3].rgb;
+    #endif
+
+    #ifdef VERTEXCOLOR
+        oColor = iColor;
+    #endif
+}
+
+void PS(float4 iTexCoord : TEXCOORD0,
+    float3 iVertexLighting : TEXCOORD1,
+    float4 iScreenPos : TEXCOORD2,
+    #ifdef VERTEXCOLOR
+        float4 iColor : COLOR0,
+    #endif
+    out float4 oColor : COLOR0)
+{
+    #ifdef DIFFMAP
+        float4 diffInput = tex2D(sDiffMap, iTexCoord.xy);
+        #ifdef ALPHAMASK
+            if (diffInput.a < 0.5)
+                discard;
+        #endif
+        float3 diffColor = cMatDiffColor.rgb * diffInput.rgb;
+    #else
+        float3 diffColor = cMatDiffColor.rgb;
+    #endif
+
+    #ifdef SPECMAP
+        float specIntensity = cMatSpecProperties.x * tex2D(sSpecMap, iTexCoord.xy).g;
+    #else
+        float specIntensity = cMatSpecProperties.x;
+    #endif
+
+    // Lights are accumulated at half intensity. Bring back to full intensity now
+    float4 lightInput = 2.0 * tex2Dproj(sLightBuffer, iScreenPos);
+    float3 lightSpecColor = lightInput.a * lightInput.rgb;
+
+    float3 finalColor = (GetAmbient(iTexCoord.z) + iVertexLighting + lightInput.rgb) * diffColor + lightSpecColor * specIntensity;
+    oColor = float4(GetFog(finalColor, iTexCoord.w), 1.0);
+}

+ 19 - 0
SourceAssets/HLSLShaders/Material.xml

@@ -0,0 +1,19 @@
+<shaders>
+    <shader name="Material" type="vs">
+        <variation name="1VL" define="NUMVERTEXLIGHTS=1" />
+        <variation name="2VL" define="NUMVERTEXLIGHTS=2" />
+        <variation name="3VL" define="NUMVERTEXLIGHTS=3" />
+        <variation name="4VL" define="NUMVERTEXLIGHTS=4" />
+        <variation name="5VL" define="NUMVERTEXLIGHTS=5" />
+        <variation name="6VL" define="NUMVERTEXLIGHTS=6" />
+        <option name="" /> <!-- Dummy option to separate the two variation groups -->
+        <variation name="" />
+        <variation name="Skinned" define="SKINNED" />
+        <variation name="Instanced" define="INSTANCED" />
+    </shader>
+    <shader name="Material" type="ps">
+        <option name="Diff" define="DIFFMAP" />
+        <option name="SpecMap" define="SPECMAP" />
+        <option name="Mask" define="ALPHAMASK" include="Diff" />
+    </shader>
+</shaders>

+ 35 - 1
SourceAssets/HLSLShaders/Samplers.hlsl

@@ -16,6 +16,11 @@ samplerCUBE sLightCubeMap : register(S8);
 samplerCUBE sFaceSelectCubeMap : register(S9);
 samplerCUBE sFaceSelectCubeMap : register(S9);
 samplerCUBE sIndirectionCubeMap : register(S10);
 samplerCUBE sIndirectionCubeMap : register(S10);
 
 
+// Deferred buffer samplers
+sampler2D sNormalBuffer : register(S0);
+sampler2D sDepthBuffer : register(S1);
+sampler2D sLightBuffer : register(S6);
+
 float4 Sample(sampler2D map, float2 texCoord)
 float4 Sample(sampler2D map, float2 texCoord)
 {
 {
     // Use tex2Dlod if available to avoid divergence and allow branching
     // Use tex2Dlod if available to avoid divergence and allow branching
@@ -44,4 +49,33 @@ float3 DecodeNormal(float4 normalInput)
     normal.xy = normalInput.ag * 2.0 - 1.0;
     normal.xy = normalInput.ag * 2.0 - 1.0;
     normal.z = sqrt(max(1.0 - dot(normal.xy, normal.xy), 0.0));
     normal.z = sqrt(max(1.0 - dot(normal.xy, normal.xy), 0.0));
     return normal;
     return normal;
-}
+}
+
+float4 PackNormalDepth(float3 normal, float depth)
+{
+    float4 ret;
+    ret.xy = normal.xz * 0.5 + 0.5;
+    ret.z = (floor(depth * 127.0) + (normal.y < 0.0) * 128.0) * (1.0 / 255.0);
+    ret.w = frac(depth * 127.0);
+    return ret;
+}
+
+void UnpackNormalDepth(float4 input, out float3 normal, out float depth)
+{
+    normal.xz = input.xy * 2.0 - 1.0;
+    normal.y = sqrt(1.0 - dot(normal.xz, normal.xz));
+
+    float hiDepth = input.z * 255.0;
+    if (hiDepth > 127.0)
+    {
+        hiDepth -= 128.0;
+        normal.y = -normal.y;
+    }
+
+    depth = (hiDepth + input.w) * (1.0 / 127.0);
+}
+
+float ReconstructDepth(float hwDepth)
+{
+    return cDepthReconstruct.y / (hwDepth - cDepthReconstruct.x);
+}

+ 35 - 0
SourceAssets/HLSLShaders/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;
+}

+ 31 - 25
SourceAssets/HLSLShaders/Uniforms.hlsl

@@ -2,32 +2,38 @@
 uniform float3 cCameraPos : register(C0);
 uniform float3 cCameraPos : register(C0);
 uniform float3x3 cCameraRot : register(C1);
 uniform float3x3 cCameraRot : register(C1);
 uniform float4 cDepthMode : register(C4);
 uniform float4 cDepthMode : register(C4);
-uniform float3 cLightDir : register(C5);
-uniform float4 cLightPos : register(C6);
-uniform float3x3 cLightVecRot: register(C7);
-uniform float4x3 cModel : register(C10);
-uniform float4x4 cSpotProj : register(C13);
-uniform float4x4 cViewProj : register(C17);
-uniform float4 cUOffset : register(C21);
-uniform float4 cVOffset : register(C22);
-uniform float3 cViewRightVector : register(C23);
-uniform float3 cViewUpVector : register(C24);
-uniform float4x3 cZone : register(C25);
-uniform float4x4 cShadowProj[4] : register(C28);
-uniform float4x3 cSkinMatrices[64] : register(C44);
-uniform float4 cVertexLights[6*3] : register(C236);
+uniform float3 cFrustumSize : register(C5);
+uniform float4 cGBufferOffsets : register(C6);
+uniform float3 cLightDir : register(C7);
+uniform float4 cLightPos : register(C8);
+uniform float3x3 cLightVecRot: register(C9);
+uniform float4x3 cModel : register(C12);
+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 cZone : register(C27);
+uniform float4x4 cShadowProj[4] : register(C30);
+uniform float4x3 cSkinMatrices[64] : register(C46);
+uniform float4 cVertexLights[6*3] : register(C238);
 
 
 // Pixel shader parameters
 // Pixel shader parameters
 uniform float3 cAmbientStartColor : register(C0);
 uniform float3 cAmbientStartColor : register(C0);
 uniform float3 cAmbientEndColor : register(C1);
 uniform float3 cAmbientEndColor : register(C1);
-uniform float4 cFogParams : register(C2);
-uniform float3 cFogColor : register(C3);
-uniform float4 cLightColor : register(C4);
-uniform float4 cMatDiffColor : register(C5);
-uniform float3 cMatEmissiveColor : register(C6);
-uniform float2 cMatSpecProperties : register(C7);
-uniform float2 cSampleOffsets : register(C8);
-uniform float4 cShadowCubeAdjust : register(C9);
-uniform float4 cShadowDepthFade : register(C10);
-uniform float4 cShadowIntensity : register(C11);
-uniform float4 cShadowSplits : register(C12);
+uniform float2 cDepthReconstruct : register(C2);
+uniform float4 cFogParams : register(C3);
+uniform float3 cFogColor : register(C4);
+uniform float4 cLightColor : register(C5);
+uniform float4 cLightPosPS : register(C6);
+uniform float3 cLightDirPS : register(C7);
+uniform float4 cMatDiffColor : register(C8);
+uniform float3 cMatEmissiveColor : register(C9);
+uniform float2 cMatSpecProperties : register(C10);
+uniform float2 cSampleOffsets : register(C11);
+uniform float4 cShadowCubeAdjust : register(C12);
+uniform float4 cShadowDepthFade : register(C13);
+uniform float4 cShadowIntensity : register(C14);
+uniform float4 cShadowSplits : register(C15);
+uniform float4 cShadowProjPS[16] :  register(C16);