diff --git a/src/DemoApp/main.cpp b/src/DemoApp/main.cpp
index defd1fbede4555983da2de622e02a4599bae571a..3326b898e6af326aedbbb26af56edd0b65d55e2d 100644
--- a/src/DemoApp/main.cpp
+++ b/src/DemoApp/main.cpp
@@ -13,9 +13,10 @@
  * This class parameterize the renderer just after the OpenGL system was initialized.
  * In the functor, The OpenGL context of the drawing window is activated.
  */
-class RendererBuilder {
+class RendererController : public RadiumNBR::RenderControlFunctor {
   public:
-    void operator ()(RadiumNBR::NodeBasedRenderer *renderer, int w, int h) {
+
+    void configure(RadiumNBR::NodeBasedRenderer *renderer, int w, int h) override {
         LOG( Ra::Core::Utils::logINFO ) << "Customizing the renderer " << renderer->getRendererName();
 
         //! [Caching some helpers and data from the Engine and the renderer]
@@ -101,6 +102,7 @@ class DemoWindowFactory : public Ra::Gui::BaseApplication::WindowFactory
     std::shared_ptr<RadiumNBR::NodeBasedRenderer> renderer;
 };
 
+
 int main( int argc, char* argv[] ) {
     if ( argc < 2 )
     {
@@ -108,7 +110,8 @@ int main( int argc, char* argv[] ) {
         return 1;
     }
     //! [Instatiating the renderer giving a customization functor]
-    auto renderer = std::make_shared<RadiumNBR::NodeBasedRenderer>(RendererBuilder{} );
+    RendererController renderControl;
+    auto renderer = std::make_shared<RadiumNBR::NodeBasedRenderer>( renderControl );
     //! [Instatiating the renderer giving a customization functor]
 
     //! [Instatiating the application]
diff --git a/src/libRender/RadiumNBR/FullFeatureRenderer.cpp b/src/libRender/RadiumNBR/FullFeatureRenderer.cpp
index f455a4e85352fefb03b1c6a88667ba32b0749fe4..faae3040c1b511f847cec88a8fc9b5af384df7fb 100644
--- a/src/libRender/RadiumNBR/FullFeatureRenderer.cpp
+++ b/src/libRender/RadiumNBR/FullFeatureRenderer.cpp
@@ -244,49 +244,36 @@ void FullFeatureRenderer::updateStepInternal( const ViewingParameters& renderDat
     // Split objects into opaque and transparent
     m_transparentRenderObjects.clear();
     m_volumetricRenderObjects.clear();
-    allRenderObjects()->clear();
-    for ( auto it = m_fancyRenderObjects.begin(); it != m_fancyRenderObjects.end(); )
-    {
-        allRenderObjects()->push_back( *it );
+
+    auto objectsToRender = allRenderObjects();
+    for( auto it = objectsToRender->begin(); it != objectsToRender->end(); ) {
         if ( ( *it )->isTransparent() )
         {
             m_transparentRenderObjects.push_back( *it );
-            it = m_fancyRenderObjects.erase( it );
+            it = objectsToRender->erase( it );
+            //++it;
         }
         else
         {
             auto material = ( *it )->getMaterial();
             if ( material &&
-                 material->getMaterialAspect() == Material::MaterialAspect::MAT_DENSITY )
+                material->getMaterialAspect() == Material::MaterialAspect::MAT_DENSITY )
             {
                 m_volumetricRenderObjects.push_back( *it );
-                it = m_fancyRenderObjects.erase( it );
+                it = objectsToRender->erase( it );
             }
             else
             { ++it; }
         }
     }
-
-    // Update passes
-    // Note that this could be expensive. Find a way to add attributes to renderObjects so
-    // that one ca factorizes some evaluations.
-    for ( auto& rp : renderPasses() )
-    {
-        if ( rp.second->isActive() ) { rp.second->update(); }
-    }
-}
-
-void FullFeatureRenderer::renderInternal( const ViewingParameters& renderData ) {
     m_clearPass->setBackground( getBackgroundColor() );
     if ( m_hasEnvMap )
     {
         // for ( auto &lm : m_lightmanagers ) { lm->removeSystemLights(); }
     }
-    NodeBasedRenderer::renderInternal( renderData );
+    NodeBasedRenderer::updateStepInternal( renderData );
 }
 
-
-
 void FullFeatureRenderer::setEnvMap( const std::string& files ) {
     if ( files.empty() )
     {
diff --git a/src/libRender/RadiumNBR/FullFeatureRenderer.hpp b/src/libRender/RadiumNBR/FullFeatureRenderer.hpp
index 44dba4f8cc0b3ab391cec03bba25086217c589d5..852011bd45e690243344c054e10893032357813c 100644
--- a/src/libRender/RadiumNBR/FullFeatureRenderer.hpp
+++ b/src/libRender/RadiumNBR/FullFeatureRenderer.hpp
@@ -55,7 +55,6 @@ class NodeBasedRenderer_LIBRARY_API FullFeatureRenderer final : public NodeBased
   protected:
     void initializeInternal() override;
     void updateStepInternal( const Ra::Engine::Data::ViewingParameters& renderData ) override;
-    void renderInternal( const Ra::Engine::Data::ViewingParameters& renderData ) override;
 
   private:
     void initPasses();
diff --git a/src/libRender/RadiumNBR/NodeBasedRenderer.cpp b/src/libRender/RadiumNBR/NodeBasedRenderer.cpp
index 19602c3f2a1dcbaa051176221dacbc0865403526..46106db91393abef25fd84d14ba16972047cbf34 100644
--- a/src/libRender/RadiumNBR/NodeBasedRenderer.cpp
+++ b/src/libRender/RadiumNBR/NodeBasedRenderer.cpp
@@ -26,11 +26,13 @@ int NodeBasedRendererMagic = 0xFF0F00F0;
 
 static const GLenum buffers[] = { GL_COLOR_ATTACHMENT0 };
 
-NodeBasedRenderer::NodeBasedRenderer() : Renderer() {}
+static  RenderControlFunctor noOpController;
 
-NodeBasedRenderer::NodeBasedRenderer( std::function<void(NodeBasedRenderer *, int, int)> configurator ) :
+NodeBasedRenderer::NodeBasedRenderer() : Renderer(), m_controller{noOpController} {}
+
+NodeBasedRenderer::NodeBasedRenderer( RenderControlFunctor & controller ) :
     Renderer(),
-    m_configurator{std::move(configurator)} {}
+    m_controller{controller} {}
 
 NodeBasedRenderer::~NodeBasedRenderer() = default;
 
@@ -45,7 +47,7 @@ bool NodeBasedRenderer::buildRenderTechnique( RenderObject* ro ) const {
     return true;
 }
 
-void NodeBasedRenderer::initShaders() {
+void NodeBasedRenderer::initResources() {
     // uses several resources from the Radium engine
     auto resourcesRootDir{ RadiumEngine::getInstance()->getResourcesDir() + "Shaders/" };
 
@@ -54,15 +56,11 @@ void NodeBasedRenderer::initShaders() {
           resourcesRootDir + "2DShaders/Basic2D.vert.glsl",
           resourcesRootDir + "2DShaders/Hdr2Ldr.frag.glsl" } );
 
-}
-
-void NodeBasedRenderer::initBuffers() {
     m_postprocessFbo = std::make_unique<globjects::Framebuffer>();
 
     // NodeBased renderer : only initializes textures that are shared between all the passes or
     // that are used internally on the renderer.
     // Each pass will manage its own textures and export them if they can be shared.
-
     TextureParameters texparams;
     texparams.width  = m_width;
     texparams.height = m_height;
@@ -106,12 +104,11 @@ void NodeBasedRenderer::initializeInternal() {
     m_lightmanagers.push_back( lmngr );
 
     // Initialize renderer resources
-    initShaders();
-    initBuffers();
+    initResources();
     for ( const auto& t : m_sharedTextures )
     { m_secondaryTextures.insert( { t.first, t.second.get() } ); }
 
-    if ( m_configurator ) { m_configurator( this, m_width, m_height ); }
+    m_controller.configure( this, m_width, m_height );
 }
 
 void NodeBasedRenderer::resizeInternal() {
@@ -269,13 +266,9 @@ void NodeBasedRenderer::postProcessInternal( const ViewingParameters& /* renderD
     m_postprocessFbo->unbind();
 }
 
-// Todo : verify if the ro partition is the good one and that the passes use the right part.
 void NodeBasedRenderer::updateStepInternal( const ViewingParameters& renderData ) {
-    m_allRenderObjects.clear();
-    for ( auto it = m_fancyRenderObjects.begin(); it != m_fancyRenderObjects.end(); ++it)
-    {
-        m_allRenderObjects.push_back( *it );
-    }
+
+    m_controller.update( renderData );
 
     // Update passes
     // Note that this could be expensive. Find a way to add attributes to renderObjects so
diff --git a/src/libRender/RadiumNBR/NodeBasedRenderer.hpp b/src/libRender/RadiumNBR/NodeBasedRenderer.hpp
index 6514175e23160e7087e342bde1cd8e30ea7c9dc1..20a69dd828b25c1b0e004d05492a8256f24e43a2 100644
--- a/src/libRender/RadiumNBR/NodeBasedRenderer.hpp
+++ b/src/libRender/RadiumNBR/NodeBasedRenderer.hpp
@@ -14,6 +14,29 @@ namespace RadiumNBR {
 /// Todo, put this somewhere else. This is needed to locate resources by cclient applications
 extern int NodeBasedRendererMagic;
 
+class NodeBasedRenderer;
+
+/**
+ * Rendering functor prototype
+ * @todo make this a concept
+ */
+struct RenderControlFunctor {
+
+    virtual ~RenderControlFunctor() = default;
+    /// Configuration function.
+    /// Called once at the configuration of the renderer
+    virtual void configure(NodeBasedRenderer *renderer, int w, int h) {};
+
+    /// Resize function
+    /// Called each time the renderer is resized
+    virtual void resize(int w, int h) {};
+
+    /// Update function
+    /// Called once before each frame to update the internal state of the renderer
+    virtual void update(const Ra::Engine::Data::ViewingParameters& renderData) {};
+};
+
+
 /** Node based for the Radium Engine
  * This Renderer is fully configurable, either dynammically or programatically.
  * It implements the Ra::Engine::Rendering/Renderer interface and can be configured by adding
@@ -32,8 +55,12 @@ class NodeBasedRenderer_LIBRARY_API NodeBasedRenderer : public Ra::Engine::Rende
 {
 
   public:
+
+    //
     NodeBasedRenderer();
-    NodeBasedRenderer( std::function<void(NodeBasedRenderer *, int, int)> configurator );
+    // TODO : instead of an std::function, restrict to a ref to a functor (class with () operator
+    // Such a functor could then be used also during the update step.
+    explicit NodeBasedRenderer( RenderControlFunctor& controller );
 
     ~NodeBasedRenderer() override;
 
@@ -64,8 +91,13 @@ class NodeBasedRenderer_LIBRARY_API NodeBasedRenderer : public Ra::Engine::Rende
     void debugInternal( const Ra::Engine::Data::ViewingParameters& renderData ) override;
     void uiInternal( const Ra::Engine::Data::ViewingParameters& renderData ) override;
 
-    virtual void initShaders();
-    virtual void initBuffers();
+    // TODO : merge these two function into initResources ?
+
+    /** Initialize internal resources for the renderer.
+     * The base function creates the depth and final color texture to be shared by the rendering
+     * passes that need them.
+     */
+    virtual void initResources();
 
   public:
     inline std::map<std::string, std::shared_ptr<Ra::Engine::Data::Texture>> &sharedTextures() {
@@ -85,7 +117,8 @@ class NodeBasedRenderer_LIBRARY_API NodeBasedRenderer : public Ra::Engine::Rende
     }
 
     inline std::vector<RenderObjectPtr> *allRenderObjects() {
-        return &m_allRenderObjects;
+        //return &m_allRenderObjects;
+        return &m_fancyRenderObjects;
     }
 
     inline int defaultPass() const {
@@ -103,13 +136,13 @@ class NodeBasedRenderer_LIBRARY_API NodeBasedRenderer : public Ra::Engine::Rende
     std::map< int, std::shared_ptr<RenderPass> > m_renderPasses;
 
     /// Backup of all objects so that global passses can execute
-    std::vector<RenderObjectPtr> m_allRenderObjects;
+    //std::vector<RenderObjectPtr> m_allRenderObjects;
 
     /// The default pass
     int m_defaultPass{-1};
 
     /// The configurator functor to use
-    std::function<void(NodeBasedRenderer *, int, int)> m_configurator;
+    RenderControlFunctor& m_controller;
 };
 
 }
diff --git a/src/libRender/RadiumNBR/Shaders/AccessibilityPass/ssao.frag.glsl b/src/libRender/RadiumNBR/Shaders/AccessibilityPass/ssao.frag.glsl
index 9ba9206dc2cb1cf719a2c9324c1f79fcab03d6d9..752bed9abddda15f650476c047dfdb55fb6651b0 100644
--- a/src/libRender/RadiumNBR/Shaders/AccessibilityPass/ssao.frag.glsl
+++ b/src/libRender/RadiumNBR/Shaders/AccessibilityPass/ssao.frag.glsl
@@ -50,7 +50,7 @@ void main() {
             }
         }
         ssdo = 1 - ssdo/nbSamples;
-        ssdo *= ssdo;
+        //ssdo *= ssdo;
         ssdo = smoothstep(0, 1, ssdo);
     }
     out_ssao = vec4(vec3(ssdo), 1);