diff --git a/indra/llmath/v4color.cpp b/indra/llmath/v4color.cpp
index a8768bda35ea1060b09f3ca95ae6948a6d602399..1f3d9b7d218c099e76052d0f15c3a2b89dc47ea6 100644
--- a/indra/llmath/v4color.cpp
+++ b/indra/llmath/v4color.cpp
@@ -59,6 +59,9 @@ LLColor4 LLColor4::grey1(0.8f, 0.8f, 0.8f, 1.0f);
 LLColor4 LLColor4::grey2(0.6f, 0.6f, 0.6f, 1.0f);
 LLColor4 LLColor4::grey3(0.4f, 0.4f, 0.4f, 1.0f);
 LLColor4 LLColor4::grey4(0.3f, 0.3f, 0.3f, 1.0f);
+// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
+LLColor4 LLColor4::silhouette(0.05f, 0.05f, 0.05f, 1.0f);
+// [/RLVa:KB]
 
 LLColor4 LLColor4::red1(1.0f, 0.0f, 0.0f, 1.0f);
 LLColor4 LLColor4::red2(0.6f, 0.0f, 0.0f, 1.0f);
diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h
index 8f353ead5a251c95aca64570f66329753868f7d3..32e82a743ea84ffd7f8ac02e7b39b22bef0bc3f9 100644
--- a/indra/llmath/v4color.h
+++ b/indra/llmath/v4color.h
@@ -154,6 +154,9 @@ class LLColor4
 		static LLColor4 grey2;
 		static LLColor4 grey3;
 		static LLColor4 grey4;
+// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
+		static LLColor4 silhouette;
+// [/RLVa:KB]
 
 		static LLColor4 red1;
 		static LLColor4 red2;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 8b5d6d395ae120765bfe2b9b57c0064d1ca94a0a..449d10c34f5a4681e47328888ec0b8496dda892b 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -3115,11 +3115,20 @@ class LLAvatarCheckImpostorMode : public view_listener_t
 		switch (mode) 
 		{
 			case 0:
-				return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_RENDER_NORMALLY);
+// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
+				return LLRenderMuteList::instance().getSavedVisualMuteSetting(avatar->getID()) == LLVOAvatar::AV_RENDER_NORMALLY;
+// [/RLVa:KB]
+//				return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_RENDER_NORMALLY);
 			case 1:
-				return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_DO_NOT_RENDER);
+// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
+				return LLRenderMuteList::instance().getSavedVisualMuteSetting(avatar->getID()) == LLVOAvatar::AV_DO_NOT_RENDER;
+// [/RLVa:KB]
+//				return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_DO_NOT_RENDER);
 			case 2:
-				return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER);
+// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
+				return LLRenderMuteList::instance().getSavedVisualMuteSetting(avatar->getID()) == LLVOAvatar::AV_ALWAYS_RENDER;
+// [/RLVa:KB]
+//				return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER);
 			default:
 				return false;
 		}
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index a25736df1e5cea59912c276310cd3cbf11fa8f72..336066c3fec5296748ad542147cd66cbae1051d3 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -100,6 +100,7 @@
 // [RLVa:KB] - Checked: RLVa-2.0.1
 #include "rlvactions.h"
 #include "rlvhandler.h"
+#include "rlvmodifiers.h"
 // [/RLVa:KB]
 
 #include "llgesturemgr.h" //needed to trigger the voice gesticulations
@@ -3382,6 +3383,12 @@ bool LLVOAvatar::isVisuallyMuted()
         {
             muted = true;
         }
+// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
+		else if (isRlvSilhouette())
+		{
+			muted = true;
+		}
+// [/RLVa:KB]
 		else
 		{
 			muted = isTooComplex();
@@ -3410,6 +3417,30 @@ bool LLVOAvatar::isInMuteList()
 	return muted;
 }
 
+// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
+bool LLVOAvatar::isRlvSilhouette()
+{
+	if (!gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_AVDIST))
+		return false;
+
+	static RlvCachedBehaviourModifier<float> s_nSetCamAvDist(RLV_MODIFIER_SETCAM_AVDIST);
+
+	const F64 now = LLFrameTimer::getTotalSeconds();
+	if (now >= mCachedRlvSilhouetteUpdateTime)
+	{
+		const F64 SECONDS_BETWEEN_NEARBY_UPDATES = .5f;
+		bool fIsRlvSilhouette = dist_vec_squared(gAgent.getPositionGlobal(), getPositionGlobal()) > s_nSetCamAvDist() * s_nSetCamAvDist();
+		if (fIsRlvSilhouette != mCachedIsRlvSilhouette)
+		{
+			mCachedIsRlvSilhouette = fIsRlvSilhouette;
+			mNeedsImpostorUpdate = TRUE;
+		}
+		mCachedRlvSilhouetteUpdateTime = now + SECONDS_BETWEEN_NEARBY_UPDATES;
+	}
+	return mCachedIsRlvSilhouette;
+}
+// [/RLVa:KB]
+
 void LLVOAvatar::updateDebugText()
 {
 	// clear debug text
@@ -9405,9 +9436,21 @@ void LLVOAvatar::calcMutedAVColor()
 
     if (getVisualMuteSettings() == AV_DO_NOT_RENDER)
     {
-        // explicitly not-rendered avatars are light grey
-        new_color = LLColor4::grey3;
-        change_msg = " not rendered: color is grey3";
+// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
+		 if (isRlvSilhouette())
+		 {
+			 new_color = LLColor4::silhouette;
+			 change_msg = " not rendered: color is silhouette";
+		 }
+		 else
+		 {
+// [/RLVa:KB]
+			// explicitly not-rendered avatars are light grey
+			 new_color = LLColor4::grey3;
+			 change_msg = " not rendered: color is grey3";
+// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
+		 }
+// [/RLVa:KB]
     }
     else if (LLMuteList::getInstance()->isMuted(av_id)) // the user blocked them
     {
@@ -9415,8 +9458,11 @@ void LLVOAvatar::calcMutedAVColor()
         new_color = LLColor4::grey4;
         change_msg = " blocked: color is grey4";
     }
-    else if ( mMutedAVColor == LLColor4::white || mMutedAVColor == LLColor4::grey3 || mMutedAVColor == LLColor4::grey4 )
-    {
+//    else if ( mMutedAVColor == LLColor4::white || mMutedAVColor == LLColor4::grey3 || mMutedAVColor == LLColor4::grey4 )
+// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
+	else if ( mMutedAVColor == LLColor4::white || mMutedAVColor == LLColor4::grey3 || mMutedAVColor == LLColor4::grey4 || mMutedAVColor == LLColor4::silhouette)
+// [/RLVa:KB]
+   {
         // select a color based on the first byte of the agents uuid so any muted agent is always the same color
         F32 color_value = (F32) (av_id.mData[0]);
         F32 spectrum = (color_value / 256.0);		// spectrum is between 0 and 1.f
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 080eb1c380d17701655436f3aceaa1dd904557b6..da941909039eef94345f876b670e3e314925ed48 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -397,6 +397,9 @@ public:
 	U32 		renderImpostor(LLColor4U color = LLColor4U(255,255,255,255), S32 diffuse_channel = 0);
 	bool		isVisuallyMuted();
 	bool 		isInMuteList();
+// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
+	bool        isRlvSilhouette();
+// [/RLVa:KB]
 	void		forceUpdateVisualMuteSettings();
 
 	enum VisualMuteSettings
@@ -406,7 +409,10 @@ public:
 		AV_ALWAYS_RENDER   = 2
 	};
 	void		setVisualMuteSettings(VisualMuteSettings set);
-	VisualMuteSettings  getVisualMuteSettings()						{ return mVisuallyMuteSetting;	};
+// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
+	VisualMuteSettings  getVisualMuteSettings()						{ return (!isRlvSilhouette()) ? mVisuallyMuteSetting : AV_DO_NOT_RENDER; };
+// [/RLVa:KB]
+//	VisualMuteSettings  getVisualMuteSettings()						{ return mVisuallyMuteSetting;	};
 
 	U32 		renderRigid();
 	U32 		renderSkinned();
@@ -437,6 +443,10 @@ public:
 
 	bool		mCachedInMuteList;
 	F64			mCachedMuteListUpdateTime;
+// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
+	mutable bool mCachedIsRlvSilhouette = false;
+	mutable F64  mCachedRlvSilhouetteUpdateTime = 0.f;
+// [/RLVa:KB]
 
 	VisualMuteSettings		mVisuallyMuteSetting;			// Always or never visually mute this AV
 
diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h
index be07ab78e7787817f62f0c01604b3522fc3165c5..f8cb3f32953b3e60fcb028b232fe3383aa4adcc0 100644
--- a/indra/newview/rlvdefines.h
+++ b/indra/newview/rlvdefines.h
@@ -206,6 +206,7 @@ enum ERlvBehaviour {
 
 	// Camera (behaviours)
 	RLV_BHVR_SETCAM,                // Gives an object exclusive control of the user's camera
+	RLV_BHVR_SETCAM_AVDIST,			// Distance at which nearby avatars turn into a silhouette
 	RLV_BHVR_SETCAM_AVDISTMIN,		// Enforces a minimum distance from the avatar (in m)
 	RLV_BHVR_SETCAM_AVDISTMAX,		// Enforces a maximum distance from the avatar (in m)
 	RLV_BHVR_SETCAM_ORIGINDISTMIN,	// Enforces a minimum distance from the camera origin (in m)
@@ -258,6 +259,7 @@ enum ERlvBehaviourModifier
 	RLV_MODIFIER_SENDIMDISTMAX,			// Maximum distance to send an IM to an otherwise restricted recipient (squared value)
 	RLV_MODIFIER_STARTIMDISTMIN,		// Minimum distance to start an IM to an otherwise restricted recipient (squared value)
 	RLV_MODIFIER_STARTIMDISTMAX,		// Maximum distance to start an IM to an otherwise restricted recipient (squared value)
+	RLV_MODIFIER_SETCAM_AVDIST,			// Distance at which nearby avatars turn into a silhouette (normal value)
 	RLV_MODIFIER_SETCAM_AVDISTMIN,		// Minimum distance between the camera position and the user's avatar (normal value)
 	RLV_MODIFIER_SETCAM_AVDISTMAX,		// Maximum distance between the camera position and the user's avatar (normal value)
 	RLV_MODIFIER_SETCAM_ORIGINDISTMIN,	// Minimum distance between the camera position and the origin point (normal value)
diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp
index 144d0242a5c7113ce5921ca649ac8761f56a8276..b159634c7c67f9483602279ad179418115fba78f 100644
--- a/indra/newview/rlvhelper.cpp
+++ b/indra/newview/rlvhelper.cpp
@@ -179,6 +179,8 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
 
 	// Camera
 	addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SETCAM, RLV_OPTION_NONE>("setcam"));
+	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_MODIFIER>("setcam_avdist", RLV_BHVR_SETCAM_AVDIST));
+	addModifier(RLV_BHVR_SETCAM_AVDIST, RLV_MODIFIER_SETCAM_AVDIST, new RlvBehaviourModifier("Camera - Silhouette Distance", 0.0f, false, new RlvBehaviourModifierCompMax()));
 	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_MODIFIER>("setcam_avdistmin", RLV_BHVR_SETCAM_AVDISTMIN, RlvBehaviourInfo::BHVR_EXPERIMENTAL));
 	addModifier(RLV_BHVR_SETCAM_AVDISTMIN, RLV_MODIFIER_SETCAM_AVDISTMIN, new RlvBehaviourModifierHandler<RLV_MODIFIER_SETCAM_AVDISTMIN>("Camera - Avatar Distance (Min)", 0.0f, false, new RlvBehaviourModifierCompMax()));
 	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_MODIFIER>("setcam_avdistmax", RLV_BHVR_SETCAM_AVDISTMAX, RlvBehaviourInfo::BHVR_EXPERIMENTAL));
@@ -200,6 +202,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
 	addModifier(RLV_BHVR_SETCAM_TEXTURES, RLV_MODIFIER_SETCAM_TEXTURE, new RlvBehaviourModifierHandler<RLV_MODIFIER_SETCAM_TEXTURE>("Camera - Forced Texture", IMG_DEFAULT, true, nullptr));
 	addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SETCAM_UNLOCK, RLV_OPTION_NONE>("setcam_unlock"));
 	// Camera (compatibility shim - to be deprecated)
+	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_MODIFIER>("camavdist", RLV_BHVR_SETCAM_AVDIST, RlvBehaviourInfo::BHVR_SYNONYM | RlvBehaviourInfo::BHVR_DEPRECATED));
 	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_MODIFIER>("camdistmin", RLV_BHVR_SETCAM_AVDISTMIN, RlvBehaviourInfo::BHVR_SYNONYM | RlvBehaviourInfo::BHVR_DEPRECATED));
 	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_MODIFIER>("camdistmax", RLV_BHVR_SETCAM_AVDISTMAX, RlvBehaviourInfo::BHVR_SYNONYM | RlvBehaviourInfo::BHVR_DEPRECATED));
 	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_MODIFIER>("camtextures", RLV_BHVR_SETCAM_TEXTURES, RlvBehaviourInfo::BHVR_SYNONYM | RlvBehaviourInfo::BHVR_DEPRECATED));