Selaa lähdekoodia

Initial postprocessing implementation. Reimplemented the FXAA edge filter using it.

Lasse Öörni 14 vuotta sitten
vanhempi
sitoutus
55ce257a9c

+ 6 - 0
Bin/Data/PostProcess/EdgeFilter.xml

@@ -0,0 +1,6 @@
+<postprocess>
+    <pass vs="EdgeFilter" ps="EdgeFilter" output="viewport">
+        <texture unit="diffuse" name="viewport" />
+        <parameter name="EdgeFilterParams" value="0.4 0.5 0.75" />
+    </pass>
+</postprocess>

+ 9 - 2
Bin/Data/Scripts/TestScene.as

@@ -3,6 +3,7 @@
 Scene@ testScene;
 Scene@ testScene;
 Camera@ camera;
 Camera@ camera;
 Node@ cameraNode;
 Node@ cameraNode;
+PostProcess@ edgeFilter;
 
 
 float yaw = 0.0;
 float yaw = 0.0;
 float pitch = 0.0;
 float pitch = 0.0;
@@ -211,8 +212,14 @@ void InitScene()
     camera = cameraNode.CreateComponent("Camera");
     camera = cameraNode.CreateComponent("Camera");
     cameraNode.position = Vector3(0, 2, 0);
     cameraNode.position = Vector3(0, 2, 0);
 
 
+    Array<PostProcess@> effectChain;
+    edgeFilter = PostProcess();
+    edgeFilter.parameters = cache.GetResource("XMLFile", "PostProcess/EdgeFilter.xml");
+    edgeFilter.active = false; // Start out disabled
+    effectChain.Push(edgeFilter);
+
     if (!engine.headless)
     if (!engine.headless)
-        renderer.viewports[0] = Viewport(testScene, camera);
+        renderer.viewports[0] = Viewport(testScene, camera, effectChain);
 }
 }
 
 
 bool CheckInLight(Drawable@ drawable)
 bool CheckInLight(Drawable@ drawable)
@@ -315,7 +322,7 @@ void HandleUpdate(StringHash eventType, VariantMap& eventData)
             camera.orthographic = !camera.orthographic;
             camera.orthographic = !camera.orthographic;
 
 
         if (input.keyPress['F'])
         if (input.keyPress['F'])
-            renderer.edgeFilter = !renderer.edgeFilter;
+            edgeFilter.active = !edgeFilter.active;
 
 
         if (input.keyPress['T'])
         if (input.keyPress['T'])
             debugHud.Toggle(DEBUGHUD_SHOW_PROFILER);
             debugHud.Toggle(DEBUGHUD_SHOW_PROFILER);

+ 11 - 4
Bin/Data/Scripts/TestSceneOld.as

@@ -12,6 +12,7 @@ Node@ cameraNode;
 Camera@ camera;
 Camera@ camera;
 Node@ cameraLightNode;
 Node@ cameraLightNode;
 Light@ cameraLight;
 Light@ cameraLight;
+PostProcess@ edgeFilter;
 float yaw = 0.0;
 float yaw = 0.0;
 float pitch = 0.0;
 float pitch = 0.0;
 float objectangle = 0.0;
 float objectangle = 0.0;
@@ -30,7 +31,7 @@ void Start()
         engine.Exit();
         engine.Exit();
         return;
         return;
     }
     }
-         
+
     InitConsole();
     InitConsole();
     InitScene();
     InitScene();
     InitUI();
     InitUI();
@@ -311,7 +312,13 @@ void CreateCamera()
     cameraLight.rampTexture = cache.GetResource("Texture2D", "Textures/RampWide.png");
     cameraLight.rampTexture = cache.GetResource("Texture2D", "Textures/RampWide.png");
     cameraLight.shapeTexture = cache.GetResource("Texture2D", "Textures/SpotWide.png");
     cameraLight.shapeTexture = cache.GetResource("Texture2D", "Textures/SpotWide.png");
 
 
-    renderer.viewports[0] = Viewport(testScene, camera);
+    Array<PostProcess@> effectChain;
+    edgeFilter = PostProcess();
+    edgeFilter.parameters = cache.GetResource("XMLFile", "PostProcess/EdgeFilter.xml");
+    edgeFilter.active = false; // Start out disabled
+    effectChain.Push(edgeFilter);
+
+    renderer.viewports[0] = Viewport(testScene, camera, effectChain);
 }
 }
 
 
 void HandleUpdate(StringHash eventType, VariantMap& eventData)
 void HandleUpdate(StringHash eventType, VariantMap& eventData)
@@ -416,8 +423,8 @@ void HandleUpdate(StringHash eventType, VariantMap& eventData)
             camera.orthographic = !camera.orthographic;
             camera.orthographic = !camera.orthographic;
 
 
         if (input.keyPress['F'])
         if (input.keyPress['F'])
-            renderer.edgeFilter = !renderer.edgeFilter;
-
+            edgeFilter.active = !edgeFilter.active;
+        
         if (input.keyPress['T'])
         if (input.keyPress['T'])
             debugHud.Toggle(DEBUGHUD_SHOW_PROFILER);
             debugHud.Toggle(DEBUGHUD_SHOW_PROFILER);
 
 

+ 18 - 25
Docs/ScriptAPI.dox

@@ -1495,11 +1495,29 @@ Properties:<br>
 - bool dataLost (readonly)
 - bool dataLost (readonly)
 
 
 
 
+PostProcess
+
+Methods:<br>
+- bool CreateRenderTarget(const String&, uint, uint, uint, bool, bool)
+- void RemoveRenderTarget(const String&)
+- bool HasRenderTarget(const String&) const
+
+Properties:<br>
+- ShortStringHash type (readonly)
+- String& typeName (readonly)
+- XMLFile@ parameters
+- uint numPasses
+- bool active
+- PostProcessPass@[] passes (readonly)
+
+
 Viewport
 Viewport
 
 
 Properties:<br>
 Properties:<br>
 - Scene@ scene
 - Scene@ scene
 - Camera@ camera
 - Camera@ camera
+- PostProcess@[] postProcesses
+- uint numPostProcesses
 - IntRect rect
 - IntRect rect
 
 
 
 
@@ -1645,21 +1663,6 @@ Properties:<br>
 - Vector4[] shaderParameters
 - Vector4[] shaderParameters
 
 
 
 
-PostProcess
-
-Methods:<br>
-- bool LoadParameters(XMLFile@)
-- bool CreateRenderTarget(const String&, uint, uint, uint, bool, bool)
-- void RemoveRenderTarget(const String&)
-- bool HasRenderTarget(const String&) const
-
-Properties:<br>
-- ShortStringHash type (readonly)
-- String& typeName (readonly)
-- uint numPasses
-- PostProcessPass@[] passes (readonly)
-
-
 Model
 Model
 
 
 Methods:<br>
 Methods:<br>
@@ -2269,14 +2272,6 @@ Properties:<br>
 - int[]@ multiSampleLevels (readonly)
 - int[]@ multiSampleLevels (readonly)
 
 
 
 
-EdgeFilterParameters
-
-Properties:<br>
-- float radius
-- float threshold
-- float strength
-
-
 Renderer
 Renderer
 
 
 Methods:<br>
 Methods:<br>
@@ -2301,8 +2296,6 @@ Properties:<br>
 - bool reuseShadowMaps
 - bool reuseShadowMaps
 - bool dynamicInstancing
 - bool dynamicInstancing
 - int maxInstanceTriangles
 - int maxInstanceTriangles
-- bool edgeFilter
-- EdgeFilterParameters& edgeFilterParameters
 - int maxOccluderTriangles
 - int maxOccluderTriangles
 - int occlusionBufferSize
 - int occlusionBufferSize
 - float occluderSizeThreshold
 - float occluderSizeThreshold

+ 0 - 4
Engine/Engine/Engine.cpp

@@ -82,7 +82,6 @@ bool Engine::Initialize(const String& windowTitle, const String& logName, const
     bool tripleBuffer = false;
     bool tripleBuffer = false;
     bool forceSM2 = false;
     bool forceSM2 = false;
     bool prepass = false;
     bool prepass = false;
-    bool fxaa = false;
     bool shadows = true;
     bool shadows = true;
     bool lqShadows = false;
     bool lqShadows = false;
     bool sound = true;
     bool sound = true;
@@ -112,8 +111,6 @@ bool Engine::Initialize(const String& windowTitle, const String& logName, const
                 stereo = false;
                 stereo = false;
             else if (argument == "prepass")
             else if (argument == "prepass")
                 prepass = true;
                 prepass = true;
-            else if (argument == "fxaa")
-                fxaa = true;
             else if (argument == "noshadows")
             else if (argument == "noshadows")
                 shadows = false;
                 shadows = false;
             else if (argument == "lqshadows")
             else if (argument == "lqshadows")
@@ -231,7 +228,6 @@ bool Engine::Initialize(const String& windowTitle, const String& logName, const
             return false;
             return false;
         
         
         renderer->SetLightPrepass(prepass);
         renderer->SetLightPrepass(prepass);
-        renderer->SetEdgeFilter(fxaa);
         renderer->SetDrawShadows(shadows);
         renderer->SetDrawShadows(shadows);
         if (shadows && lqShadows)
         if (shadows && lqShadows)
             renderer->SetShadowQuality(SHADOWQUALITY_LOW_16BIT);
             renderer->SetShadowQuality(SHADOWQUALITY_LOW_16BIT);

+ 57 - 28
Engine/Engine/GraphicsAPI.cpp

@@ -144,6 +144,30 @@ static void ConstructViewportSceneCameraRect(Scene* scene, Camera* camera, const
     new(ptr) Viewport(scene, camera, rect);
     new(ptr) Viewport(scene, camera, rect);
 }
 }
 
 
+static void ConstructViewportSceneCameraPostProcesses(Scene* scene, Camera* camera, CScriptArray* arr, Viewport* ptr)
+{
+    Vector<SharedPtr<PostProcess> > vec;
+    if (arr)
+    {
+        for (unsigned i = 0; i < arr->GetSize(); ++i)
+            vec.Push(SharedPtr<PostProcess>(*(static_cast<PostProcess**>(arr->At(i)))));
+    }
+    
+    new(ptr) Viewport(scene, camera, vec);
+}
+
+static void ConstructViewportSceneCameraRectPostProcesses(Scene* scene, Camera* camera, const IntRect& rect, CScriptArray* arr, Viewport* ptr)
+{
+    Vector<SharedPtr<PostProcess> > vec;
+    if (arr)
+    {
+        for (unsigned i = 0; i < arr->GetSize(); ++i)
+            vec.Push(SharedPtr<PostProcess>(*(static_cast<PostProcess**>(arr->At(i)))));
+    }
+    
+    new(ptr) Viewport(scene, camera, rect, vec);
+}
+
 static void DestructViewport(Viewport* ptr)
 static void DestructViewport(Viewport* ptr)
 {
 {
     ptr->~Viewport();
     ptr->~Viewport();
@@ -169,6 +193,27 @@ static Camera* ViewportGetCamera(Viewport* ptr)
     return ptr->camera_;
     return ptr->camera_;
 }
 }
 
 
+static void ViewportSetPostProcess(unsigned index, PostProcess* effect, Viewport* ptr)
+{
+    if (index < ptr->postProcesses_.Size())
+        ptr->postProcesses_[index] = effect;
+}
+
+static PostProcess* ViewportGetPostProcess(unsigned index, Viewport* ptr)
+{
+    return index < ptr->postProcesses_.Size() ? ptr->postProcesses_[index] : (PostProcess*)0;
+}
+
+static void ViewportSetNumPostProcesses(unsigned num, Viewport* ptr)
+{
+    ptr->postProcesses_.Resize(num);
+}
+
+static unsigned ViewportGetNumPostProcesses(Viewport* ptr)
+{
+    return ptr->postProcesses_.Size();
+}
+
 static bool Texture2DLoad(Image* image, bool useAlpha, Texture2D* ptr)
 static bool Texture2DLoad(Image* image, bool useAlpha, Texture2D* ptr)
 {
 {
     return ptr->Load(SharedPtr<Image>(image), useAlpha);
     return ptr->Load(SharedPtr<Image>(image), useAlpha);
@@ -217,11 +262,15 @@ static void RegisterTextures(asIScriptEngine* engine)
     
     
     RegisterTexture<Texture>(engine, "Texture");
     RegisterTexture<Texture>(engine, "Texture");
     
     
+    // Must register PostProcess early as Viewport needs it
+    RegisterObject<PostProcess>(engine, "PostProcess");
     engine->RegisterObjectType("Viewport", sizeof(Viewport), asOBJ_VALUE | asOBJ_APP_CLASS_CDAK);
     engine->RegisterObjectType("Viewport", sizeof(Viewport), asOBJ_VALUE | asOBJ_APP_CLASS_CDAK);
     engine->RegisterObjectBehaviour("Viewport", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructViewport), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("Viewport", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructViewport), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("Viewport", asBEHAVE_CONSTRUCT, "void f(const Viewport&in)", asFUNCTION(ConstructViewportCopy), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("Viewport", asBEHAVE_CONSTRUCT, "void f(const Viewport&in)", asFUNCTION(ConstructViewportCopy), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("Viewport", asBEHAVE_CONSTRUCT, "void f(Scene@+, Camera@+)", asFUNCTION(ConstructViewportSceneCamera), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("Viewport", asBEHAVE_CONSTRUCT, "void f(Scene@+, Camera@+)", asFUNCTION(ConstructViewportSceneCamera), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("Viewport", asBEHAVE_CONSTRUCT, "void f(Scene@+, Camera@+, const IntRect&in)", asFUNCTION(ConstructViewportSceneCameraRect), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("Viewport", asBEHAVE_CONSTRUCT, "void f(Scene@+, Camera@+, const IntRect&in)", asFUNCTION(ConstructViewportSceneCameraRect), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectBehaviour("Viewport", asBEHAVE_CONSTRUCT, "void f(Scene@+, Camera@+, Array<PostProcess@>@+)", asFUNCTION(ConstructViewportSceneCameraPostProcesses), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectBehaviour("Viewport", asBEHAVE_CONSTRUCT, "void f(Scene@+, Camera@+, const IntRect&in, Array<PostProcess@>@+)", asFUNCTION(ConstructViewportSceneCameraRectPostProcesses), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("Viewport", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(DestructViewport), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("Viewport", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(DestructViewport), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("Viewport", "Viewport& opAssign(const Viewport&in)", asMETHOD(Viewport, operator =), asCALL_THISCALL);
     engine->RegisterObjectMethod("Viewport", "Viewport& opAssign(const Viewport&in)", asMETHOD(Viewport, operator =), asCALL_THISCALL);
     engine->RegisterObjectMethod("Viewport", "void set_scene(Scene@+)", asFUNCTION(ViewportSetScene), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("Viewport", "void set_scene(Scene@+)", asFUNCTION(ViewportSetScene), asCALL_CDECL_OBJLAST);
@@ -229,6 +278,10 @@ static void RegisterTextures(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Viewport", "Scene@+ get_scene() const", asFUNCTION(ViewportGetScene), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("Viewport", "Scene@+ get_scene() const", asFUNCTION(ViewportGetScene), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("Viewport", "Camera@+ get_camera() const", asFUNCTION(ViewportGetCamera), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("Viewport", "Camera@+ get_camera() const", asFUNCTION(ViewportGetCamera), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectProperty("Viewport", "IntRect rect", offsetof(Viewport, rect_));
     engine->RegisterObjectProperty("Viewport", "IntRect rect", offsetof(Viewport, rect_));
+    engine->RegisterObjectMethod("Viewport", "void set_postProcesses(uint, PostProcess@+)", asFUNCTION(ViewportSetPostProcess), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("Viewport", "PostProcess@+ get_postProcesses(uint) const", asFUNCTION(ViewportGetPostProcess), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("Viewport", "void set_numPostProcesses(uint)", asFUNCTION(ViewportSetNumPostProcesses), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("Viewport", "uint get_numPostProcesses() const", asFUNCTION(ViewportGetNumPostProcesses), asCALL_CDECL_OBJLAST);
     
     
     engine->RegisterObjectType("RenderSurface", 0, asOBJ_REF);
     engine->RegisterObjectType("RenderSurface", 0, asOBJ_REF);
     engine->RegisterObjectBehaviour("RenderSurface", asBEHAVE_ADDREF, "void f()", asMETHOD(RenderSurface, AddRef), asCALL_THISCALL);
     engine->RegisterObjectBehaviour("RenderSurface", asBEHAVE_ADDREF, "void f()", asMETHOD(RenderSurface, AddRef), asCALL_THISCALL);
@@ -371,14 +424,16 @@ static void RegisterPostProcess(asIScriptEngine* engine)
     engine->RegisterObjectMethod("PostProcessPass", "void set_shaderParameters(const String&in, const Vector4&in)", asMETHOD(PostProcessPass, SetShaderParameter), asCALL_THISCALL);
     engine->RegisterObjectMethod("PostProcessPass", "void set_shaderParameters(const String&in, const Vector4&in)", asMETHOD(PostProcessPass, SetShaderParameter), asCALL_THISCALL);
     engine->RegisterObjectMethod("PostProcessPass", "Vector4 get_shaderParameters(const String&in) const", asMETHOD(PostProcessPass, GetShaderParameter), asCALL_THISCALL);
     engine->RegisterObjectMethod("PostProcessPass", "Vector4 get_shaderParameters(const String&in) const", asMETHOD(PostProcessPass, GetShaderParameter), asCALL_THISCALL);
     
     
-    RegisterObject<PostProcess>(engine, "PostProcess");
     RegisterObjectConstructor<PostProcess>(engine, "PostProcess");
     RegisterObjectConstructor<PostProcess>(engine, "PostProcess");
-    engine->RegisterObjectMethod("PostProcess", "bool LoadParameters(XMLFile@+)", asMETHOD(PostProcess, LoadParameters), asCALL_THISCALL);
     engine->RegisterObjectMethod("PostProcess", "bool CreateRenderTarget(const String&in, uint, uint, uint, bool, bool)", asMETHOD(PostProcess, CreateRenderTarget), asCALL_THISCALL);
     engine->RegisterObjectMethod("PostProcess", "bool CreateRenderTarget(const String&in, uint, uint, uint, bool, bool)", asMETHOD(PostProcess, CreateRenderTarget), asCALL_THISCALL);
     engine->RegisterObjectMethod("PostProcess", "void RemoveRenderTarget(const String&in)", asMETHOD(PostProcess, RemoveRenderTarget), asCALL_THISCALL);
     engine->RegisterObjectMethod("PostProcess", "void RemoveRenderTarget(const String&in)", asMETHOD(PostProcess, RemoveRenderTarget), asCALL_THISCALL);
     engine->RegisterObjectMethod("PostProcess", "bool HasRenderTarget(const String&in) const", asMETHOD(PostProcess, HasRenderTarget), asCALL_THISCALL);
     engine->RegisterObjectMethod("PostProcess", "bool HasRenderTarget(const String&in) const", asMETHOD(PostProcess, HasRenderTarget), asCALL_THISCALL);
+    engine->RegisterObjectMethod("PostProcess", "bool set_parameters(XMLFile@+)", asMETHOD(PostProcess, LoadParameters), asCALL_THISCALL);
+    engine->RegisterObjectMethod("PostProcess", "XMLFile@+ get_parameters() const", asMETHOD(PostProcess, GetParameters), asCALL_THISCALL);
     engine->RegisterObjectMethod("PostProcess", "void set_numPasses(uint)", asMETHOD(PostProcess, SetNumPasses), asCALL_THISCALL);
     engine->RegisterObjectMethod("PostProcess", "void set_numPasses(uint)", asMETHOD(PostProcess, SetNumPasses), asCALL_THISCALL);
     engine->RegisterObjectMethod("PostProcess", "uint get_numPasses() const", asMETHOD(PostProcess, GetNumPasses), asCALL_THISCALL);
     engine->RegisterObjectMethod("PostProcess", "uint get_numPasses() const", asMETHOD(PostProcess, GetNumPasses), asCALL_THISCALL);
+    engine->RegisterObjectMethod("PostProcess", "void set_active(bool)", asMETHOD(PostProcess, SetActive), asCALL_THISCALL);
+    engine->RegisterObjectMethod("PostProcess", "bool get_active() const", asMETHOD(PostProcess, IsActive), asCALL_THISCALL);
     engine->RegisterObjectMethod("PostProcess", "PostProcessPass@+ get_passes(uint) const", asMETHOD(PostProcess, GetPass), asCALL_THISCALL);
     engine->RegisterObjectMethod("PostProcess", "PostProcessPass@+ get_passes(uint) const", asMETHOD(PostProcess, GetPass), asCALL_THISCALL);
 }
 }
 
 
@@ -777,21 +832,6 @@ static Renderer* GetRenderer()
     return GetScriptContext()->GetSubsystem<Renderer>();
     return GetScriptContext()->GetSubsystem<Renderer>();
 }
 }
 
 
-static void ConstructEdgeFilterParameters(EdgeFilterParameters* ptr)
-{
-    new(ptr) EdgeFilterParameters(0.0f, 0.0f, 0.0f);
-}
-
-static void ConstructEdgeFilterParametersCopy(EdgeFilterParameters& parameters, EdgeFilterParameters* ptr)
-{
-    new(ptr) EdgeFilterParameters(parameters);
-}
-
-static void ConstructEdgeFilterParametersInit(float radius, float threshold, float strength, BiasParameters* ptr)
-{
-    new(ptr) EdgeFilterParameters(radius, threshold, strength);
-}
-
 static void RegisterRenderer(asIScriptEngine* engine)
 static void RegisterRenderer(asIScriptEngine* engine)
 {
 {
     engine->RegisterGlobalProperty("const int QUALITY_LOW", (void*)&QUALITY_LOW);
     engine->RegisterGlobalProperty("const int QUALITY_LOW", (void*)&QUALITY_LOW);
@@ -802,13 +842,6 @@ static void RegisterRenderer(asIScriptEngine* engine)
     engine->RegisterGlobalProperty("const int SHADOWQUALITY_LOW_24BIT", (void*)&SHADOWQUALITY_LOW_24BIT);
     engine->RegisterGlobalProperty("const int SHADOWQUALITY_LOW_24BIT", (void*)&SHADOWQUALITY_LOW_24BIT);
     engine->RegisterGlobalProperty("const int SHADOWQUALITY_HIGH_16BIT", (void*)&SHADOWQUALITY_HIGH_16BIT);
     engine->RegisterGlobalProperty("const int SHADOWQUALITY_HIGH_16BIT", (void*)&SHADOWQUALITY_HIGH_16BIT);
     engine->RegisterGlobalProperty("const int SHADOWQUALITY_HIGH_24BIT", (void*)&SHADOWQUALITY_HIGH_24BIT);
     engine->RegisterGlobalProperty("const int SHADOWQUALITY_HIGH_24BIT", (void*)&SHADOWQUALITY_HIGH_24BIT);
-    engine->RegisterObjectType("EdgeFilterParameters", sizeof(EdgeFilterParameters), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C);
-    engine->RegisterObjectBehaviour("EdgeFilterParameters", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructEdgeFilterParameters), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectBehaviour("EdgeFilterParameters", asBEHAVE_CONSTRUCT, "void f(const EdgeFilterParameters&in)", asFUNCTION(ConstructEdgeFilterParametersCopy), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectBehaviour("EdgeFilterParameters", asBEHAVE_CONSTRUCT, "void f(float, float, float)", asFUNCTION(ConstructEdgeFilterParametersInit), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectProperty("EdgeFilterParameters", "float radius", offsetof(EdgeFilterParameters, radius_));
-    engine->RegisterObjectProperty("EdgeFilterParameters", "float threshold", offsetof(EdgeFilterParameters, threshold_));
-    engine->RegisterObjectProperty("EdgeFilterParameters", "float strength", offsetof(EdgeFilterParameters, strength_));
     
     
     RegisterObject<Renderer>(engine, "Renderer");
     RegisterObject<Renderer>(engine, "Renderer");
     engine->RegisterObjectMethod("Renderer", "void DrawDebugGeometry(bool) const", asMETHOD(Renderer, DrawDebugGeometry), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "void DrawDebugGeometry(bool) const", asMETHOD(Renderer, DrawDebugGeometry), asCALL_THISCALL);
@@ -844,10 +877,6 @@ static void RegisterRenderer(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Renderer", "bool get_dynamicInstancing() const", asMETHOD(Renderer, GetDynamicInstancing), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "bool get_dynamicInstancing() const", asMETHOD(Renderer, GetDynamicInstancing), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "void set_maxInstanceTriangles(int)", asMETHOD(Renderer, SetMaxInstanceTriangles), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "void set_maxInstanceTriangles(int)", asMETHOD(Renderer, SetMaxInstanceTriangles), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "int get_maxInstanceTriangles() const", asMETHOD(Renderer, GetMaxInstanceTriangles), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "int get_maxInstanceTriangles() const", asMETHOD(Renderer, GetMaxInstanceTriangles), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Renderer", "bool get_edgeFilter() const", asMETHOD(Renderer, GetEdgeFilter), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Renderer", "void set_edgeFilter(bool)", asMETHOD(Renderer, SetEdgeFilter), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Renderer", "const EdgeFilterParameters& get_edgeFilterParameters() const", asMETHOD(Renderer, GetEdgeFilterParameters), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Renderer", "void set_edgeFilterParameters(const EdgeFilterParameters& in)", asMETHOD(Renderer, SetEdgeFilterParameters), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "void set_maxOccluderTriangles(int)", asMETHOD(Renderer, SetMaxOccluderTriangles), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "void set_maxOccluderTriangles(int)", asMETHOD(Renderer, SetMaxOccluderTriangles), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "int get_maxOccluderTriangles() const", asMETHOD(Renderer, GetMaxOccluderTriangles), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "int get_maxOccluderTriangles() const", asMETHOD(Renderer, GetMaxOccluderTriangles), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "void set_occlusionBufferSize(int)", asMETHOD(Renderer, SetOcclusionBufferSize), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "void set_occlusionBufferSize(int)", asMETHOD(Renderer, SetOcclusionBufferSize), asCALL_THISCALL);

+ 16 - 0
Engine/Graphics/Direct3D9/D3D9RenderSurface.cpp

@@ -51,6 +51,22 @@ Viewport::Viewport(Scene* scene, Camera* camera, const IntRect& rect) :
 {
 {
 }
 }
 
 
+Viewport::Viewport(Scene* scene, Camera* camera, const Vector<SharedPtr<PostProcess> >& postProcesses) :
+    scene_(scene),
+    camera_(camera),
+    rect_(IntRect::ZERO),
+    postProcesses_(postProcesses)
+{
+}
+
+Viewport::Viewport(Scene* scene, Camera* camera, const IntRect& rect, const Vector<SharedPtr<PostProcess> >& postProcesses) :
+    scene_(scene),
+    camera_(camera),
+    rect_(rect),
+    postProcesses_(postProcesses)
+{
+}
+
 RenderSurface::RenderSurface(Texture* parentTexture) :
 RenderSurface::RenderSurface(Texture* parentTexture) :
     parentTexture_(parentTexture),
     parentTexture_(parentTexture),
     surface_(0)
     surface_(0)

+ 7 - 0
Engine/Graphics/Direct3D9/D3D9RenderSurface.h

@@ -25,6 +25,7 @@
 
 
 #include "Rect.h"
 #include "Rect.h"
 #include "GraphicsDefs.h"
 #include "GraphicsDefs.h"
+#include "PostProcess.h"
 #include "Ptr.h"
 #include "Ptr.h"
 
 
 class Camera;
 class Camera;
@@ -40,6 +41,10 @@ struct Viewport
     Viewport(Scene* scene, Camera* camera);
     Viewport(Scene* scene, Camera* camera);
     /// Construct with a specified rectangle.
     /// Construct with a specified rectangle.
     Viewport(Scene* scene, Camera* camera, const IntRect& rect);
     Viewport(Scene* scene, Camera* camera, const IntRect& rect);
+    /// Construct with a full rectangle and post-processing effects.
+    Viewport(Scene* scene, Camera* camera, const Vector<SharedPtr<PostProcess> >& postProcesses);
+    /// Construct with a specified rectangle and post-processing effects.
+    Viewport(Scene* scene, Camera* camera, const IntRect& rect, const Vector<SharedPtr<PostProcess> >& postProcesses);
     
     
     /// Scene pointer.
     /// Scene pointer.
     WeakPtr<Scene> scene_;
     WeakPtr<Scene> scene_;
@@ -47,6 +52,8 @@ struct Viewport
     WeakPtr<Camera> camera_;
     WeakPtr<Camera> camera_;
     /// Viewport rectangle.
     /// Viewport rectangle.
     IntRect rect_;
     IntRect rect_;
+    /// Post-processing effects.
+    Vector<SharedPtr<PostProcess> > postProcesses_;
 };
 };
 
 
 /// %Color or depth-stencil surface that can be rendered into.
 /// %Color or depth-stencil surface that can be rendered into.

+ 0 - 1
Engine/Graphics/GraphicsDefs.cpp

@@ -47,7 +47,6 @@ StringHash VSP_SKINMATRICES("SkinMatrices");
 StringHash VSP_VERTEXLIGHTS("VertexLights");
 StringHash VSP_VERTEXLIGHTS("VertexLights");
 StringHash PSP_AMBIENTCOLOR("AmbientColor");
 StringHash PSP_AMBIENTCOLOR("AmbientColor");
 StringHash PSP_DEPTHRECONSTRUCT("DepthReconstruct");
 StringHash PSP_DEPTHRECONSTRUCT("DepthReconstruct");
-StringHash PSP_EDGEFILTERPARAMS("EdgeFilterParams");
 StringHash PSP_FOGCOLOR("FogColor");
 StringHash PSP_FOGCOLOR("FogColor");
 StringHash PSP_FOGPARAMS("FogParams");
 StringHash PSP_FOGPARAMS("FogParams");
 StringHash PSP_LIGHTCOLOR("LightColor");
 StringHash PSP_LIGHTCOLOR("LightColor");

+ 0 - 1
Engine/Graphics/GraphicsDefs.h

@@ -217,7 +217,6 @@ extern StringHash VSP_SKINMATRICES;
 extern StringHash VSP_VERTEXLIGHTS;
 extern StringHash VSP_VERTEXLIGHTS;
 extern StringHash PSP_AMBIENTCOLOR;
 extern StringHash PSP_AMBIENTCOLOR;
 extern StringHash PSP_DEPTHRECONSTRUCT;
 extern StringHash PSP_DEPTHRECONSTRUCT;
-extern StringHash PSP_EDGEFILTERPARAMS;
 extern StringHash PSP_FOGCOLOR;
 extern StringHash PSP_FOGCOLOR;
 extern StringHash PSP_FOGPARAMS;
 extern StringHash PSP_FOGPARAMS;
 extern StringHash PSP_LIGHTCOLOR;
 extern StringHash PSP_LIGHTCOLOR;

+ 16 - 0
Engine/Graphics/OpenGL/OGLRenderSurface.cpp

@@ -51,6 +51,22 @@ Viewport::Viewport(Scene* scene, Camera* camera, const IntRect& rect) :
 {
 {
 }
 }
 
 
+Viewport::Viewport(Scene* scene, Camera* camera, const Vector<SharedPtr<PostProcess> >& postProcesses) :
+    scene_(scene),
+    camera_(camera),
+    rect_(IntRect::ZERO),
+    postProcesses_(postProcesses)
+{
+}
+
+Viewport::Viewport(Scene* scene, Camera* camera, const IntRect& rect, const Vector<SharedPtr<PostProcess> >& postProcesses) :
+    scene_(scene),
+    camera_(camera),
+    rect_(rect),
+    postProcesses_(postProcesses)
+{
+}
+
 RenderSurface::RenderSurface(Texture* parentTexture, unsigned target) :
 RenderSurface::RenderSurface(Texture* parentTexture, unsigned target) :
     parentTexture_(parentTexture),
     parentTexture_(parentTexture),
     target_(target),
     target_(target),

+ 6 - 0
Engine/Graphics/OpenGL/OGLRenderSurface.h

@@ -40,6 +40,10 @@ struct Viewport
     Viewport(Scene* scene, Camera* camera);
     Viewport(Scene* scene, Camera* camera);
     /// Construct with a specified rectangle.
     /// Construct with a specified rectangle.
     Viewport(Scene* scene, Camera* camera, const IntRect& rect);
     Viewport(Scene* scene, Camera* camera, const IntRect& rect);
+    /// Construct with a full rectangle and post-processing effects.
+    Viewport(Scene* scene, Camera* camera, const Vector<SharedPtr<PostProcess> >& postProcesses);
+    /// Construct with a specified rectangle and post-processing effects.
+    Viewport(Scene* scene, Camera* camera, const IntRect& rect, const Vector<SharedPtr<PostProcess> >& postProcesses);
     
     
     /// Scene pointer.
     /// Scene pointer.
     WeakPtr<Scene> scene_;
     WeakPtr<Scene> scene_;
@@ -47,6 +51,8 @@ struct Viewport
     WeakPtr<Camera> camera_;
     WeakPtr<Camera> camera_;
     /// Viewport rectangle.
     /// Viewport rectangle.
     IntRect rect_;
     IntRect rect_;
+    /// Post-processing effects.
+    Vector<SharedPtr<PostProcess> > postProcesses_;
 };
 };
 
 
 /// %Color or depth-stencil surface that can be rendered into.
 /// %Color or depth-stencil surface that can be rendered into.

+ 11 - 4
Engine/Graphics/PostProcess.cpp

@@ -53,7 +53,7 @@ void PostProcessPass::SetPixelShader(const String& name)
 
 
 void PostProcessPass::SetTexture(TextureUnit unit, const String& name)
 void PostProcessPass::SetTexture(TextureUnit unit, const String& name)
 {
 {
-    if (unit < MAX_TEXTURE_UNITS)
+    if (unit < MAX_MATERIAL_TEXTURE_UNITS)
         textureNames_[unit] = name;
         textureNames_[unit] = name;
 }
 }
 
 
@@ -74,7 +74,7 @@ void PostProcessPass::SetOutput(const String& name)
 
 
 const String& PostProcessPass::GetTexture(TextureUnit unit) const
 const String& PostProcessPass::GetTexture(TextureUnit unit) const
 {
 {
-    return unit < MAX_TEXTURE_UNITS ? textureNames_[unit] : emptyName;
+    return unit < MAX_MATERIAL_TEXTURE_UNITS ? textureNames_[unit] : emptyName;
 }
 }
 
 
 const Vector4& PostProcessPass::GetShaderParameter(const String& name) const
 const Vector4& PostProcessPass::GetShaderParameter(const String& name) const
@@ -86,7 +86,8 @@ const Vector4& PostProcessPass::GetShaderParameter(const String& name) const
 OBJECTTYPESTATIC(PostProcess);
 OBJECTTYPESTATIC(PostProcess);
 
 
 PostProcess::PostProcess(Context* context) :
 PostProcess::PostProcess(Context* context) :
-    Object(context)
+    Object(context),
+    active_(true)
 {
 {
 }
 }
 
 
@@ -99,7 +100,7 @@ bool PostProcess::LoadParameters(XMLFile* file)
     if (!file)
     if (!file)
         return false;
         return false;
     
     
-    XMLElement rootElem = parameterSource_->GetRoot();
+    XMLElement rootElem = file->GetRoot();
     if (!rootElem)
     if (!rootElem)
         return false;
         return false;
     
     
@@ -172,6 +173,7 @@ bool PostProcess::LoadParameters(XMLFile* file)
                 String name = textureElem.GetAttribute("name");
                 String name = textureElem.GetAttribute("name");
                 pass->SetTexture(unit, name);
                 pass->SetTexture(unit, name);
             }
             }
+            
             textureElem = textureElem.GetNext("texture");
             textureElem = textureElem.GetNext("texture");
         }
         }
         
         
@@ -223,6 +225,11 @@ void PostProcess::RemoveRenderTarget(const String& name)
     renderTargets_.Erase(StringHash(name));
     renderTargets_.Erase(StringHash(name));
 }
 }
 
 
+void PostProcess::SetActive(bool active)
+{
+    active_ = active;
+}
+
 PostProcessPass* PostProcess::GetPass(unsigned index) const
 PostProcessPass* PostProcess::GetPass(unsigned index) const
 {
 {
     if (index < passes_.Size())
     if (index < passes_.Size())

+ 14 - 1
Engine/Graphics/PostProcess.h

@@ -58,8 +58,12 @@ public:
     const String& GetPixelShader() const { return pixelShaderName_; }
     const String& GetPixelShader() const { return pixelShaderName_; }
     /// Return texture name.
     /// Return texture name.
     const String& GetTexture(TextureUnit unit) const;
     const String& GetTexture(TextureUnit unit) const;
+    /// Return all texture names.
+    const String* GetTextures() const { return &textureNames_[0]; }
     /// Return shader parameter.
     /// Return shader parameter.
     const Vector4& GetShaderParameter(const String& name) const;
     const Vector4& GetShaderParameter(const String& name) const;
+    /// Return all shader parameters.
+    const HashMap<StringHash, Vector4>& GetShaderParameters() const { return shaderParameters_; }
     /// Return output rendertarget name.
     /// Return output rendertarget name.
     const String& GetOutput() const { return outputName_; }
     const String& GetOutput() const { return outputName_; }
     
     
@@ -69,7 +73,7 @@ private:
     /// Pixel shader name.
     /// Pixel shader name.
     String pixelShaderName_;
     String pixelShaderName_;
     /// Texture names by unit.
     /// Texture names by unit.
-    String textureNames_[MAX_TEXTURE_UNITS];
+    String textureNames_[MAX_MATERIAL_TEXTURE_UNITS];
     /// Shader parameters.
     /// Shader parameters.
     HashMap<StringHash, Vector4> shaderParameters_;
     HashMap<StringHash, Vector4> shaderParameters_;
     /// Output rendertarget name.
     /// Output rendertarget name.
@@ -108,6 +112,8 @@ public:
     bool CreateRenderTarget(const String& name, unsigned width, unsigned height, unsigned format, bool sizeDivisor, bool filtered);
     bool CreateRenderTarget(const String& name, unsigned width, unsigned height, unsigned format, bool sizeDivisor, bool filtered);
     /// Remove a rendertarget.
     /// Remove a rendertarget.
     void RemoveRenderTarget(const String& name);
     void RemoveRenderTarget(const String& name);
+    /// Set active flag.
+    void SetActive(bool active);
     
     
     /// Return parameter XML file.
     /// Return parameter XML file.
     XMLFile* GetParameters() const { return parameterSource_; }
     XMLFile* GetParameters() const { return parameterSource_; }
@@ -117,6 +123,11 @@ public:
     PostProcessPass* GetPass(unsigned index) const;
     PostProcessPass* GetPass(unsigned index) const;
     /// Return if has a specific rendertarget.
     /// Return if has a specific rendertarget.
     bool HasRenderTarget(const String& name) const;
     bool HasRenderTarget(const String& name) const;
+    /// Return all rendertargets.
+    const HashMap<StringHash, PostProcessRenderTarget>& GetRenderTargets() const { return renderTargets_; }
+    
+    /// Return active flag.
+    bool IsActive() const { return active_; }
     
     
 private:
 private:
     /// Parameter XML file.
     /// Parameter XML file.
@@ -125,4 +136,6 @@ private:
     Vector<SharedPtr<PostProcessPass> > passes_;
     Vector<SharedPtr<PostProcessPass> > passes_;
     /// Rendertargets.
     /// Rendertargets.
     HashMap<StringHash, PostProcessRenderTarget> renderTargets_;
     HashMap<StringHash, PostProcessRenderTarget> renderTargets_;
+    /// Active flag.
+    bool active_;
 };
 };

+ 10 - 30
Engine/Graphics/Renderer.cpp

@@ -258,19 +258,11 @@ static const unsigned INSTANCING_BUFFER_MASK = MASK_INSTANCEMATRIX1 | MASK_INSTA
 static const unsigned MAX_BUFFER_AGE = 2000;
 static const unsigned MAX_BUFFER_AGE = 2000;
 static const Viewport noViewport;
 static const Viewport noViewport;
 
 
-void EdgeFilterParameters::Validate()
-{
-    radius_ = Max(radius_, 0.0f);
-    threshold_ = Max(threshold_, 0.0f);
-    strength_ = Max(strength_, 0.0f);
-}
-
 OBJECTTYPESTATIC(Renderer);
 OBJECTTYPESTATIC(Renderer);
 
 
 Renderer::Renderer(Context* context) :
 Renderer::Renderer(Context* context) :
     Object(context),
     Object(context),
     defaultZone_(new Zone(context)),
     defaultZone_(new Zone(context)),
-    edgeFilterParameters_(EdgeFilterParameters(0.4f, 0.5f, 0.9f)),
     numViews_(0),
     numViews_(0),
     numShadowCameras_(0),
     numShadowCameras_(0),
     numOcclusionBuffers_(0),
     numOcclusionBuffers_(0),
@@ -292,7 +284,6 @@ Renderer::Renderer(Context* context) :
     drawShadows_(true),
     drawShadows_(true),
     reuseShadowMaps_(true),
     reuseShadowMaps_(true),
     dynamicInstancing_(true),
     dynamicInstancing_(true),
-    edgeFilter_(false),
     shadersDirty_(true),
     shadersDirty_(true),
     initialized_(false)
     initialized_(false)
 {
 {
@@ -471,27 +462,6 @@ void Renderer::SetMaxInstanceTriangles(int triangles)
     maxInstanceTriangles_ = Max(triangles, 0);
     maxInstanceTriangles_ = Max(triangles, 0);
 }
 }
 
 
-void Renderer::SetEdgeFilter(bool enable)
-{
-    if (enable)
-    {
-        // Edge filter is incompatible with hardware multisampling, so set new screen mode with 1x sampling if in use
-        if (graphics_->GetMultiSample() > 1)
-        {
-            graphics_->SetMode(graphics_->GetWidth(), graphics_->GetHeight(), graphics_->GetFullscreen(), graphics_->GetVSync(),
-                graphics_->GetTripleBuffer(), 1);
-        }
-    }
-    
-    edgeFilter_ = enable;
-}
-
-void Renderer::SetEdgeFilterParameters(const EdgeFilterParameters& parameters)
-{
-    edgeFilterParameters_ = parameters;
-    edgeFilterParameters_.Validate();
-}
-
 void Renderer::SetMaxOccluderTriangles(int triangles)
 void Renderer::SetMaxOccluderTriangles(int triangles)
 {
 {
     maxOccluderTriangles_ = Max(triangles, 0);
     maxOccluderTriangles_ = Max(triangles, 0);
@@ -1233,6 +1203,16 @@ bool Renderer::ResizeInstancingBuffer(unsigned numInstances)
     return true;
     return true;
 }
 }
 
 
+void Renderer::SaveScreenBufferAllocations()
+{
+    savedScreenBufferAllocations_ = screenBufferAllocations_;
+}
+
+void Renderer::RestoreScreenBufferAllocations()
+{
+    screenBufferAllocations_ = savedScreenBufferAllocations_;
+}
+
 void Renderer::RemoveUnusedBuffers()
 void Renderer::RemoveUnusedBuffers()
 {
 {
     for (unsigned i = occlusionBuffers_.Size() - 1; i < occlusionBuffers_.Size(); --i)
     for (unsigned i = occlusionBuffers_.Size() - 1; i < occlusionBuffers_.Size(); --i)

+ 8 - 41
Engine/Graphics/Renderer.h

@@ -154,33 +154,6 @@ enum DeferredLightPSVariation
     MAX_DEFERRED_LIGHT_PS_VARIATIONS
     MAX_DEFERRED_LIGHT_PS_VARIATIONS
 };
 };
 
 
-/// %Edge filter parameters.
-struct EdgeFilterParameters
-{
-    /// Construct undefined.
-    EdgeFilterParameters()
-    {
-    }
-    
-    /// Construct with initial values.
-    EdgeFilterParameters(float radius, float threshold, float strength) :
-        radius_(radius),
-        threshold_(threshold),
-        strength_(strength)
-    {
-    }
-    
-    //! Validate parameters.
-    void Validate();
-    
-    //! Radius for calculating luminance gradient.
-    float radius_;
-    //! Luminance difference threshold needed before filtering occurs.
-    float threshold_;
-    //! Filter strength.
-    float strength_;
-};
-
 /// High-level rendering subsystem. Manages drawing of 3D views.
 /// High-level rendering subsystem. Manages drawing of 3D views.
 class Renderer : public Object
 class Renderer : public Object
 {
 {
@@ -224,10 +197,6 @@ public:
     void SetDynamicInstancing(bool enable);
     void SetDynamicInstancing(bool enable);
     /// %Set maximum number of triangles per object for instancing.
     /// %Set maximum number of triangles per object for instancing.
     void SetMaxInstanceTriangles(int triangles);
     void SetMaxInstanceTriangles(int triangles);
-    /// %Set edge filter on/off.
-    void SetEdgeFilter(bool enable);
-    /// %Set edge filter parameters.
-    void SetEdgeFilterParameters(const EdgeFilterParameters& parameters);
     /// %Set maximum number of occluder trianges.
     /// %Set maximum number of occluder trianges.
     void SetMaxOccluderTriangles(int triangles);
     void SetMaxOccluderTriangles(int triangles);
     /// %Set occluder buffer width.
     /// %Set occluder buffer width.
@@ -266,10 +235,6 @@ public:
     bool GetDynamicInstancing() const { return dynamicInstancing_; }
     bool GetDynamicInstancing() const { return dynamicInstancing_; }
     /// Return maximum number of triangles per object for instancing.
     /// Return maximum number of triangles per object for instancing.
     int GetMaxInstanceTriangles() { return maxInstanceTriangles_; }
     int GetMaxInstanceTriangles() { return maxInstanceTriangles_; }
-    /// Return whether edge filter is enabled.
-    bool GetEdgeFilter() const { return edgeFilter_; }
-    /// Return edge filter parameters.
-    const EdgeFilterParameters& GetEdgeFilterParameters() const { return edgeFilterParameters_; }
     /// Return maximum number of occluder triangles.
     /// Return maximum number of occluder triangles.
     int GetMaxOccluderTriangles() const { return maxOccluderTriangles_; }
     int GetMaxOccluderTriangles() const { return maxOccluderTriangles_; }
     /// Return occlusion buffer width.
     /// Return occlusion buffer width.
@@ -345,6 +310,10 @@ public:
     void SetCullMode(CullMode mode, Camera* camera);
     void SetCullMode(CullMode mode, Camera* camera);
     /// Ensure sufficient size of the instancing vertex buffer. Return true if successful.
     /// Ensure sufficient size of the instancing vertex buffer. Return true if successful.
     bool ResizeInstancingBuffer(unsigned numInstances);
     bool ResizeInstancingBuffer(unsigned numInstances);
+    /// Save the screen buffer allocation status. Called by View.
+    void SaveScreenBufferAllocations();
+    /// Restore the screen buffer allocation status. Called by View.
+    void RestoreScreenBufferAllocations();
     
     
 private:
 private:
     /// Initialize when screen mode initially set.
     /// Initialize when screen mode initially set.
@@ -424,10 +393,12 @@ private:
     HashMap<int, SharedPtr<Texture2D> > colorShadowMaps_;
     HashMap<int, SharedPtr<Texture2D> > colorShadowMaps_;
     /// Shadow map allocations by resolution.
     /// Shadow map allocations by resolution.
     HashMap<int, PODVector<Light*> > shadowMapAllocations_;
     HashMap<int, PODVector<Light*> > shadowMapAllocations_;
-    /// Renderbuffers by resolution and format.
+    /// Screen buffers by resolution and format.
     HashMap<long long, Vector<SharedPtr<Texture2D> > > screenBuffers_;
     HashMap<long long, Vector<SharedPtr<Texture2D> > > screenBuffers_;
-    /// Renderbuffer current allocations by resolution and format.
+    /// Current screen buffer allocations by resolution and format.
     HashMap<long long, unsigned> screenBufferAllocations_;
     HashMap<long long, unsigned> screenBufferAllocations_;
+    /// Saved status of screen buffer allocations for restoring.
+    HashMap<long long, unsigned> savedScreenBufferAllocations_;
     /// Viewports.
     /// Viewports.
     Vector<Viewport> viewports_;
     Vector<Viewport> viewports_;
     /// Views.
     /// Views.
@@ -438,8 +409,6 @@ private:
     HashSet<Technique*> shaderErrorDisplayed_;
     HashSet<Technique*> shaderErrorDisplayed_;
     /// Mutex for shadow camera allocation.
     /// Mutex for shadow camera allocation.
     Mutex rendererMutex_;
     Mutex rendererMutex_;
-    /// Edge filter parameters.
-    EdgeFilterParameters edgeFilterParameters_;
     /// Vertex shader format.
     /// Vertex shader format.
     String vsFormat_;
     String vsFormat_;
     /// Pixel shader format.
     /// Pixel shader format.
@@ -494,8 +463,6 @@ private:
     bool reuseShadowMaps_;
     bool reuseShadowMaps_;
     /// Dynamic instancing flag.
     /// Dynamic instancing flag.
     bool dynamicInstancing_;
     bool dynamicInstancing_;
-    /// Edge filter flag.
-    bool edgeFilter_;
     /// Shaders need reloading flag.
     /// Shaders need reloading flag.
     bool shadersDirty_;
     bool shadersDirty_;
     /// Initialized flag.
     /// Initialized flag.

+ 203 - 49
Engine/Graphics/View.cpp

@@ -32,6 +32,7 @@
 #include "OcclusionBuffer.h"
 #include "OcclusionBuffer.h"
 #include "Octree.h"
 #include "Octree.h"
 #include "Renderer.h"
 #include "Renderer.h"
+#include "ResourceCache.h"
 #include "Profiler.h"
 #include "Profiler.h"
 #include "Scene.h"
 #include "Scene.h"
 #include "ShaderVariation.h"
 #include "ShaderVariation.h"
@@ -150,8 +151,7 @@ View::View(Context* context) :
     camera_(0),
     camera_(0),
     cameraZone_(0),
     cameraZone_(0),
     farClipZone_(0),
     farClipZone_(0),
-    renderTarget_(0),
-    screenBuffer_(0)
+    renderTarget_(0)
 {
 {
     frame_.camera_ = 0;
     frame_.camera_ = 0;
     
     
@@ -181,7 +181,7 @@ bool View::Define(RenderSurface* renderTarget, const Viewport& viewport)
     octree_ = octree;
     octree_ = octree;
     camera_ = viewport.camera_;
     camera_ = viewport.camera_;
     renderTarget_ = renderTarget;
     renderTarget_ = renderTarget;
-    screenBuffer_ = 0;
+    postProcesses_ = &viewport.postProcesses_;
     
     
     // Validate the rect and calculate size. If zero rect, use whole rendertarget size
     // Validate the rect and calculate size. If zero rect, use whole rendertarget size
     int rtWidth = renderTarget ? renderTarget->GetWidth() : graphics_->GetWidth();
     int rtWidth = renderTarget ? renderTarget->GetWidth() : graphics_->GetWidth();
@@ -211,8 +211,6 @@ bool View::Define(RenderSurface* renderTarget, const Viewport& viewport)
     drawShadows_ = renderer_->GetDrawShadows();
     drawShadows_ = renderer_->GetDrawShadows();
     materialQuality_ = renderer_->GetMaterialQuality();
     materialQuality_ = renderer_->GetMaterialQuality();
     maxOccluderTriangles_ = renderer_->GetMaxOccluderTriangles();
     maxOccluderTriangles_ = renderer_->GetMaxOccluderTriangles();
-    // Use edge filter only when final target is the backbuffer
-    edgeFilter_ = !renderTarget_ && renderer_->GetEdgeFilter();
     
     
     // Set possible quality overrides from the camera
     // Set possible quality overrides from the camera
     unsigned viewOverrideFlags = camera_->GetViewOverrideFlags();
     unsigned viewOverrideFlags = camera_->GetViewOverrideFlags();
@@ -236,7 +234,8 @@ void View::Update(const FrameInfo& frame)
     frame_.frameNumber_ = frame.frameNumber_;
     frame_.frameNumber_ = frame.frameNumber_;
     frame_.viewSize_ = viewSize_;
     frame_.viewSize_ = viewSize_;
     
     
-    // Clear old light scissor cache, geometry, light, occluder & batch lists
+    // Clear screen buffers, old light scissor cache, geometry, light, occluder & batch lists
+    screenBuffers_.Clear();
     lightScissorCache_.Clear();
     lightScissorCache_.Clear();
     geometries_.Clear();
     geometries_.Clear();
     allGeometries_.Clear();
     allGeometries_.Clear();
@@ -274,6 +273,9 @@ void View::Render()
     if (!octree_ || !camera_)
     if (!octree_ || !camera_)
         return;
         return;
     
     
+    // Allocate screen buffers for post-processing and blitting as necessary
+    AllocateScreenBuffers();
+    
     // Forget parameter sources from the previous view
     // Forget parameter sources from the previous view
     graphics_->ClearParameterSources();
     graphics_->ClearParameterSources();
     
     
@@ -337,13 +339,14 @@ void View::Render()
         }
         }
     }
     }
     
     
-    // Blit if necessary (OpenGL light pre-pass, or edge filter)
-    #ifdef USE_OPENGL
-    if (lightPrepass_ || edgeFilter_)
-    #else
-    if (edgeFilter_)
-    #endif
-        BlitFramebuffer();
+    // Run post-processes or framebuffer blitting now
+    if (screenBuffers_.Size())
+    {
+        if (postProcesses_->Size())
+            RunPostProcesses();
+        else
+            BlitFramebuffer();
+    }
     
     
     // "Forget" the camera, octree and zone after rendering
     // "Forget" the camera, octree and zone after rendering
     camera_ = 0;
     camera_ = 0;
@@ -970,10 +973,7 @@ void View::RenderBatchesForward()
     // Reset the light optimization stencil reference value
     // Reset the light optimization stencil reference value
     lightStencilValue_ = 1;
     lightStencilValue_ = 1;
     
     
-    bool needBlit = edgeFilter_;
-    if (needBlit)
-        screenBuffer_ = renderer_->GetScreenBuffer(rtSize_.x_, rtSize_.y_, Graphics::GetRGBFormat(), true);
-    RenderSurface* renderTarget = needBlit ? screenBuffer_->GetRenderSurface() : renderTarget_;
+    RenderSurface* renderTarget = screenBuffers_.Size() ? screenBuffers_[0]->GetRenderSurface() : renderTarget_;
     RenderSurface* depthStencil = GetDepthStencil(renderTarget);
     RenderSurface* depthStencil = GetDepthStencil(renderTarget);
     
     
     // If not reusing shadowmaps, render all of them first
     // If not reusing shadowmaps, render all of them first
@@ -1072,14 +1072,7 @@ void View::RenderBatchesLightPrepass()
     Texture2D* depthBuffer = renderer_->GetScreenBuffer(rtSize_.x_, rtSize_.y_, hwDepth ? Graphics::GetDepthStencilFormat() :
     Texture2D* depthBuffer = renderer_->GetScreenBuffer(rtSize_.x_, rtSize_.y_, hwDepth ? Graphics::GetDepthStencilFormat() :
         Graphics::GetLinearDepthFormat());
         Graphics::GetLinearDepthFormat());
     
     
-    #ifdef USE_OPENGL
-    bool needBlit = true;
-    #else
-    bool needBlit = edgeFilter_;
-    #endif
-    if (needBlit)
-        screenBuffer_ = renderer_->GetScreenBuffer(rtSize_.x_, rtSize_.y_, Graphics::GetRGBFormat(), true);
-    RenderSurface* renderTarget = needBlit ? screenBuffer_->GetRenderSurface() : renderTarget_;
+    RenderSurface* renderTarget = screenBuffers_.Size() ? screenBuffers_[0]->GetRenderSurface() : renderTarget_;
     RenderSurface* depthStencil;
     RenderSurface* depthStencil;
     
     
     // Hardware depth support: render to RGBA normal buffer and read hardware depth
     // Hardware depth support: render to RGBA normal buffer and read hardware depth
@@ -1202,6 +1195,32 @@ void View::RenderBatchesLightPrepass()
     }
     }
 }
 }
 
 
+void View::AllocateScreenBuffers()
+{
+    unsigned neededBuffers = 0;
+    #ifdef USE_OPENGL
+    if (lightPrepass_)
+        neededBuffers = 1;
+    #endif
+    
+    unsigned postProcessPasses = 0;
+    for (unsigned i = 0; i < postProcesses_->Size(); ++i)
+    {
+        PostProcess* effect = postProcesses_->At(i);
+        if (effect && effect->IsActive())
+            postProcessPasses += effect->GetNumPasses();
+    }
+    
+    // If more than one post-process pass, need 2 buffers for ping-pong rendering
+    if (postProcessPasses)
+        neededBuffers = Min((int)postProcessPasses, 2);
+    
+    // Allocate screen buffers with filtering active in case the post-processing effects need that
+    screenBuffers_.Clear();
+    for (unsigned i = 0; i < neededBuffers; ++i)
+        screenBuffers_.Push(renderer_->GetScreenBuffer(rtSize_.x_, rtSize_.y_, Graphics::GetRGBFormat(), true));
+}
+
 void View::BlitFramebuffer()
 void View::BlitFramebuffer()
 {
 {
     // Blit the final image to destination rendertarget
     // Blit the final image to destination rendertarget
@@ -1216,41 +1235,174 @@ void View::BlitFramebuffer()
     graphics_->SetDepthStencil(GetDepthStencil(renderTarget_));
     graphics_->SetDepthStencil(GetDepthStencil(renderTarget_));
     graphics_->SetViewport(viewRect_);
     graphics_->SetViewport(viewRect_);
     
     
-    String shaderName = edgeFilter_ ? "EdgeFilter" : "CopyFramebuffer";
+    String shaderName = "CopyFramebuffer";
     graphics_->SetShaders(renderer_->GetVertexShader(shaderName), renderer_->GetPixelShader(shaderName));
     graphics_->SetShaders(renderer_->GetVertexShader(shaderName), renderer_->GetPixelShader(shaderName));
     
     
     float rtWidth = (float)rtSize_.x_;
     float rtWidth = (float)rtSize_.x_;
     float rtHeight = (float)rtSize_.y_;
     float rtHeight = (float)rtSize_.y_;
+    float widthRange = 0.5f * viewSize_.x_ / rtWidth;
+    float heightRange = 0.5f * viewSize_.y_ / rtHeight;
     
     
+    #ifdef USE_OPENGL
+    Vector4 bufferUVOffset(((float)viewRect_.left_) / rtWidth + widthRange,
+        1.0f - (((float)viewRect_.top_) / rtHeight + heightRange), widthRange, heightRange);
+    #else
+    Vector4 bufferUVOffset((0.5f + (float)viewRect_.left_) / rtWidth + widthRange,
+        (0.5f + (float)viewRect_.top_) / rtHeight + heightRange, widthRange, heightRange);
+    #endif
+    
+    graphics_->SetShaderParameter(VSP_GBUFFEROFFSETS, bufferUVOffset);
+    
+    graphics_->SetTexture(TU_DIFFUSE, screenBuffers_[0]);
+    DrawFullscreenQuad(camera_, false);
+}
+
+void View::RunPostProcesses()
+{
+    ResourceCache* cache = GetSubsystem<ResourceCache>();
+    
+    // Ping-pong buffer indices for read and write
+    unsigned readRtIndex = 0;
+    unsigned writeRtIndex = screenBuffers_.Size() - 1;
+    
+    graphics_->SetAlphaTest(false);
+    graphics_->SetBlendMode(BLEND_REPLACE);
+    graphics_->SetDepthTest(CMP_ALWAYS);
+    graphics_->SetDepthWrite(true);
+    graphics_->SetScissorTest(false);
+    graphics_->SetStencilTest(false);
+    
+    // Find out the index of last active effect to see when the final output should be rendered
+    unsigned lastActiveEffect = 0;
+    for (unsigned i = 0; i < postProcesses_->Size(); ++i)
     {
     {
-        float widthRange = 0.5f * viewSize_.x_ / rtWidth;
-        float heightRange = 0.5f * viewSize_.y_ / rtHeight;
-        
-        #ifdef USE_OPENGL
-        Vector4 bufferUVOffset(((float)viewRect_.left_) / rtWidth + widthRange,
-            1.0f - (((float)viewRect_.top_) / rtHeight + heightRange), widthRange, heightRange);
-        #else
-        Vector4 bufferUVOffset((0.5f + (float)viewRect_.left_) / rtWidth + widthRange,
-            (0.5f + (float)viewRect_.top_) / rtHeight + heightRange, widthRange, heightRange);
-        #endif
-        
-        graphics_->SetShaderParameter(VSP_GBUFFEROFFSETS, bufferUVOffset);
+        PostProcess* effect = postProcesses_->At(i);
+        if (!effect || !effect->IsActive())
+            continue;
+        lastActiveEffect = i;
     }
     }
     
     
-    if (edgeFilter_)
+    for (unsigned i = 0; i < postProcesses_->Size(); ++i)
     {
     {
-        const EdgeFilterParameters& parameters = renderer_->GetEdgeFilterParameters();
-        graphics_->SetShaderParameter(PSP_EDGEFILTERPARAMS, Vector4(parameters.radius_, parameters.threshold_,
-            parameters.strength_, 0.0f));
+        PostProcess* effect = postProcesses_->At(i);
+        if (!effect || !effect->IsActive())
+            continue;
         
         
-        float addX = 1.0f / rtWidth;
-        float addY = 1.0f / rtHeight;
-        graphics_->SetShaderParameter(PSP_SAMPLEOFFSETS, Vector4(addX, addY, 0.0f, 0.0f));
+        // For each effect, rendertargets can be re-used. Allocate them now
+        renderer_->SaveScreenBufferAllocations();
+        const HashMap<StringHash, PostProcessRenderTarget>& renderTargetInfos = effect->GetRenderTargets();
+        HashMap<StringHash, Texture2D*> renderTargets;
+        for (HashMap<StringHash, PostProcessRenderTarget>::ConstIterator j = renderTargetInfos.Begin(); j !=
+            renderTargetInfos.End(); ++j)
+        {
+            if (j->second_.sizeDivisor_)
+            {
+                renderTargets[j->first_] = renderer_->GetScreenBuffer(rtSize_.x_ / j->second_.size_.x_,
+                    rtSize_.y_ / j->second_.size_.y_, j->second_.format_, j->second_.filtered_);
+            }
+            else
+            {
+                renderTargets[j->first_] = renderer_->GetScreenBuffer(j->second_.size_.x_, j->second_.size_.y_,
+                    j->second_.format_, j->second_.filtered_);
+            }
+        }
+        
+        // Run each effect pass
+        for (unsigned j = 0; j < effect->GetNumPasses(); ++j)
+        {
+            PostProcessPass* pass = effect->GetPass(j);
+            bool lastPass = (i == lastActiveEffect) && (j == effect->GetNumPasses() - 1);
+            bool swapBuffers = false;
+            
+            // Set output rendertarget
+            RenderSurface* rt = 0;
+            String output = pass->GetOutput().ToLower();
+            if (output == "viewport")
+            {
+                if (!lastPass)
+                {
+                    rt = screenBuffers_[writeRtIndex]->GetRenderSurface();
+                    swapBuffers = true;
+                }
+                else
+                    rt = renderTarget_;
+                
+                graphics_->SetRenderTarget(0, rt);
+                graphics_->SetDepthStencil(GetDepthStencil(rt));
+                graphics_->SetViewport(viewRect_);
+            }
+            else
+            {
+                HashMap<StringHash, Texture2D*>::ConstIterator k = renderTargets.Find(StringHash(output));
+                if (k != renderTargets.End())
+                    rt = k->second_->GetRenderSurface();
+                else
+                    continue; // Skip pass if rendertarget can not be found
+                
+                graphics_->SetRenderTarget(0, rt);
+                graphics_->SetDepthStencil(GetDepthStencil(rt));
+            }
+            
+            // Set shaders, shader parameters and textures
+            graphics_->SetShaders(renderer_->GetVertexShader(pass->GetVertexShader()),
+                renderer_->GetPixelShader(pass->GetPixelShader()));
+            
+            const HashMap<StringHash, Vector4>& parameters = pass->GetShaderParameters();
+            for (HashMap<StringHash, Vector4>::ConstIterator k = parameters.Begin(); k != parameters.End(); ++k)
+                graphics_->SetShaderParameter(k->first_, k->second_);
+            
+            float rtWidth = (float)rtSize_.x_;
+            float rtHeight = (float)rtSize_.y_;
+            float widthRange = 0.5f * viewSize_.x_ / rtWidth;
+            float heightRange = 0.5f * viewSize_.y_ / rtHeight;
+            
+            #ifdef USE_OPENGL
+            Vector4 bufferUVOffset(((float)viewRect_.left_) / rtWidth + widthRange,
+                1.0f - (((float)viewRect_.top_) / rtHeight + heightRange), widthRange, heightRange);
+            #else
+            Vector4 bufferUVOffset((0.5f + (float)viewRect_.left_) / rtWidth + widthRange,
+                (0.5f + (float)viewRect_.top_) / rtHeight + heightRange, widthRange, heightRange);
+            #endif
+            
+            graphics_->SetShaderParameter(VSP_GBUFFEROFFSETS, bufferUVOffset);
+            graphics_->SetShaderParameter(PSP_SAMPLEOFFSETS, Vector4(1.0f / rtWidth, 1.0f / rtHeight, 0.0f, 0.0f));
+            
+            const String* textureNames = pass->GetTextures();
+            for (unsigned k = 0; k < MAX_MATERIAL_TEXTURE_UNITS; ++k)
+            {
+                if (!textureNames[k].Empty())
+                {
+                    // Texture may either refer to a rendertarget or to a texture resource
+                    if (!textureNames[k].Compare("viewport", false))
+                        graphics_->SetTexture(k, screenBuffers_[readRtIndex]);
+                    else
+                    {
+                        HashMap<StringHash, Texture2D*>::ConstIterator l = renderTargets.Find(StringHash(textureNames[k]));
+                        if (l != renderTargets.End())
+                            graphics_->SetTexture(k, l->second_);
+                        else
+                        {
+                            // If requesting a texture fails, clear the texture name to prevent redundant attempts
+                            Texture2D* texture = cache->GetResource<Texture2D>(textureNames[k]);
+                            if (texture)
+                                graphics_->SetTexture(k, texture);
+                            else
+                                pass->SetTexture((TextureUnit)k, String());
+                        }
+                    }
+                }
+            }
+            
+            DrawFullscreenQuad(camera_, false);
+            
+            // Swap the ping-pong buffer sides now if necessary
+            if (swapBuffers)
+                Swap(readRtIndex, writeRtIndex);
+        }
+        
+        // Forget the rendertargets allocated during this effect
+        renderer_->RestoreScreenBufferAllocations();
     }
     }
-    
-    graphics_->SetTexture(TU_DIFFUSE, screenBuffer_);
-    DrawFullscreenQuad(camera_, false);
-    graphics_->SetTexture(TU_DIFFUSE, 0);
 }
 }
 
 
 void View::UpdateOccluders(PODVector<Drawable*>& occluders, Camera* camera)
 void View::UpdateOccluders(PODVector<Drawable*>& occluders, Camera* camera)
@@ -2349,3 +2501,5 @@ RenderSurface* View::GetDepthStencil(RenderSurface* renderTarget)
         depthStencil = renderer_->GetDepthStencil(renderTarget->GetWidth(), renderTarget->GetHeight());
         depthStencil = renderer_->GetDepthStencil(renderTarget->GetWidth(), renderTarget->GetHeight());
     return depthStencil;
     return depthStencil;
 }
 }
+
+

+ 8 - 4
Engine/Graphics/View.h

@@ -125,8 +125,12 @@ private:
     void RenderBatchesForward();
     void RenderBatchesForward();
     /// Render batches using light pre-pass rendering.
     /// Render batches using light pre-pass rendering.
     void RenderBatchesLightPrepass();
     void RenderBatchesLightPrepass();
+    /// Allocate needed screen buffers for post-processing and/or framebuffer blitting.
+    void AllocateScreenBuffers();
     /// Blit the framebuffer to destination. Used in OpenGL light pre-pass mode and when applying edge filter.
     /// Blit the framebuffer to destination. Used in OpenGL light pre-pass mode and when applying edge filter.
     void BlitFramebuffer();
     void BlitFramebuffer();
+    /// Run post-processing effects.
+    void RunPostProcesses();
     /// Query for occluders as seen from a camera.
     /// Query for occluders as seen from a camera.
     void UpdateOccluders(PODVector<Drawable*>& occluders, Camera* camera);
     void UpdateOccluders(PODVector<Drawable*>& occluders, Camera* camera);
     /// Draw occluders to occlusion buffer.
     /// Draw occluders to occlusion buffer.
@@ -202,8 +206,10 @@ private:
     OcclusionBuffer* occlusionBuffer_;
     OcclusionBuffer* occlusionBuffer_;
     /// Color rendertarget to use.
     /// Color rendertarget to use.
     RenderSurface* renderTarget_;
     RenderSurface* renderTarget_;
-    /// Intermediate screen buffer used in postprocessing and OpenGL light pre-pass framebuffer blit.
-    Texture2D* screenBuffer_;
+    /// Post-processing effects.
+    const Vector<SharedPtr<PostProcess> >* postProcesses_;
+    /// Intermediate screen buffers used in postprocessing and OpenGL light pre-pass framebuffer blit.
+    PODVector<Texture2D*> screenBuffers_;
     /// Viewport rectangle.
     /// Viewport rectangle.
     IntRect viewRect_;
     IntRect viewRect_;
     /// Viewport size.
     /// Viewport size.
@@ -270,8 +276,6 @@ private:
     unsigned char lightStencilValue_;
     unsigned char lightStencilValue_;
     /// Light prepass flag.
     /// Light prepass flag.
     bool lightPrepass_;
     bool lightPrepass_;
-    /// Edge filter flag.
-    bool edgeFilter_;
     /// Camera zone's override flag.
     /// Camera zone's override flag.
     bool cameraZoneOverride_;
     bool cameraZoneOverride_;
     /// Draw shadows flag.
     /// Draw shadows flag.

+ 3 - 2
SourceAssets/GLSLShaders/EdgeFilter.frag

@@ -1,6 +1,6 @@
 /*============================================================================
 /*============================================================================
- 
-                  FXAA v2 CONSOLE by TIMOTHY LOTTES @ NVIDIA                                
+
+                  FXAA v2 CONSOLE by TIMOTHY LOTTES @ NVIDIA
 
 
 ============================================================================*/
 ============================================================================*/
 
 
@@ -9,6 +9,7 @@
 #include "Uniforms.frag"
 #include "Uniforms.frag"
 #include "Samplers.frag"
 #include "Samplers.frag"
 
 
+uniform vec3 cEdgeFilterParams;
 varying vec2 vScreenPos;
 varying vec2 vScreenPos;
 
 
 void main()
 void main()

+ 0 - 1
SourceAssets/GLSLShaders/Uniforms.frag

@@ -1,6 +1,5 @@
 uniform vec3 cAmbientColor;
 uniform vec3 cAmbientColor;
 uniform vec2 cDepthReconstruct;
 uniform vec2 cDepthReconstruct;
-uniform vec3 cEdgeFilterParams;
 uniform vec3 cFogParams;
 uniform vec3 cFogParams;
 uniform vec3 cFogColor;
 uniform vec3 cFogColor;
 uniform vec4 cLightColor;
 uniform vec4 cLightColor;

+ 4 - 2
SourceAssets/HLSLShaders/EdgeFilter.hlsl

@@ -1,6 +1,6 @@
 /*============================================================================
 /*============================================================================
- 
-                  FXAA v2 CONSOLE by TIMOTHY LOTTES @ NVIDIA                                
+
+                  FXAA v2 CONSOLE by TIMOTHY LOTTES @ NVIDIA
 
 
 ============================================================================*/
 ============================================================================*/
 
 
@@ -11,6 +11,8 @@
 #include "Transform.hlsl"
 #include "Transform.hlsl"
 #include "ScreenPos.hlsl"
 #include "ScreenPos.hlsl"
 
 
+uniform float4 cEdgeFilterParams;
+
 void VS(float4 iPos : POSITION,
 void VS(float4 iPos : POSITION,
     out float4 oPos : POSITION,
     out float4 oPos : POSITION,
     out float2 oScreenPos : TEXCOORD0)
     out float2 oScreenPos : TEXCOORD0)

+ 0 - 1
SourceAssets/HLSLShaders/Uniforms.hlsl

@@ -22,7 +22,6 @@ uniform float4 cVertexLights[6*3];
 // Pixel shader uniforms
 // Pixel shader uniforms
 uniform float3 cAmbientColor;
 uniform float3 cAmbientColor;
 uniform float2 cDepthReconstruct;
 uniform float2 cDepthReconstruct;
-uniform float3 cEdgeFilterParams;
 uniform float3 cFogParams;
 uniform float3 cFogParams;
 uniform float3 cFogColor;
 uniform float3 cFogColor;
 uniform float4 cLightColor;
 uniform float4 cLightColor;