diff --git a/indra/newview/llvisualeffect.cpp b/indra/newview/llvisualeffect.cpp
index 88e0b358076991986a18fe69323624ca973270ca..af68a5741360138001127e503e6f7f21d0a7aa80 100644
--- a/indra/newview/llvisualeffect.cpp
+++ b/indra/newview/llvisualeffect.cpp
@@ -107,33 +107,33 @@ bool LLVfxManager::removeEffect(const LLUUID& idEffect)
 	return true;
 }
 
-void LLVfxManager::runEffect(EVisualEffect eCode, const LLVisualEffectParams* pParams)
+void LLVfxManager::runEffect(EVisualEffect eCode, LLVisualEffectParams* pParams)
 {
 	// *TODO-Catz: once we're done, check whether iterating over the entire list still has negliable impact
 	auto pred = [eCode](const LLVisualEffect* pEffect) { return pEffect->getCode() == eCode; };
 
-	auto beginEffect = boost::make_filter_iterator(pred, m_Effects.begin(), m_Effects.end()),
+	auto itEffect = boost::make_filter_iterator(pred, m_Effects.begin(), m_Effects.end()),
 	     endEffect = boost::make_filter_iterator(pred, m_Effects.end(), m_Effects.end());
-
-	auto effectRange = boost::make_iterator_range(beginEffect, endEffect);
-	for (LLVisualEffect* pEffect : effectRange)
+	for (; itEffect != endEffect; ++itEffect)
 	{
-		pEffect->run(pParams);
+		if (pParams)
+			pParams->step(itEffect == endEffect);
+		(*itEffect)->run(pParams);
 	}
 }
 
-void LLVfxManager::runEffect(EVisualEffectType eType, const LLVisualEffectParams* pParams)
+void LLVfxManager::runEffect(EVisualEffectType eType, LLVisualEffectParams* pParams)
 {
 	// *TODO-Catz: once we're done, check whether iterating over the entire list still has negliable impact
 	auto pred = [eType](const LLVisualEffect* pEffect) { return pEffect->getType() == eType;  };
 
-	auto beginEffect = boost::make_filter_iterator(pred, m_Effects.begin(), m_Effects.end()),
-		endEffect = boost::make_filter_iterator(pred, m_Effects.end(), m_Effects.end());
-
-	auto effectRange = boost::make_iterator_range(beginEffect, endEffect);
-	for (LLVisualEffect* pEffect : effectRange)
+	auto itEffect = boost::make_filter_iterator(pred, m_Effects.begin(), m_Effects.end()),
+	     endEffect = boost::make_filter_iterator(pred, m_Effects.end(), m_Effects.end());
+	for (; itEffect != endEffect; ++itEffect)
 	{
-		pEffect->run(pParams);
+		if (pParams)
+			pParams->step(itEffect == endEffect);
+		(*itEffect)->run(pParams);
 	}
 }
 
diff --git a/indra/newview/llvisualeffect.h b/indra/newview/llvisualeffect.h
index 0bceec5fbb4d1410cfe8006af89679d89e4f091c..6419e26b297016a159207b1e83f39c3acd4fe486 100644
--- a/indra/newview/llvisualeffect.h
+++ b/indra/newview/llvisualeffect.h
@@ -46,14 +46,23 @@ enum class EVisualEffectType
 
 struct LLVisualEffectParams
 {
+	virtual void step(bool isLast) = 0;
 };
 
 struct LLShaderEffectParams : LLVisualEffectParams
 {
-	explicit LLShaderEffectParams(LLRenderTarget* pSrcBuffer, LLRenderTarget* pDstBuffer) : m_pSrcBuffer(pSrcBuffer), m_pDstBuffer(pDstBuffer) {}
+	explicit LLShaderEffectParams(LLRenderTarget* pSrcBuffer, LLRenderTarget* pScratchBuffer, bool fBindLast) : m_pSrcBuffer(pScratchBuffer), m_pDstBuffer(pSrcBuffer), m_fBindLast(fBindLast) {}
+
+	void step(bool isLast) override
+	{
+		LLRenderTarget* pPrevSrc = m_pSrcBuffer, *pPrevDst = m_pDstBuffer;
+		m_pSrcBuffer = pPrevDst;
+		m_pDstBuffer = (!isLast || !m_fBindLast) ? pPrevSrc : nullptr;
+	}
 
 	LLRenderTarget* m_pSrcBuffer = nullptr;
 	LLRenderTarget* m_pDstBuffer = nullptr;
+	bool            m_fBindLast = false;
 };
 
 // ============================================================================
@@ -155,8 +164,8 @@ class LLVfxManager : public LLSingleton<LLVfxManager>
 	LLVisualEffect* getEffect(EVisualEffect eCode) const;
 	template<typename T> T* getEffect(EVisualEffect eCode) const { return dynamic_cast<T*>(getEffect(eCode)); }
 	bool            removeEffect(const LLUUID& idEffect);
-	void            runEffect(EVisualEffect eCode, const LLVisualEffectParams* pParams = nullptr);
-	void            runEffect(EVisualEffectType eType, const LLVisualEffectParams* pParams = nullptr);
+	void            runEffect(EVisualEffect eCode, LLVisualEffectParams* pParams = nullptr);
+	void            runEffect(EVisualEffectType eType, LLVisualEffectParams* pParams = nullptr);
 protected:
 
 	/*
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 2b36180488cd55c9c6e31ba8ff99e24bd767984e..ba40807dcb7dcf3b56a7cb427a1955f648f5748b 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -8098,7 +8098,7 @@ void LLPipeline::renderFinalize()
 // [RLVa:KB] - @setsphere
 		if (RlvActions::hasBehaviour(RLV_BHVR_SETSPHERE))
 		{
-			LLShaderEffectParams params(pRenderBuffer, (multisample) ? &mScreen : nullptr);
+			LLShaderEffectParams params(pRenderBuffer, &mScreen, !multisample);
 			LLVfxManager::instance().runEffect(EVisualEffect::RlvSphere, &params);
 			pRenderBuffer = params.m_pDstBuffer;
 		}
@@ -8186,7 +8186,7 @@ void LLPipeline::renderFinalize()
 // [RLVa:KB] - @setsphere
 		if (RlvActions::hasBehaviour(RLV_BHVR_SETSPHERE))
 		{
-			LLShaderEffectParams params(&mScreen, &mDeferredLight);
+			LLShaderEffectParams params(&mScreen, &mDeferredLight, false);
 			LLVfxManager::instance().runEffect(EVisualEffect::RlvSphere, &params);
 			pRenderBuffer = params.m_pDstBuffer;
 		}