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() void LLFetchedGLTFMaterial::materialBegin()
{ {
llassert(!mFetching); llassert(!mFetching);

View File

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

View File

@ -5090,11 +5090,10 @@ void LLViewerObject::setNumTEs(const U8 num_tes)
if (base_material && override_material) if (base_material && override_material)
{ {
tep->setGLTFMaterialOverride(new LLGLTFMaterial(*override_material)); tep->setGLTFMaterialOverride(new LLGLTFMaterial(*override_material));
}
LLGLTFMaterial* render_material = new LLFetchedGLTFMaterial(); if (base_material)
*render_material = *base_material; {
render_material->applyOverride(*override_material); initRenderMaterial(i);
tep->setGLTFRenderMaterial(render_material);
} }
} }
} }
@ -5270,6 +5269,9 @@ void LLViewerObject::updateTEMaterialTextures(U8 te)
}); });
} }
getTE(te)->setGLTFMaterial(mat); 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) else if (mat_id.isNull() && mat != nullptr)
{ {
@ -5659,6 +5661,42 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri
return retval; 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) S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_mat)
{ {
LL_PROFILE_ZONE_SCOPED; LL_PROFILE_ZONE_SCOPED;
@ -5692,22 +5730,13 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma
if (retval) if (retval)
{ {
retval = initRenderMaterial(te) | retval;
if (override_mat) 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) for (LLGLTFMaterial::local_tex_map_t::value_type &val : override_mat->mTrackingIdToLocalTexture)
{ {
LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.first, override_mat); LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.first, override_mat);
} }
}
else if (tep->setGLTFRenderMaterial(nullptr))
{
retval = TEM_CHANGE_TEXTURE;
} }
} }
@ -7577,27 +7606,17 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
// the overrides have not changed due to being only texture // the overrides have not changed due to being only texture
// transforms. Re-apply the overrides to the render material here, // transforms. Re-apply the overrides to the render material here,
// if present. // if present.
const LLGLTFMaterial* override_material = tep->getGLTFMaterialOverride(); // Also, sometimes, the material has baked textures, which requires
if (override_material) // 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); LLViewerObject* obj = gObjectList.findObject(obj_id);
if (!obj) { return; } if (!obj) { return; }
LLTextureEntry* tep = obj->getTE(te); obj->initRenderMaterial(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);
}); });
} }
} }
}
// signal to render pipe that render batches must be rebuilt for this object // signal to render pipe that render batches must be rebuilt for this object
if (!new_material) if (!new_material)

View File

@ -392,6 +392,7 @@ public:
/*virtual*/ S32 setTEGlow(const U8 te, const F32 glow); /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
/*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID); /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
/*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams); /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams);
S32 initRenderMaterial(const U8 te);
virtual S32 setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat); virtual S32 setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat);
// Used by Materials update functions to properly kick off rebuilds // Used by Materials update functions to properly kick off rebuilds