Browse Source

Removed the fallback shadow code, as GPUs that actually need it are also too low-performance to render shadows acceptably.

Lasse Öörni 14 years ago
parent
commit
35c21f06d7

+ 0 - 3
Docs/GettingStarted.dox

@@ -142,11 +142,8 @@ Urho3D.exe understands the following command line options:
 -nosound    Disable sound output
 -noip       Disable sound mixing interpolation
 -sm2        Force SM2.0 rendering
--fallback   Force fallback rendering (*)
 \endverbatim
 
-(*) Uses only RGBA render targets, and 2-sample shadow filtering. Implies SM2.0. Relevant only on Direct3D9.
-
 
 \page Structure Overall structure
 

+ 1 - 1
Docs/Reference.dox

@@ -374,7 +374,7 @@ When setting the initial screen mode, Graphics does a few checks:
 
 - For Direct3D9, the supported shader model is checked. 2.0 is minimum, but 3.0 will be used if available. %Shader model 2.0 can be forced by calling \ref Graphics::SetForceSM2 "SetForceSM2()".
 - For OpenGL, version 2.0 with EXT_framebuffer_object and EXT_packed_depth_stencil extensions is checked for.
-- Are hardware shadow maps supported? Both ATI & NVIDIA style shadow maps can be used. If neither are available, a fallback mode using a color texture and minimal shadow filtering will be chosen instead.
+- Are hardware shadow maps supported? Both ATI & NVIDIA style shadow maps can be used. If neither are available, no shadows will be rendered.
 - Is light pre-pass rendering supported? This requires either readable hardware depth-stencil texture, or multiple rendertarget and R32F texture format support.
 
 \section Rendering_Renderer Renderer

+ 0 - 2
Docs/ScriptAPI.dox

@@ -2218,14 +2218,12 @@ Properties:<br>
 - bool deviceLost (readonly)
 - uint numPrimitives (readonly)
 - uint numBatches (readonly)
-- bool fallback (readonly)
 - bool sm3Support (readonly)
 - bool lightPrepassSupport (readonly)
 - bool hardwareDepthSupport (readonly)
 - bool hardwareShadowSupport (readonly)
 - bool hiresShadowSupport (readonly)
 - bool forceSM2
-- bool forceFallback
 - IntVector2[]@ resolutions (readonly)
 - int[]@ multiSampleLevels (readonly)
 

+ 1 - 6
Engine/Engine/DebugHud.cpp

@@ -172,12 +172,7 @@ void DebugHud::Update(float timeStep)
         if (graphics->GetSM3Support())
             mode += "SM3";
         else
-        {
-            if (graphics->GetFallback())
-                mode += "SM2 (FB)";
-            else
-                mode += "SM2";
-        }
+            mode += "SM2";
         #endif
         
         modeText_->SetText(mode);

+ 0 - 4
Engine/Engine/Engine.cpp

@@ -81,7 +81,6 @@ bool Engine::Initialize(const String& windowTitle, const String& logName, const
     bool vsync = false;
     bool tripleBuffer = false;
     bool forceSM2 = false;
-    bool forceFallback = false;
     bool prepass = false;
     bool fxaa = false;
     bool shadows = true;
@@ -125,8 +124,6 @@ bool Engine::Initialize(const String& windowTitle, const String& logName, const
                 threads = false;
             else if (argument == "sm2")
                 forceSM2 = true;
-            else if (argument == "fallback")
-                forceFallback = true;
             else
             {
                 switch (tolower(argument[0]))
@@ -229,7 +226,6 @@ bool Engine::Initialize(const String& windowTitle, const String& logName, const
         
         graphics->SetFlushGPU(flush);
         graphics->SetForceSM2(forceSM2);
-        graphics->SetForceFallback(forceFallback);
         graphics->SetWindowTitle(windowTitle);
         if (!graphics->SetMode(width, height, fullscreen, vsync, tripleBuffer, multiSample))
             return false;

+ 0 - 3
Engine/Engine/GraphicsAPI.cpp

@@ -742,7 +742,6 @@ static void RegisterGraphics(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Graphics", "bool get_deviceLost() const", asMETHOD(Graphics, IsDeviceLost), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "uint get_numPrimitives() const", asMETHOD(Graphics, GetNumPrimitives), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "uint get_numBatches() const", asMETHOD(Graphics, GetNumBatches), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Graphics", "bool get_fallback() const", asMETHOD(Graphics, GetFallback), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "bool get_sm3Support() const", asMETHOD(Graphics, GetSM3Support), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "bool get_lightPrepassSupport() const", asMETHOD(Graphics, GetLightPrepassSupport), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "bool get_hardwareDepthSupport() const", asMETHOD(Graphics, GetHardwareDepthSupport), asCALL_THISCALL);
@@ -750,8 +749,6 @@ static void RegisterGraphics(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Graphics", "bool get_hiresShadowSupport() const", asMETHOD(Graphics, GetHiresShadowSupport), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "void set_forceSM2(bool)", asMETHOD(Graphics, SetForceSM2), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "bool get_forceSM2() const", asMETHOD(Graphics, GetForceSM2), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Graphics", "void set_forceFallback(bool)", asMETHOD(Graphics, SetForceFallback), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Graphics", "bool get_forceFallback() const", asMETHOD(Graphics, GetForceFallback), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "Array<IntVector2>@ get_resolutions() const", asFUNCTION(GraphicsGetResolutions), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("Graphics", "Array<int>@ get_multiSampleLevels() const", asFUNCTION(GraphicsGetMultiSampleLevels), asCALL_CDECL_OBJLAST);
     engine->RegisterGlobalFunction("Graphics@+ get_graphics()", asFUNCTION(GetGraphics), asCALL_CDECL);

+ 6 - 21
Engine/Graphics/Batch.cpp

@@ -65,7 +65,7 @@ inline bool CompareBatchGroupsFrontToBack(BatchGroup* lhs, BatchGroup* rhs)
     return lhs->instances_[0].distance_ < rhs->instances_[0].distance_;
 }
 
-void CalculateShadowMatrix(Matrix4& dest, LightBatchQueue* queue, unsigned split, Graphics* graphics, Renderer* renderer, const Vector3& translation)
+void CalculateShadowMatrix(Matrix4& dest, LightBatchQueue* queue, unsigned split, Renderer* renderer, const Vector3& translation)
 {
     Camera* shadowCamera = queue->shadowSplits_[split].shadowCamera_;
     const IntRect& viewport = queue->shadowSplits_[split].shadowViewport_;
@@ -112,9 +112,6 @@ void CalculateShadowMatrix(Matrix4& dest, LightBatchQueue* queue, unsigned split
         offset.x_ -= 0.5f / width;
         offset.y_ -= 0.5f / height;
     }
-    // If using 2 shadow samples (fallback mode), offset the position horizontally only
-    if (graphics->GetFallback())
-        offset.x_ -= 0.5f / width;
     scale.y_ = -scale.y_;
     texAdjust.SetTranslation(Vector3(offset.x_, offset.y_, 0.0f));
     texAdjust.SetScale(Vector3(scale.x_, scale.y_, 1.0f));
@@ -347,7 +344,7 @@ void Batch::Prepare(Graphics* graphics, Renderer* renderer, bool setModelTransfo
                     Matrix4 shadowMatrices[MAX_CASCADE_SPLITS];
                     unsigned numSplits = lightQueue_->shadowSplits_.Size();
                     for (unsigned i = 0; i < numSplits; ++i)
-                        CalculateShadowMatrix(shadowMatrices[i], lightQueue_, i, graphics, renderer, Vector3::ZERO);
+                        CalculateShadowMatrix(shadowMatrices[i], lightQueue_, i, renderer, Vector3::ZERO);
                     
                     graphics->SetShaderParameter(VSP_LIGHTMATRICES, shadowMatrices[0].GetData(), 16 * numSplits);
                 }
@@ -360,7 +357,7 @@ void Batch::Prepare(Graphics* graphics, Renderer* renderer, bool setModelTransfo
                     CalculateSpotMatrix(shadowMatrices[0], light, Vector3::ZERO);
                     bool isShadowed = lightQueue_->shadowMap_ != 0;
                     if (isShadowed)
-                        CalculateShadowMatrix(shadowMatrices[1], lightQueue_, 0, graphics, renderer, Vector3::ZERO);
+                        CalculateShadowMatrix(shadowMatrices[1], lightQueue_, 0, renderer, Vector3::ZERO);
                     
                     graphics->SetShaderParameter(VSP_LIGHTMATRICES, shadowMatrices[0].GetData(), isShadowed ? 32 : 16);
                 }
@@ -481,9 +478,6 @@ void Batch::Prepare(Graphics* graphics, Renderer* renderer, bool setModelTransfo
                     addX -= 0.5f / width;
                     addY -= 0.5f / height;
                 }
-                // If using 2 shadow samples (fallback mode), offset the position horizontally only
-                if (graphics->GetFallback())
-                    addX -= 0.5f / width;
                 graphics->SetShaderParameter(PSP_SHADOWCUBEADJUST, Vector4(mulX, mulY, addX, addY));
             }
             
@@ -515,16 +509,7 @@ void Batch::Prepare(Graphics* graphics, Renderer* renderer, bool setModelTransfo
                     intensity = Lerp(intensity, 1.0f, Clamp((light->GetDistance() - fadeStart) / (fadeEnd - fadeStart), 0.0f, 1.0f));
                 float pcfValues = (1.0f - intensity);
                 float samples = renderer->GetShadowQuality() >= SHADOWQUALITY_HIGH_16BIT ? 4.0f : 1.0f;
-                float fallbackBias = 0.0f;
-                // Fallback mode requires manual depth biasing. We do not do proper slope scale biasing,
-                // instead just fudge the bias values together
-                if (graphics->GetFallback())
-                {
-                    samples = 2.0f;
-                    fallbackBias = graphics->GetDepthConstantBias() + 2.0f * graphics->GetDepthSlopeScaledBias() *
-                        graphics->GetDepthConstantBias();
-                }
-                graphics->SetShaderParameter(PSP_SHADOWINTENSITY, Vector4(pcfValues / samples, intensity, fallbackBias, 0.0f));
+                graphics->SetShaderParameter(PSP_SHADOWINTENSITY, Vector4(pcfValues / samples, intensity, 0.0f, 0.0f));
             }
             
             if (graphics->NeedParameterUpdate(PSP_SHADOWSPLITS, light))
@@ -550,7 +535,7 @@ void Batch::Prepare(Graphics* graphics, Renderer* renderer, bool setModelTransfo
                     Matrix4 shadowMatrices[MAX_CASCADE_SPLITS];
                     unsigned numSplits = lightQueue_->shadowSplits_.Size();
                     for (unsigned i = 0; i < numSplits; ++i)
-                        CalculateShadowMatrix(shadowMatrices[i], lightQueue_, i, graphics, renderer, camera_->GetWorldPosition());
+                        CalculateShadowMatrix(shadowMatrices[i], lightQueue_, i, renderer, camera_->GetWorldPosition());
                     
                     graphics->SetShaderParameter(PSP_LIGHTMATRICES, shadowMatrices[0].GetData(), 16 * numSplits);
                 }
@@ -563,7 +548,7 @@ void Batch::Prepare(Graphics* graphics, Renderer* renderer, bool setModelTransfo
                     CalculateSpotMatrix(shadowMatrices[0], light, camera_->GetWorldPosition());
                     bool isShadowed = lightQueue_->shadowMap_ != 0;
                     if (isShadowed)
-                        CalculateShadowMatrix(shadowMatrices[1], lightQueue_, 0, graphics, renderer, camera_->GetWorldPosition());
+                        CalculateShadowMatrix(shadowMatrices[1], lightQueue_, 0, renderer, camera_->GetWorldPosition());
                     
                     graphics->SetShaderParameter(PSP_LIGHTMATRICES, shadowMatrices[0].GetData(), isShadowed ? 32 : 16);
                 }

+ 34 - 57
Engine/Graphics/Direct3D9/D3D9Graphics.cpp

@@ -179,10 +179,8 @@ Graphics::Graphics(Context* context) :
     hardwareShadowSupport_(false),
     hiresShadowSupport_(false),
     streamOffsetSupport_(false),
-    fallback_(false),
     hasSM3_(false),
     forceSM2_(false),
-    forceFallback_(false),
     queryIndex_(0),
     numPrimitives_(0),
     numBatches_(0),
@@ -1725,15 +1723,6 @@ void Graphics::SetForceSM2(bool enable)
         CheckFeatureSupport();
 }
 
-void Graphics::SetForceFallback(bool enable)
-{
-    forceFallback_ = enable;
-    
-    // If screen mode has been set, recheck features
-    if (IsInitialized())
-        CheckFeatureSupport();
-}
-
 bool Graphics::IsInitialized() const
 {
     return impl_->window_ != 0 && impl_->GetDevice() != 0;
@@ -2024,19 +2013,29 @@ void Graphics::CheckFeatureSupport()
     hardwareShadowSupport_ = false;
     hiresShadowSupport_ = false;
     streamOffsetSupport_ = false;
-    fallback_ = false;
     hasSM3_ = false;
     
     // Prefer NVIDIA style hardware depth compared shadow maps if available
-    if (!forceFallback_)
+    shadowMapFormat_ = D3DFMT_D16;
+    if (impl_->CheckFormatSupport((D3DFORMAT)shadowMapFormat_, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE))
     {
-        shadowMapFormat_ = D3DFMT_D16;
+        hardwareShadowSupport_ = true;
+    
+        // Check for hires depth support
+        hiresShadowMapFormat_ = D3DFMT_D24X8;
+        if (impl_->CheckFormatSupport((D3DFORMAT)hiresShadowMapFormat_, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE))
+            hiresShadowSupport_ = true;
+        else
+            hiresShadowMapFormat_ = shadowMapFormat_;
+    }
+    else
+    {
+        // ATI DF16 format needs manual depth compare in the shader
+        shadowMapFormat_ = MAKEFOURCC('D', 'F', '1', '6');
         if (impl_->CheckFormatSupport((D3DFORMAT)shadowMapFormat_, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE))
         {
-            hardwareShadowSupport_ = true;
-        
             // Check for hires depth support
-            hiresShadowMapFormat_ = D3DFMT_D24X8;
+            hiresShadowMapFormat_ = MAKEFOURCC('D', 'F', '2', '4');
             if (impl_->CheckFormatSupport((D3DFORMAT)hiresShadowMapFormat_, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE))
                 hiresShadowSupport_ = true;
             else
@@ -2044,32 +2043,13 @@ void Graphics::CheckFeatureSupport()
         }
         else
         {
-            // ATI DF16 format needs manual depth compare in the shader
-            shadowMapFormat_ = MAKEFOURCC('D', 'F', '1', '6');
-            if (impl_->CheckFormatSupport((D3DFORMAT)shadowMapFormat_, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE))
-            {
-                // Check for hires depth support
-                hiresShadowMapFormat_ = MAKEFOURCC('D', 'F', '2', '4');
-                if (impl_->CheckFormatSupport((D3DFORMAT)hiresShadowMapFormat_, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE))
-                    hiresShadowSupport_ = true;
-                else
-                    hiresShadowMapFormat_ = shadowMapFormat_;
-            }
-            else
-                // No depth texture shadow map support, use fallback mode
-                fallback_ = true;
+            // No shadow map support
+            shadowMapFormat_ = 0;
+            hiresShadowMapFormat_ = 0;
         }
     }
-    else
-        fallback_ = true;
     
-    if (fallback_)
-    {
-        shadowMapFormat_ = D3DFMT_A8R8G8B8;
-        hiresShadowMapFormat_ = D3DFMT_A8R8G8B8;
-    }
-    
-    if (!forceSM2_ && !fallback_)
+    if (!forceSM2_)
     {
         if (impl_->deviceCaps_.VertexShaderVersion >= D3DVS_VERSION(3, 0) && impl_->deviceCaps_.PixelShaderVersion >=
             D3DPS_VERSION(3, 0))
@@ -2084,28 +2064,25 @@ void Graphics::CheckFeatureSupport()
             hardwareShadowSupport_ = false;
     }
     
-    if (!fallback_)
+    if (impl_->CheckFormatSupport((D3DFORMAT)MAKEFOURCC('I', 'N', 'T', 'Z'), D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE))
     {
-        if (impl_->CheckFormatSupport((D3DFORMAT)MAKEFOURCC('I', 'N', 'T', 'Z'), D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE))
-        {
-            // Sampling INTZ buffer directly while also using it for depth test results in performance loss on ATI GPUs,
-            // so use INTZ buffer only with other vendors
-            if (impl_->adapterIdentifier_.VendorId != 0x1002)
-            {
-                hardwareDepthSupport_ = true;
-                lightPrepassSupport_ = true;
-            }
-        }
-        
-        if (!hardwareDepthSupport_)
+        // Sampling INTZ buffer directly while also using it for depth test results in performance loss on ATI GPUs,
+        // so use INTZ buffer only with other vendors
+        if (impl_->adapterIdentifier_.VendorId != 0x1002)
         {
-            // If hardware depth is not supported, must support 2 rendertargets and R32F format for light pre-pass
-            if (impl_->deviceCaps_.NumSimultaneousRTs >= 2 && impl_->CheckFormatSupport(D3DFMT_R32F, D3DUSAGE_RENDERTARGET,
-                D3DRTYPE_TEXTURE))
-                lightPrepassSupport_ = true;
+            hardwareDepthSupport_ = true;
+            lightPrepassSupport_ = true;
         }
     }
     
+    if (!hardwareDepthSupport_)
+    {
+        // If hardware depth is not supported, must support 2 rendertargets and R32F format for light pre-pass
+        if (impl_->deviceCaps_.NumSimultaneousRTs >= 2 && impl_->CheckFormatSupport(D3DFMT_R32F, D3DUSAGE_RENDERTARGET,
+            D3DRTYPE_TEXTURE))
+            lightPrepassSupport_ = true;
+    }
+    
     dummyColorFormat_ = D3DFMT_A8R8G8B8;
     D3DFORMAT nullFormat = (D3DFORMAT)MAKEFOURCC('N', 'U', 'L', 'L');
     if (impl_->CheckFormatSupport(nullFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE))

+ 0 - 10
Engine/Graphics/Direct3D9/D3D9Graphics.h

@@ -178,8 +178,6 @@ public:
     void ResetStreamFrequencies();
     /// %Set force Shader Model 2 flag.
     void SetForceSM2(bool enable);
-    /// %Set force fallback shaders flag.
-    void SetForceFallback(bool enable);
     
     /// Return whether rendering initialized.
     bool IsInitialized() const;
@@ -217,8 +215,6 @@ public:
     unsigned GetHiresShadowMapFormat() const { return hiresShadowMapFormat_; }
     /// Return whether texture rendertargets are supported. Always true on Direct3D9
     bool GetRenderTargetSupport() const { return true; }
-    /// Return whether fallback shaders are required.
-    bool GetFallback() const { return fallback_; }
     /// Return whether Shader Model 3 is supported.
     bool GetSM3Support() const { return hasSM3_; }
     /// Return whether light pre-pass rendering is supported.
@@ -307,8 +303,6 @@ public:
     IntVector2 GetRenderTargetDimensions() const;
     /// Return force Shader Model 2 flag.
     bool GetForceSM2() const { return forceSM2_; }
-    /// Return force fallback mode flag.
-    bool GetForceFallback() const { return forceFallback_; }
     
     /// Add a GPU object to keep track of. Called by GPUObject.
     void AddGPUObject(GPUObject* object);
@@ -390,14 +384,10 @@ private:
     bool hiresShadowSupport_;
     /// Stream offset support flag.
     bool streamOffsetSupport_;
-    /// Fallback shader mode flag.
-    bool fallback_;
     /// Shader Model 3 flag.
     bool hasSM3_;
     /// Force Shader Model 2 flag.
     bool forceSM2_;
-    /// Force fallback shaders flag.
-    bool forceFallback_;
     /// Query (used to flush the GPU command queue) issued flags.
     bool queryIssued_[NUM_QUERIES];
     /// Current query index

+ 0 - 4
Engine/Graphics/OpenGL/OGLGraphics.cpp

@@ -1628,10 +1628,6 @@ void Graphics::SetForceSM2(bool enable)
 {
 }
 
-void Graphics::SetForceFallback(bool enable)
-{
-}
-
 bool Graphics::IsInitialized() const
 {
     return impl_->window_ != 0;

+ 2 - 8
Engine/Graphics/OpenGL/OGLGraphics.h

@@ -200,9 +200,7 @@ public:
     void ResetStreamFrequencies();
     /// Set force Shader Model 2 flag. No effect on OpenGL.
     void SetForceSM2(bool enable);
-    /// %Set force fallback shaders flag. No effect on OpenGL.
-    void SetForceFallback(bool enable);
-    
+
     /// Return whether rendering initialized.
     bool IsInitialized() const;
     /// Return graphics implementation, which holds the actual API-specific resources.
@@ -237,8 +235,6 @@ public:
     unsigned GetShadowMapFormat() const { return shadowMapFormat_; }
     /// Return 24-bit shadow map depth texture format, or 0 if not supported.
     unsigned GetHiresShadowMapFormat() const { return hiresShadowMapFormat_; }
-    /// Return whether fallback shaders are required. Always false on OpenGL.
-    bool GetFallback() const { return false; }
     /// Return whether Shader Model 3 is supported. Always false on OpenGL.
     bool GetSM3Support() const { return false; }
     /// Return whether light pre-pass rendering is supported.
@@ -329,9 +325,7 @@ public:
     IntVector2 GetRenderTargetDimensions() const;
     /// Return force Shader Model 2 flag. Always false on OpenGL.
     bool GetForceSM2() const { return false; }
-    /// Return force fallback mode flag. Always false on OpenGL.
-    bool GetForceFallback() const { return false; }
-    
+
     /// Add a GPU object to keep track of. Called by GPUObject.
     void AddGPUObject(GPUObject* object);
     /// Remove a GPU object. Called by GPUObject.

+ 12 - 45
Engine/Graphics/Renderer.cpp

@@ -185,12 +185,6 @@ static const String shadowVariations[] =
     #endif
 };
 
-static const String fallbackVariations[] =
-{
-    "",
-    "FB"
-};
-
 static const String hwVariations[] =
 {
     "",
@@ -432,7 +426,7 @@ void Renderer::SetMaterialQuality(int quality)
 
 void Renderer::SetDrawShadows(bool enable)
 {
-    if (!graphics_)
+    if (!graphics_ || !graphics_->GetShadowMapFormat())
         return;
     
     drawShadows_ = enable;
@@ -465,8 +459,6 @@ void Renderer::SetShadowQuality(int quality)
         quality |= SHADOWQUALITY_HIGH_16BIT;
     if (!graphics_->GetHiresShadowSupport())
         quality &= SHADOWQUALITY_HIGH_16BIT;
-    if (graphics_->GetFallback())
-        quality = SHADOWQUALITY_LOW_16BIT;
     
     if (quality != shadowQuality_)
     {
@@ -918,10 +910,9 @@ Texture2D* Renderer::GetShadowMap(Light* light, Camera* camera, unsigned viewWid
     }
     #else
     // Create shadow map and dummy color rendertarget
-    bool fallback = graphics_->GetFallback();
     while (retries)
     {
-        if (!newShadowMap->SetSize(width, height, shadowMapFormat, fallback ? TEXTURE_RENDERTARGET : TEXTURE_DEPTHSTENCIL))
+        if (!newShadowMap->SetSize(width, height, shadowMapFormat, TEXTURE_DEPTHSTENCIL))
         {
             width >>= 1;
             height >>= 1;
@@ -930,27 +921,14 @@ Texture2D* Renderer::GetShadowMap(Light* light, Camera* camera, unsigned viewWid
         else
         {
             newShadowMap->SetFilterMode(FILTER_BILINEAR);
-            if (!fallback)
+            // If no dummy color rendertarget for this size exists yet, create one now
+            if (!colorShadowMaps_.Contains(searchKey))
             {
-                // If no dummy color rendertarget for this size exists yet, create one now
-                if (!colorShadowMaps_.Contains(searchKey))
-                {
-                    colorShadowMaps_[searchKey] = new Texture2D(context_);
-                    colorShadowMaps_[searchKey]->SetSize(width, height, dummyColorFormat, TEXTURE_RENDERTARGET);
-                }
-                // Link the color rendertarget to the shadow map
-                newShadowMap->GetRenderSurface()->SetLinkedRenderTarget(colorShadowMaps_[searchKey]->GetRenderSurface());
-            }
-            else
-            {
-                // In fallback mode link the shared shadow map depth-stencil to the shadow map instead.
-                // Create it first if not created yet, and resize larger if necessary
-                if (!shadowDepthStencil_)
-                    shadowDepthStencil_ = new Texture2D(context_);
-                if (shadowDepthStencil_->GetWidth() < width || shadowDepthStencil_->GetHeight() < height)
-                    shadowDepthStencil_->SetSize(width, height, D3DFMT_D16, TEXTURE_DEPTHSTENCIL);
-                newShadowMap->GetRenderSurface()->SetLinkedDepthStencil(shadowDepthStencil_->GetRenderSurface());
+                colorShadowMaps_[searchKey] = new Texture2D(context_);
+                colorShadowMaps_[searchKey]->SetSize(width, height, dummyColorFormat, TEXTURE_RENDERTARGET);
             }
+            // Link the color rendertarget to the shadow map
+            newShadowMap->GetRenderSurface()->SetLinkedRenderTarget(colorShadowMaps_[searchKey]->GetRenderSurface());
             break;
         }
     }
@@ -1282,6 +1260,9 @@ void Renderer::Initialize()
     }
     #endif
     
+    if (!graphics_->GetShadowMapFormat())
+        drawShadows_ = false;
+    
     defaultLightRamp_ = cache->GetResource<Texture2D>("Textures/Ramp.png");
     defaultLightSpot_ = cache->GetResource<Texture2D>("Textures/Spot.png");
     defaultMaterial_ = cache->GetResource<Material>("Materials/Default.xml");
@@ -1381,9 +1362,6 @@ void Renderer::LoadPassShaders(Technique* technique, PassType type, bool allowSh
         return;
     
     unsigned shadows = (graphics_->GetHardwareShadowSupport() ? 1 : 0) | (shadowQuality_ & SHADOWQUALITY_HIGH_16BIT);
-    unsigned fallback = graphics_->GetFallback() ? 1 : 0;
-    if (fallback)
-        shadows = SHADOWQUALITY_HIGH_16BIT;
     
     String vertexShaderName = pass->GetVertexShaderName();
     String pixelShaderName = pass->GetPixelShaderName();
@@ -1402,13 +1380,6 @@ void Renderer::LoadPassShaders(Technique* technique, PassType type, bool allowSh
         pixelShaderName += hwVariations[hwDepth];
     }
     
-    // Check for fallback shadow rendering mode (write depth into an RGBA rendertarget)
-    if (type == PASS_SHADOW)
-    {
-        vertexShaderName += fallbackVariations[fallback];
-        pixelShaderName += fallbackVariations[fallback];
-    }
-    
     Vector<SharedPtr<ShaderVariation> >& vertexShaders = pass->GetVertexShaders();
     Vector<SharedPtr<ShaderVariation> >& pixelShaders = pass->GetPixelShaders();
     
@@ -1443,10 +1414,7 @@ void Renderer::LoadPassShaders(Technique* technique, PassType type, bool allowSh
             if (j & LPS_SHADOW)
             {
                 if (allowShadows)
-                {
-                    pixelShaders[j] = GetPixelShader(pixelShaderName + lightPSVariations[j] + shadowVariations[shadows] +
-                        fallbackVariations[fallback]);
-                }
+                    pixelShaders[j] = GetPixelShader(pixelShaderName + lightPSVariations[j] + shadowVariations[shadows]);
                 else
                     pixelShaders[j].Reset();
             }
@@ -1622,7 +1590,6 @@ void Renderer::ResetShadowMaps()
 {
     shadowMaps_.Clear();
     colorShadowMaps_.Clear();
-    shadowDepthStencil_.Reset();
 }
 
 void Renderer::CheckScreenBuffer()

+ 0 - 2
Engine/Graphics/Renderer.h

@@ -432,8 +432,6 @@ private:
     HashMap<int, SharedPtr<Texture2D> > colorShadowMaps_;
     /// Shadow map allocations by resolution.
     HashMap<int, PODVector<Light*> > shadowMapAllocations_;
-    /// Shadow map stencil buffer, fallback mode only.
-    SharedPtr<Texture2D> shadowDepthStencil_;
     /// Viewports.
     Vector<Viewport> viewports_;
     /// Views.

+ 5 - 18
Engine/Graphics/View.cpp

@@ -552,8 +552,6 @@ void View::GetBatches()
     
     // Build light queues and lit batches
     {
-        bool fallback = graphics_->GetFallback();
-        
         maxLightsDrawables_.Clear();
         lightQueueMapping_.Clear();
         
@@ -2294,24 +2292,13 @@ void View::RenderShadowMap(const LightBatchQueue& queue)
     PROFILE(RenderShadowMap);
     
     Texture2D* shadowMap = queue.shadowMap_;
-    
-    graphics_->SetStencilTest(false);
     graphics_->SetTexture(TU_SHADOWMAP, 0);
     
-    if (!graphics_->GetFallback())
-    {
-        graphics_->SetColorWrite(false);
-        graphics_->SetRenderTarget(0, shadowMap->GetRenderSurface()->GetLinkedRenderTarget());
-        graphics_->SetDepthStencil(shadowMap);
-        graphics_->Clear(CLEAR_DEPTH);
-    }
-    else
-    {
-        graphics_->SetColorWrite(true);
-        graphics_->SetRenderTarget(0, shadowMap->GetRenderSurface());
-        graphics_->SetDepthStencil(shadowMap->GetRenderSurface()->GetLinkedDepthStencil());
-        graphics_->Clear(CLEAR_COLOR | CLEAR_DEPTH, Color::WHITE);
-    }
+    graphics_->SetColorWrite(false);
+    graphics_->SetStencilTest(false);
+    graphics_->SetRenderTarget(0, shadowMap->GetRenderSurface()->GetLinkedRenderTarget());
+    graphics_->SetDepthStencil(shadowMap);
+    graphics_->Clear(CLEAR_DEPTH);
     
     // Set shadow depth bias
     BiasParameters parameters = queue.light_->GetShadowBias();

+ 1 - 1
SourceAssets/GLSLShaders/Uniforms.frag

@@ -13,6 +13,6 @@ uniform vec4 cMatSpecColor;
 uniform vec2 cSampleOffsets;
 uniform vec4 cShadowCubeAdjust;
 uniform vec4 cShadowDepthFade;
-uniform vec3 cShadowIntensity;
+uniform vec2 cShadowIntensity;
 uniform vec4 cShadowSplits;
 uniform mat4 cLightMatricesPS[4];

+ 0 - 6
SourceAssets/HLSLShaders/ForwardLit.xml

@@ -26,11 +26,5 @@
         <option name="Shadow" define="SHADOW" />
         <option name="LQ" define="LQSHADOW" require="HWSHADOW" />
         <option name="HW" define="HWSHADOW" require="SHADOW" />
-        <option name="FB" define="FALLBACK">
-            <exclude name="LQ" />
-            <exclude name="HW" />
-            <require name="SHADOW" />
-            <require name="SM2" />
-        </option>
     </shader>
 </shaders>

+ 26 - 44
SourceAssets/HLSLShaders/Lighting.hlsl

@@ -90,57 +90,39 @@ float GetVertexLight(int index, float3 worldPos, float3 normal)
 float GetShadow(float4 shadowPos)
 {
     // Note: in case of sampling a point light cube shadow, we optimize out the w divide as it has already been performed
-    #ifndef FALLBACK
-        #ifndef LQSHADOW
-            // Take four samples and average them
-            #ifndef POINTLIGHT
-                float2 offsets = cSampleOffsets * shadowPos.w;
-            #else
-                float2 offsets = cSampleOffsets;
-            #endif
-            float4 inLight = float4(
-                tex2Dproj(sShadowMap, shadowPos).r,
-                tex2Dproj(sShadowMap, float4(shadowPos.x + offsets.x, shadowPos.yzw)).r,
-                tex2Dproj(sShadowMap, float4(shadowPos.x, shadowPos.y + offsets.y, shadowPos.zw)).r,
-                tex2Dproj(sShadowMap, float4(shadowPos.xy + offsets.xy, shadowPos.zw)).r
-            );
-            #ifdef HWSHADOW
-                return cShadowIntensity.y + dot(inLight, cShadowIntensity.x);
-            #else
-                #ifndef POINTLIGHT
-                    return cShadowIntensity.y + dot(inLight * shadowPos.w > shadowPos.z, cShadowIntensity.x);
-                #else
-                    return cShadowIntensity.y + dot(inLight > shadowPos.z, cShadowIntensity.x);
-                #endif
-            #endif
-        #else
-            // Take one sample
-            float inLight = tex2Dproj(sShadowMap, shadowPos).r;
-            #ifdef HWSHADOW
-                return cShadowIntensity.y + cShadowIntensity.x * inLight;
-            #else
-                #ifndef POINTLIGHT
-                    return cShadowIntensity.y + cShadowIntensity.x * (inLight * shadowPos.w > shadowPos.z);
-                #else
-                    return cShadowIntensity.y + cShadowIntensity.x * (inLight > shadowPos.z);
-                #endif
-            #endif
-        #endif
-    #else
-        // Fallback mode: take two samples, depth needs to be decoded from RG channels
+    #ifndef LQSHADOW
+        // Take four samples and average them
         #ifndef POINTLIGHT
             float2 offsets = cSampleOffsets * shadowPos.w;
         #else
             float2 offsets = cSampleOffsets;
         #endif
-        float2 inLight = float2(
-            DecodeDepth(tex2Dproj(sShadowMap, shadowPos).rg),
-            DecodeDepth(tex2Dproj(sShadowMap, float4(shadowPos.x + offsets.x, shadowPos.yzw)).rg)
+        float4 inLight = float4(
+            tex2Dproj(sShadowMap, shadowPos).r,
+            tex2Dproj(sShadowMap, float4(shadowPos.x + offsets.x, shadowPos.yzw)).r,
+            tex2Dproj(sShadowMap, float4(shadowPos.x, shadowPos.y + offsets.y, shadowPos.zw)).r,
+            tex2Dproj(sShadowMap, float4(shadowPos.xy + offsets.xy, shadowPos.zw)).r
         );
-        #ifndef POINTLIGHT
-            return cShadowIntensity.y + dot(inLight * shadowPos.w > shadowPos.z, cShadowIntensity.x);
+        #ifdef HWSHADOW
+            return cShadowIntensity.y + dot(inLight, cShadowIntensity.x);
+        #else
+            #ifndef POINTLIGHT
+                return cShadowIntensity.y + dot(inLight * shadowPos.w > shadowPos.z, cShadowIntensity.x);
+            #else
+                return cShadowIntensity.y + dot(inLight > shadowPos.z, cShadowIntensity.x);
+            #endif
+        #endif
+    #else
+        // Take one sample
+        float inLight = tex2Dproj(sShadowMap, shadowPos).r;
+        #ifdef HWSHADOW
+            return cShadowIntensity.y + cShadowIntensity.x * inLight;
         #else
-            return cShadowIntensity.y + dot(inLight > shadowPos.z, cShadowIntensity.x);
+            #ifndef POINTLIGHT
+                return cShadowIntensity.y + cShadowIntensity.x * (inLight * shadowPos.w > shadowPos.z);
+            #else
+                return cShadowIntensity.y + cShadowIntensity.x * (inLight > shadowPos.z);
+            #endif
         #endif
     #endif
 }

+ 1 - 15
SourceAssets/HLSLShaders/Shadow.hlsl

@@ -14,9 +14,6 @@ void VS(float4 iPos : POSITION,
         float2 iTexCoord : TEXCOORD0,
         out float2 oTexCoord : TEXCOORD0,
     #endif
-    #ifdef FALLBACK
-        out float4 oClipPos : TEXCOORD1,
-    #endif
     out float4 oPos : POSITION)
 {
     float4x3 modelMatrix = iModelMatrix;
@@ -26,18 +23,12 @@ void VS(float4 iPos : POSITION,
     #ifdef ALPHAMASK
         oTexCoord = GetTexCoord(iTexCoord);
     #endif
-    #ifdef FALLBACK
-        oClipPos = oPos;
-    #endif
 }
 
 void PS(
     #ifdef ALPHAMASK
         float2 iTexCoord : TEXCOORD0,
     #endif
-    #ifdef FALLBACK
-        float4 iClipPos : TEXCOORD1,
-    #endif
     out float4 oColor : COLOR0)
 {
     #ifdef ALPHAMASK
@@ -46,10 +37,5 @@ void PS(
         const float alpha = 1.0;
     #endif
 
-    #ifdef FALLBACK
-        float depth = min(iClipPos.z / iClipPos.w + cShadowIntensity.z, 1.0);
-        oColor = float4(EncodeDepth(depth), 1.0, alpha);
-    #else
-        oColor = alpha;
-    #endif
+    oColor = alpha;
 }

+ 0 - 2
SourceAssets/HLSLShaders/Shadow.xml

@@ -1,13 +1,11 @@
 <shaders>
     <shader name="Shadow" type="vs">
         <option name="Mask" define="ALPHAMASK" />
-        <option name="FB" define="FALLBACK" require="SM2" />
         <variation name="" />
         <variation name="Skinned" define="SKINNED" />
         <variation name="Instanced" define="INSTANCED" require="SM3" />
     </shader>
     <shader name="Shadow" type="ps">
         <option name="Mask" define="ALPHAMASK" />
-        <option name="FB" define="FALLBACK" require="SM2" />
     </shader>
 </shaders>

+ 1 - 1
SourceAssets/HLSLShaders/Uniforms.hlsl

@@ -35,7 +35,7 @@ uniform float4 cMatSpecColor : register(C11);
 uniform float2 cSampleOffsets : register(C12);
 uniform float4 cShadowCubeAdjust : register(C13);
 uniform float4 cShadowDepthFade : register(C14);
-uniform float3 cShadowIntensity : register(C15);
+uniform float2 cShadowIntensity : register(C15);
 uniform float4 cShadowSplits : register(C16);
 #ifdef SM3
     uniform float4x4 cLightMatricesPS[4] : register(C17);