Skip to content

Commit

Permalink
Fix FSAA in UI and lower VRAM consumption
Browse files Browse the repository at this point in the history
FSAA was being requested however due to how the compositor was setup,
this effect was not taking effect.

Additionally, the Compositor setup was improved to lower memory
consumption. Originally the setup was taken from Ogre samples which
assume they will ultimately be rendering to a window.

However this is not the case and thus IGN was creating 3 render targets
(two for ping-ponging between postprocess FXs + one for storing the
final result)
This was optimized so that we only create 2 render targets: two for
ping-ponging between postprocess FXs and we pick at runtime which one is
storing the final result via the new variable renderTargetResultsIdx

Further performance optimizations could be made in Ogre 2.2 to improve
unnecessary MSAA resolving when doing postprocess, though considering
there's currently only one postprocessing effect (the Gaussian filter) I
doubt this optimization would make much of a difference

Signed-off-by: Matias N. Goldberg <dark_sylinc@yahoo.com.ar>
  • Loading branch information
darksylinc committed May 2, 2021
1 parent 07c4ca9 commit 3ef8156
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 127 deletions.
33 changes: 27 additions & 6 deletions ogre2/include/ignition/rendering/ogre2/Ogre2RenderTarget.hh
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,16 @@ namespace ignition
/// \see Camera::SetShadowsNodeDefDirty
public: void SetShadowsNodeDefDirty();

/// \brief Get a pointer to the ogre's internal texture name
/// \param[in] _idx In range [0; 1]
/// \see Ogre2RenderTarget::renderTargetResultsIdx
public: virtual const std::string* InternalTextureName(
size_t _idx) const = 0;

/// \brief Get a pointer to the ogre render target
public: virtual Ogre::RenderTarget *RenderTarget() const = 0;
/// \param[in] _idx In range [0; 1]
/// \see Ogre2RenderTarget::renderTargetResultsIdx
public: virtual Ogre::RenderTarget *RenderTarget(size_t _idx) const = 0;

/// \brief Get visibility mask for the viewport associated with this
/// render target
Expand All @@ -133,7 +141,8 @@ namespace ignition
Ogre::CompositorWorkspace *_workspace,
const std::string &_workspaceDefName,
const std::string &_baseNode, const std::string &_finalNode,
const std::vector<RenderPassPtr> &_renderPasses, bool _recreateNodes);
const std::vector<RenderPassPtr> &_renderPasses,
uint8_t &_renderTargetResultsIdx, bool _recreateNodes);

/// \brief Update the background color
protected: virtual void UpdateBackgroundColor();
Expand Down Expand Up @@ -188,7 +197,7 @@ namespace ignition
protected: MaterialPtr material;

/// \brief Helper class that applies the material to the render target
protected: Ogre2RenderTargetMaterialPtr materialApplicator;
protected: Ogre2RenderTargetMaterialPtr materialApplicator[2];

/// \brief Flag to indicate if the render target color has changed
protected: bool colorDirty = true;
Expand All @@ -197,6 +206,10 @@ namespace ignition
/// changed
protected: bool backgroundMaterialDirty = false;

/// \brief The index to RenderTarget(_idx) where the results are being
/// stored. In range [0; 1]
protected: uint8_t renderTargetResultsIdx = 0u;

/// \brief Anti-aliasing level
protected: unsigned int antiAliasing = 4;

Expand Down Expand Up @@ -230,7 +243,12 @@ namespace ignition
public: virtual unsigned int GLId() const override;

// Documentation inherited.
public: virtual Ogre::RenderTarget *RenderTarget() const override;
public: virtual const std::string* InternalTextureName(
size_t _idx) const override;

// Documentation inherited.
public: virtual Ogre::RenderTarget *RenderTarget(
size_t _idx) const override;

// Documentation inherited.
protected: virtual void RebuildTarget() override;
Expand All @@ -242,7 +260,9 @@ namespace ignition
protected: virtual void BuildTarget();

/// \brief Pointer to the internal ogre render texture object
protected: Ogre::Texture *ogreTexture = nullptr;
/// There's two because we ping pong postprocessing effects
/// and the final result may be in either of them
protected: Ogre::Texture *ogreTexture[2] = {nullptr, nullptr};

/// \brief Make scene our friend so it can create a ogre2 render texture
private: friend class Ogre2Scene;
Expand All @@ -262,7 +282,8 @@ namespace ignition
public: virtual void Destroy() override;

// Documentation inherited.
public: virtual Ogre::RenderTarget *RenderTarget() const override;
public: virtual Ogre::RenderTarget *RenderTarget(
size_t _idx) const override;

// Documentation inherited.
protected: virtual void RebuildTarget() override;
Expand Down
106 changes: 51 additions & 55 deletions ogre2/src/Ogre2DepthCamera.cc
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class ignition::rendering::Ogre2DepthCameraPrivate
public: Ogre::CompositorWorkspace *ogreCompositorWorkspace = nullptr;

/// \brief Output texture with depth and color data
public: Ogre::TexturePtr ogreDepthTexture;
public: Ogre::TexturePtr ogreDepthTexture[2];

/// \brief Dummy render texture for the depth data
public: RenderTexturePtr depthTexture;
Expand All @@ -121,6 +121,10 @@ class ignition::rendering::Ogre2DepthCameraPrivate
/// \brief Flag to indicate if render pass need to be rebuilt
public: bool renderPassDirty = false;

/// \brief The index to ogreDepthTexture[idx] where the results are being
/// stored. In range [0; 1]
public: uint8_t renderTargetResultsIdx = 0u;

/// \brief Event used to signal rgb point cloud data
public: ignition::common::EventT<void(const float *,
unsigned int, unsigned int, unsigned int,
Expand Down Expand Up @@ -297,10 +301,13 @@ void Ogre2DepthCamera::Destroy()
Ogre::CompositorManager2 *ogreCompMgr = ogreRoot->getCompositorManager2();

// remove depth texture, material, compositor
if (this->dataPtr->ogreDepthTexture)
for( size_t i = 0u; i < 2u; ++i )
{
Ogre::TextureManager::getSingleton().remove(
this->dataPtr->ogreDepthTexture->getName());
if (this->dataPtr->ogreDepthTexture[i])
{
Ogre::TextureManager::getSingleton().remove(
this->dataPtr->ogreDepthTexture[i]->getName());
}
}
if (this->dataPtr->ogreCompositorWorkspace)
{
Expand Down Expand Up @@ -588,41 +595,11 @@ void Ogre2DepthCamera::CreateDepthTexture()
this->dataPtr->ogreCompositorBaseNodeDef = baseNodeDefName;
Ogre::CompositorNodeDef *baseNodeDef =
ogreCompMgr->addNodeDefinition(baseNodeDefName);
Ogre::TextureDefinitionBase::TextureDefinition *rt0TexDef =
baseNodeDef->addTextureDefinition("rt0");
rt0TexDef->textureType = Ogre::TEX_TYPE_2D;
rt0TexDef->width = 0;
rt0TexDef->height = 0;
rt0TexDef->depth = 1;
rt0TexDef->numMipmaps = 0;
rt0TexDef->widthFactor = 1;
rt0TexDef->heightFactor = 1;
rt0TexDef->formatList = {Ogre::PF_FLOAT32_RGBA};
rt0TexDef->fsaa = 0;
rt0TexDef->uav = false;
rt0TexDef->automipmaps = false;
rt0TexDef->hwGammaWrite = Ogre::TextureDefinitionBase::BoolFalse;
rt0TexDef->depthBufferId = Ogre::DepthBuffer::POOL_INVALID;
rt0TexDef->depthBufferFormat = Ogre::PF_UNKNOWN;
rt0TexDef->fsaaExplicitResolve = false;

Ogre::TextureDefinitionBase::TextureDefinition *rt1TexDef =
baseNodeDef->addTextureDefinition("rt1");
rt1TexDef->textureType = Ogre::TEX_TYPE_2D;
rt1TexDef->width = 0;
rt1TexDef->height = 0;
rt1TexDef->depth = 1;
rt1TexDef->numMipmaps = 0;
rt1TexDef->widthFactor = 1;
rt1TexDef->heightFactor = 1;
rt1TexDef->formatList = {Ogre::PF_FLOAT32_RGBA};
rt1TexDef->fsaa = 0;
rt1TexDef->uav = false;
rt1TexDef->automipmaps = false;
rt1TexDef->hwGammaWrite = Ogre::TextureDefinitionBase::BoolFalse;
rt1TexDef->depthBufferId = Ogre::DepthBuffer::POOL_INVALID;
rt1TexDef->depthBufferFormat = Ogre::PF_UNKNOWN;
rt1TexDef->fsaaExplicitResolve = false;

baseNodeDef->addTextureSourceName(
"rt0", 0u, Ogre::TextureDefinitionBase::TEXTURE_INPUT);
baseNodeDef->addTextureSourceName(
"rt1", 1u, Ogre::TextureDefinitionBase::TEXTURE_INPUT);

Ogre::TextureDefinitionBase::TextureDefinition *depthTexDef =
baseNodeDef->addTextureDefinition("depthTexture");
Expand Down Expand Up @@ -853,10 +830,10 @@ void Ogre2DepthCamera::CreateDepthTexture()
Ogre::CompositorNodeDef *finalNodeDef =
ogreCompMgr->addNodeDefinition(finalNodeDefName);

// output texture
finalNodeDef->addTextureSourceName("rt_output", 0,
finalNodeDef->addTextureSourceName("rt_input", 0,
Ogre::TextureDefinitionBase::TEXTURE_INPUT);
finalNodeDef->addTextureSourceName("rt_input", 1,
// output texture
finalNodeDef->addTextureSourceName("rt_output", 1,
Ogre::TextureDefinitionBase::TEXTURE_INPUT);

finalNodeDef->setNumTargetPass(1);
Expand Down Expand Up @@ -892,8 +869,9 @@ void Ogre2DepthCamera::CreateDepthTexture()
Ogre::CompositorWorkspaceDef *workDef =
ogreCompMgr->addWorkspaceDefinition(wsDefName);

workDef->connect(baseNodeDefName, 0, finalNodeDefName, 1);
workDef->connectExternal(0, finalNodeDefName, 0);
workDef->connectExternal(0, baseNodeDefName, 0);
workDef->connectExternal(1, baseNodeDefName, 1);
workDef->connect(baseNodeDefName, finalNodeDefName);
}
Ogre::CompositorWorkspaceDef *wsDef =
ogreCompMgr->getWorkspaceDefinition(wsDefName);
Expand All @@ -905,12 +883,21 @@ void Ogre2DepthCamera::CreateDepthTexture()
}

// create render texture - these textures pack the range data
this->dataPtr->ogreDepthTexture =
Ogre::TextureManager::getSingleton().createManual(
this->Name() + "_depth", "General", Ogre::TEX_TYPE_2D,
this->ImageWidth(), this->ImageHeight(), 1, 0,
Ogre::PF_FLOAT32_RGBA, Ogre::TU_RENDERTARGET,
0, false, 0, Ogre::BLANKSTRING, false, true);
for( size_t i = 0u; i < 2u; ++i )
{
this->dataPtr->ogreDepthTexture[i] =
Ogre::TextureManager::getSingleton().createManual(
this->Name() + "_depth" + std::to_string(i), "General",
Ogre::TEX_TYPE_2D, this->ImageWidth(), this->ImageHeight(), 1, 0,
Ogre::PF_FLOAT32_RGBA, Ogre::TU_RENDERTARGET,
0, false, 0, Ogre::BLANKSTRING, false, true);

Ogre::RenderTarget *rt =
this->dataPtr->ogreDepthTexture[i]->getBuffer()->getRenderTarget();
rt->setDepthBufferPool(Ogre::DepthBuffer::POOL_INVALID);
}

this->dataPtr->renderTargetResultsIdx = 1u;

CreateWorkspaceInstance();
}
Expand All @@ -922,13 +909,19 @@ void Ogre2DepthCamera::CreateWorkspaceInstance()
auto ogreRoot = engine->OgreRoot();
Ogre::CompositorManager2 *ogreCompMgr = ogreRoot->getCompositorManager2();

Ogre::RenderTarget *rt =
this->dataPtr->ogreDepthTexture->getBuffer()->getRenderTarget();
Ogre::CompositorChannelVec externalTargets(2u);
for( size_t i = 0u; i < 2u; ++i )
{
externalTargets[i].target =
this->dataPtr->ogreDepthTexture[i]->getBuffer()->getRenderTarget();
externalTargets[i].textures.push_back(this->dataPtr->ogreDepthTexture[i]);
}

// create compositor worksspace
this->dataPtr->ogreCompositorWorkspace =
ogreCompMgr->addWorkspace(this->scene->OgreSceneManager(),
rt, this->ogreCamera, this->dataPtr->ogreCompositorWorkspaceDef, false);
externalTargets, this->ogreCamera,
this->dataPtr->ogreCompositorWorkspaceDef, false);

// add the listener
Ogre::CompositorNode *node =
Expand Down Expand Up @@ -963,7 +956,7 @@ void Ogre2DepthCamera::Render()
//////////////////////////////////////////////////
void Ogre2DepthCamera::PreRender()
{
if (!this->dataPtr->ogreDepthTexture)
if (!this->dataPtr->ogreDepthTexture[0])
this->CreateDepthTexture();

if (!this->dataPtr->ogreCompositorWorkspace)
Expand All @@ -976,6 +969,7 @@ void Ogre2DepthCamera::PreRender()
this->dataPtr->ogreCompositorBaseNodeDef,
this->dataPtr->ogreCompositorFinalNodeDef,
this->dataPtr->renderPasses,
this->dataPtr->renderTargetResultsIdx,
this->dataPtr->renderPassDirty);
for (auto &pass : this->dataPtr->renderPasses)
pass->PreRender();
Expand Down Expand Up @@ -1028,7 +1022,9 @@ void Ogre2DepthCamera::PostRender()
1, imageFormat, this->dataPtr->depthBuffer);

// blit data from gpu to cpu
auto rt = this->dataPtr->ogreDepthTexture->getBuffer()->getRenderTarget();
auto rt = this->dataPtr->ogreDepthTexture[
this->dataPtr->renderTargetResultsIdx]->
getBuffer()->getRenderTarget();
rt->copyContentsToMemory(dstBox, Ogre::RenderTarget::FB_AUTO);

if (!this->dataPtr->depthImage)
Expand Down
Loading

0 comments on commit 3ef8156

Please sign in to comment.