DRTVWR-592: Render PBR material terrain like legacy, using baseColor texture

master
Cosmic Linden 2023-10-13 09:57:02 -07:00
parent 76bf3390eb
commit 94e824739b
3 changed files with 194 additions and 105 deletions

View File

@ -256,10 +256,31 @@ void LLDrawPoolTerrain::renderFullShader()
// Hack! Get the region that this draw pool is rendering from!
LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
LLVLComposition *compp = regionp->getComposition();
LLViewerTexture *detail_texture0p = compp->mDetailTextures[0];
LLViewerTexture *detail_texture1p = compp->mDetailTextures[1];
LLViewerTexture *detail_texture2p = compp->mDetailTextures[2];
LLViewerTexture *detail_texture3p = compp->mDetailTextures[3];
LLViewerTexture *detail_texture0p;
LLViewerTexture *detail_texture1p;
LLViewerTexture *detail_texture2p;
LLViewerTexture *detail_texture3p;
BOOL use_textures = compp->texturesReady() || !compp->materialsReady();
if (use_textures)
{
detail_texture0p = compp->mDetailTextures[0];
detail_texture1p = compp->mDetailTextures[1];
detail_texture2p = compp->mDetailTextures[2];
detail_texture3p = compp->mDetailTextures[3];
}
else // use materials
{
detail_texture0p = compp->mDetailMaterials[0]->mBaseColorTexture;
detail_texture1p = compp->mDetailMaterials[1]->mBaseColorTexture;
detail_texture2p = compp->mDetailMaterials[2]->mBaseColorTexture;
detail_texture3p = compp->mDetailMaterials[3]->mBaseColorTexture;
LLViewerTexture* blank = LLViewerFetchedTexture::sWhiteImagep;
if (!detail_texture0p) { detail_texture0p = blank; }
if (!detail_texture1p) { detail_texture1p = blank; }
if (!detail_texture2p) { detail_texture2p = blank; }
if (!detail_texture3p) { detail_texture3p = blank; }
}
LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal();
F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale;

View File

@ -34,6 +34,8 @@
#include "lltextureview.h"
#include "llviewertexture.h"
#include "llviewertexturelist.h"
#include "llfetchedgltfmaterial.h"
#include "llgltfmateriallist.h"
#include "llviewerregion.h"
#include "noise.h"
#include "llregionhandle.h" // for from_region_handle
@ -59,8 +61,7 @@ F32 bilinear(const F32 v00, const F32 v01, const F32 v10, const F32 v11, const F
LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale) :
LLViewerLayer(width, scale),
mParamsReady(FALSE)
LLViewerLayer(width, scale)
{
mSurfacep = surfacep;
@ -76,9 +77,11 @@ LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32
mStartHeight[i] = gSavedSettings.getF32("TerrainColorStartHeight");
mHeightRange[i] = gSavedSettings.getF32("TerrainColorHeightRange");
}
mTexScaleX = 16.f;
mTexScaleY = 16.f;
mTexturesLoaded = FALSE;
for (S32 i = 0; i < ASSET_COUNT; ++i)
{
mMaterialTexturesSet[i] = false;
}
}
@ -92,8 +95,19 @@ void LLVLComposition::setSurface(LLSurface *surfacep)
mSurfacep = surfacep;
}
LLPointer<LLViewerFetchedTexture> fetch_terrain_texture(const LLUUID& id)
{
if (id.isNull())
{
return nullptr;
}
void LLVLComposition::setDetailAssetID(S32 corner, const LLUUID& id)
LLPointer<LLViewerFetchedTexture> tex = LLViewerTextureManager::getFetchedTexture(id);
tex->setNoDelete();
return tex;
}
void LLVLComposition::setDetailAssetID(S32 asset, const LLUUID& id)
{
if(id.isNull())
{
@ -101,28 +115,11 @@ void LLVLComposition::setDetailAssetID(S32 corner, const LLUUID& id)
}
// This is terrain texture, but we are not setting it as BOOST_TERRAIN
// since we will be manipulating it later as needed.
mDetailTextures[corner] = LLViewerTextureManager::getFetchedTexture(id);
mDetailTextures[corner]->setNoDelete() ;
mRawImages[corner] = NULL;
// *TODO: Decide if we have textures or materials. Whichever loads first determines the terrain type.
// *TODO: As the material textures are loaded, prevent deletion
mDetailMaterials[corner] = LLGLTFMaterialList::getMaterial(id);
}
void LLVLComposition::setDetailMaterialID(S32 corner, const LLUUID& id)
{
if(id.isNull())
{
mDetailMaterials[corner] = nullptr;
}
else
{
// This is terrain material, but we are not setting it as BOOST_TERRAIN
// since we will be manipulating it later as needed.
mDetailTextures[corner] = LLViewerTextureManager::getFetchedTexture(id);
mDetailTextures[corner]->setNoDelete() ;
mRawImages[corner] = NULL;
}
mDetailTextures[asset] = fetch_terrain_texture(id);
mRawImages[asset] = NULL;
LLPointer<LLFetchedGLTFMaterial>& mat = mDetailMaterials[asset];
mat = gGLTFMaterialList.getMaterial(id);
mMaterialTexturesSet[asset] = false;
}
BOOL LLVLComposition::generateHeights(const F32 x, const F32 y,
@ -228,82 +225,130 @@ static const U32 BASE_SIZE = 128;
// Boost the texture loading priority
// Return true when ready to use (i.e. texture is sufficiently loaded)
bool boost_texture_until_ready(LLPointer<LLViewerFetchedTexture>& tex)
// static
BOOL LLVLComposition::textureReady(LLPointer<LLViewerFetchedTexture>& tex, BOOL boost)
{
if (tex->getDiscardLevel() < 0)
{
tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail
tex->addTextureStats(BASE_SIZE*BASE_SIZE);
return false;
if (boost)
{
tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail
tex->addTextureStats(BASE_SIZE*BASE_SIZE);
}
return FALSE;
}
if ((tex->getDiscardLevel() != 0 &&
(tex->getWidth() < BASE_SIZE ||
tex->getHeight() < BASE_SIZE)))
{
S32 width = tex->getFullWidth();
S32 height = tex->getFullHeight();
S32 min_dim = llmin(width, height);
S32 ddiscard = 0;
while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL)
if (boost)
{
ddiscard++;
min_dim /= 2;
S32 width = tex->getFullWidth();
S32 height = tex->getFullHeight();
S32 min_dim = llmin(width, height);
S32 ddiscard = 0;
while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL)
{
ddiscard++;
min_dim /= 2;
}
tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail
tex->setMinDiscardLevel(ddiscard);
tex->addTextureStats(BASE_SIZE*BASE_SIZE); // priority
}
tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail
tex->setMinDiscardLevel(ddiscard);
tex->addTextureStats(BASE_SIZE*BASE_SIZE); // priority
return false;
return FALSE;
}
return true;
return TRUE;
}
// Boost the loading priority of every known texture in the material
// Return true when ready to use (i.e. material and all textures within are sufficiently loaded)
// static
BOOL LLVLComposition::materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, BOOL boost)
{
if (!mat->isLoaded())
{
return FALSE;
}
// Material is loaded, but textures may not be
if (!textures_set)
{
// *NOTE: These can sometimes be set to to nullptr due to
// updateTEMaterialTextures. For the sake of robustness, we emulate
// that fetching behavior by setting textures of null IDs to nullptr.
mat->mBaseColorTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]);
mat->mNormalTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]);
mat->mMetallicRoughnessTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]);
mat->mEmissiveTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]);
textures_set = true;
return FALSE;
}
if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].notNull() && !textureReady(mat->mBaseColorTexture, boost))
{
return FALSE;
}
if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].notNull() && !textureReady(mat->mNormalTexture, boost))
{
return FALSE;
}
if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].notNull() && !textureReady(mat->mMetallicRoughnessTexture, boost))
{
return FALSE;
}
if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].notNull() && !textureReady(mat->mEmissiveTexture, boost))
{
return FALSE;
}
return TRUE;
}
BOOL LLVLComposition::texturesReady(BOOL boost)
{
for (S32 i = 0; i < ASSET_COUNT; i++)
{
if (!textureReady(mDetailTextures[i], boost))
{
return FALSE;
}
}
return TRUE;
}
BOOL LLVLComposition::materialsReady(BOOL boost)
{
for (S32 i = 0; i < ASSET_COUNT; i++)
{
if (!materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost))
{
return FALSE;
}
}
return TRUE;
}
BOOL LLVLComposition::generateComposition()
{
if (!mParamsReady)
{
// All the parameters haven't been set yet (we haven't gotten the message from the sim)
return FALSE;
}
bool textures_ready = true;
for (S32 i = 0; i < ASSET_COUNT; i++)
{
if (!boost_texture_until_ready(mDetailTextures[i]))
{
textures_ready = false;
break;
}
}
if (textures_ready)
if (texturesReady(TRUE))
{
return TRUE;
}
bool materials_ready = true;
for (S32 i = 0; i < ASSET_COUNT; i++)
{
const LLPointer<LLFetchedGLTFMaterial>& mat = mDetailMaterials[i];
if (!mat.isLoaded() ||
(mat->mBaseColorTexture && !boost_texture_until_ready(mat->mBaseColorTexture)) ||
(mat->mNormalTexture && !boost_texture_until_ready(mat->mNormalTexture)) ||
(mat->mMetallicRoughnessTexture && !boost_texture_until_ready(mat->mMetallicRoughnessTexture)) ||
(mat->mEmissiveTexture && !boost_texture_until_ready(mat->mEmissiveTexture)))
{
materials_ready = false;
break;
}
}
if (materials_ready)
if (materialsReady(TRUE))
{
return TRUE;
}
else
{
return FALSE;
}
return FALSE;
}
BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
@ -323,15 +368,28 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
//
// These have already been validated by generateComposition.
U8* st_data[4];
S32 st_data_size[4]; // for debugging
U8* st_data[ASSET_COUNT];
S32 st_data_size[ASSET_COUNT]; // for debugging
for (S32 i = 0; i < 4; i++)
const bool use_textures = texturesReady();
for (S32 i = 0; i < ASSET_COUNT; i++)
{
if (mRawImages[i].isNull())
{
// Read back a raw image for this discard level, if it exists
S32 min_dim = llmin(mDetailTextures[i]->getFullWidth(), mDetailTextures[i]->getFullHeight());
LLViewerFetchedTexture* tex;
if (use_textures)
{
tex = mDetailTextures[i];
}
else
{
tex = mDetailMaterials[i]->mBaseColorTexture;
if (!tex) { tex = LLViewerFetchedTexture::sWhiteImagep; }
}
S32 min_dim = llmin(tex->getFullWidth(), tex->getFullHeight());
S32 ddiscard = 0;
while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL)
{
@ -339,31 +397,31 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
min_dim /= 2;
}
BOOL delete_raw = (mDetailTextures[i]->reloadRawImage(ddiscard) != NULL) ;
if(mDetailTextures[i]->getRawImageLevel() != ddiscard)//raw iamge is not ready, will enter here again later.
BOOL delete_raw = (tex->reloadRawImage(ddiscard) != NULL) ;
if(tex->getRawImageLevel() != ddiscard)//raw iamge is not ready, will enter here again later.
{
if (mDetailTextures[i]->getFetchPriority() <= 0.0f && !mDetailTextures[i]->hasSavedRawImage())
if (tex->getFetchPriority() <= 0.0f && !tex->hasSavedRawImage())
{
mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_MAP);
mDetailTextures[i]->forceToRefetchTexture(ddiscard);
tex->setBoostLevel(LLGLTexture::BOOST_MAP);
tex->forceToRefetchTexture(ddiscard);
}
if(delete_raw)
{
mDetailTextures[i]->destroyRawImage() ;
tex->destroyRawImage() ;
}
LL_DEBUGS("Terrain") << "cached raw data for terrain detail texture is not ready yet: " << mDetailTextures[i]->getID() << " Discard: " << ddiscard << LL_ENDL;
LL_DEBUGS("Terrain") << "cached raw data for terrain detail texture is not ready yet: " << tex->getID() << " Discard: " << ddiscard << LL_ENDL;
return FALSE;
}
mRawImages[i] = mDetailTextures[i]->getRawImage() ;
mRawImages[i] = tex->getRawImage() ;
if(delete_raw)
{
mDetailTextures[i]->destroyRawImage() ;
tex->destroyRawImage() ;
}
if (mDetailTextures[i]->getWidth(ddiscard) != BASE_SIZE ||
mDetailTextures[i]->getHeight(ddiscard) != BASE_SIZE ||
mDetailTextures[i]->getComponents() != 3)
if (tex->getWidth(ddiscard) != BASE_SIZE ||
tex->getHeight(ddiscard) != BASE_SIZE ||
tex->getComponents() != 3)
{
LLPointer<LLImageRaw> newraw = new LLImageRaw(BASE_SIZE, BASE_SIZE, 3);
newraw->composite(mRawImages[i]);
@ -514,7 +572,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
}
texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin);
for (S32 i = 0; i < 4; i++)
for (S32 i = 0; i < ASSET_COUNT; i++)
{
// Un-boost detatil textures (will get re-boosted if rendering in high detail)
mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_NONE);
@ -526,7 +584,10 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
LLUUID LLVLComposition::getDetailAssetID(S32 corner)
{
llassert(mDetailTextures[corner] && mDetailMaterials[corner] && mDetailTextures[corner]->getID() == mDetailMaterials[corner].getID());
llassert(mDetailTextures[corner] && mDetailMaterials[corner]);
// *HACK: Assume both the the material and texture were fetched in the same
// way using the same UUID. However, we may not know at this point which
// one will load.
return mDetailTextures[corner]->getID();
}

View File

@ -30,6 +30,8 @@
#include "llviewerlayer.h"
#include "llpointer.h"
#include "llimage.h"
class LLSurface;
class LLViewerFetchedTexture;
@ -75,21 +77,26 @@ public:
friend class LLDrawPoolTerrain;
void setParamsReady() { mParamsReady = TRUE; }
BOOL getParamsReady() const { return mParamsReady; }
protected:
BOOL mParamsReady;
LLSurface *mSurfacep;
BOOL mTexturesLoaded;
BOOL texturesReady(BOOL boost = FALSE);
BOOL materialsReady(BOOL boost = FALSE);
protected:
static BOOL textureReady(LLPointer<LLViewerFetchedTexture>& tex, BOOL boost = FALSE);
static BOOL materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, BOOL boost = FALSE);
BOOL mParamsReady = FALSE;
LLSurface *mSurfacep;
// TODO: Set flag to indicate whether the textures or materials loaded first
LLPointer<LLViewerFetchedTexture> mDetailTextures[ASSET_COUNT];
LLPointer<LLImageRaw> mRawImages[ASSET_COUNT];
LLPointer<LLFetchedGLTFMaterial> mDetailMaterials[ASSET_COUNT];
bool mMaterialTexturesSet[ASSET_COUNT];
F32 mStartHeight[CORNER_COUNT];
F32 mHeightRange[CORNER_COUNT];
F32 mTexScaleX;
F32 mTexScaleY;
F32 mTexScaleX = 16.f;
F32 mTexScaleY = 16.f;
};
#endif //LL_LLVLCOMPOSITION_H