diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp
index 17a487b860d3cbeb4b7e5f289e4d3e6f0974a30d..6d872d0763a5ff85acbd75561ef4bca166eb8396 100644
--- a/indra/llrender/llcubemap.cpp
+++ b/indra/llrender/llcubemap.cpp
@@ -40,8 +40,9 @@
 
 #include "llglheaders.h"
 
-const F32 epsilon = 1e-7f;
-const U16 RESOLUTION = 64;
+namespace {
+    const U16 RESOLUTION = 64;
+}
 
 bool LLCubeMap::sUseCubeMaps = true;
 
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 024e886b2d468649f72ae9c37b644052668744a1..90895d0eec3e606b5150f9297d73561be3316d4b 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -2319,7 +2319,11 @@ void LLPanelFace::onCommitMaterialMaskCutoff(LLUICtrl* ctrl, void* userdata)
 void LLPanelFace::onCommitMaterialID(LLUICtrl* ctrl, void* userdata)
 {
 	LLPanelFace* self = static_cast<LLPanelFace*>(userdata);
-	LLSelectedTEMaterial::setMaterialID(self, self->getCurrentMaterialID());
+    LLUUID matID = self->getCurrentMaterialID();
+	LLSelectedTEMaterial::setMaterialID(self, matID);
+
+    // Temporary demo hack - replace the TE entries with those from the Material's LLSD
+    applyMaterialUUID(matID, userdata);
 }
 
 // static
@@ -2559,6 +2563,7 @@ void LLPanelFace::onAlignTexture(void* userdata)
 }
 
 #include "llagent.h"
+#include "llfilesystem.h"
 #include "llviewerassetupload.h"
 #include "llviewermenufile.h"
 #include "llsd.h"
@@ -2569,9 +2574,7 @@ void LLPanelFace::onAlignTexture(void* userdata)
 void LLPanelFace::onSaveMaterial(void* userdata)
 {
     // DRTVWR-559, Q&D material picker - save to inventory goes here
-    LL_DEBUGS("Material") << "saving material to inventory" << LL_ENDL;
-
-    //LLPanelFace* self = static_cast<LLPanelFace*>(userdata);
+    LL_DEBUGS("Material") << "saving render material to inventory" << LL_ENDL;
 
     std::string name = "New Material";
 
@@ -2582,10 +2585,11 @@ void LLPanelFace::onSaveMaterial(void* userdata)
 
     // gen a new uuid for this asset
     LLTransactionID tid;
-    tid.generate();
+    tid.generate();     // timestamp-based randomization + uniquification
     LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
 
-	std::stringstream output;
+    renderMaterialToLLSD(&material_data, new_asset_id, userdata);
+    std::stringstream output;
     LLSDSerialize::toNotation(material_data, output);
 
     //S32 expected_upload_cost = 0;// LLAgentBenefitsMgr::current().getTextureUploadCost();
@@ -2629,6 +2633,120 @@ void LLPanelFace::onSaveMaterial(void* userdata)
 
 }
 
+// Fill an LLSD with data describing the current face's texture settings
+// TODO 2022-05 FUBAR there are both colliding and different data in LLPanelFace vs the TE.  Also, neither one has the diffuse tex settings.
+//              
+void LLPanelFace::renderMaterialToLLSD(LLSD* sd, LLUUID uuid, void* userdata)
+{
+    llassert(userdata != nullptr);
+
+    sd->insert("RenderMaterialUUID",    LLSD(uuid));
+
+    /* pf stuff is probably useless
+    // pull data from the LLPanelFace
+    LLPanelFace* instance = static_cast<LLPanelFace*>(userdata);
+    sd->insert("pfNormalMap",         LLSD(instance->getCurrentNormalMap()));
+    sd->insert("pfSpecularMap",       LLSD(instance->getCurrentSpecularMap()));
+    sd->insert("pfShininess",         LLSD(static_cast<S32>(instance->getCurrentShininess())));
+    sd->insert("pfBumpiness",         LLSD(static_cast<S32>(instance->getCurrentBumpiness())));
+    sd->insert("pfAlphaMode",         LLSD(static_cast<S32>(instance->getCurrentDiffuseAlphaMode())));
+    sd->insert("pfAlphaCutoff",       LLSD(static_cast<S32>(instance->getCurrentAlphaMaskCutoff())));
+    sd->insert("pfEnvIntensity",      LLSD(static_cast<S32>(instance->getCurrentEnvIntensity())));
+    sd->insert("pfGlossiness",        LLSD(static_cast<S32>(instance->getCurrentGlossiness())));
+    sd->insert("pfNormalRotation",    LLSD(instance->getCurrentBumpyRot()));
+    sd->insert("pfNormalScaleU",      LLSD(instance->getCurrentBumpyScaleU()));
+    sd->insert("pfNormalScaleV",      LLSD(instance->getCurrentBumpyScaleV()));
+    sd->insert("pfNormalOffsetU",     LLSD(instance->getCurrentBumpyOffsetU()));
+    sd->insert("pfNormalOffsetV",     LLSD(instance->getCurrentBumpyOffsetV()));
+    sd->insert("pfSpecularRotation",  LLSD(instance->getCurrentShinyRot()));
+    sd->insert("pfSpecularScaleU",    LLSD(instance->getCurrentShinyScaleU()));
+    sd->insert("pfSpecularScaleV",    LLSD(instance->getCurrentShinyScaleV()));
+    sd->insert("pfSpecularOffsetU",   LLSD(instance->getCurrentShinyOffsetU()));
+    sd->insert("pfSpecularOffsetV",   LLSD(instance->getCurrentShinyOffsetV()));
+    sd->insert("pfMaterialID",        LLSD(instance->getCurrentMaterialID()));
+    */
+
+    // now pull same data from the selected TE (same but different. W T F?) 
+    LLMaterialPtr mat = nullptr;
+    bool ident; // ?
+    LLSelectedTEMaterial::getCurrent(mat, ident);
+
+    sd->insert("teMaterialID", LLSD(mat->getMaterialID()));
+
+    sd->insert("teNormalMap", LLSD(mat->getNormalID()));
+    sd->insert("teNormalOffsetX", LLSD(mat->getNormalOffsetX()));
+    sd->insert("teNormalOffsetY", LLSD(mat->getNormalOffsetY()));
+    sd->insert("teNormalRepeatX", LLSD(mat->getNormalRepeatX()));
+    sd->insert("teNormalRepeatY", LLSD(mat->getNormalRepeatY()));
+    sd->insert("teNormalRotation", LLSD(mat->getNormalRotation()));
+
+    sd->insert("teSpecularMap", LLSD(mat->getSpecularID()));
+    LLColor4U color = mat->getSpecularLightColor();
+    sd->insert("teSpecularColorR", LLSD(static_cast<S32>(color.mV[0])));
+    sd->insert("teSpecularColorG", LLSD(static_cast<S32>(color.mV[1])));
+    sd->insert("teSpecularColorB", LLSD(static_cast<S32>(color.mV[2])));
+    sd->insert("teSpecularColorA", LLSD(static_cast<S32>(color.mV[3])));
+    sd->insert("teSpecularExponent", LLSD(static_cast<S32>(mat->getSpecularLightExponent())));
+    sd->insert("teSpecularOffsetX", LLSD(mat->getSpecularOffsetX()));
+    sd->insert("teSpecularOffsetY", LLSD(mat->getSpecularOffsetY()));
+    sd->insert("teSpecularRepeatX", LLSD(mat->getSpecularRepeatX()));
+    sd->insert("teSpecularRepeatY", LLSD(mat->getSpecularRepeatY()));
+    sd->insert("teSpecularRotation", LLSD(mat->getSpecularRotation()));
+
+    sd->insert("teAlphaMode", LLSD(static_cast<S32>(mat->getDiffuseAlphaMode())));
+    sd->insert("teAlphaCutoff", LLSD(static_cast<S32>(mat->getAlphaMaskCutoff())));
+    sd->insert("teEnvIntensity", LLSD(static_cast<S32>(mat->getEnvironmentIntensity())));
+    sd->insert("teShaderMask", LLSD(static_cast<S32>(mat->getShaderMask())));
+}
+
+// Take the individual texture settings from the material and apply to current face & TE
+void LLPanelFace::applyMaterialUUID(LLUUID uuid, void* userdata)
+{
+    llassert(userdata != nullptr);
+    //LLPanelFace* instance = static_cast<LLPanelFace*>(userdata);
+    
+    LLFileSystem material_file(uuid, LLAssetType::AT_MATERIAL, LLFileSystem::READ);
+    S32 bufsize = material_file.getSize();
+    llassert(bufsize > 0);
+    U8* buffer = new U8(bufsize);
+    material_file.read(buffer, bufsize);
+    LLSD* matSD = (LLSD*) buffer;   // static_cast complains here (?)
+
+    llassert(uuid == matSD->get("MaterialUUID").asUUID());      // if not, whoo boy
+
+    LLMaterialPtr mat = nullptr;
+    bool ident; // ?
+    LLSelectedTEMaterial::getCurrent(mat, ident);
+
+    mat->setMaterialID(matSD->get("teMaterialID").asUUID());
+
+    mat->setNormalID(matSD->get("teNormalMap").asUUID());
+    mat->setNormalOffsetX(matSD->get("teNormalOffsetX").asReal());
+    mat->setNormalOffsetY(matSD->get("teNormalOffsetY").asReal());
+    mat->setNormalRepeatX(matSD->get("teNormalRepeatX").asReal());
+    mat->setNormalRepeatY(matSD->get("teNormalRepeatY").asReal());
+    mat->setNormalRotation(matSD->get("teNormalRotation").asReal());
+
+    mat->setSpecularID(matSD->get("teSpecularMap").asUUID());
+    LLColor4U color;
+    color.mV[0] = static_cast<U8>(matSD->get("teSecularColorR").asInteger());
+    color.mV[1] = static_cast<U8>(matSD->get("teSecularColorG").asInteger());
+    color.mV[2] = static_cast<U8>(matSD->get("teSecularColorB").asInteger());
+    color.mV[3] = static_cast<U8>(matSD->get("teSecularColorA").asInteger());
+    mat->setSpecularLightColor(color);
+    mat->setSpecularLightExponent(static_cast<U8>(matSD->get("teSpecularExponent").asInteger()));
+    mat->setSpecularOffsetX(matSD->get("teSpecularOffsetX").asReal());
+    mat->setSpecularOffsetY(matSD->get("teSpecularOffsetY").asReal());
+    mat->setSpecularRepeatX(matSD->get("teSpecularRepeatX").asReal());
+    mat->setSpecularRepeatY(matSD->get("teSpecularRepeatY").asReal());
+    mat->setSpecularRotation(matSD->get("teSpecularRotation").asReal());
+
+    mat->setDiffuseAlphaMode(static_cast<U8>(matSD->get("teAlphaMode").asInteger()));
+    mat->setAlphaMaskCutoff(static_cast<U8>(matSD->get("teAlphaCutoff").asInteger()));
+    mat->setEnvironmentIntensity(static_cast<U8>(matSD->get("teEnvIntensity").asInteger()));
+    //mat->setShaderMask(static_cast<U32>(matSD->get(teShaderMask").asInteger());
+}
+
 
 // TODO: I don't know who put these in or what these are for???
 void LLPanelFace::setMediaURL(const std::string& url)
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index 9282b70b3c3d541dd4ad31ce849db70982ed9c12..2a53b7ff15563860ae55f9431d7b1ac953b78a42 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -205,7 +205,10 @@ class LLPanelFace : public LLPanel
 	static void		onCommitRepeatsPerMeter(	LLUICtrl* ctrl, void* userinfo);
 	static void		onClickAutoFix(void*);
     static void		onAlignTexture(void*);
+
     static void		onSaveMaterial(void*);
+    static void     renderMaterialToLLSD(LLSD* sd, LLUUID uuid, void* userdata);
+    static void     applyMaterialUUID(LLUUID uuid, void*);
 
 	static F32     valueGlow(LLViewerObject* object, S32 face);