diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 827d86f6011f43e84e8a567ab68827b5f52d1286..2839c1b196c2f65c4cc537ac39a4fbc2fc6d3a43 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -979,8 +979,8 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
 
 			setPositionAgent(getPositionAgent() - delta);
 
-			LLVector3 camera_position_agent = LLViewerCamera::getInstance()->getOrigin();
-			LLViewerCamera::getInstance()->setOrigin(camera_position_agent - delta);
+			LLVector3 camera_position_agent = LLViewerCamera::getInstanceFast()->getOrigin();
+			LLViewerCamera::getInstanceFast()->setOrigin(camera_position_agent - delta);
 
 			// Update all of the regions.
 			LLWorld::getInstance()->updateAgentOffset(agent_offset_global);
@@ -1017,8 +1017,8 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
 			delta.setVec(regionp->getOriginGlobal());
 
 			setPositionAgent(getPositionAgent() - delta);
-			LLVector3 camera_position_agent = LLViewerCamera::getInstance()->getOrigin();
-			LLViewerCamera::getInstance()->setOrigin(camera_position_agent - delta);
+			LLVector3 camera_position_agent = LLViewerCamera::getInstanceFast()->getOrigin();
+			LLViewerCamera::getInstanceFast()->setOrigin(camera_position_agent - delta);
 
 			// Update all of the regions.
 			LLWorld::getInstance()->updateAgentOffset(mAgentOriginGlobal);
@@ -2439,7 +2439,7 @@ void LLAgent::endAnimationUpdateUI()
 			}
 			if (gAgentAvatarp->getParent())
 			{
-				LLVector3 at_axis = LLViewerCamera::getInstance()->getAtAxis();
+				LLVector3 at_axis = LLViewerCamera::getInstanceFast()->getAtAxis();
 				LLViewerObject* root_object = (LLViewerObject*)gAgentAvatarp->getRoot();
 				if (root_object->flagCameraDecoupled())
 				{
@@ -3216,7 +3216,7 @@ LLQuaternion LLAgent::getHeadRotation()
 	}
 
 	// We must be in mouselook
-	LLVector3 look_dir( LLViewerCamera::getInstance()->getAtAxis() );
+	LLVector3 look_dir( LLViewerCamera::getInstanceFast()->getAtAxis() );
 	LLVector3 up = look_dir % mFrameAgent.getLeftAxis();
 	LLVector3 left = up % look_dir;
 
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 5befdfeda1a447cfd3e8d33972bf30c4e5af2815..757dd6074b0466b5f33d543a58fb7e9d73476d86 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -204,12 +204,12 @@ void LLAgentCamera::init()
 
 	mDrawDistance = gSavedSettings.getF32("RenderFarClip");
 
-	LLViewerCamera::getInstance()->setView(DEFAULT_FIELD_OF_VIEW);
+	LLViewerCamera::getInstanceFast()->setView(DEFAULT_FIELD_OF_VIEW);
 	// Leave at 0.1 meters until we have real near clip management
-	LLViewerCamera::getInstance()->setNear(0.1f);
-	LLViewerCamera::getInstance()->setFar(mDrawDistance);			// if you want to change camera settings, do so in camera.h
-	LLViewerCamera::getInstance()->setAspect( gViewerWindow->getWorldViewAspectRatio() );		// default, overridden in LLViewerWindow::reshape
-	LLViewerCamera::getInstance()->setViewHeightInPixels(768);			// default, overridden in LLViewerWindow::reshape
+	LLViewerCamera::getInstanceFast()->setNear(0.1f);
+	LLViewerCamera::getInstanceFast()->setFar(mDrawDistance);			// if you want to change camera settings, do so in camera.h
+	LLViewerCamera::getInstanceFast()->setAspect( gViewerWindow->getWorldViewAspectRatio() );		// default, overridden in LLViewerWindow::reshape
+	LLViewerCamera::getInstanceFast()->setViewHeightInPixels(768);			// default, overridden in LLViewerWindow::reshape
 
 	mCameraFocusOffsetTarget = LLVector4(gSavedSettings.getVector3("CameraOffsetBuild"));
 	
@@ -438,7 +438,7 @@ LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 origi
 	// make sure they object extents are non-zero
 	object_extents.clamp(0.001f, F32_MAX);
 
-	auto& viewerCamera = LLViewerCamera::instance();
+	auto& viewerCamera = LLViewerCamera::instanceFast();
 	const auto& viewer_camera_origin = viewerCamera.getOrigin();
 
 	// obj_to_cam_ray is unit vector pointing from object center to camera, in the coordinate frame of the object
@@ -751,7 +751,7 @@ BOOL LLAgentCamera::calcCameraMinDistance(F32 &obj_min_distance)
 	// clamp obj distance to diagonal of 10 by 10 cube
 	obj_min_distance = llmin(obj_min_distance, 10.f * F_SQRT3);
 
-	obj_min_distance += LLViewerCamera::getInstance()->getNear() + (soft_limit ? 0.1f : 0.2f);
+	obj_min_distance += LLViewerCamera::getInstanceFast()->getNear() + (soft_limit ? 0.1f : 0.2f);
 	
 	return TRUE;
 }
@@ -904,7 +904,7 @@ void LLAgentCamera::cameraOrbitOver(const F32 angle)
 		F32 angle_from_up = acos( camera_offset_unit * gAgent.getReferenceUpVector() );
 
 		LLVector3d left_axis;
-		left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis());
+		left_axis.setVec(LLViewerCamera::getInstanceFast()->getLeftAxis());
 		F32 new_angle = llclamp(angle_from_up - angle, 1.f * DEG_TO_RAD, 179.f * DEG_TO_RAD);
 		mOrbitOverAngle += angle_from_up - new_angle;
 		mCameraFocusOffsetTarget.rotVec(angle_from_up - new_angle, left_axis);
@@ -919,7 +919,7 @@ void LLAgentCamera::resetCameraOrbit()
 	camera_offset_unit.normalize();
 
 	LLVector3d left_axis;
-	left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis());
+	left_axis.setVec(LLViewerCamera::getInstanceFast()->getLeftAxis());
 	mCameraFocusOffsetTarget.rotVec(-mOrbitOverAngle, left_axis);
 	
 	mCameraFocusOffsetTarget.rotVec(-mOrbitAroundRadians, 0.f, 0.f, 1.f);
@@ -1092,7 +1092,7 @@ void LLAgentCamera::cameraOrbitIn(const F32 meters)
 void LLAgentCamera::cameraPanIn(F32 meters)
 {
 	LLVector3d at_axis;
-	at_axis.setVec(LLViewerCamera::getInstance()->getAtAxis());
+	at_axis.setVec(LLViewerCamera::getInstanceFast()->getAtAxis());
 
 	mPanFocusDiff += meters * at_axis;
 
@@ -1110,7 +1110,7 @@ void LLAgentCamera::cameraPanIn(F32 meters)
 void LLAgentCamera::cameraPanLeft(F32 meters)
 {
 	LLVector3d left_axis;
-	left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis());
+	left_axis.setVec(LLViewerCamera::getInstanceFast()->getLeftAxis());
 
 	mPanFocusDiff += meters * left_axis;
 
@@ -1132,7 +1132,7 @@ void LLAgentCamera::cameraPanLeft(F32 meters)
 void LLAgentCamera::cameraPanUp(F32 meters)
 {
 	LLVector3d up_axis;
-	up_axis.setVec(LLViewerCamera::getInstance()->getUpAxis());
+	up_axis.setVec(LLViewerCamera::getInstanceFast()->getUpAxis());
 
 	mPanFocusDiff += meters * up_axis;
 
@@ -1210,7 +1210,7 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y)
 		// Move head based on cursor position
 		ELookAtType lookAtType = LOOKAT_TARGET_NONE;
 		LLVector3 headLookAxis;
-		LLCoordFrame frameCamera = *((LLCoordFrame*)LLViewerCamera::getInstance());
+		LLCoordFrame frameCamera = *((LLCoordFrame*)LLViewerCamera::getInstanceFast());
 
 		if (cameraMouselook())
 		{
@@ -1305,6 +1305,8 @@ void LLAgentCamera::updateCamera()
 											   gAgentCamera.getPanDownKey() > 0.f);		// bottom
 	}
 
+	auto& vwr_camera = LLViewerCamera::instanceFast();
+
 	// Handle camera movement based on keyboard.
 	const F32 ORBIT_OVER_RATE = 90.f * DEG_TO_RAD;			// radians per second
 	const F32 ORBIT_AROUND_RATE = 90.f * DEG_TO_RAD;		// radians per second
@@ -1326,7 +1328,7 @@ void LLAgentCamera::updateCamera()
 	{
 		F32 input_rate = gAgentCamera.getOrbitInKey() - gAgentCamera.getOrbitOutKey();
 		
-		LLVector3d to_focus = gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin()) - calcFocusPositionTargetGlobal();
+		LLVector3d to_focus = gAgent.getPosGlobalFromAgent(vwr_camera.getOrigin()) - calcFocusPositionTargetGlobal();
 		F32 distance_to_focus = (F32)to_focus.magVec();
 		// Move at distance (in meters) meters per second
 		cameraOrbitIn( input_rate * distance_to_focus / gFPSClamped );
@@ -1513,12 +1515,11 @@ void LLAgentCamera::updateCamera()
 	mCameraPositionAgent = gAgent.getPosAgentFromGlobal(camera_pos_global);
 
 	// Move the camera
-
-	LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, mCameraUpVector, focus_agent);
+	vwr_camera.updateCameraLocation(mCameraPositionAgent, mCameraUpVector, focus_agent);
 	//LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, camera_skyward, focus_agent);
 	
 	// Change FOV
-	LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / (1.f + mCameraCurrentFOVZoomFactor));
+	vwr_camera.setView(vwr_camera.getDefaultFOV() / (1.f + mCameraCurrentFOVZoomFactor));
 
 	// follow camera when in customize mode
 	if (cameraCustomizeAvatar())	
@@ -1583,11 +1584,8 @@ void LLAgentCamera::updateCamera()
 					
 				}
 			}
-			auto camera_instance = LLViewerCamera::getInstance();
-			if(camera_instance)
-			{
-				camera_instance->updateCameraLocation(head_pos, mCameraUpVector, gAgentAvatarp->mHeadp->getWorldPosition() + LLVector3(1.0, 0.0, 0.0) * agent_rot);
-			}
+
+			vwr_camera.updateCameraLocation(head_pos, mCameraUpVector, gAgentAvatarp->mHeadp->getWorldPosition() + LLVector3(1.0, 0.0, 0.0) * agent_rot);
 		}
 		else
 		{
@@ -1776,7 +1774,7 @@ void LLAgentCamera::setupSitCamera()
 //-----------------------------------------------------------------------------
 const LLVector3 &LLAgentCamera::getCameraPositionAgent() const
 {
-	return LLViewerCamera::getInstance()->getOrigin();
+	return LLViewerCamera::getInstanceFast()->getOrigin();
 }
 
 //-----------------------------------------------------------------------------
@@ -1784,7 +1782,7 @@ const LLVector3 &LLAgentCamera::getCameraPositionAgent() const
 //-----------------------------------------------------------------------------
 LLVector3d LLAgentCamera::getCameraPositionGlobal() const
 {
-	return gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin());
+	return gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstanceFast()->getOrigin());
 }
 
 //-----------------------------------------------------------------------------
@@ -2179,7 +2177,7 @@ bool LLAgentCamera::clampCameraPosition(LLVector3d& posCamGlobal, const LLVector
 
 LLVector3 LLAgentCamera::getCurrentCameraOffset()
 {
-	return (LLViewerCamera::getInstance()->getOrigin() - getAvatarRootPosition() - mThirdPersonHeadOffset) * ~getCurrentAvatarRotation();
+	return (LLViewerCamera::getInstanceFast()->getOrigin() - getAvatarRootPosition() - mThirdPersonHeadOffset) * ~getCurrentAvatarRotation();
 }
 
 LLVector3d LLAgentCamera::getCurrentFocusOffset()
@@ -2440,7 +2438,7 @@ void LLAgentCamera::changeCameraToFollow(BOOL animate)
 		ALAOEngine::getInstance()->inMouselook(false);
 
 		// bang-in the current focus, position, and up vector of the follow cam
-		mFollowCam.reset(mCameraPositionAgent, LLViewerCamera::getInstance()->getPointOfInterest(), LLVector3::z_axis);
+		mFollowCam.reset(mCameraPositionAgent, LLViewerCamera::getInstanceFast()->getPointOfInterest(), LLVector3::z_axis);
 		
 		if (gBasicToolset)
 		{
@@ -2933,7 +2931,7 @@ void LLAgentCamera::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate, BOOL re
                 LLVector3 vect = getCameraOffsetInitial();
                 F32 rotxy = F32(atan2(vect.mV[VY], vect.mV[VX]));
 
-                LLCoordFrame frameCamera = *((LLCoordFrame*)LLViewerCamera::getInstance());
+                LLCoordFrame frameCamera = *((LLCoordFrame*)LLViewerCamera::getInstanceFast());
                 // front view angle rotxy is zero, rear view rotxy angle is 180, compensate
                 frameCamera.yaw((180 * DEG_TO_RAD) - rotxy);
                 at_axis = frameCamera.getAtAxis();
diff --git a/indra/newview/llagentpilot.cpp b/indra/newview/llagentpilot.cpp
index a07341ee4ee1213bbfa1ce23cd5a7f20de0cd754..8afa848010c60c6f82fd93755574143670083dd8 100644
--- a/indra/newview/llagentpilot.cpp
+++ b/indra/newview/llagentpilot.cpp
@@ -238,12 +238,12 @@ void LLAgentPilot::addAction(enum EActionType action_type)
 	action.mType = action_type;
 	action.mTarget = gAgent.getPositionGlobal();
 	action.mTime = mTimer.getElapsedTimeF32();
-	LLViewerCamera *cam = LLViewerCamera::getInstance();
-	action.mCameraView = cam->getView();
-	action.mCameraOrigin = cam->getOrigin();
-	action.mCameraXAxis = cam->getXAxis();
-	action.mCameraYAxis = cam->getYAxis();
-	action.mCameraZAxis = cam->getZAxis();
+	LLViewerCamera& cam = LLViewerCamera::instance();
+	action.mCameraView = cam.getView();
+	action.mCameraOrigin = cam.getOrigin();
+	action.mCameraXAxis = cam.getXAxis();
+	action.mCameraYAxis = cam.getYAxis();
+	action.mCameraZAxis = cam.getZAxis();
 	mLastRecordTime = (F32)action.mTime;
 	mActions.push_back(action);
 }
@@ -320,11 +320,12 @@ void LLAgentPilot::moveCamera()
 		LLQuaternion quat = nlerp(t, start_quat, end_quat);
 		LLMatrix3 mat(quat);
 	
-		LLViewerCamera::getInstance()->setView(view);
-		LLViewerCamera::getInstance()->setOrigin(origin);
-		LLViewerCamera::getInstance()->mXAxis = LLVector3(mat.mMatrix[0]);
-		LLViewerCamera::getInstance()->mYAxis = LLVector3(mat.mMatrix[1]);
-		LLViewerCamera::getInstance()->mZAxis = LLVector3(mat.mMatrix[2]);
+		LLViewerCamera& cam = LLViewerCamera::instance();
+		cam.setView(view);
+		cam.setOrigin(origin);
+		cam.mXAxis = LLVector3(mat.mMatrix[0]);
+		cam.mYAxis = LLVector3(mat.mMatrix[1]);
+		cam.mZAxis = LLVector3(mat.mMatrix[2]);
 	}
 }
 
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index d05aded017ff2bb3a4ae6e2ff400c2ecad0628dd..94b349bee99196c79e58f6aa247f2ca581084678 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -88,7 +88,7 @@ std::vector<LLPointer<LLDrawable> > LLDrawable::sDeadList;
 void LLDrawable::incrementVisible() 
 {
 	LLViewerOctreeEntryData::incrementVisible();
-	sCurPixelAngle = (F32) gViewerWindow->getWindowHeightRaw()/LLViewerCamera::getInstance()->getView();
+	sCurPixelAngle = (F32) gViewerWindow->getWindowHeightRaw()/LLViewerCamera::getInstanceFast()->getView();
 }
 
 LLDrawable::LLDrawable(LLViewerObject *vobj, bool new_entry)
@@ -911,7 +911,7 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
             if (avatarp)
             {
                 const LLVector3* av_box = avatarp->getLastAnimExtents();
-                LLVector3 cam_pos_from_agent = LLViewerCamera::getInstance()->getOrigin();
+                LLVector3 cam_pos_from_agent = LLViewerCamera::getInstanceFast()->getOrigin();
                 LLVector3 cam_to_box_offset = point_to_box_offset(cam_pos_from_agent, av_box);
                 mDistanceWRTCamera = llmax(0.01f, ll_round(cam_to_box_offset.magVec(), 0.01f));
 #ifdef SHOW_DEBUG
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index c8da1a1dcd245b177b86d306ed8756fffb78facd..397f1e022a4688e000ff17cb9cf90bf85f02314a 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -1712,7 +1712,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
 	if ((sShaderLevel >= SHADER_LEVEL_CLOTH))
 	{
 		LLMatrix4 rot_mat;
-		LLViewerCamera::getInstance()->getMatrixToLocal(rot_mat);
+		LLViewerCamera::getInstanceFast()->getMatrixToLocal(rot_mat);
 		LLMatrix4 cfr(OGL_TO_CFR_ROTATION);
 		rot_mat *= cfr;
 		
diff --git a/indra/newview/lldrawpoolground.cpp b/indra/newview/lldrawpoolground.cpp
index 5b74264dab4cb2ddca721316f733de27ebe174fb..535a7f92ca2d764bd7839413e777c91348c882a7 100644
--- a/indra/newview/lldrawpoolground.cpp
+++ b/indra/newview/lldrawpoolground.cpp
@@ -63,7 +63,7 @@ void LLDrawPoolGround::render(S32 pass)
 
 	F32 water_height = gAgent.getRegion()->getWaterHeight();
 	gGL.pushMatrix();
-	LLVector3 origin = LLViewerCamera::getInstance()->getOrigin();
+	LLVector3 origin = LLViewerCamera::getInstanceFast()->getOrigin();
 	gGL.translatef(origin.mV[0], origin.mV[1], llmax(origin.mV[2], water_height));
 
 	LLFace *facep = mDrawFace[0];
diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp
index b6f55e800afe8b21b57723351754763028bb2cd4..3fd3e78e3bcf932b725d0e7b9d26928c34ebcd63 100644
--- a/indra/newview/lldrawpoolsky.cpp
+++ b/indra/newview/lldrawpoolsky.cpp
@@ -95,10 +95,10 @@ void LLDrawPoolSky::render(S32 pass)
 
 	LLGLSPipelineDepthTestSkyBox gls_skybox(true, false);
 
-	LLGLEnable fog_enable( (mShaderLevel < 1 && LLViewerCamera::getInstance()->cameraUnderWater()) ? GL_FOG : 0);
+	LLGLEnable fog_enable( (mShaderLevel < 1 && LLViewerCamera::getInstanceFast()->cameraUnderWater()) ? GL_FOG : 0);
 	
 	gGL.pushMatrix();
-	LLVector3 origin = LLViewerCamera::getInstance()->getOrigin();
+	LLVector3 origin = LLViewerCamera::getInstanceFast()->getOrigin();
 	gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
 
 	S32 face_count = (S32)mDrawFace.size();
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index a02d2eba0d8f26e6e34acbe6fbc5635bdc9dddf5..5b039120a2e6ca3502fd690644677a94c253710b 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -237,7 +237,7 @@ void LLDrawPoolTerrain::beginShadowPass(S32 pass)
 	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	gDeferredShadowProgram.bind();
 
-    LLEnvironment& environment = LLEnvironment::instance();
+    LLEnvironment& environment = LLEnvironment::instanceFast();
     gDeferredShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
 }
 
@@ -329,7 +329,7 @@ void LLDrawPoolTerrain::renderFullShader()
 	shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV);
 	shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV);
 
-	const LLSettingsWater::ptr_t& pwater = LLEnvironment::instance().getCurrentWater();
+	const LLSettingsWater::ptr_t& pwater = LLEnvironment::getInstanceFast()->getCurrentWater();
 
     ((LLSettingsVOWater*)pwater.get())->updateShader(shader);
 
diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp
index 9edd5bd648fda157bee10b41e4f44fdc1fa59725..648af83a07fb0586a02dc1fb022ad1439d83db19 100644
--- a/indra/newview/lldrawpooltree.cpp
+++ b/indra/newview/lldrawpooltree.cpp
@@ -178,7 +178,7 @@ void LLDrawPoolTree::beginShadowPass(S32 pass)
 	glPolygonOffset(gSavedSettings.getF32("RenderDeferredTreeShadowOffset"),
 					gSavedSettings.getF32("RenderDeferredTreeShadowBias"));
 
-    LLEnvironment& environment = LLEnvironment::instance();
+	LLEnvironment& environment = LLEnvironment::instanceFast();
 
 	gDeferredTreeShadowProgram.bind();
     gDeferredTreeShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 660a0b6da0122ddeb69a79f6192bbe40fa192c4c..641f32bd9f9692c29d11cd8d1370069fc9a2f1d4 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -110,7 +110,7 @@ void LLDrawPoolWater::prerender()
 
 S32 LLDrawPoolWater::getNumPasses()
 {
-	if (LLViewerCamera::getInstance()->getOrigin().mV[2] < 1024.f)
+	if (LLViewerCamera::getInstanceFast()->getOrigin().mV[2] < 1024.f)
 	{
 		return 1;
 	}
@@ -202,11 +202,11 @@ void LLDrawPoolWater::render(S32 pass)
 	gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE);
 	gGL.getTexUnit(2)->bind(mWaterImagep[1]) ;
 
-	LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();
+	LLVector3 camera_up = LLViewerCamera::getInstanceFast()->getUpAxis();
 	F32 up_dot = camera_up * LLVector3::z_axis;
 
 	LLColor4 water_color;
-	if (LLViewerCamera::getInstance()->cameraUnderWater())
+	if (LLViewerCamera::getInstanceFast()->cameraUnderWater())
 	{
 		water_color.setVec(1.f, 1.f, 1.f, 0.4f);
 	}
@@ -279,7 +279,7 @@ void LLDrawPoolWater::render(S32 pass)
 
 		gGL.matrixMode(LLRender::MM_TEXTURE);
 		gGL.loadIdentity();
-		LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview();
+		LLMatrix4 camera_mat = LLViewerCamera::getInstanceFast()->getModelview();
 		LLMatrix4 camera_rot(camera_mat.getMat3());
 		camera_rot.invert();
 
@@ -463,8 +463,8 @@ void LLDrawPoolWater::renderReflection(LLFace* face)
 
 void LLDrawPoolWater::shade2(bool edge, LLGLSLShader* shader, const LLColor3& light_diffuse, const LLVector3& light_dir, F32 light_exp)
 {
-	LLEnvironment& environment = LLEnvironment::instance();
-	LLViewerCamera& viewerCamera = LLViewerCamera::instance();
+	LLEnvironment& environment = LLEnvironment::instanceFast();
+	LLViewerCamera& viewerCamera = LLViewerCamera::instanceFast();
 
 	F32  water_height  = environment.getWaterHeight();
     F32  camera_height = viewerCamera.getOrigin().mV[2];
@@ -667,7 +667,7 @@ void LLDrawPoolWater::shade()
 	F32 light_exp = 0.0f;
 	LLVector3 light_dir;
 
-    LLEnvironment& environment = LLEnvironment::instance();
+    LLEnvironment& environment = LLEnvironment::instanceFast();
 	const LLSettingsSky::ptr_t& psky   = environment.getCurrentSky();
 
     light_dir = environment.getLightDirection();
@@ -703,7 +703,7 @@ void LLDrawPoolWater::shade()
 
 	LLGLSLShader* shader = nullptr;
 
-	F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - environment.getWaterHeight();
+	F32 eyedepth = LLViewerCamera::getInstanceFast()->getOrigin().mV[2] - environment.getWaterHeight();
 	
 	if (eyedepth < 0.f && LLPipeline::sWaterReflections)
 	{
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index fcc08c13f5946e9c2f1abd5fff0caffcb34e1666..5eef6cbae72ae45f35c6ab2c07237209a00e7acd 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -94,9 +94,9 @@ void LLDrawPoolWLSky::beginRenderPass( S32 pass )
 				&gObjectFullbrightNoColorWaterProgram :
 				&gCustomAlphaProgram;
 
-    auto& environment = LLEnvironment::instance();
+    auto& environment = LLEnvironment::instanceFast();
     mCamHeightLocal = environment.getCamHeight();
-    mCameraOrigin = LLViewerCamera::getInstance()->getOrigin();
+    mCameraOrigin = LLViewerCamera::getInstanceFast()->getOrigin();
     mCurrentSky = environment.getCurrentSky();
 }
 
@@ -130,9 +130,9 @@ void LLDrawPoolWLSky::beginDeferredPass(S32 pass)
 				&gObjectFullbrightNoColorWaterProgram :
 				&gDeferredStarProgram;
 
-    auto& environment = LLEnvironment::instance();
+    auto& environment = LLEnvironment::instanceFast();
     mCamHeightLocal = environment.getCamHeight();
-    mCameraOrigin = LLViewerCamera::getInstance()->getOrigin();
+    mCameraOrigin = LLViewerCamera::getInstanceFast()->getOrigin();
     mCurrentSky = environment.getCurrentSky();
 }
 
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index 65cbd300235920e54e7212a2b0b00299c6d826de..3465522abf6023f6f661d512df91cccbbc3a80e9 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -145,7 +145,7 @@ void LLViewerDynamicTexture::preRender(BOOL clear_depth)
 
 	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	// Set up camera
-	LLViewerCamera* camera = LLViewerCamera::getInstance();
+	LLViewerCamera* camera = LLViewerCamera::getInstanceFast();
 	mCamera.setOrigin(*camera);
 	mCamera.setAxes(*camera);
 	mCamera.setAspect(camera->getAspect());
@@ -188,7 +188,7 @@ void LLViewerDynamicTexture::postRender(BOOL success)
 	gViewerWindow->setup2DViewport();
 
 	// restore camera
-	LLViewerCamera* camera = LLViewerCamera::getInstance();
+	LLViewerCamera* camera = LLViewerCamera::getInstanceFast();
 	camera->setOrigin(mCamera);
 	camera->setAxes(mCamera);
 	camera->setAspect(mCamera.getAspect());
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 27d54126eb2e26ce02240e8515b7ab41a4574f7b..849849109162f30a7ff92ce2e16eeb1a43bd7257 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -656,10 +656,10 @@ void LLFace::renderOneWireframe(const LLColor4 &color, F32 fogCfx, bool wirefram
 			{
 				LLGLEnable fog(GL_FOG);
 				glFogi(GL_FOG_MODE, GL_LINEAR);
-				float d = (LLViewerCamera::getInstance()->getPointOfInterest() - LLViewerCamera::getInstance()->getOrigin()).magVec();
+				float d = (LLViewerCamera::getInstanceFast()->getPointOfInterest() - LLViewerCamera::getInstanceFast()->getOrigin()).magVec();
 				LLColor4 fogCol = color * fogCfx;
 				glFogf(GL_FOG_START, d);
-				glFogf(GL_FOG_END, d * (1 + (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV())));
+				glFogf(GL_FOG_END, d * (1 + (LLViewerCamera::getInstanceFast()->getView() / LLViewerCamera::getInstanceFast()->getDefaultFOV())));
 				glFogfv(GL_FOG_COLOR, fogCol.mV);
 			}
             gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
@@ -2212,7 +2212,7 @@ BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
 	size.setSub(mExtents[1], mExtents[0]);
 	size.mul(0.5f);
 
-	LLViewerCamera* camera = LLViewerCamera::getInstance();
+	LLViewerCamera* camera = LLViewerCamera::getInstanceFast();
 
 	F32 size_squared = size.dot3(size).getF32();
 	LLVector4a lookAt;
@@ -2317,7 +2317,7 @@ F32 LLFace::calcImportanceToCamera(F32 cos_angle_to_view_dir, F32 dist)
 {
 	F32 importance = 0.f ;
 	
-	LLViewerCamera& camera = LLViewerCamera::instance();
+	LLViewerCamera& camera = LLViewerCamera::instanceFast();
 
 	if(cos_angle_to_view_dir > camera.getCosHalfFov() &&
 		dist < FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[FACE_IMPORTANCE_LEVEL - 1][0]) 
diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp
index 3651c958582b8a4013e338eb49ad11e68bac88f2..bd3bafc8f21320682aadfd9d57deda81d6752cec 100644
--- a/indra/newview/llflexibleobject.cpp
+++ b/indra/newview/llflexibleobject.cpp
@@ -312,7 +312,7 @@ void LLVolumeImplFlexible::updateRenderRes()
 	F32 app_angle = ll_round((F32) atan2( mVO->getScale().mV[2]*2.f, drawablep->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f);
 
  	// Rendering sections increases with visible angle on the screen
-	mRenderRes = (S32)(FLEXIBLE_OBJECT_MAX_SECTIONS*4*app_angle*DEG_TO_RAD/LLViewerCamera::getInstance()->getView());
+	mRenderRes = (S32)(FLEXIBLE_OBJECT_MAX_SECTIONS*4*app_angle*DEG_TO_RAD/LLViewerCamera::getInstanceFast()->getView());
 #endif
 		
 	mRenderRes = llclamp(mRenderRes, new_res-1, (S32) FLEXIBLE_OBJECT_MAX_SECTIONS);
@@ -360,7 +360,7 @@ void LLVolumeImplFlexible::doIdleUpdate()
 				// Note: Flexies afar will be rarely updated, closer ones will be updated more frequently.
 				// But frequency differences are extremely noticeable, so consider modifying update factor,
 				// or at least clamping value a bit more from both sides.
-				U32 update_period = (U32) (llmax((S32) (LLViewerCamera::getInstance()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f))),0)+1);
+				U32 update_period = (U32) (llmax((S32) (LLViewerCamera::getInstanceFast()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f))),0)+1);
 				// MAINT-1890 Clamp the update period to ensure that the update_period is no greater than 32 frames
 				update_period = llclamp(update_period, 1U, 32U);
 
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index 708e3473b561d1f8259009f8d62ed9efbe78e080..242c89dc4120ae3c4fc4115779e7c4f89511ce3b 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -103,8 +103,10 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
 	top = ll_round((F32) top * LLUI::getScaleFactor().mV[VY]);
 	bottom = ll_round((F32) bottom * LLUI::getScaleFactor().mV[VY]);
 
-	F32 old_far_plane = LLViewerCamera::getInstance()->getFar();
-	F32 old_near_plane = LLViewerCamera::getInstance()->getNear();
+	LLViewerCamera* viewer_cam = LLViewerCamera::getInstanceFast();
+
+	F32 old_far_plane = viewer_cam->getFar();
+	F32 old_near_plane = viewer_cam->getNear();
 
 	S32 width = right - left + 1;
 	S32 height = top - bottom + 1;
@@ -142,15 +144,15 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
 	{
 		// ...select distance from control
 		LLVector3 relative_av_pos = av_pos;
-		relative_av_pos -= LLViewerCamera::getInstance()->getOrigin();
+		relative_av_pos -= viewer_cam->getOrigin();
 
-		F32 new_far = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() + ALControlCache::MaxSelectDistance;
-		F32 new_near = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() - ALControlCache::MaxSelectDistance;
+		F32 new_far = relative_av_pos * viewer_cam->getAtAxis() + ALControlCache::MaxSelectDistance;
+		F32 new_near = relative_av_pos * viewer_cam->getAtAxis() - ALControlCache::MaxSelectDistance;
 
 		new_near = llmax(new_near, 0.1f);
 
-		LLViewerCamera::getInstance()->setFar(new_far);
-		LLViewerCamera::getInstance()->setNear(new_near);
+		viewer_cam->setFar(new_far);
+		viewer_cam->setNear(new_near);
 	}
 // [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e) | Modified: RLVa-1.0.0g
 	if (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH))
@@ -160,22 +162,22 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
 		// We'll allow drag selection under fartouch, but only within the fartouch range
 		// (just copy/paste the code above us to make that work, thank you Lindens!)
 		LLVector3 relative_av_pos = av_pos;
-		relative_av_pos -= LLViewerCamera::getInstance()->getOrigin();
+		relative_av_pos -= viewer_cam->getOrigin();
 
-		F32 new_far = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() + s_nFartouchDist;
-		F32 new_near = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() - s_nFartouchDist;
+		F32 new_far = relative_av_pos * viewer_cam->getAtAxis() + s_nFartouchDist;
+		F32 new_near = relative_av_pos * viewer_cam->getAtAxis() - s_nFartouchDist;
 
 		new_near = llmax(new_near, 0.1f);
 
-		LLViewerCamera::getInstance()->setFar(new_far);
-		LLViewerCamera::getInstance()->setNear(new_near);
+		viewer_cam->setFar(new_far);
+		viewer_cam->setNear(new_near);
 
 		// Usurp these two
 		limit_select_distance = TRUE;
 		select_dist_squared = s_nFartouchDist * s_nFartouchDist;
 	}
 // [/RLVa:KB]
-	LLViewerCamera::getInstance()->setPerspective(FOR_SELECTION, 
+	viewer_cam->setPerspective(FOR_SELECTION,
 							center_x-width/2, center_y-height/2, width, height, 
 							limit_select_distance);
 
@@ -190,17 +192,17 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
 				{
 					return true;
 				}
-				S32 result = LLViewerCamera::getInstance()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius());
+				S32 result = LLViewerCamera::getInstanceFast()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius());
 				switch (result)
 				{
 				  case 0:
-					LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp);
+					LLSelectMgr::getInstanceFast()->unhighlightObjectOnly(vobjp);
 					break;
 				  case 1:
 					// check vertices
-					if (!LLViewerCamera::getInstance()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive))
+					if (!LLViewerCamera::getInstanceFast()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive))
 					{
-						LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp);
+						LLSelectMgr::getInstanceFast()->unhighlightObjectOnly(vobjp);
 					}
 					break;
 				  default:
@@ -209,21 +211,21 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
 				return true;
 			}
 		} func;
-		LLSelectMgr::getInstance()->getHighlightedObjects()->applyToObjects(&func);
+		LLSelectMgr::getInstanceFast()->getHighlightedObjects()->applyToObjects(&func);
 	}
 
 	if (grow_selection)
 	{
 		std::vector<LLDrawable*> potentials;
 				
-		for (LLViewerRegion* region : LLWorld::getInstance()->getRegionList())
+		for (LLViewerRegion* region : LLWorld::getInstanceFast()->getRegionList())
 		{
 			for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
 			{
 				LLSpatialPartition* part = region->getSpatialPartition(i);
 				if (part)
 				{	
-					part->cull(*LLViewerCamera::getInstance(), &potentials, TRUE);
+					part->cull(*viewer_cam, &potentials, TRUE);
 				}
 			}
 		}
@@ -254,20 +256,20 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
 			}
 // [/RLVa:KB]
 
-			S32 result = LLViewerCamera::getInstance()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius());
+			S32 result = viewer_cam->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius());
 			if (result)
 			{
 				switch (result)
 				{
 				case 1:
 					// check vertices
-					if (LLViewerCamera::getInstance()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive))
+					if (viewer_cam->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive))
 					{
-						LLSelectMgr::getInstance()->highlightObjectOnly(vobjp);
+						LLSelectMgr::getInstanceFast()->highlightObjectOnly(vobjp);
 					}
 					break;
 				case 2:
-					LLSelectMgr::getInstance()->highlightObjectOnly(vobjp);
+					LLSelectMgr::getInstanceFast()->highlightObjectOnly(vobjp);
 					break;
 				default:
 					break;
@@ -282,8 +284,8 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
 	gGL.matrixMode(LLRender::MM_MODELVIEW);
 
 	// restore camera
-	LLViewerCamera::getInstance()->setFar(old_far_plane);
-	LLViewerCamera::getInstance()->setNear(old_near_plane);
+	LLViewerCamera::getInstanceFast()->setFar(old_far_plane);
+	LLViewerCamera::getInstanceFast()->setNear(old_near_plane);
 	gViewerWindow->setup3DRender();
 }
 
diff --git a/indra/newview/llhudeffectblob.cpp b/indra/newview/llhudeffectblob.cpp
index c909551b51755d2725f62597e712e1e88932fce5..a41a772a4d55aabb2bc9530f93f3c57a380f8dc9 100644
--- a/indra/newview/llhudeffectblob.cpp
+++ b/indra/newview/llhudeffectblob.cpp
@@ -64,7 +64,7 @@ void LLHUDEffectBlob::render()
 
 	LLVector3 pixel_up, pixel_right;
 
-	LLViewerCamera::instance().getPixelVectors(pos_agent, pixel_up, pixel_right);
+	LLViewerCamera::instanceFast().getPixelVectors(pos_agent, pixel_up, pixel_right);
 
 	LLGLSPipelineAlpha gls_pipeline_alpha;
 	gGL.getTexUnit(0)->bind(mImage->getImage());
diff --git a/indra/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp
index 85a878c4a2f1586ef160c9111aa795f3841cf77d..9e065ff244e263fc5bdb6e101e39851b76384b9d 100644
--- a/indra/newview/llhudicon.cpp
+++ b/indra/newview/llhudicon.cpp
@@ -99,7 +99,7 @@ void LLHUDIcon::renderIcon(BOOL for_select)
 
 	// put icon above object, and in front
 	// RN: don't use drawable radius, it's fricking HUGE
-	LLViewerCamera* camera = LLViewerCamera::getInstance();
+	LLViewerCamera* camera = LLViewerCamera::getInstanceFast();
 	LLVector3 icon_relative_pos = (camera->getUpAxis() * ~mSourceObject->getRenderRotation());
 	icon_relative_pos.abs();
 
@@ -109,7 +109,7 @@ void LLHUDIcon::renderIcon(BOOL for_select)
 	F32 up_distance = 0.5f * distance_scale;
 	LLVector3 icon_position = obj_position + (up_distance * camera->getUpAxis()) * 1.2f;
 
-	LLVector3 icon_to_cam = LLViewerCamera::getInstance()->getOrigin() - icon_position;
+	LLVector3 icon_to_cam = camera->getOrigin() - icon_position;
 	icon_to_cam.normVec();
 
 	icon_position += icon_to_cam * mSourceObject->mDrawable->getRadius() * 1.1f;
@@ -218,7 +218,7 @@ BOOL LLHUDIcon::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
 
 	// put icon above object, and in front
 	// RN: don't use drawable radius, it's fricking HUGE
-	LLViewerCamera* camera = LLViewerCamera::getInstance();
+	LLViewerCamera* camera = LLViewerCamera::getInstanceFast();
 	LLVector3 icon_relative_pos = (camera->getUpAxis() * ~mSourceObject->getRenderRotation());
 	icon_relative_pos.abs();
 
@@ -228,7 +228,7 @@ BOOL LLHUDIcon::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
 	F32 up_distance = 0.5f * distance_scale;
 	LLVector3 icon_position = obj_position + (up_distance * camera->getUpAxis()) * 1.2f;
 
-	LLVector3 icon_to_cam = LLViewerCamera::getInstance()->getOrigin() - icon_position;
+	LLVector3 icon_to_cam = camera->getOrigin() - icon_position;
 	icon_to_cam.normVec();
 
 	icon_position += icon_to_cam * mSourceObject->mDrawable->getRadius() * 1.1f;
diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index a120d0905c97efaca28eadb3f61c24f03ba0ecd6..b20968fd8cbecc4f9219d2bb88fe50b99293209c 100644
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -147,7 +147,7 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector4a& start, const LLVector4
 
 	LLVector3 position = mPositionAgent;
 
-	auto& viewerCamera = LLViewerCamera::instance();
+	auto& viewerCamera = LLViewerCamera::instanceFast();
 
 	if (mSourceObject)
 	{ //get intersection of eye through mPositionAgent to plane of source object
@@ -291,7 +291,7 @@ void LLHUDNameTag::renderText(BOOL for_select)
 	LLVector3 x_pixel_vec;
 	LLVector3 y_pixel_vec;
 	
-	LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);
+	LLViewerCamera::getInstanceFast()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);
 
 	LLVector3 width_vec = mWidth * x_pixel_vec;
 	LLVector3 height_vec = mHeight * y_pixel_vec;
@@ -299,7 +299,7 @@ void LLHUDNameTag::renderText(BOOL for_select)
 	mRadius = (width_vec + height_vec).magVec() * 0.5f;
 
 	LLCoordGL screen_pos;
-	LLViewerCamera::getInstance()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE);
+	LLViewerCamera::getInstanceFast()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE);
 
 	LLVector2 screen_offset = updateScreenPos(mPositionOffset);
 
@@ -585,7 +585,7 @@ void LLHUDNameTag::updateVisibility()
 		return;
 	}
 
-	auto& viewerCamera = LLViewerCamera::instance();
+	auto& viewerCamera = LLViewerCamera::instanceFast();
 
 	// push text towards camera by radius of object, but not past camera
 	LLVector3 vec_from_camera = mPositionAgent - viewerCamera.getOrigin();
@@ -648,7 +648,7 @@ LLVector2 LLHUDNameTag::updateScreenPos(LLVector2 &offset)
 	LLVector2 screen_pos_vec;
 	LLVector3 x_pixel_vec;
 	LLVector3 y_pixel_vec;
-	auto& viewerCamera = LLViewerCamera::instance();
+	auto& viewerCamera = LLViewerCamera::instanceFast();
 
 	viewerCamera.getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);
 	LLVector3 world_pos = mPositionAgent + (offset.mV[VX] * x_pixel_vec) + (offset.mV[VY] * y_pixel_vec);
diff --git a/indra/newview/llhudrender.cpp b/indra/newview/llhudrender.cpp
index 5a7257012c2b794080f0afe48cee9f84e8debf4c..075cba566ee08ee7aaba3319992ec34e3cecbeeb 100644
--- a/indra/newview/llhudrender.cpp
+++ b/indra/newview/llhudrender.cpp
@@ -59,7 +59,7 @@ void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent,
 					const LLColor4& color,
 					const BOOL orthographic)
 {
-	LLViewerCamera* camera = LLViewerCamera::getInstance();
+	LLViewerCamera* camera = LLViewerCamera::getInstanceFast();
 	// Do cheap plane culling
 	LLVector3 dir_vec = pos_agent - camera->getOrigin();
 	dir_vec /= dir_vec.magVec();
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index a470d5c2f21cf37b51b954ad2250c59531168896..dbdc18d6f81fb33cad29c307ac5c7caecd322c9b 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -156,7 +156,7 @@ void LLHUDText::renderText()
 	}
 	else
 	{
-		LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);
+		LLViewerCamera::getInstanceFast()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);
 	}
 
 	LLVector3 width_vec = mWidth * x_pixel_vec;
@@ -380,7 +380,7 @@ void LLHUDText::updateVisibility()
 	}
 
 	// push text towards camera by radius of object, but not past camera
-	auto& viewerCamera = LLViewerCamera::instance();
+	auto& viewerCamera = LLViewerCamera::instanceFast();
 	LLVector3 vec_from_camera = mPositionAgent - viewerCamera.getOrigin();
 	LLVector3 dir_from_camera = vec_from_camera;
 	dir_from_camera.normVec();
@@ -464,7 +464,7 @@ LLVector2 LLHUDText::updateScreenPos(const LLVector2 &offset)
 	LLVector2 screen_pos_vec;
 //	LLVector3 x_pixel_vec;
 //	LLVector3 y_pixel_vec;
-//	LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);
+//	LLViewerCamera::getInstanceFast()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);
 //	LLVector3 world_pos = mPositionAgent + (offset.mV[VX] * x_pixel_vec) + (offset.mV[VY] * y_pixel_vec);
 //	if (!LLViewerCamera::getInstance()->projectPosAgentToScreen(world_pos, screen_pos, FALSE) && mVisibleOffScreen)
 //	{
diff --git a/indra/newview/lllegacyatmospherics.cpp b/indra/newview/lllegacyatmospherics.cpp
index 5c28fe5150b05c22ed7e77de7085b379982ab32e..584703f73679c5404aed1e8300de78d7b050f1b6 100644
--- a/indra/newview/lllegacyatmospherics.cpp
+++ b/indra/newview/lllegacyatmospherics.cpp
@@ -405,7 +405,7 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
 	// LLWorld::getInstance()->getWaterHeight();
 	F32 camera_height = gAgentCamera.getCameraPositionAgent().mV[2];
 
-	F32 near_clip_height = LLViewerCamera::getInstance()->getAtAxis().mV[VZ] * LLViewerCamera::getInstance()->getNear();
+	F32 near_clip_height = LLViewerCamera::getInstanceFast()->getAtAxis().mV[VZ] * LLViewerCamera::getInstanceFast()->getNear();
 	camera_height += near_clip_height;
 
 	F32 fog_distance = 0.f;
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 620a024801220f2c8ae107db736ce4f9b066af26..eda47ff2bf38a376738778756ea159df349a2285 100644
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -229,7 +229,7 @@ void LLNetMap::draw()
 	gGL.scalef(scale.mV[0], scale.mV[1], scale.mV[2]);
 	gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]);
 
-	auto& viewer_camera = LLViewerCamera::instance();
+	auto& viewer_camera = LLViewerCamera::instanceFast();
 	
 	{
 		LLLocalClipRect clip(getLocalRect());
@@ -692,7 +692,7 @@ LLVector3 LLNetMap::globalPosToView(const LLVector3d& global_pos)
 	static LLUICachedControl<bool> rotate_map("MiniMapRotate", true);
 	if( rotate_map )
 	{
-		F32 radians = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] );
+		F32 radians = atan2( LLViewerCamera::getInstanceFast()->getAtAxis().mV[VX], LLViewerCamera::getInstanceFast()->getAtAxis().mV[VY] );
 		LLQuaternion rot(radians, LLVector3(0.f, 0.f, 1.f));
 		pos_local.rotVec( rot );
 	}
@@ -736,7 +736,7 @@ LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y )
 
 	LLVector3 pos_local( (F32)x, (F32)y, 0 );
 
-	F32 radians = - atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] );
+	F32 radians = - atan2( LLViewerCamera::getInstanceFast()->getAtAxis().mV[VX], LLViewerCamera::getInstanceFast()->getAtAxis().mV[VY] );
 
 	static LLUICachedControl<bool> rotate_map("MiniMapRotate", true);
 	if( rotate_map )
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 124bdf6973ffbac99c2f2c74ab6df953b588e64b..7440ce25ae9b4f59af0529489215a78c02fcff39 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -5766,7 +5766,7 @@ void LLSelectMgr::updateSilhouettes()
 		num_sils_genned	= 0;
 
 		// render silhouettes for highlighted objects
-		const auto& viewer_cam_origin = LLViewerCamera::instance().getOrigin();
+		const auto& viewer_cam_origin = LLViewerCamera::instanceFast().getOrigin();
 		//BOOL subtracting_from_selection = (gKeyboard->currentMask(TRUE) == MASK_CONTROL);
 		for (S32 pass = 0; pass < 2; pass++)
 		{
@@ -5841,7 +5841,7 @@ void LLSelectMgr::updateSelectionSilhouette(LLObjectSelectionHandle object_handl
 
 		//mSilhouetteImagep->bindTexture();
 		//glAlphaFunc(GL_GREATER, sHighlightAlphaTest);
-		const auto& viewer_cam_origin = LLViewerCamera::instance().getOrigin();
+		const auto& viewer_cam_origin = LLViewerCamera::instanceFast().getOrigin();
 		for (S32 pass = 0; pass < 2; pass++)
 		{
 			for (LLSelectNode* node : object_handle->begin_end())
@@ -5904,7 +5904,7 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
 		gGL.pushMatrix();
 		gGL.loadIdentity();
 		F32 depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f);
-		auto& viewerCamera = LLViewerCamera::instance();
+		auto& viewerCamera = LLViewerCamera::instanceFast();
 		gGL.ortho(-0.5f * viewerCamera.getAspect(), 0.5f * viewerCamera.getAspect(), -0.5f, 0.5f, 0.f, depth);
 
 		gGL.matrixMode(LLRender::MM_MODELVIEW);
@@ -6504,7 +6504,7 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color)
 	LLVolume *volume = objectp->getVolume();
 	if (volume)
 	{
-		auto& viewerCamera = LLViewerCamera::instance();
+		auto& viewerCamera = LLViewerCamera::instanceFast();
 
 		F32 silhouette_thickness;
 		if (isAgentAvatarValid() && is_hud_object)
@@ -7883,12 +7883,14 @@ bool LLSelectMgr::selectionMove(const LLVector3& displ,
 		// calculate the distance of the object closest to the camera origin
 		F32 min_dist_squared = F32_MAX; // value will be overridden in the loop
 		
+		const auto& origin = LLViewerCamera::getInstanceFast()->getOrigin();
+
 		LLVector3 obj_pos;
 		for (LLSelectNode* nodep : selection->root_begin_end())
 		{
 			obj_pos = nodep->getObject()->getPositionEdit();
 			
-			F32 obj_dist_squared = dist_vec_squared(obj_pos, LLViewerCamera::getInstance()->getOrigin());
+			F32 obj_dist_squared = dist_vec_squared(obj_pos, origin);
 			if (obj_dist_squared < min_dist_squared)
 			{
 				min_dist_squared = obj_dist_squared;
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 2889ed138ef870701573b3ce2c3b56c6099e01aa..e51134df832a15e429bec793ee254f912397d743 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -3854,7 +3854,7 @@ bool LLSpatialPartition::isHUDPartition()
 
 BOOL LLSpatialPartition::isVisible(const LLVector3& v)
 {
-	if (!LLViewerCamera::getInstance()->sphereInFrustum(v, 4.0f))
+	if (!LLViewerCamera::getInstanceFast()->sphereInFrustum(v, 4.0f))
 	{
 		return FALSE;
 	}
diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp
index 5e056944e995252bb94dd0b7331cfe92ac4dce06..e158db196bc53bd9ba93e8249647443e7319744a 100644
--- a/indra/newview/llsurfacepatch.cpp
+++ b/indra/newview/llsurfacepatch.cpp
@@ -863,7 +863,7 @@ void LLSurfacePatch::updateVisibility()
 	radius.splat(mRadius);
 
 	// sphere in frustum on global coordinates
-	if (LLViewerCamera::getInstance()->AABBInFrustumNoFarClip(center, radius))
+	if (LLViewerCamera::getInstanceFast()->AABBInFrustumNoFarClip(center, radius))
 	{
 		// We now need to calculate the render stride based on patchp's distance 
 		// from LLCamera render_stride is governed by a relation something like this...
diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp
index f5789948c0632bcf6fd6306fc83850b625054324..e8f43e67883d254ad3972cd16bbcc7177816d02e 100644
--- a/indra/newview/lltoolfocus.cpp
+++ b/indra/newview/lltoolfocus.cpp
@@ -293,7 +293,7 @@ BOOL LLToolCamera::handleMouseUp(S32 x, S32 y, MASK mask)
 			{
 				LLCoordGL mouse_pos;
 				LLVector3 focus_pos = gAgent.getPosAgentFromGlobal(gAgentCamera.getFocusGlobal());
-				BOOL success = LLViewerCamera::getInstance()->projectPosAgentToScreen(focus_pos, mouse_pos);
+				BOOL success = LLViewerCamera::getInstanceFast()->projectPosAgentToScreen(focus_pos, mouse_pos);
 				if (success)
 				{
 					LLUI::setMousePositionScreen(mouse_pos.mX, mouse_pos.mY);
diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp
index 7490515c5806d79510edc43317bf12e7cd52f5af..65ed11a3510708c6d56bb97859127fb8d300e821 100644
--- a/indra/newview/lltracker.cpp
+++ b/indra/newview/lltracker.cpp
@@ -505,7 +505,7 @@ void LLTracker::drawBeacon(LLVector3 pos_agent, std::string direction, LLColor4
 
 		gGL.color4fv(fogged_color.mV);
 		
-		LLVector3 x_axis = LLViewerCamera::getInstance()->getLeftAxis();
+		LLVector3 x_axis = LLViewerCamera::getInstanceFast()->getLeftAxis();
 		F32 t = gRenderStartTime.getElapsedTimeF32();
 		
 		for (U32 i = 0; i < BEACON_VERTS; i++)
@@ -563,14 +563,14 @@ void LLTracker::renderBeacon(LLVector3d pos_global,
 
 	F32 dist = (F32)to_vec.magVec();
 	F32 color_frac = 1.f;
-	if (dist > 0.99f * LLViewerCamera::getInstance()->getFar())
+	if (dist > 0.99f * LLViewerCamera::getInstanceFast()->getFar())
 	{
 		color_frac = 0.4f;
 	//	pos_global = gAgentCamera.getCameraPositionGlobal() + 0.99f*(LLViewerCamera::getInstance()->getFar()/dist)*to_vec;
 		}
 	else
 	{
-		color_frac = 1.f - 0.6f*(dist/LLViewerCamera::getInstance()->getFar());
+		color_frac = 1.f - 0.6f*(dist/LLViewerCamera::getInstanceFast()->getFar());
 	}
 
 	LLColor4 fogged_color = color_frac * color + (1 - color_frac)*gSky.getSkyFogColor();
@@ -684,9 +684,9 @@ void LLTracker::drawMarker(const LLVector3d& pos_global, const LLColor4& color,
 	S32 y = 0;
 	const BOOL CLAMP = TRUE;
 
-	bool on_screen = LLViewerCamera::getInstance()->projectPosAgentToScreen(pos_local, screen, CLAMP);
+	bool on_screen = LLViewerCamera::getInstanceFast()->projectPosAgentToScreen(pos_local, screen, CLAMP);
 	if (on_screen && is_iff) return;
-	if (on_screen || LLViewerCamera::getInstance()->projectPosAgentToScreenEdge(pos_local, screen) )
+	if (on_screen || LLViewerCamera::getInstanceFast()->projectPosAgentToScreenEdge(pos_local, screen) )
 	{
 		gHUDView->screenPointToLocal(screen.mX, screen.mY, &x, &y);
 
diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
index 41a1f6a091c5b8d4e2a442d91819dbb6d4559d3a..eb8a6ec92336eafe0c8bc8cb2761796a67106c16 100644
--- a/indra/newview/llvieweraudio.cpp
+++ b/indra/newview/llvieweraudio.cpp
@@ -422,7 +422,7 @@ void audio_update_volume(bool force_update)
 
 		static const LLCachedControl<F32> rolloff_volume(gSavedSettings, "AudioLevelRolloff");
 		static const LLCachedControl<F32> underwater_rolloff_volume(gSavedSettings, "AudioLevelUnderwaterRolloff");
-		if(!LLViewerCamera::getInstance()->cameraUnderWater())
+		if(!LLViewerCamera::getInstanceFast()->cameraUnderWater())
 			gAudiop->setRolloffFactor(rolloff_volume);
 		else
 			gAudiop->setRolloffFactor(underwater_rolloff_volume);
@@ -508,8 +508,8 @@ void audio_update_listener()
 							 // LLViewerCamera::getInstance()VelocitySmoothed, 
 							 // LLVector3::zero,	
 							 gAgent.getVelocity(),    // !!! *TODO: need to replace this with smoothed velocity!
-							 LLViewerCamera::getInstance()->getUpAxis(),
-							 LLViewerCamera::getInstance()->getAtAxis());
+							 LLViewerCamera::getInstanceFast()->getUpAxis(),
+							 LLViewerCamera::getInstanceFast()->getAtAxis());
 	}
 }
 
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index ccfa6e08c6c2618e9cbfe4401eba8b9427326154..06c31e0ce9ebdcf85859c0d687236e111dbde14e 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -203,7 +203,7 @@ void display_update_camera()
 	{
 		final_far *= 0.5f;
 	}
-	LLViewerCamera::getInstance()->setFar(final_far);
+	LLViewerCamera::getInstanceFast()->setFar(final_far);
 	gViewerWindow->setup3DRender();
 	
 	// Update land visibility too
@@ -609,7 +609,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 	//
 
 	LLAppViewer::instance()->pingMainloopTimeout(STR_DISPLAY_CAMERA);
-	auto& vwrCamera = LLViewerCamera::instance();
+	auto& vwrCamera = LLViewerCamera::instanceFast();
 	vwrCamera.setZoomParameters(zoom_factor, subfield);
 	vwrCamera.setNear(MIN_NEAR_PLANE);
 
@@ -1126,7 +1126,7 @@ void render_hud_attachments()
 	if (!ALCinematicMode::isEnabled() && LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices())
 	{
 		LLPipeline::sRenderingHUDs = TRUE;
-		LLCamera hud_cam = *LLViewerCamera::getInstance();
+		LLCamera hud_cam = LLViewerCamera::instanceFast();
 		hud_cam.setOrigin(-1.f,0,0);
 		hud_cam.setAxes(LLVector3(1,0,0), LLVector3(0,1,0), LLVector3(0,0,1));
 		LLViewerCamera::updateFrustumPlanes(hud_cam, TRUE);
@@ -1218,7 +1218,7 @@ LLRect get_whole_screen_region()
 	LLRect whole_screen = gViewerWindow->getWorldViewRectScaled();
 	
 	// apply camera zoom transform (for high res screenshots)
-	auto& vwrCamera = LLViewerCamera::instance();
+	auto& vwrCamera = LLViewerCamera::instanceFast();
 	F32 zoom_factor = vwrCamera.getZoomFactor();
 	S16 sub_region = vwrCamera.getZoomSubRegion();
 	if (zoom_factor > 1.f)
@@ -1238,7 +1238,7 @@ bool get_hud_matrices(const LLRect& screen_region, glh::matrix4f &proj, glh::mat
 {
 	if (isAgentAvatarValid() && gAgentAvatarp->hasHUDAttachment())
 	{
-		auto& vwrCamera = LLViewerCamera::instance();
+		auto& vwrCamera = LLViewerCamera::instanceFast();
 		F32 zoom_level = gAgentCamera.mHUDCurZoom;
 		LLBBox hud_bbox = gAgentAvatarp->getHUDBBox();
 		
@@ -1516,7 +1516,7 @@ void render_ui_2d()
 	//  Menu overlays, HUD, etc
 	gViewerWindow->setup2DRender();
 
-	auto& vwrCamera = LLViewerCamera::instance();
+	auto& vwrCamera = LLViewerCamera::instanceFast();
 	F32 zoom_factor = vwrCamera.getZoomFactor();
 	S16 sub_region = vwrCamera.getZoomSubRegion();
 
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 225c5f8b0006855ebf19a8f5821ba0fdbec96fc6..72169b5284b0b6950e176a6640e7aaa3eb31a1cc 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -3425,7 +3425,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
 			look_at_point = agent_pos + look_at_point.rotVec(gAgent.getQuat());
 
 			static LLVector3 up_direction(0.0f, 0.0f, 1.0f);
-			LLViewerCamera::getInstance()->lookAt(agent_pos, look_at_point, up_direction);
+			LLViewerCamera::getInstanceFast()->lookAt(agent_pos, look_at_point, up_direction);
 		}
 	}
 
@@ -3608,7 +3608,7 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
 	U8		flag_change = 0;
 
 	cam_center_chg = last_camera_pos_agent - camera_pos_agent;
-	cam_rot_chg = last_camera_at - LLViewerCamera::getInstance()->getAtAxis();
+	cam_rot_chg = last_camera_at - LLViewerCamera::getInstanceFast()->getAtAxis();
 
 	// If a modifier key is held down, turn off
 	// LBUTTON and ML_LBUTTON so that using the camera (alt-key) doesn't
@@ -3746,9 +3746,9 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
 //		}
 		
 		msg->addVector3Fast(_PREHASH_CameraCenter, camera_pos_agent);
-		msg->addVector3Fast(_PREHASH_CameraAtAxis, LLViewerCamera::getInstance()->getAtAxis());
-		msg->addVector3Fast(_PREHASH_CameraLeftAxis, LLViewerCamera::getInstance()->getLeftAxis());
-		msg->addVector3Fast(_PREHASH_CameraUpAxis, LLViewerCamera::getInstance()->getUpAxis());
+		msg->addVector3Fast(_PREHASH_CameraAtAxis, LLViewerCamera::getInstanceFast()->getAtAxis());
+		msg->addVector3Fast(_PREHASH_CameraLeftAxis, LLViewerCamera::getInstanceFast()->getLeftAxis());
+		msg->addVector3Fast(_PREHASH_CameraUpAxis, LLViewerCamera::getInstanceFast()->getUpAxis());
 		msg->addF32Fast(_PREHASH_Far, gAgentCamera.mDrawDistance);
 		
 		msg->addU32Fast(_PREHASH_ControlFlags, control_flags);
@@ -3783,9 +3783,9 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
 		last_head_rot = head_rotation;
 		last_render_state = render_state;
 		last_camera_pos_agent = camera_pos_agent;
-		last_camera_at = LLViewerCamera::getInstance()->getAtAxis();
-		last_camera_left = LLViewerCamera::getInstance()->getLeftAxis();
-		last_camera_up = LLViewerCamera::getInstance()->getUpAxis();
+		last_camera_at = LLViewerCamera::getInstanceFast()->getAtAxis();
+		last_camera_left = LLViewerCamera::getInstanceFast()->getLeftAxis();
+		last_camera_up = LLViewerCamera::getInstanceFast()->getUpAxis();
 		last_control_flags = control_flags;
 		last_flags = flags;
 	}
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 90fe11d80b581cd1a0c916e60130b25d4039e119..88c391c0f1637759c8d9231473b8668a54d298f7 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -3702,7 +3702,7 @@ void LLViewerObject::setPixelAreaAndAngle(LLAgent &agent)
 	// I don't think there's a better way to do this without calculating distance per-poly
 	F32 range = sqrt(dx*dx + dy*dy + dz*dz) - min_scale/2;
 
-	LLViewerCamera* camera = LLViewerCamera::getInstance();
+	LLViewerCamera* camera = LLViewerCamera::getInstanceFast();
 	if (range < 0.001f || isHUDAttachment())		// range == zero
 	{
 		mAppAngle = 180.f;
diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index c3ade861b34f29d1c6f2ab14f396379d3bcf292c..b70a28c30914628797f04f303c7e4c634532ee08 100644
--- a/indra/newview/llviewerpartsim.cpp
+++ b/indra/newview/llviewerpartsim.cpp
@@ -281,7 +281,7 @@ void LLViewerPartGroup::updateParticles(const F32 lastdt)
 
 	LLViewerPartSim::checkParticleCount(mParticles.size());
 
-	LLViewerCamera* camera = LLViewerCamera::getInstance();
+	LLViewerCamera* camera = LLViewerCamera::getInstanceFast();
 	LLViewerRegion *regionp = getRegion();
 	S32 end = (S32) mParticles.size();
 	for (S32 i = 0 ; i < (S32)mParticles.size();)
@@ -580,7 +580,7 @@ LLViewerPartGroup *LLViewerPartSim::put(LLViewerPart* part)
 	}
 	else
 	{	
-		LLViewerCamera* camera = LLViewerCamera::getInstance();
+		LLViewerCamera* camera = LLViewerCamera::getInstanceFast();
 		F32 desired_size = calc_desired_size(camera, part->mPosAgent, part->mScale);
 
 		S32 count = (S32) mViewerPartGroups.size();
diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp
index 606e91c7f1ff59581c100fb9cceeeae106c6789d..f20175436c393c275b000d89a79a8d57dc234c8c 100644
--- a/indra/newview/llviewerpartsource.cpp
+++ b/indra/newview/llviewerpartsource.cpp
@@ -215,7 +215,7 @@ void LLViewerPartSourceScript::update(const F32 dt)
 		first_run = TRUE;
 	}
 
-	LLViewerCamera& vwrCamera = LLViewerCamera::instance();
+	LLViewerCamera& vwrCamera = LLViewerCamera::instanceFast();
 
 	F32 max_time = llmax(1.f, 10.f*mPartSysData.mBurstRate);
 	dt_update = llmin(max_time, dt_update);
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 8ad25f8936b0867572f3b7ee24020bbe9e059ef9..8dbefbd84e1f8b3ca9e2f4ede9a5f36a28b12bf9 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1295,7 +1295,7 @@ void LLViewerRegion::updateVisibleEntries(F32 max_time)
 	}
 
 	const F32 LARGE_SCENE_CONTRIBUTION = 1000.f; //a large number to force to load the object.
-	const LLVector3 camera_origin = LLViewerCamera::getInstance()->getOrigin();
+	const LLVector3 camera_origin = LLViewerCamera::getInstanceFast()->getOrigin();
 	const U32 cur_frame = LLViewerOctreeEntryData::getCurrentFrame();
 	bool needs_update = ((cur_frame - mImpl->mLastCameraUpdate) > 5) && ((camera_origin - mImpl->mLastCameraOrigin).lengthSquared() > 10.f);	
 	U32 last_update = mImpl->mLastCameraUpdate;
@@ -1607,9 +1607,9 @@ void LLViewerRegion::killInvisibleObjects(F32 max_time)
 
 	LLTimer update_timer;
 	LLVector4a camera_origin;
-	camera_origin.load3(LLViewerCamera::getInstance()->getOrigin().mV);
+	camera_origin.load3(LLViewerCamera::getInstanceFast()->getOrigin().mV);
 	LLVector4a local_origin;
-	local_origin.load3((LLViewerCamera::getInstance()->getOrigin() - getOriginAgent()).mV);
+	local_origin.load3((LLViewerCamera::getInstanceFast()->getOrigin() - getOriginAgent()).mV);
 	F32 back_threshold = LLVOCacheEntry::sRearFarRadius;
 	
 	size_t max_update = 64; 
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index ddad4387feded1dabaf416302d2109fce7d4481f..a304a26ec08210823fd7e489313a45c333fe2919 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -4160,7 +4160,7 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls,
 			gGL.pushMatrix();
 			gGL.loadIdentity();
 			F32 depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f);
-			gGL.ortho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, depth);
+			gGL.ortho(-0.5f * LLViewerCamera::getInstanceFast()->getAspect(), 0.5f * LLViewerCamera::getInstanceFast()->getAspect(), -0.5f, 0.5f, 0.f, depth);
 			
 			gGL.matrixMode(LLRender::MM_MODELVIEW);
 			gGL.pushMatrix();
@@ -4425,7 +4425,7 @@ LLHUDIcon* LLViewerWindow::cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 dep
 	// world coordinates of mouse
 	// VECTORIZE THIS
 	LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y);
-	LLVector3 mouse_point_global = LLViewerCamera::getInstance()->getOrigin();
+	LLVector3 mouse_point_global = LLViewerCamera::getInstanceFast()->getOrigin();
 	LLVector3 mouse_world_start = mouse_point_global;
 	LLVector3 mouse_world_end   = mouse_point_global + mouse_direction_global * depth;
 
@@ -4465,11 +4465,11 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
 	
 	// world coordinates of mouse
 	LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y);
-	LLVector3 mouse_point_global = LLViewerCamera::getInstance()->getOrigin();
+	LLVector3 mouse_point_global = LLViewerCamera::getInstanceFast()->getOrigin();
 	
 	//get near clip plane
-	LLVector3 n = LLViewerCamera::getInstance()->getAtAxis();
-	LLVector3 p = mouse_point_global + n * LLViewerCamera::getInstance()->getNear();
+	LLVector3 n = LLViewerCamera::getInstanceFast()->getAtAxis();
+	LLVector3 p = mouse_point_global + n * LLViewerCamera::getInstanceFast()->getNear();
 
 	//project mouse point onto plane
 	LLVector3 pos;
@@ -4573,7 +4573,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
 // indicating direction of point on screen x,y
 LLVector3 LLViewerWindow::mouseDirectionGlobal(const S32 x, const S32 y) const
 {
-	auto& viewerCamera = LLViewerCamera::instance();
+	auto& viewerCamera = LLViewerCamera::instanceFast();
 
 	// find vertical field of view
 	F32			fov = viewerCamera.getView();
@@ -4619,7 +4619,7 @@ LLVector3 LLViewerWindow::mousePointHUD(const S32 x, const S32 y) const
 // indicating direction of point on screen x,y
 LLVector3 LLViewerWindow::mouseDirectionCamera(const S32 x, const S32 y) const
 {
-	auto& viewerCamera = LLViewerCamera::instance();
+	auto& viewerCamera = LLViewerCamera::instanceFast();
 
 	// find vertical field of view
 	F32			fov_height = viewerCamera.getView();
@@ -5100,7 +5100,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
 
 	LLRenderTarget scratch_space;
 
-	auto& viewerCamera = LLViewerCamera::instance();
+	auto& viewerCamera = LLViewerCamera::instanceFast();
 
 	F32 scale_factor = 1.0f ;
 	if (!keep_window_aspect || (image_width > window_width) || (image_height > window_height))
@@ -5191,7 +5191,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
 	F32 depth_conversion_factor_1 = (viewerCamera.getFar() + viewerCamera.getNear()) / (2.f * viewerCamera.getFar() * viewerCamera.getNear());
 	F32 depth_conversion_factor_2 = (viewerCamera.getFar() - viewerCamera.getNear()) / (2.f * viewerCamera.getFar() * viewerCamera.getNear());
 
-	gObjectList.generatePickList(*LLViewerCamera::getInstance());
+	gObjectList.generatePickList(LLViewerCamera::instanceFast());
 
 	// Subimages are in fact partial rendering of the final view. This happens when the final view is bigger than the screen.
 	// In most common cases, scale_factor is 1 and there's no more than 1 iteration on x and y
@@ -5512,7 +5512,7 @@ void LLViewerWindow::setup2DViewport(S32 x_offset, S32 y_offset)
 void LLViewerWindow::setup3DRender()
 {
 	// setup perspective camera
-	LLViewerCamera::getInstance()->setPerspective(NOT_FOR_SELECTION, mWorldViewRectRaw.mLeft, mWorldViewRectRaw.mBottom,  mWorldViewRectRaw.getWidth(), mWorldViewRectRaw.getHeight(), FALSE, LLViewerCamera::getInstance()->getNear(), MAX_FAR_CLIP*2.f);
+	LLViewerCamera::getInstanceFast()->setPerspective(NOT_FOR_SELECTION, mWorldViewRectRaw.mLeft, mWorldViewRectRaw.mBottom,  mWorldViewRectRaw.getWidth(), mWorldViewRectRaw.getHeight(), FALSE, LLViewerCamera::getInstanceFast()->getNear(), MAX_FAR_CLIP*2.f);
 	setup3DViewport();
 }
 
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 95bab25c29eb82a26df591c840dec6e4e9b2db12..87ab372e7b0f7732e844143ce00031ca51ff5609 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1494,7 +1494,7 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
     size.setSub(newMax,newMin);
     size.mul(0.5f);
     
-    mPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance());
+    mPixelArea = LLPipeline::calcPixelArea(center, size, LLViewerCamera::instanceFast());
 }
 
 void render_sphere_and_line(const LLVector3& begin_pos, const LLVector3& end_pos, F32 sphere_scale, const LLVector3& occ_color, const LLVector3& visible_color)
@@ -3549,7 +3549,7 @@ void LLVOAvatar::invalidateNameTags()
 // Compute name tag position during idle update
 void LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
 {
-	auto& viewerCamera = LLViewerCamera::instance();
+	auto& viewerCamera = LLViewerCamera::instanceFast();
 	LLQuaternion root_rot = mRoot->getWorldRotation();
 	LLQuaternion inv_root_rot = ~root_rot;
 	LLVector3 pixel_right_vec;
@@ -4232,11 +4232,11 @@ void LLVOAvatar::updateOrientation(LLAgent& agent, F32 speed, F32 delta_time)
 				// make sure fwdDir stays in same general direction as primdir
 				if (gAgent.getFlying())
 				{
-					fwdDir = LLViewerCamera::getInstance()->getAtAxis();
+					fwdDir = LLViewerCamera::getInstanceFast()->getAtAxis();
 				}
 				else
 				{
-					LLVector3 at_axis = LLViewerCamera::getInstance()->getAtAxis();
+					LLVector3 at_axis = LLViewerCamera::getInstanceFast()->getAtAxis();
 					LLVector3 up_vector = gAgent.getReferenceUpVector();
 					at_axis -= up_vector * (at_axis * up_vector);
 					at_axis.normalize();
@@ -4739,7 +4739,7 @@ void LLVOAvatar::updateHeadOffset()
 	// since we only care about Z, just grab one of the eyes
 	LLVector3 midEyePt = mEyeLeftp->getWorldPosition();
 	midEyePt -= mDrawable.notNull() ? mDrawable->getWorldPosition() : mRoot->getWorldPosition();
-	midEyePt.mV[VZ] = llmax(-mPelvisToFoot + LLViewerCamera::getInstance()->getNear(), midEyePt.mV[VZ]);
+	midEyePt.mV[VZ] = llmax(-mPelvisToFoot + LLViewerCamera::getInstanceFast()->getNear(), midEyePt.mV[VZ]);
 
 	if (mDrawable.notNull())
 	{
@@ -5324,7 +5324,7 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel)
 		return 0;
 	}
 
-	auto& camera = LLViewerCamera::instance();
+	auto& camera = LLViewerCamera::instanceFast();
 
 	LLVector3 pos(getRenderPosition()+mImpostorOffset);
 	LLVector3 at = (pos - camera.getOrigin());
@@ -7164,7 +7164,7 @@ void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent)
 	size.setSub(ext[1], ext[0]);
 	size.mul(0.5f);
 
-	mImpostorPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance());
+	mImpostorPixelArea = LLPipeline::calcPixelArea(center, size, LLViewerCamera::instanceFast());
 
 	F32 range = mDrawable->mDistanceWRTCamera;
 
@@ -10493,7 +10493,7 @@ void LLVOAvatar::getImpostorValues(LLVector4a* extents, LLVector3& angle, F32& d
 	extents[0] = ext[0];
 	extents[1] = ext[1];
 
-	auto& vwrCamera = LLViewerCamera::instance();
+	auto& vwrCamera = LLViewerCamera::instanceFast();
 
 	LLVector3 at = vwrCamera.getOrigin()-(getRenderPosition()+mImpostorOffset);
 	distance = at.normalize();
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 3403fdbbb3985cf7da74121e85baa3e8dd178537..b9d7c51436ec36a07761a4652e56394653e4e309 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -350,7 +350,7 @@ BOOL LLVOAvatarSelf::buildSkeletonSelf(const LLAvatarSkeletonInfo *info)
 	mScreenp = new LLViewerJoint("mScreen", NULL);
 	// for now, put screen at origin, as it is only used during special
 	// HUD rendering mode
-	F32 aspect = LLViewerCamera::getInstance()->getAspect();
+	F32 aspect = LLViewerCamera::getInstanceFast()->getAspect();
 	LLVector3 scale(1.f, aspect, 1.f);
 	mScreenp->setScale(scale);
 	// SL-315
@@ -687,7 +687,7 @@ bool LLVOAvatarSelf::updateCharacter(LLAgent &agent)
 	// update screen joint size
 	if (mScreenp)
 	{
-		F32 aspect = LLViewerCamera::getInstance()->getAspect();
+		F32 aspect = LLViewerCamera::getInstanceFast()->getAspect();
 		LLVector3 scale(1.f, aspect, 1.f);
 		mScreenp->setScale(scale);
 		mScreenp->updateWorldMatrixChildren();
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index d1bf50d26c246687a269621b0c1706b73cc48e2c..628fdb55ec4159362614a9a381a18aa5f6d190d3 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -426,7 +426,7 @@ F32 LLVOCacheEntry::getSquaredPixelThreshold(bool is_front)
 	}
 
 	//object projected area threshold
-	F32 pixel_meter_ratio = LLViewerCamera::getInstance()->getPixelMeterRatio();
+	F32 pixel_meter_ratio = LLViewerCamera::getInstanceFast()->getPixelMeterRatio();
 	F32 projection_threshold = pixel_meter_ratio > 0.f ? threshold / pixel_meter_ratio : 0.f;
 	projection_threshold *= projection_threshold;
 
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index 16fe001269f516dce0e32dbaa58a29c926221b20..eba3950b0d9275a47273a0d23af816f492237d0b 100644
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -316,7 +316,7 @@ void LLVOGrass::setPixelAreaAndAngle(LLAgent &agent)
 	mAppAngle = (F32) atan2( max_scale, range) * RAD_TO_DEG;
 
 	// Compute pixels per meter at the given range
-	auto& viewerCamera = LLViewerCamera::instance();
+	auto& viewerCamera = LLViewerCamera::instanceFast();
 	F32 pixels_per_meter = viewerCamera.getViewHeightInPixels() / (tan(viewerCamera.getView()) * range);
 
 	// Assume grass texture is a 5 meter by 5 meter sprite at the grass object's center
@@ -457,7 +457,7 @@ void LLVOGrass::plantBlades()
 		face->mCenterLocal = mPosition + mRegionp->getOriginAgent();
 	}
 
-	auto& viewerCamera = LLViewerCamera::instance();
+	auto& viewerCamera = LLViewerCamera::instanceFast();
 	mDepth = (face->mCenterLocal - viewerCamera.getOrigin())* viewerCamera.getAtAxis();
 	mDrawable->setPosition(face->mCenterLocal);
 	mDrawable->movePartition();
@@ -612,7 +612,7 @@ void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count
 
 	mFaceList.clear();
 
-	LLViewerCamera* camera = LLViewerCamera::getInstance();
+	LLViewerCamera* camera = LLViewerCamera::getInstanceFast();
 	for (LLSpatialGroup::element_iter i = group->getDataBegin(), i_end = group->getDataEnd(); i != i_end; ++i)
 	{
 		LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable();
diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp
index 95264fe77373a3c9db7633431c6b63a8fd4537c0..689705b150bd456b73d9f6f783c0e08f26eb1b31 100644
--- a/indra/newview/llvoground.cpp
+++ b/indra/newview/llvoground.cpp
@@ -115,13 +115,13 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable)
 	//
 	//
 	//
-	LLVector3 at_dir = LLViewerCamera::getInstance()->getAtAxis();
+	LLVector3 at_dir = LLViewerCamera::getInstanceFast()->getAtAxis();
 	at_dir.mV[VZ] = 0.f;
 	if (at_dir.normVec() < 0.01)
 	{
 		// We really don't care, as we're not looking anywhere near the horizon.
 	}
-	LLVector3 left_dir = LLViewerCamera::getInstance()->getLeftAxis();
+	LLVector3 left_dir = LLViewerCamera::getInstanceFast()->getLeftAxis();
 	left_dir.mV[VZ] = 0.f;
 	left_dir.normVec();
 
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index d044c97c155ae5459f09c528a851a911af7a1774..5ef7b15bb1c9154561ef3308cd189761524f1c6f 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -223,7 +223,7 @@ void LLVOPartGroup::setPixelAreaAndAngle(LLAgent &agent)
 {
 	// mPixelArea is calculated during render
 	F32 mid_scale = getMidScale();
-	F32 range = (getRenderPosition()-LLViewerCamera::getInstance()->getOrigin()).length();
+	F32 range = (getRenderPosition()-LLViewerCamera::getInstanceFast()->getOrigin()).length();
 
 	if (range < 0.001f || isHUDAttachment())		// range == zero
 	{
@@ -351,7 +351,7 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
 	F32 tot_area = 0;
 
 	F32 max_area = LLViewerPartSim::getMaxPartCount() * MAX_PARTICLE_AREA_SCALE; 
-	F32 pixel_meter_ratio = LLViewerCamera::getInstance()->getPixelMeterRatio();
+	F32 pixel_meter_ratio = LLViewerCamera::getInstanceFast()->getPixelMeterRatio();
 	pixel_meter_ratio *= pixel_meter_ratio;
 
 	LLViewerPartSim::checkParticleCount(mViewerPartGroupp->mParticles.size()) ;
@@ -724,7 +724,7 @@ void LLVOPartGroup::getGeometry(S32 idx,
 
 	if (!(part.mFlags & LLPartData::LL_PART_EMISSIVE_MASK))
 	{ //not fullbright, needs normal
-		LLVector3 normal = -LLViewerCamera::getInstance()->getXAxis();
+		LLVector3 normal = -LLViewerCamera::getInstanceFast()->getXAxis();
 		*normalsp++   = normal;
 		*normalsp++   = normal;
 		*normalsp++   = normal;
@@ -803,7 +803,7 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co
 
 	mFaceList.clear();
 
-	LLViewerCamera* camera = LLViewerCamera::getInstance();
+	LLViewerCamera* camera = LLViewerCamera::getInstanceFast();
 	for (LLSpatialGroup::element_iter i = group->getDataBegin(), i_end = group->getDataEnd(); i != i_end; ++i)
 	{
 		LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable();
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index 00352abbcc36b700eb7bbb37e889abb02bb1c57c..c5b0b319654a27da417f14f908656f6c86436b9c 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -1047,7 +1047,7 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
 		}
 	}
 
-	const LLVector3 &look_at = LLViewerCamera::getInstance()->getAtAxis();
+	const LLVector3 &look_at = LLViewerCamera::getInstanceFast()->getAtAxis();
 	LLVector3 right = look_at % LLVector3::z_axis;
 	LLVector3 up = right % look_at;
 	right.normalize();
@@ -1223,7 +1223,7 @@ F32 dtClip(const LLVector3& v0, const LLVector3& v1, F32 far_clip2)
 void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
 										 const LLHeavenBody& HB)
 {
-	const LLVector3 &look_at = LLViewerCamera::getInstance()->getAtAxis();
+	const LLVector3 &look_at = LLViewerCamera::getInstanceFast()->getAtAxis();
 	// const F32 water_height = gAgent.getRegion()->getWaterHeight() + 0.001f;
 	// LLWorld::getInstance()->getWaterHeight() + 0.001f;
 
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index fbb8203372b14967345c4e073e4f0fbd78320d4f..d245b4ccc3eca82ed9b63b55091ae8dcb5f278a2 100644
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -418,7 +418,7 @@ void LLVOTree::render(LLAgent &agent)
 
 void LLVOTree::setPixelAreaAndAngle(LLAgent &agent)
 {
-	auto& viewerCamera = LLViewerCamera::instance();
+	auto& viewerCamera = LLViewerCamera::instanceFast();
 
 	LLVector3 center = getPositionAgent();//center of tree.
 	LLVector3 viewer_pos_agent = gAgentCamera.getCameraPositionAgent();
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 8002d7edc091b3f8b357864cd9fa71fd01434a4b..b225408f99bac7edcc6cbd9fea1d914eb887a027 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -760,7 +760,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
 
 	const S32 num_faces = mDrawable->getNumFaces();
 	F32 min_vsize=999999999.f, max_vsize=0.f;
-	LLViewerCamera* camera = LLViewerCamera::getInstance();
+	LLViewerCamera* camera = LLViewerCamera::getInstanceFast();
 	for (S32 i = 0; i < num_faces; i++)
 	{
 		LLFace* face = mDrawable->getFace(i);
@@ -981,7 +981,7 @@ LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline)
 	
 	updateRadius();
 	bool force_update = true; // avoid non-alpha mDistance update being optimized away
-	mDrawable->updateDistance(*LLViewerCamera::getInstance(), force_update);
+	mDrawable->updateDistance(LLViewerCamera::instanceFast(), force_update);
 
 	return mDrawable;
 }
@@ -1461,7 +1461,7 @@ BOOL LLVOVolume::calcLOD()
 	static LLCachedControl<bool> ignore_fov_zoom(gSavedSettings,"IgnoreFOVZoomForLODs");
 	if(!ignore_fov_zoom)
 	{
-		lod_factor *= DEFAULT_FIELD_OF_VIEW / LLViewerCamera::getInstance()->getDefaultFOV();
+		lod_factor *= DEFAULT_FIELD_OF_VIEW / LLViewerCamera::getInstanceFast()->getDefaultFOV();
 	}
 
     mLODAdjustedDistance = distance;
@@ -3377,7 +3377,7 @@ F32 LLVOVolume::getSpotLightPriority() const
 
 void LLVOVolume::updateSpotLightPriority()
 {
-	auto& viewerCamera = LLViewerCamera::instance();
+	auto& viewerCamera = LLViewerCamera::instanceFast();
 
     F32 r = getLightRadius();
 	LLVector3 pos = mDrawable->getPositionAgent();
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index ee0fe77429eb8a1e46eed8b2a65515e7ce5fdeeb..66820743b0d0cfb46a47105c01a7b117e883e318 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -603,7 +603,7 @@ LLVector3 LLWorld::resolveLandNormalGlobal(const LLVector3d &pos_global)
 
 void LLWorld::updateVisibilities()
 {
-	auto& viewerCamera = LLViewerCamera::instance();
+	auto& viewerCamera = LLViewerCamera::instanceFast();
 
 	F32 cur_far_clip = viewerCamera.getFar();
 
@@ -669,7 +669,7 @@ void LLWorld::updateRegions(F32 max_update_time)
 	LLTimer update_timer;
 	mNumOfActiveCachedObjects = 0;
 	
-	if(LLViewerCamera::getInstance()->isChanged())
+	if(LLViewerCamera::getInstanceFast()->isChanged())
 	{
 		LLViewerRegion::sLastCameraUpdated = LLViewerOctreeEntryData::getCurrentFrame() + 1;
 	}
@@ -934,7 +934,7 @@ void LLWorld::updateWaterObjects()
 	S32 rwidth = 256;
 
 	// We only want to fill in water for stuff that's near us, say, within 256 or 512m
-	S32 range = LLViewerCamera::getInstance()->getFar() > 256.f ? 512 : 256;
+	S32 range = LLViewerCamera::getInstanceFast()->getFar() > 256.f ? 512 : 256;
 
 	LLViewerRegion* regionp = gAgent.getRegion();
 	from_region_handle(regionp->getHandle(), &region_x, &region_y);
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index 07dc37a156044fa5086f5ace8ac8eaabab67427a..197eb5588ea2b97ac07428ebd1f427d0877ec5a9 100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -900,7 +900,7 @@ void LLWorldMapView::drawAgents()
 
 void LLWorldMapView::drawFrustum()
 {
-	auto& viewerCamera = LLViewerCamera::instance();
+	auto& viewerCamera = LLViewerCamera::instanceFast();
 
 	// Draw frustum
 	F32 meters_to_pixels = sMapScale/ REGION_WIDTH_METERS;
@@ -928,8 +928,8 @@ void LLWorldMapView::drawFrustum()
 		gGL.begin( LLRender::TRIANGLES  );
 		{
 			// get camera look at and left axes
-			LLVector3 at_axis = LLViewerCamera::instance().getAtAxis();
-			LLVector3 left_axis = LLViewerCamera::instance().getLeftAxis();
+			LLVector3 at_axis = viewerCamera.getAtAxis();
+			LLVector3 left_axis = viewerCamera.getLeftAxis();
 
 			// grab components along XY plane
 			LLVector2 cam_lookat(at_axis.mV[VX], at_axis.mV[VY]);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index c2dda40f40eb77297be05b275f785a0fc5534a3f..faeeb0e5a3afed44395e59ef278c4b40c77bb674 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6117,7 +6117,7 @@ void LLPipeline::setupAvatarLights(bool for_edit)
 	{
 		LLColor4 diffuse(1.f, 1.f, 1.f, 0.f);
 		LLVector4 light_pos_cam(-8.f, 0.25f, 10.f, 0.f);  // w==0 => directional light
-		LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview();
+		LLMatrix4 camera_mat = LLViewerCamera::getInstanceFast()->getModelview();
 		LLMatrix4 camera_rot(camera_mat.getMat3());
 		camera_rot.invert();
 		LLVector4 light_pos = light_pos_cam * camera_rot;
@@ -7862,7 +7862,7 @@ void LLPipeline::renderFinalize()
 // [/RLVa:KB]
     if (LLPipeline::sRenderDeferred)
     {
-		auto& viewerCamera = LLViewerCamera::instance();
+		auto& viewerCamera = LLViewerCamera::instanceFast();
 		bool dof_enabled = (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
                            RenderDepthOfField;
 
@@ -8698,7 +8698,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
 		shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mShadow[4].getWidth(), mShadow[4].getHeight());
 
 		//F32 shadow_offset_error = 1.f + RenderShadowOffsetError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]);
-		F32 shadow_bias_error = RenderShadowBiasError * fabsf(LLViewerCamera::instance().getOrigin().mV[2]) / 3000.f;
+		F32 shadow_bias_error = RenderShadowBiasError * fabsf(LLViewerCamera::getInstanceFast()->getOrigin().mV[2]) / 3000.f;
 		F32 shadow_bias = RenderShadowBias + shadow_bias_error;
 
 		shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_OFFSET, RenderShadowOffset); //*shadow_offset_error);
@@ -8741,7 +8741,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
 
 	if (shader.getUniformLocation(LLShaderMgr::DEFERRED_NEAR_CLIP) > -1)
 	{
-		shader.uniform1f(LLShaderMgr::DEFERRED_NEAR_CLIP, LLViewerCamera::instance().getNear() * 2.f);
+		shader.uniform1f(LLShaderMgr::DEFERRED_NEAR_CLIP, LLViewerCamera::getInstanceFast()->getNear() * 2.f);
 	}
 
 	shader.uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, mTransformedSunDir.mV);
@@ -8803,7 +8803,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
     LLRenderTarget *deferred_depth_target = &mDeferredDepth;
     LLRenderTarget *deferred_light_target = &mDeferredLight;
 
-	LLViewerCamera& camera = LLViewerCamera::instance();
+	LLViewerCamera& camera = LLViewerCamera::instanceFast();
 
     {
         LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED);
@@ -9558,7 +9558,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
         LLCamera camera = camera_in;
         camera.setFar(camera_in.getFar() * 0.75f);
 
-        bool camera_is_underwater = LLViewerCamera::getInstance()->cameraUnderWater();
+        bool camera_is_underwater = LLViewerCamera::getInstanceFast()->cameraUnderWater();
 
         LLPipeline::sReflectionRender = true;
 
@@ -11240,7 +11240,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
 	sShadowRender = true;
 	sImpostorRender = true;
 
-	LLViewerCamera& viewer_camera = LLViewerCamera::instance();
+	LLViewerCamera& viewer_camera = LLViewerCamera::instanceFast();
 
 	{
 		LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_MARK_VISIBLE);