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"};