secondlife/viewer#2570: Fix baked texture shared between avatars when in PBR material

master
Cosmic Linden 2024-11-11 10:45:47 -08:00 committed by Andrey Kleshchev
parent eb9cb1ab8c
commit 69d7c0f7ef
4 changed files with 62 additions and 33 deletions

View File

@ -222,6 +222,14 @@ void LLFetchedGLTFMaterial::updateTextureTracking()
}
}
void LLFetchedGLTFMaterial::clearFetchedTextures()
{
mBaseColorTexture = nullptr;
mNormalTexture = nullptr;
mMetallicRoughnessTexture = nullptr;
mEmissiveTexture = nullptr;
}
void LLFetchedGLTFMaterial::materialBegin()
{
llassert(!mFetching);

View File

@ -67,6 +67,7 @@ public:
LLPointer<LLViewerFetchedTexture> mNormalTexture;
LLPointer<LLViewerFetchedTexture> mMetallicRoughnessTexture;
LLPointer<LLViewerFetchedTexture> mEmissiveTexture;
void clearFetchedTextures();
std::set<LLTextureEntry*> mTextureEntires;

View File

@ -5090,11 +5090,10 @@ void LLViewerObject::setNumTEs(const U8 num_tes)
if (base_material && override_material)
{
tep->setGLTFMaterialOverride(new LLGLTFMaterial(*override_material));
LLGLTFMaterial* render_material = new LLFetchedGLTFMaterial();
*render_material = *base_material;
render_material->applyOverride(*override_material);
tep->setGLTFRenderMaterial(render_material);
}
if (base_material)
{
initRenderMaterial(i);
}
}
}
@ -5270,6 +5269,9 @@ void LLViewerObject::updateTEMaterialTextures(U8 te)
});
}
getTE(te)->setGLTFMaterial(mat);
initRenderMaterial(te);
mat = (LLFetchedGLTFMaterial*) getTE(te)->getGLTFRenderMaterial();
llassert(mat == nullptr || dynamic_cast<LLFetchedGLTFMaterial*>(getTE(te)->getGLTFRenderMaterial()) != nullptr);
}
else if (mat_id.isNull() && mat != nullptr)
{
@ -5659,6 +5661,42 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri
return retval;
}
// Set render material if there are overrides or if the base material is has a
// baked texture. Otherwise, set it to null.
// If you are setting the material override and not sending an update message,
// you should probably call this function.
S32 LLViewerObject::initRenderMaterial(U8 te)
{
LL_PROFILE_ZONE_SCOPED;
LLTextureEntry* tep = getTE(te);
if (!tep) { return 0; }
const LLFetchedGLTFMaterial* base_material = static_cast<LLFetchedGLTFMaterial*>(tep->getGLTFMaterial());
llassert(base_material);
if (!base_material) { return 0; }
const LLGLTFMaterial* override_material = tep->getGLTFMaterialOverride();
LLFetchedGLTFMaterial* render_material = nullptr;
bool need_render_material = override_material;
if (!need_render_material)
{
for (const LLUUID& texture_id : base_material->mTextureId)
{
if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(texture_id))
{
need_render_material = true;
break;
}
}
}
if (need_render_material)
{
render_material = new LLFetchedGLTFMaterial(*base_material);
if (override_material) { render_material->applyOverride(*override_material); }
render_material->clearFetchedTextures();
}
return tep->setGLTFRenderMaterial(render_material);
}
S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_mat)
{
LL_PROFILE_ZONE_SCOPED;
@ -5692,22 +5730,13 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma
if (retval)
{
retval = initRenderMaterial(te) | retval;
if (override_mat)
{
LLFetchedGLTFMaterial* render_mat = new LLFetchedGLTFMaterial(*src_mat);
render_mat->applyOverride(*override_mat);
tep->setGLTFRenderMaterial(render_mat);
retval = TEM_CHANGE_TEXTURE;
for (LLGLTFMaterial::local_tex_map_t::value_type &val : override_mat->mTrackingIdToLocalTexture)
{
LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.first, override_mat);
}
}
else if (tep->setGLTFRenderMaterial(nullptr))
{
retval = TEM_CHANGE_TEXTURE;
}
}
@ -7577,25 +7606,15 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
// the overrides have not changed due to being only texture
// transforms. Re-apply the overrides to the render material here,
// if present.
const LLGLTFMaterial* override_material = tep->getGLTFMaterialOverride();
if (override_material)
// Also, sometimes, the material has baked textures, which requires
// a copy unique to this object.
// Currently, we do not deduplicate render materials.
new_material->onMaterialComplete([obj_id = getID(), te]()
{
new_material->onMaterialComplete([obj_id = getID(), te]()
{
LLViewerObject* obj = gObjectList.findObject(obj_id);
if (!obj) { return; }
LLTextureEntry* tep = obj->getTE(te);
if (!tep) { return; }
const LLGLTFMaterial* new_material = tep->getGLTFMaterial();
if (!new_material) { return; }
const LLGLTFMaterial* override_material = tep->getGLTFMaterialOverride();
if (!override_material) { return; }
LLGLTFMaterial* render_material = new LLFetchedGLTFMaterial();
*render_material = *new_material;
render_material->applyOverride(*override_material);
tep->setGLTFRenderMaterial(render_material);
});
}
LLViewerObject* obj = gObjectList.findObject(obj_id);
if (!obj) { return; }
obj->initRenderMaterial(te);
});
}
}

View File

@ -392,6 +392,7 @@ 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);
S32 initRenderMaterial(const U8 te);
virtual S32 setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat);
// Used by Materials update functions to properly kick off rebuilds