diff --git a/src/DemoApp/main.cpp b/src/DemoApp/main.cpp
index 5f8827ccc549ff20a48577479dcd93ccb229b10c..daed45425f0b2123906db3f9298bccbfcd61da63 100644
--- a/src/DemoApp/main.cpp
+++ b/src/DemoApp/main.cpp
@@ -181,6 +181,9 @@ const std::string customFragmentColor{
     "if (e==1) { finalColor = finalColor*envd + specColor*envs; }\n"
     "else { finalColor = (finalColor + specColor) * max(lightDir.z, 0) \n"
     "       * lightContributionFrom(light, getWorldSpacePosition().xyz); }\n"
+    "#ifdef EXPORT_VECTOR_FIELD\n"
+    "out_vector_field = vec4(getWorldSpaceTangent(), 1);\n"
+    "#endif\n"
     "return vec4( finalColor, 1); \n"
     "}\n"
    };
diff --git a/src/libRender/RadiumNBR/Gui/VisualizationGui.cpp b/src/libRender/RadiumNBR/Gui/VisualizationGui.cpp
index 72d9640613349511935493d9a9420b78e45060f5..64b6c8b6e36f793f2a837328284e4ca9d45dd046 100644
--- a/src/libRender/RadiumNBR/Gui/VisualizationGui.cpp
+++ b/src/libRender/RadiumNBR/Gui/VisualizationGui.cpp
@@ -77,9 +77,18 @@ buildControllerGui( NodeBasedRenderer* renderer, const std::function<void()>& ap
     controlPanel->endLayout();
     controlPanel->endLayout( true );
 
-
-    // TODO : add a double slider to get the good value. ask @dlyr for its doubleSliderClass ...
     controlPanel->beginLayout( QBoxLayout::LeftToRight );
+    controlPanel->addOption(
+        " Exports vector field ",
+        [&controller, appUpdateCallback]( bool b ) {
+          controller.exportVectorField( b );
+          appUpdateCallback();
+        },
+        // TODO : find a way to initialise this according to futre controller configuration
+        true /*controller.exportsVectorField()*/ );
+
+    controlPanel->addSeparator();
+
     auto splatSizeCtrl = [&controller]( double v ) { controller.setSplatSize( v ); };
     controlPanel->addPowerSliderInput(
         "Splat size", splatSizeCtrl, controller.getSplatSize(), 0, 5 );
diff --git a/src/libRender/RadiumNBR/NodeBasedRenderer.cpp b/src/libRender/RadiumNBR/NodeBasedRenderer.cpp
index 285b4aa4bfcaddc3cfb3fa3676a4b577ebdd84f6..e09328cd9f63ca3f09ee9d757fbc3a9e87faa682 100644
--- a/src/libRender/RadiumNBR/NodeBasedRenderer.cpp
+++ b/src/libRender/RadiumNBR/NodeBasedRenderer.cpp
@@ -106,13 +106,13 @@ void NodeBasedRenderer::initializeInternal() {
 
     // Initialize renderer resources
     initResources();
+    m_controller.configure( this, m_width, m_height );
+
     for ( const auto& t : m_sharedTextures )
     {
         m_secondaryTextures.insert( {t.first, t.second.get()} );
     }
 
-    m_controller.configure( this, m_width, m_height );
-
     // Todo cache this in an attribute ?
     auto resourcesCheck = Ra::Core::Resources::getResourcesPath(
         reinterpret_cast<void*>( &RadiumNBR::NodeBasedRendererMagic ), {"Resources/RadiumNBR"} );
diff --git a/src/libRender/RadiumNBR/Passes/ClearPass.cpp b/src/libRender/RadiumNBR/Passes/ClearPass.cpp
index 5b09749ea0abd88fc60086f5c19db734e3089151..c844c8728603c7ef942b938aff58db5a4427ebc6 100644
--- a/src/libRender/RadiumNBR/Passes/ClearPass.cpp
+++ b/src/libRender/RadiumNBR/Passes/ClearPass.cpp
@@ -43,7 +43,6 @@ void ClearPass::resize( size_t width, size_t height ) {
 }
 
 void ClearPass::execute( const Ra::Engine::Data::ViewingParameters& viewParams ) const {
-    using ClearColor = Ra::Core::Utils::Color;
     m_fbo->bind();
     GL_ASSERT( glDrawBuffers( 1, buffers ) );
     GL_ASSERT( glDisable( GL_BLEND ) );
diff --git a/src/libRender/RadiumNBR/Passes/CustomAttribToColorPass.cpp b/src/libRender/RadiumNBR/Passes/CustomAttribToColorPass.cpp
index 43f47119eed7c275e1f1bafdf10487940d8f8f24..49866b1848e5d6a42ef1a4aeefa72eead3765be5 100644
--- a/src/libRender/RadiumNBR/Passes/CustomAttribToColorPass.cpp
+++ b/src/libRender/RadiumNBR/Passes/CustomAttribToColorPass.cpp
@@ -73,7 +73,7 @@ class PointCloudParameterProvider : public Ra::Engine::Data::ShaderParameterProv
     Ra::Engine::Scene::PointCloudComponent* m_component;
 };
 
-static const GLenum buffers[] = {GL_COLOR_ATTACHMENT0};
+static const GLenum buffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
 
 CustomAttribToColorPass::CustomAttribToColorPass(
     const std::vector<RenderObjectPtr>* objectsToRender,
@@ -82,12 +82,25 @@ CustomAttribToColorPass::CustomAttribToColorPass(
 
 CustomAttribToColorPass::~CustomAttribToColorPass() = default;
 
-bool CustomAttribToColorPass::initializePass( size_t /* width */,
-                                              size_t /* height */,
+bool CustomAttribToColorPass::initializePass( size_t width,
+                                              size_t height,
                                               Ra::Engine::Data::ShaderProgramManager* shaderMngr ) {
     m_shaderMngr = shaderMngr;
     m_fbo        = std::make_unique<globjects::Framebuffer>();
 
+    Ra::Engine::Data::TextureParameters texparams;
+    texparams.width          = width;
+    texparams.height         = height;
+    texparams.target         = GL_TEXTURE_2D;
+    texparams.minFilter      = GL_LINEAR;
+    texparams.magFilter      = GL_LINEAR;
+    texparams.internalFormat = GL_RGBA32F;
+    texparams.format         = GL_RGBA;
+    texparams.type           = GL_FLOAT;
+    texparams.name      = "CustomAtt2Clr::VectorField";
+    m_sharedTextures.insert(
+        {texparams.name, std::make_shared<Ra::Engine::Data::Texture>( texparams )} );
+
     return true;
 }
 
@@ -121,6 +134,8 @@ void CustomAttribToColorPass::resize( size_t width, size_t height ) {
     m_fbo->attachTexture( GL_DEPTH_ATTACHMENT,
                           m_importedTextures["CustomAtt2Clr::Depth"]->texture() );
     m_fbo->attachTexture( GL_COLOR_ATTACHMENT0, m_outputTexture.second->texture() );
+    m_fbo->attachTexture( GL_COLOR_ATTACHMENT1,
+                          m_sharedTextures["CustomAtt2Clr::VectorField"]->texture() );
 #ifdef PASSES_LOG
     if ( m_fbo->checkStatus() != GL_FRAMEBUFFER_COMPLETE )
     { LOG( logERROR ) << "FBO Error (EmissivityPass::resize): " << m_fbo->checkStatus(); }
@@ -132,9 +147,16 @@ void CustomAttribToColorPass::resize( size_t width, size_t height ) {
 void CustomAttribToColorPass::execute(
     const Ra::Engine::Data::ViewingParameters& viewParams ) const {
     static constexpr const float clearDepth{1.0f};
+    static const float clearColor[4] {0.f, 0.f, 0.f, 0.f};
     m_fbo->bind();
-    // only draw into 1 buffers (Color)
-    GL_ASSERT( glDrawBuffers( 1, buffers ) );
+    // only draw into 1 or 2 buffers depending on the export of a vector field
+    if ( m_exportVectorField ) {
+        GL_ASSERT( glDrawBuffers( 2, buffers ) );
+        GL_ASSERT( glClearBufferfv( GL_COLOR, 1, clearColor ) );
+    } else {
+        GL_ASSERT( glDrawBuffers( 1, buffers ) );
+    }
+
     GL_ASSERT( glDepthMask( GL_TRUE ) );
     GL_ASSERT( glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ) );
     GL_ASSERT( glEnable( GL_DEPTH_TEST ) );
@@ -253,6 +275,9 @@ bool CustomAttribToColorPass::buildRenderTechnique(
             "layout (location = 5) in vec3 in_viewVector;\n"
             "layout (location = 6) in vec3 in_lightVector;\n"
             "layout (location = 0) out vec4 out_color;\n"
+            "#ifdef EXPORT_VECTOR_FIELD\n"
+            "layout (location = 1) out vec4 out_vector_field;\n"
+            "#endif\n"
             "vec4 computeCustomColor(Material mat, vec3 light_dir, vec3 view_dir, vec3 "
             "normal_world);\n"
             "void main()\n"
@@ -287,6 +312,12 @@ bool CustomAttribToColorPass::buildRenderTechnique(
                                        fragmentShadersource + noopEnvMapFunction + m_customFragmentColor );
         }
 
+        if ( m_exportVectorField ) {
+            theConfig.addProperty( "EXPORT_VECTOR_FIELD" );
+        } else {
+            theConfig.removeProperty( "EXPORT_VECTOR_FIELD" );
+        }
+
         theConfig.addInclude( "\"" + mat->getMaterialName() + ".glsl\"",
                               Ra::Engine::Data::ShaderType::ShaderType_FRAGMENT );
 
@@ -356,7 +387,7 @@ bool CustomAttribToColorPass::buildRenderTechnique(
             "    out_position    = point[idx];\n"
             "    out_texcoord    = vec3( uv[idx], 0. );\n"
             "    out_normal      = normal;\n"
-            "    out_tangent     = in_tangent[0];\n"
+            "    out_tangent     = length(in_tangent[0]) == 0 ? (point[2] - point[1]) : in_tangent[0];\n"
             "    out_viewVector  = in_viewVector[0];\n"
             "    out_lightVector = in_lightVector[0];\n"
             "    out_vertexcolor = in_vertexColor[0];\n"
diff --git a/src/libRender/RadiumNBR/Passes/CustomAttribToColorPass.hpp b/src/libRender/RadiumNBR/Passes/CustomAttribToColorPass.hpp
index fa0745be6dad7e709485292ec8eb94c244043af1..c44c0c518c66e2f0520ad964879f0175bc9ae56a 100644
--- a/src/libRender/RadiumNBR/Passes/CustomAttribToColorPass.hpp
+++ b/src/libRender/RadiumNBR/Passes/CustomAttribToColorPass.hpp
@@ -72,6 +72,13 @@ class CustomAttribToColorPass : public RenderPass
     /// get the strength (aka "power") of the env map
     int getEnvStrength() const { return int( m_envStrength * 100 ); }
 
+    /// get/set the export vector field state
+    void exportVectorField( bool state ) {
+        m_exportVectorField = state;
+        rebuildShaders();
+    };
+    bool exportsVectorField() const { return m_exportVectorField;}
+
   private:
     /// The framebuffer used to render this pass
     std::unique_ptr<globjects::Framebuffer> m_fbo{nullptr};
@@ -105,6 +112,9 @@ class CustomAttribToColorPass : public RenderPass
         "if (e==1) { finalColor = diffColor*envd + specColor*envs; }\n"
         "else { finalColor = (diffColor + specColor) * max(lightDir.z, 0) \n"
         "       * lightContributionFrom(light, getWorldSpacePosition().xyz); }\n"
+        "#ifdef EXPORT_VECTOR_FIELD\n"
+        "out_vector_field = vec4(getWorldSpaceTangent(), 1);\n"
+        "#endif\n"
         "return vec4( finalColor, 1); \n"
         "}\n"};
 
@@ -122,5 +132,8 @@ class CustomAttribToColorPass : public RenderPass
 
     /// The strength of the envmap
     float m_envStrength;
+
+    /// Export a vector texture
+    bool m_exportVectorField{true};
 };
 } // namespace RadiumNBR
diff --git a/src/libRender/RadiumNBR/Renderer/Visualization.cpp b/src/libRender/RadiumNBR/Renderer/Visualization.cpp
index edc5998096cb17e87e79ba69dfd0d8664433c00a..c415fc72fab8f2747dfe9460c1f6dcb6bf087606 100644
--- a/src/libRender/RadiumNBR/Renderer/Visualization.cpp
+++ b/src/libRender/RadiumNBR/Renderer/Visualization.cpp
@@ -62,6 +62,11 @@ void VisualizationController::configure( RadiumNBR::NodeBasedRenderer* renderer,
         m_customPass->initializePass( w, h, shaderManager );
         // add the pass to the renderer and activate it
         renderer->addPass( m_customPass, m_customPass->index() );
+        // Add the exported (shared) texture to the set of available textures
+        auto &sharedTextures = renderer->sharedTextures();
+        for (auto t : m_customPass->getOutputImages() ) {
+            sharedTextures.insert( {t.first, t.second} );
+        }
         m_customPass->activate();
     }
     //! [Adding a CustomAttribToColorPass pass]
@@ -155,4 +160,13 @@ void VisualizationController::showEnvMap( bool state ) {
 void VisualizationController::setEnvStrength( int s ) {
     m_customPass->setEnvStrength( s );
 }
+
+void VisualizationController::exportVectorField( bool state ) {
+    m_customPass->exportVectorField( state );
+}
+
+bool VisualizationController::exportsVectorField() const {
+    return m_customPass->exportsVectorField();
+}
+
 } // namespace RadiumNBR
diff --git a/src/libRender/RadiumNBR/Renderer/Visualization.hpp b/src/libRender/RadiumNBR/Renderer/Visualization.hpp
index 35f13fda841cd7aedf1f00ab13a2455aa3fd11eb..cdd65750cb9a8b30f673aff0b3635c43ecfe971a 100644
--- a/src/libRender/RadiumNBR/Renderer/Visualization.hpp
+++ b/src/libRender/RadiumNBR/Renderer/Visualization.hpp
@@ -44,6 +44,9 @@ class NodeBasedRenderer_LIBRARY_API VisualizationController
     void showEnvMap( bool state );
     void setEnvStrength( int s );
 
+    void exportVectorField( bool state );
+    bool exportsVectorField() const;
+
   private:
     /// The custom pass if needed for modification
     std::shared_ptr<RadiumNBR::CustomAttribToColorPass> m_customPass;
@@ -67,6 +70,9 @@ class NodeBasedRenderer_LIBRARY_API VisualizationController
         "if (e==1) { finalColor = diffColor*envd + specColor*envs; }\n"
         "else { finalColor = (diffColor + specColor) * max(lightDir.z, 0) \n"
         "       * lightContributionFrom(light, getWorldSpacePosition().xyz); }\n"
+        "#ifdef EXPORT_VECTOR_FIELD\n"
+        "out_vector_field = vec4(getWorldSpaceTangent(), 1);\n"
+        "#endif\n"
         "return vec4( finalColor, 1); \n"
         "}\n"};