瀏覽代碼

Add multisampling possibility for VSM shadows.

Lasse Öörni 9 年之前
父節點
當前提交
f01024881f

+ 2 - 0
Source/Urho3D/AngelScript/GraphicsAPI.cpp

@@ -1946,6 +1946,8 @@ static void RegisterRenderer(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Renderer", "float get_shadowSoftness() const", asMETHOD(Renderer, GetShadowSoftness), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "float get_shadowSoftness() const", asMETHOD(Renderer, GetShadowSoftness), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "void set_vsmShadowParameters(const Vector2&in)", asFUNCTION(RendererSetVSMShadowParameters), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("Renderer", "void set_vsmShadowParameters(const Vector2&in)", asFUNCTION(RendererSetVSMShadowParameters), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("Renderer", "Vector2 get_vsmShadowParameters() const", asMETHOD(Renderer, GetVSMShadowParameters), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "Vector2 get_vsmShadowParameters() const", asMETHOD(Renderer, GetVSMShadowParameters), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Renderer", "void set_vsmMultiSample(int)", asMETHOD(Renderer, SetVSMMultiSample), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Renderer", "int get_vsmMultiSample() const", asMETHOD(Renderer, GetVSMMultiSample), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "void set_maxShadowMaps(int)", asMETHOD(Renderer, SetMaxShadowMaps), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "void set_maxShadowMaps(int)", asMETHOD(Renderer, SetMaxShadowMaps), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "int get_maxShadowMaps() const", asMETHOD(Renderer, GetMaxShadowMaps), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "int get_maxShadowMaps() const", asMETHOD(Renderer, GetMaxShadowMaps), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "void set_reuseShadowMaps(bool)", asMETHOD(Renderer, SetReuseShadowMaps), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "void set_reuseShadowMaps(bool)", asMETHOD(Renderer, SetReuseShadowMaps), asCALL_THISCALL);

+ 14 - 1
Source/Urho3D/Graphics/Renderer.cpp

@@ -278,6 +278,7 @@ Renderer::Renderer(Context* context) :
     shadowQuality_(SHADOWQUALITY_PCF_16BIT),
     shadowQuality_(SHADOWQUALITY_PCF_16BIT),
     shadowSoftness_(1.0f),
     shadowSoftness_(1.0f),
     vsmShadowParams_(0.0000001f, 0.2f),
     vsmShadowParams_(0.0000001f, 0.2f),
+    vsmMultiSample_(1),
     maxShadowMaps_(1),
     maxShadowMaps_(1),
     minInstances_(2),
     minInstances_(2),
     maxSortedInstances_(1000),
     maxSortedInstances_(1000),
@@ -456,6 +457,16 @@ void Renderer::SetVSMShadowParameters(float minVariance, float lightBleedingRedu
     vsmShadowParams_.y_ = Clamp(lightBleedingReduction, 0.0f, 1.0f);
     vsmShadowParams_.y_ = Clamp(lightBleedingReduction, 0.0f, 1.0f);
 }
 }
 
 
+void Renderer::SetVSMMultiSample(int multiSample)
+{
+    multiSample = Clamp(multiSample, 1, 16);
+    if (multiSample != vsmMultiSample_)
+    {
+        vsmMultiSample_ = multiSample;
+        ResetShadowMaps();
+    }
+}
+
 void Renderer::SetShadowMapFilter(Object* instance, ShadowMapFilter functionPtr)
 void Renderer::SetShadowMapFilter(Object* instance, ShadowMapFilter functionPtr)
 {
 {
     shadowMapFilterInstance_ = instance;
     shadowMapFilterInstance_ = instance;
@@ -930,6 +941,7 @@ Texture2D* Renderer::GetShadowMap(Light* light, Camera* camera, unsigned viewWid
     // Find format and usage of the shadow map
     // Find format and usage of the shadow map
     unsigned shadowMapFormat = 0;
     unsigned shadowMapFormat = 0;
     TextureUsage shadowMapUsage = TEXTURE_DEPTHSTENCIL;
     TextureUsage shadowMapUsage = TEXTURE_DEPTHSTENCIL;
+    int multiSample = 1;
 
 
     switch (shadowQuality_)
     switch (shadowQuality_)
     {
     {
@@ -947,6 +959,7 @@ Texture2D* Renderer::GetShadowMap(Light* light, Camera* camera, unsigned viewWid
     case SHADOWQUALITY_BLUR_VSM:
     case SHADOWQUALITY_BLUR_VSM:
         shadowMapFormat = graphics_->GetRGFloat32Format();
         shadowMapFormat = graphics_->GetRGFloat32Format();
         shadowMapUsage = TEXTURE_RENDERTARGET;
         shadowMapUsage = TEXTURE_RENDERTARGET;
+        multiSample = vsmMultiSample_;
         break;
         break;
     }
     }
 
 
@@ -959,7 +972,7 @@ Texture2D* Renderer::GetShadowMap(Light* light, Camera* camera, unsigned viewWid
 
 
     while (retries)
     while (retries)
     {
     {
-        if (!newShadowMap->SetSize(width, height, shadowMapFormat, shadowMapUsage))
+        if (!newShadowMap->SetSize(width, height, shadowMapFormat, shadowMapUsage, multiSample))
         {
         {
             width >>= 1;
             width >>= 1;
             height >>= 1;
             height >>= 1;

+ 8 - 1
Source/Urho3D/Graphics/Renderer.h

@@ -212,6 +212,8 @@ public:
     void SetShadowSoftness(float shadowSoftness);
     void SetShadowSoftness(float shadowSoftness);
     /// Set shadow parameters when VSM is used, they help to reduce light bleeding. LightBleeding must be in [0, 1[
     /// Set shadow parameters when VSM is used, they help to reduce light bleeding. LightBleeding must be in [0, 1[
     void SetVSMShadowParameters(float minVariance, float lightBleedingReduction);
     void SetVSMShadowParameters(float minVariance, float lightBleedingReduction);
+    /// Set VSM shadow map multisampling level. Default 1 (no multisampling.)
+    void SetVSMMultiSample(int multiSample);
     /// Set post processing filter to the shadow map
     /// Set post processing filter to the shadow map
     void SetShadowMapFilter(Object* instance, ShadowMapFilter functionPtr);
     void SetShadowMapFilter(Object* instance, ShadowMapFilter functionPtr);
     /// Set reuse of shadow maps. Default is true. If disabled, also transparent geometry can be shadowed.
     /// Set reuse of shadow maps. Default is true. If disabled, also transparent geometry can be shadowed.
@@ -286,9 +288,12 @@ public:
     /// Return shadow softness.
     /// Return shadow softness.
     float GetShadowSoftness() const { return shadowSoftness_; }
     float GetShadowSoftness() const { return shadowSoftness_; }
 
 
-    /// Return VSM shadow parameters
+    /// Return VSM shadow parameters.
     Vector2 GetVSMShadowParameters() const { return vsmShadowParams_; };
     Vector2 GetVSMShadowParameters() const { return vsmShadowParams_; };
 
 
+    /// Return VSM shadow multisample level.
+    int GetVSMMultiSample() const { return vsmMultiSample_; }
+
     /// Return whether shadow maps are reused.
     /// Return whether shadow maps are reused.
     bool GetReuseShadowMaps() const { return reuseShadowMaps_; }
     bool GetReuseShadowMaps() const { return reuseShadowMaps_; }
 
 
@@ -545,6 +550,8 @@ private:
     float shadowSoftness_;
     float shadowSoftness_;
     /// Shadow parameters when VSM is used, they help to reduce light bleeding.
     /// Shadow parameters when VSM is used, they help to reduce light bleeding.
     Vector2 vsmShadowParams_;
     Vector2 vsmShadowParams_;
+    /// Multisample level for VSM shadows.
+    int vsmMultiSample_;
     /// Maximum number of shadow maps per resolution.
     /// Maximum number of shadow maps per resolution.
     int maxShadowMaps_;
     int maxShadowMaps_;
     /// Minimum number of instances required in a batch group to render as instanced.
     /// Minimum number of instances required in a batch group to render as instanced.

+ 4 - 1
Source/Urho3D/LuaScript/pkgs/Graphics/Renderer.pkg

@@ -18,6 +18,7 @@ class Renderer
     void SetShadowQuality(ShadowQuality quality);
     void SetShadowQuality(ShadowQuality quality);
     void SetShadowSoftness(float shadowSoftness);
     void SetShadowSoftness(float shadowSoftness);
     void SetVSMShadowParameters(float minVariance, float lightBleedingReduction);
     void SetVSMShadowParameters(float minVariance, float lightBleedingReduction);
+    void SetVSMMultiSample(int multiSample);
     void SetReuseShadowMaps(bool enable);
     void SetReuseShadowMaps(bool enable);
     void SetMaxShadowMaps(int shadowMaps);
     void SetMaxShadowMaps(int shadowMaps);
     void SetDynamicInstancing(bool enable);
     void SetDynamicInstancing(bool enable);
@@ -32,7 +33,7 @@ class Renderer
     void SetMobileShadowBiasAdd(float add);
     void SetMobileShadowBiasAdd(float add);
     void SetMobileNormalOffsetMul(float mul);
     void SetMobileNormalOffsetMul(float mul);
     void ReloadShaders();
     void ReloadShaders();
-    
+
     unsigned GetNumViewports() const;
     unsigned GetNumViewports() const;
     Viewport* GetViewport(unsigned index) const;
     Viewport* GetViewport(unsigned index) const;
     RenderPath* GetDefaultRenderPath() const;
     RenderPath* GetDefaultRenderPath() const;
@@ -48,6 +49,7 @@ class Renderer
     ShadowQuality GetShadowQuality() const;
     ShadowQuality GetShadowQuality() const;
     float GetShadowSoftness() const;
     float GetShadowSoftness() const;
     Vector2 GetVSMShadowParameters() const;
     Vector2 GetVSMShadowParameters() const;
+    int GetVSMMultiSample() const;
     bool GetReuseShadowMaps() const;
     bool GetReuseShadowMaps() const;
     int GetMaxShadowMaps() const;
     int GetMaxShadowMaps() const;
     bool GetDynamicInstancing() const;
     bool GetDynamicInstancing() const;
@@ -88,6 +90,7 @@ class Renderer
     tolua_property__get_set int shadowMapSize;
     tolua_property__get_set int shadowMapSize;
     tolua_property__get_set ShadowQuality shadowQuality;
     tolua_property__get_set ShadowQuality shadowQuality;
     tolua_property__get_set float shadowSoftness;
     tolua_property__get_set float shadowSoftness;
+    tolua_property__get_set int VSMMultiSample;
     tolua_property__get_set bool reuseShadowMaps;
     tolua_property__get_set bool reuseShadowMaps;
     tolua_property__get_set int maxShadowMaps;
     tolua_property__get_set int maxShadowMaps;
     tolua_property__get_set bool dynamicInstancing;
     tolua_property__get_set bool dynamicInstancing;