diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index c446132289d76aaeb1c497ac511554e88ec88f97..b5bb11b90c189c42ca499e3576b2d0ded8705dee 100755
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -171,6 +171,8 @@ BOOL	LLPanelFace::postBuild()
 		mTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectTexture, this, _2) );
 		mTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
 		mTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1));
+		mTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) );
+
 		mTextureCtrl->setFollowsTop();
 		mTextureCtrl->setFollowsLeft();
 		mTextureCtrl->setImmediateFilterPermMask(PERM_NONE);
@@ -184,6 +186,8 @@ BOOL	LLPanelFace::postBuild()
 		mShinyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitSpecularTexture, this, _2) );
 		mShinyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelSpecularTexture, this, _2) );
 		mShinyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectSpecularTexture, this, _2) );
+		mShinyTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) );
+		
 		mShinyTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
 		mShinyTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1));
 		mShinyTextureCtrl->setFollowsTop();
@@ -200,6 +204,8 @@ BOOL	LLPanelFace::postBuild()
 		mBumpyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitNormalTexture, this, _2) );
 		mBumpyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelNormalTexture, this, _2) );
 		mBumpyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectNormalTexture, this, _2) );
+		mBumpyTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) );
+
 		mBumpyTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
 		mBumpyTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1));
 		mBumpyTextureCtrl->setFollowsTop();
@@ -832,7 +838,7 @@ void LLPanelFace::updateUI()
 
 			updateAlphaControls();
 			
-			if(texture_ctrl && !texture_ctrl->isPickerShown())
+			if(texture_ctrl)
 			{
 				if (identical_diffuse)
 				{
@@ -892,7 +898,7 @@ void LLPanelFace::updateUI()
 				}
          }
 
-         if (bumpytexture_ctrl && !bumpytexture_ctrl->isPickerShown())
+         if (bumpytexture_ctrl)
          {
 				if (identical_norm && (bumpy == BUMPY_TEXTURE))
 				{
@@ -1796,6 +1802,12 @@ void LLPanelFace::onSelectTexture(const LLSD& data)
 	LLSelectedTEMaterial::setDiffuseAlphaMode(this, getCurrentDiffuseAlphaMode());
 }
 
+void LLPanelFace::onCloseTexturePicker(const LLSD& data)
+{
+	LL_DEBUGS("Materials") << data << LL_ENDL;
+	updateUI();
+}
+
 void LLPanelFace::onCommitSpecularTexture( const LLSD& data )
 {
 	LL_DEBUGS("Materials") << data << LL_ENDL;
@@ -1805,7 +1817,7 @@ void LLPanelFace::onCommitSpecularTexture( const LLSD& data )
 void LLPanelFace::onCommitNormalTexture( const LLSD& data )
 {
 	LL_DEBUGS("Materials") << data << LL_ENDL;
-	sendBump(getCurrentNormalMap().isNull() ? 0 : BUMPY_TEXTURE);
+	sendBump(BUMPY_TEXTURE);
 }
 
 void LLPanelFace::onCancelSpecularTexture(const LLSD& data)
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index c6a53b6aef3d9c016996fed061d0509690fff92d..222f8f3688f971f1776e6c7eb334338e66c2be06 100755
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -132,6 +132,8 @@ protected:
 	void 	onCancelColor(const LLSD& data);
 	void 	onSelectColor(const LLSD& data);
 
+	void 	onCloseTexturePicker(const LLSD& data);
+
 	// Make UI reflect state of currently selected material (refresh)
 	// and UI mode (e.g. editing normal map v diffuse map)
 	//
@@ -298,7 +300,7 @@ private:
 				if (tep)
 				{
 					material_ptr = tep->getMaterialParams();
-					if (!material_ptr.isNull() && !tep->getMaterialID().isNull())
+					if (!material_ptr.isNull())
 					{
 						ret = (material_ptr->*(MaterialGetFunc))();
 					}
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 9badba4143bb3545d61eb219e28b08716d9bacfe..4676f7b251327f250d4a38e73d259559637732d9 100755
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -1040,6 +1040,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
 	mDragCallback(NULL),
 	mDropCallback(NULL),
 	mOnCancelCallback(NULL),
+	mOnCloseCallback(NULL),
 	mOnSelectCallback(NULL),
 	mBorderColor( p.border_color() ),
 	mAllowNoTexture( FALSE ),
@@ -1296,6 +1297,10 @@ void LLTextureCtrl::onFloaterClose()
 
 	if (floaterp)
 	{
+		if (mOnCloseCallback)
+		{
+			mOnCloseCallback(this,LLSD());
+		}
 		floaterp->setOwner(NULL);
 	}
 
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index a7ef1b3f788f722d1c45e7c18657b968fd14efa3..ad79042ef161a86839c5ca83954f71b2301ea844 100755
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -178,7 +178,7 @@ public:
 	void setDropCallback(drag_n_drop_callback cb)	{ mDropCallback = cb; }
 	
 	void setOnCancelCallback(commit_callback_t cb)	{ mOnCancelCallback = cb; }
-	
+	void setOnCloseCallback(commit_callback_t cb)	{ mOnCloseCallback = cb; }
 	void setOnSelectCallback(commit_callback_t cb)	{ mOnSelectCallback = cb; }
 
 	/*
@@ -199,6 +199,7 @@ private:
 	drag_n_drop_callback	 	mDropCallback;
 	commit_callback_t		 	mOnCancelCallback;
 	commit_callback_t		 	mOnSelectCallback;
+	commit_callback_t		 	mOnCloseCallback;
 	texture_selected_callback	mOnTextureSelectedCallback;
 	LLPointer<LLViewerFetchedTexture> mTexturep;
 	LLUIColor				 	mBorderColor;
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 198b13ee066e52ab224ab4195cb152679f4f0276..6c20f638e5e155162eaf7de90b0a1237f26e9085 100755
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -4389,17 +4389,7 @@ S32 LLViewerObject::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID
 							 << ", material " << pMaterialID
 							 << LL_ENDL;
 		retval = LLPrimitive::setTEMaterialID(te, pMaterialID);
-		if (retval)
-		{
-			// Kitty would like to know if this is necessary?
-			// Since we should get a setTEMaterialParams that does it anyway?
-			//
-			setChanged(TEXTURE);
-			if (mDrawable.notNull())
-			{
-				gPipeline.markTextured(mDrawable);
-			}
-		}
+		refreshMaterials();
 	}
 	return retval;
 }
@@ -4414,23 +4404,28 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri
 		return 0;
 	}
 
-		retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams);
-		LL_DEBUGS("Material") << "Changing material params for te " << (S32)te
-							  << ", object " << mID
-			                  << " (" << retval << ")"
-							  << LL_ENDL;
-		setTENormalMap(te, (pMaterialParams) ? pMaterialParams->getNormalID() : LLUUID::null);
-		setTESpecularMap(te, (pMaterialParams) ? pMaterialParams->getSpecularID() : LLUUID::null);
-
-		setChanged(TEXTURE);
-		if (mDrawable.notNull())
-		{
-			gPipeline.markTextured(mDrawable);
-		}
+	retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams);
+	LL_DEBUGS("Material") << "Changing material params for te " << (S32)te
+							<< ", object " << mID
+			               << " (" << retval << ")"
+							<< LL_ENDL;
+	setTENormalMap(te, (pMaterialParams) ? pMaterialParams->getNormalID() : LLUUID::null);
+	setTESpecularMap(te, (pMaterialParams) ? pMaterialParams->getSpecularID() : LLUUID::null);
 
+	refreshMaterials();
 	return retval;
 }
 
+void LLViewerObject::refreshMaterials()
+{
+	setChanged(ALL_CHANGED);
+	if (mDrawable.notNull())
+	{
+		gPipeline.markTextured(mDrawable);
+		gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL);
+		dirtySpatialGroup(TRUE);
+	}
+}
 
 S32 LLViewerObject::setTEScale(const U8 te, const F32 s, const F32 t)
 {
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 932846c211acb7213295f094b9e570cdc12b6fbe..ea0d55cda53828367bc969fc2912923be61e0a45 100755
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -324,6 +324,12 @@ public:
 	/*virtual*/ S32     setTEGlow(const U8 te, const F32 glow);
 	/*virtual*/ S32     setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
 	/*virtual*/ S32		setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams);
+
+	// Used by Materials update functions to properly kick off rebuilds
+	// of VBs etc when materials updates require changes.
+	//
+	void refreshMaterials();
+
 	/*virtual*/	BOOL	setMaterial(const U8 material);
 	virtual		void	setTEImage(const U8 te, LLViewerTexture *imagep); // Not derived from LLPrimitive
 	virtual     void    changeTEImage(S32 index, LLViewerTexture* new_image)  ;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index bd3be5b9cf76b910b0b65da195392c0463fa7ef6..0aa56fcc0f42e9625caf828f76452f7380b05918 100755
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -2002,10 +2002,11 @@ S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
 	{
 		LLMaterialMgr::instance().getTE(getRegion()->getRegionID(), pMaterialID, te, boost::bind(&LLVOVolume::setTEMaterialParamsCallbackTE, getID(), _1, _2, _3));
 
-		setChanged(TEXTURE);
+		setChanged(ALL_CHANGED);
 		if (!mDrawable.isNull())
 		{
 			gPipeline.markTextured(mDrawable);
+			gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL);
 		}
 		mFaceMappingChanged = TRUE;
 	}
@@ -2018,10 +2019,11 @@ S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialPa
 	LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterialParams) ? pMaterialParams->asLLSD() : LLSD("null")) << " res " << res
 							 << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" )
 							 << LL_ENDL;
-	setChanged(TEXTURE);
+	setChanged(ALL_CHANGED);
 	if (!mDrawable.isNull())
 	{
 		gPipeline.markTextured(mDrawable);
+		gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL);
 	}
 	mFaceMappingChanged = TRUE;
 	return TEM_CHANGE_TEXTURE;
@@ -4114,8 +4116,6 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 	LLMaterial* mat = facep->getTextureEntry()->getMaterialParams().get(); 
 	LLMaterialID mat_id = facep->getTextureEntry()->getMaterialID();
 
-	mat = mat_id.isNull() ? NULL : mat;
-
 	bool batchable = false;
 
 	U32 shader_mask = 0xFFFFFFFF; //no shader
@@ -4546,7 +4546,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 						}
 
 						LLMaterial* mat = te->getMaterialParams().get();
-						mat = te->getMaterialID().isNull() ? NULL : mat;
 
 						if (mat && LLPipeline::sRenderDeferred)
 						{
@@ -4766,7 +4765,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 						if (gPipeline.canUseWindLightShadersOnObjects()
 							&& LLPipeline::sRenderBump)
 						{
-							if (LLPipeline::sRenderDeferred && te->getMaterialParams().notNull() && !te->getMaterialID().isNull())
+							if (LLPipeline::sRenderDeferred && te->getMaterialParams().notNull())
 							{
 								LLMaterial* mat = te->getMaterialParams().get();
 								if (mat->getNormalID().notNull())
@@ -5343,8 +5342,6 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
 		
 			LLMaterial* mat = te->getMaterialParams().get();
 
-			mat = te->getMaterialID().isNull() ? NULL : mat;
-
 			bool can_be_shiny = true;
 			if (mat)
 			{
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index c144a07512b7190c140bccae895a162d4a3e4191..05ef8060d41c30c0fbbdf0620bfb8171a0ff98af 100755
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -1724,10 +1724,10 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
 	{
 		return LLDrawPool::POOL_ALPHA;
 	}
-	else if ((te->getBumpmap() || te->getShiny()) && te->getMaterialID().isNull())
+	else if ((te->getBumpmap() || te->getShiny()) && !te->getMaterialParams().isNull())
 	{
 		return LLDrawPool::POOL_BUMP;
-	} else if (!te->getMaterialID().isNull() && !alpha)
+	} else if (!te->getMaterialParams().isNull() && !alpha)
 	{
 		return LLDrawPool::POOL_MATERIALS;
 	}