diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 454969b912c626a1155f4aff1810a7ea3c2f0518..21df7f2b2d3a1bd1b3fb5cd217cd8a5af2002793 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -2102,14 +2102,11 @@ void LLVolume::regen()
 	createVolumeFaces();
 }
 
-void LLVolume::genTangents(S32 face, bool mikktspace)
+void LLVolume::genTangents(S32 face)
 {
     // generate legacy tangents for the specified face
-    // if mikktspace is true, only generate tangents if mikktspace tangents are not present (handles the case for non-mesh prims)
-    if (!mikktspace || mVolumeFaces[face].mMikktSpaceTangents == nullptr)
-    {
-        mVolumeFaces[face].createTangents();
-    }
+    llassert(!isMeshAssetLoaded() || mVolumeFaces[face].mTangents != nullptr); // if this is a complete mesh asset, we should already have tangents
+    mVolumeFaces[face].createTangents();
 }
 
 LLVolume::~LLVolume()
@@ -2492,15 +2489,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
             {
                 face.mNormalizedScale.set(1, 1, 1);
             }
-            if (mdl[i].has("NormalizedTranslation"))
-            {
-                face.mNormalizedTranslation.setValue(mdl[i]["NormalizedTranslation"]);
-            }
-            else
-            {
-                face.mNormalizedTranslation.set(1, 1, 1);
-            }
-
+            
 			LLVector4a pos_range;
 			pos_range.setSub(max_pos, min_pos);
 			LLVector2 tc_range2 = max_tc - min_tc;
@@ -2551,17 +2540,16 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
 				}
 			}
 
-#if 0
+#if 0 // keep this code for now in case we decide to add support for on-the-wire tangents
             {
                 if (!tangent.empty())
                 {
-                    face.allocateTangents(face.mNumVertices, true);
+                    face.allocateTangents(face.mNumVertices);
                     U16* t = (U16*)&(tangent[0]);
 
-                    // store incoming tangents in mMikktSpaceTangents
-                    // NOTE: tangents coming from the asset may not be mikkt space, but they should always be used by the CLTF shaders to 
+                    // NOTE: tangents coming from the asset may not be mikkt space, but they should always be used by the GLTF shaders to 
                     // maintain compliance with the GLTF spec
-                    LLVector4a* t_out = face.mMikktSpaceTangents; 
+                    LLVector4a* t_out = face.mTangents; 
 
                     for (U32 j = 0; j < num_verts; ++j)
                     {
@@ -4111,7 +4099,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en
 		{
 			if (tangent_out != NULL) // if the caller wants tangents, we may need to generate them
 			{
-				genTangents(i);
+                genTangents(i);
 			}
 
 			if (isUnique())
@@ -4854,15 +4842,15 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)
 			mTangents = NULL;
 		}
 
-        if (src.mMikktSpaceTangents)
+        if (src.mTangents)
         {
-            allocateTangents(src.mNumVertices, true);
-            LLVector4a::memcpyNonAliased16((F32*)mMikktSpaceTangents, (F32*)src.mMikktSpaceTangents, vert_size);
+            allocateTangents(src.mNumVertices);
+            LLVector4a::memcpyNonAliased16((F32*)mTangents, (F32*)src.mTangents, vert_size);
         }
         else
         {
-            ll_aligned_free_16(mMikktSpaceTangents);
-            mMikktSpaceTangents = nullptr;
+            ll_aligned_free_16(mTangents);
+            mTangents = nullptr;
         }
 
 		if (src.mWeights)
@@ -4909,8 +4897,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)
 
 	mOptimized = src.mOptimized;
     mNormalizedScale = src.mNormalizedScale;
-    mNormalizedTranslation = src.mNormalizedTranslation;
-    
+
 	//delete 
 	return *this;
 }
@@ -4937,8 +4924,6 @@ void LLVolumeFace::freeData()
 	mIndices = NULL;
 	ll_aligned_free_16(mTangents);
 	mTangents = NULL;
-    ll_aligned_free_16(mMikktSpaceTangents);
-    mMikktSpaceTangents = nullptr;
 	ll_aligned_free_16(mWeights);
 	mWeights = NULL;
 
@@ -5060,9 +5045,6 @@ void LLVolumeFace::remap()
     ll_aligned_free_16(mTangents);
     mTangents = NULL;
 
-    ll_aligned_free_16(mMikktSpaceTangents);
-    mMikktSpaceTangents = nullptr;
-
     // Assign new values
     mIndices = remap_indices;
     mPositions = remap_positions;
@@ -5484,10 +5466,10 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
 	llassert(!mOptimized);
 	mOptimized = TRUE;
 
-    if (mMikktSpaceTangents == nullptr && gen_tangents && mNormals && mTexCoords)
-    { // make sure to generate mikkt space tangents for cache optimizing since the index buffer may change
-        allocateTangents(mNumVertices, true);
-
+    if (gen_tangents && mNormals && mTexCoords)
+    { // generate mikkt space tangents before cache optimizing since the index buffer may change
+        // a bit of a hack to do this here, but this function gets called exactly once for the lifetime of a mesh
+        // and is executed on a background thread
         SMikkTSpaceInterface ms;
 
         ms.m_getNumFaces = [](const SMikkTSpaceContext* pContext)
@@ -5573,7 +5555,7 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
             allocateWeights(vert_count);
         }
 
-        allocateTangents(mNumVertices, true);
+        allocateTangents(mNumVertices);
 
         for (int i = 0; i < mNumIndices; ++i)
         {
@@ -5585,7 +5567,7 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
             mNormals[dst_idx].load3(data.n[src_idx].mV);
             mTexCoords[dst_idx] = data.tc[src_idx];
 
-            mMikktSpaceTangents[dst_idx].loadua(data.t[src_idx].mV);
+            mTangents[dst_idx].loadua(data.t[src_idx].mV);
 
             if (mWeights)
             {
@@ -5605,10 +5587,10 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
             mPositions[i].mul(inv_scale);
             mNormals[i].mul(scale);
             mNormals[i].normalize3();
-            F32 w = mMikktSpaceTangents[i].getF32ptr()[3];
-            mMikktSpaceTangents[i].mul(scale);
-            mMikktSpaceTangents[i].normalize3();
-            mMikktSpaceTangents[i].getF32ptr()[3] = w;
+            F32 w = mTangents[i].getF32ptr()[3];
+            mTangents[i].mul(scale);
+            mTangents[i].normalize3();
+            mTangents[i].getF32ptr()[3] = w;
         }
     }
 
@@ -5703,7 +5685,6 @@ void LLVolumeFace::swapData(LLVolumeFace& rhs)
 	llswap(rhs.mPositions, mPositions);
 	llswap(rhs.mNormals, mNormals);
 	llswap(rhs.mTangents, mTangents);
-    llswap(rhs.mMikktSpaceTangents, mMikktSpaceTangents);
 	llswap(rhs.mTexCoords, mTexCoords);
 	llswap(rhs.mIndices,mIndices);
 	llswap(rhs.mNumVertices, mNumVertices);
@@ -6415,7 +6396,6 @@ void LLVolumeFace::createTangents()
 {
     LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
 
-    
     if (!mTangents)
     {
         allocateTangents(mNumVertices);
@@ -6539,11 +6519,10 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con
 	mNumVertices++;	
 }
 
-void LLVolumeFace::allocateTangents(S32 num_verts, bool mikktspace)
+void LLVolumeFace::allocateTangents(S32 num_verts)
 {
-    auto& buff = mikktspace ? mMikktSpaceTangents : mTangents;
-	ll_aligned_free_16(buff);
-	buff = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
+	ll_aligned_free_16(mTangents);
+	mTangents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
 }
 
 void LLVolumeFace::allocateWeights(S32 num_verts)
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index 6ea12c6920fc3b8350f0cd4e0fb97f1b8048c7d5..3aa70343573f8e22028df3b5c82784a6f5c3b996 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -873,7 +873,7 @@ class LLVolumeFace
 	void createTangents();
 	
 	void resizeVertices(S32 num_verts);
-	void allocateTangents(S32 num_verts, bool mikktspace = false);
+	void allocateTangents(S32 num_verts);
 	void allocateWeights(S32 num_verts);
     void allocateJointIndices(S32 num_verts);
 	void resizeIndices(S32 num_indices);
@@ -947,7 +947,6 @@ class LLVolumeFace
 	LLVector4a* mPositions; // Contains vertices, nortmals and texcoords
 	LLVector4a* mNormals; // pointer into mPositions
 	LLVector4a* mTangents;
-    LLVector4a* mMikktSpaceTangents = nullptr; // for GLTF rendering, use mikkt space tangents
 	LLVector2*  mTexCoords; // pointer into mPositions
 
 	// mIndices contains mNumIndices amount of elements.
@@ -984,7 +983,6 @@ class LLVolumeFace
     // when encoding the source mesh into a unit cube
     // used for regenerating tangents
     LLVector3 mNormalizedScale = LLVector3(1,1,1);
-    LLVector3 mNormalizedTranslation;
 
 private:
 	BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE);
@@ -1031,7 +1029,7 @@ class LLVolume : public LLRefCount
 	void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); }
 
 	void regen();
-    void genTangents(S32 face, bool mikktspace = false);
+    void genTangents(S32 face);
 
 	BOOL isConvex() const;
 	BOOL isCap(S32 face);
diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp
index dbb34ab60bae94686d74f38b691c167014ec98d8..73b97cec08f083c7c9544c0178429ce8ba5b9293 100644
--- a/indra/llprimitive/lldaeloader.cpp
+++ b/indra/llprimitive/lldaeloader.cpp
@@ -2581,7 +2581,7 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector<LLModel*>& mo
 			next->mLabel = model_name + (char)((int)'a' + next->mSubmodelID) + lod_suffix[mLod];
 			next->getVolumeFaces() = remainder;
 			next->mNormalizedScale = ret->mNormalizedScale;
-			next->mNormalizedTranslation = ret->mNormalizedTranslation;
+			
 			if ( ret->mMaterialList.size() > LL_SCULPT_MESH_MAX_FACES)
 			{
 				next->mMaterialList.assign(ret->mMaterialList.begin() + LL_SCULPT_MESH_MAX_FACES, ret->mMaterialList.end());
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index a6492f43d462c83cef25c5eb532797c28ac73113..33d52d89bd41231aa90a6c1a14d7e795dbfe194c 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -53,7 +53,6 @@ const int MODEL_NAMES_LENGTH = sizeof(model_names) / sizeof(std::string);
 LLModel::LLModel(LLVolumeParams& params, F32 detail)
 	: LLVolume(params, detail), 
       mNormalizedScale(1,1,1), 
-      mNormalizedTranslation(0,0,0), 
       mPelvisOffset( 0.0f ), 
       mStatus(NO_ERRORS), 
       mSubmodelID(0)
@@ -296,7 +295,7 @@ void LLModel::normalizeVolumeFaces()
 			// the positions to fit within the unit cube.
 			LLVector4a* pos = (LLVector4a*) face.mPositions;
 			LLVector4a* norm = (LLVector4a*) face.mNormals;
-            LLVector4a* t = (LLVector4a*)face.mMikktSpaceTangents;
+            LLVector4a* t = (LLVector4a*)face.mTangents;
 
 			for (U32 j = 0; j < face.mNumVertices; ++j)
 			{
@@ -329,10 +328,10 @@ void LLModel::normalizeVolumeFaces()
 		mNormalizedTranslation.set(trans.getF32ptr());
 		mNormalizedTranslation *= -1.f; 
 
+        // remember normalized scale so original dimensions can be recovered for mesh processing (i.e. tangent generation)
         for (auto& face : mVolumeFaces)
         {
             face.mNormalizedScale = mNormalizedScale;
-            face.mNormalizedTranslation = mNormalizedTranslation;
         }
 	}
 }
@@ -800,10 +799,10 @@ LLSD LLModel::writeModel(
 						}
 					}
 
-#if 0
-                    if (face.mMikktSpaceTangents)
+#if 0 // keep this code for now in case we want to support transporting tangents with mesh assets
+                    if (face.mTangents)
                     { //normals
-                        F32* tangent = face.mMikktSpaceTangents[j].getF32ptr();
+                        F32* tangent = face.mTangents[j].getF32ptr();
 
                         for (U32 k = 0; k < 4; ++k)
                         { //for each component
@@ -848,7 +847,6 @@ LLSD LLModel::writeModel(
 				mdl[model_names[idx]][i]["PositionDomain"]["Min"] = min_pos.getValue();
 				mdl[model_names[idx]][i]["PositionDomain"]["Max"] = max_pos.getValue();
                 mdl[model_names[idx]][i]["NormalizedScale"] = face.mNormalizedScale.getValue();
-                mdl[model_names[idx]][i]["NormalizedTranslation"] = face.mNormalizedTranslation.getValue();
 
 				mdl[model_names[idx]][i]["Position"] = verts;
 				
@@ -857,10 +855,12 @@ LLSD LLModel::writeModel(
 					mdl[model_names[idx]][i]["Normal"] = normals;
 				}
 
-                if (face.mMikktSpaceTangents)
+#if 0 // keep this code for now in case we decide to transport tangents with mesh assets
+                if (face.mTangents)
                 {
                     mdl[model_names[idx]][i]["Tangent"] = tangents;
                 }
+#endif
 
 				if (face.mTexCoords)
 				{
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 01271ddc28106bd92b84048bd3ff2ac97ceec771..f183f490390c0d91dbd26be7b411f17e1147459e 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -10558,17 +10558,6 @@
     <key>Value</key>
     <integer>0</integer>
   </map>
-  <key>RenderUseMikktSpace</key>
-  <map>
-    <key>Comment</key>
-    <string>Use Mikkt Space tangents on GLTF materials.</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>Boolean</string>
-    <key>Value</key>
-    <integer>1</integer>
-  </map>
   <key>RenderUseTriStrips</key>
   <map>
     <key>Comment</key>
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 5de8bda787fb180767c12c478bdd20189534cbe2..b24bc697910c25789493f234ee572732e3593aa3 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -1968,24 +1968,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 			mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount, map_range);
 			F32* tangents = (F32*) tangent.get();
 			
-            LLGLTFMaterial* gltf_mat = tep->getGLTFMaterial();
-            static LLCachedControl<bool> use_mikktspace(gSavedSettings, "RenderUseMikktSpace");
-            bool mikktspace = use_mikktspace && gltf_mat != nullptr;
-
-			mVObjp->getVolume()->genTangents(f, mikktspace);
+            mVObjp->getVolume()->genTangents(f);
 			
 			LLVector4Logical mask;
 			mask.clear();
 			mask.setElement<3>();
 
-            LLVector4a* tbuff = mikktspace ? vf.mMikktSpaceTangents : vf.mTangents;
-            if (tbuff == nullptr)
-            { // non-mesh prims will not have mikktspace tangents
-                tbuff = vf.mTangents;
-            }
-
-			LLVector4a* src = tbuff;
-			LLVector4a* end = tbuff+num_vertices;
+			LLVector4a* src = vf.mTangents;
+			LLVector4a* end = vf.mTangents +num_vertices;
 
 			while (src < end)
 			{
diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
index 076ebd80c23484b25374b17266cb0b3b52948dae..aa3446a3084f766caa955670c4f53b6642179a74 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -1549,7 +1549,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
         {
             new_face.resizeIndices(buf_indices_copied);
             new_face.resizeVertices(buf_positions_copied);
-            new_face.allocateTangents(buf_positions_copied, true);
+            new_face.allocateTangents(buf_positions_copied);
             S32 idx_size = (buf_indices_copied * sizeof(U16) + 0xF) & ~0xF;
             LLVector4a::memcpyNonAliased16((F32*)new_face.mIndices, (F32*)buffer_indices, idx_size);
 
@@ -1839,7 +1839,6 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
                 LLVolumeFace& src = base->getVolumeFace(i);
                 LLVolumeFace& dst = target_model->getVolumeFace(i);
                 dst.mNormalizedScale = src.mNormalizedScale;
-                dst.mNormalizedTranslation = src.mNormalizedTranslation;
             }
 
             S32 model_meshopt_mode = meshopt_mode;