summaryrefslogtreecommitdiff
path: root/indra/newview/llvlcomposition.cpp
diff options
context:
space:
mode:
authorCosmic Linden <cosmic@lindenlab.com>2023-10-13 09:58:13 -0700
committerCosmic Linden <cosmic@lindenlab.com>2023-10-13 09:58:13 -0700
commit94d8f669acc57d670000498edf22589f7b178af0 (patch)
treeffe847c2127eda4a0b78ea857feb0907daade01b /indra/newview/llvlcomposition.cpp
parent039116abd4166903005b8de6fa5d64f0fdf75422 (diff)
DRTVWR-592: Add debug options LocalTerrainAssetN. Fix PBR terrain texture flickering
Diffstat (limited to 'indra/newview/llvlcomposition.cpp')
-rw-r--r--indra/newview/llvlcomposition.cpp345
1 files changed, 183 insertions, 162 deletions
diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp
index 815489f753..c4bed85be7 100644
--- a/indra/newview/llvlcomposition.cpp
+++ b/indra/newview/llvlcomposition.cpp
@@ -42,6 +42,8 @@
#include "llviewercontrol.h"
+static const U32 BASE_SIZE = 128;
+
F32 bilinear(const F32 v00, const F32 v01, const F32 v10, const F32 v11, const F32 x_frac, const F32 y_frac)
{
@@ -59,40 +61,40 @@ F32 bilinear(const F32 v00, const F32 v01, const F32 v10, const F32 v11, const F
return result;
}
-
-LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale) :
- LLViewerLayer(width, scale)
+LLTerrainMaterials::LLTerrainMaterials()
{
- mSurfacep = surfacep;
-
- // Load Terrain Textures - Original ones
- setDetailAssetID(0, TERRAIN_DIRT_DETAIL);
- setDetailAssetID(1, TERRAIN_GRASS_DETAIL);
- setDetailAssetID(2, TERRAIN_MOUNTAIN_DETAIL);
- setDetailAssetID(3, TERRAIN_ROCK_DETAIL);
-
- // Initialize the texture matrix to defaults.
- for (S32 i = 0; i < CORNER_COUNT; ++i)
- {
- mStartHeight[i] = gSavedSettings.getF32("TerrainColorStartHeight");
- mHeightRange[i] = gSavedSettings.getF32("TerrainColorHeightRange");
- }
-
for (S32 i = 0; i < ASSET_COUNT; ++i)
{
mMaterialTexturesSet[i] = false;
}
}
-
-LLVLComposition::~LLVLComposition()
+LLTerrainMaterials::~LLTerrainMaterials()
{
}
+BOOL LLTerrainMaterials::generateMaterials()
+{
+ if (texturesReady(TRUE))
+ {
+ return TRUE;
+ }
-void LLVLComposition::setSurface(LLSurface *surfacep)
+ if (materialsReady(TRUE))
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+LLUUID LLTerrainMaterials::getDetailAssetID(S32 asset)
{
- mSurfacep = surfacep;
+ llassert(mDetailTextures[asset] && mDetailMaterials[asset]);
+ // *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[asset]->getID();
}
LLPointer<LLViewerFetchedTexture> fetch_terrain_texture(const LLUUID& id)
@@ -107,126 +109,51 @@ LLPointer<LLViewerFetchedTexture> fetch_terrain_texture(const LLUUID& id)
return tex;
}
-void LLVLComposition::setDetailAssetID(S32 asset, const LLUUID& id)
+void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id)
{
- if(id.isNull())
- {
- return;
- }
// This is terrain texture, but we are not setting it as BOOST_TERRAIN
// since we will be manipulating it later as needed.
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,
- const F32 width, const F32 height)
+BOOL LLTerrainMaterials::useTextures()
{
- if (!mParamsReady)
- {
- // All the parameters haven't been set yet (we haven't gotten the message from the sim)
- return FALSE;
- }
-
- llassert(mSurfacep);
-
- if (!mSurfacep || !mSurfacep->getRegion())
- {
- // We don't always have the region yet here....
- return FALSE;
- }
-
- S32 x_begin, y_begin, x_end, y_end;
+ LL_PROFILE_ZONE_SCOPED;
- x_begin = ll_round( x * mScaleInv );
- y_begin = ll_round( y * mScaleInv );
- x_end = ll_round( (x + width) * mScaleInv );
- y_end = ll_round( (y + width) * mScaleInv );
+ return texturesReady() || !materialsReady();
+}
- if (x_end > mWidth)
- {
- x_end = mWidth;
- }
- if (y_end > mWidth)
+BOOL LLTerrainMaterials::texturesReady(BOOL boost)
+{
+ for (S32 i = 0; i < ASSET_COUNT; i++)
{
- y_end = mWidth;
+ if (!textureReady(mDetailTextures[i], boost))
+ {
+ return FALSE;
+ }
}
+ return TRUE;
+}
- LLVector3d origin_global = from_region_handle(mSurfacep->getRegion()->getHandle());
-
- // For perlin noise generation...
- const F32 slope_squared = 1.5f*1.5f;
- const F32 xyScale = 4.9215f; //0.93284f;
- const F32 zScale = 4; //0.92165f;
- const F32 z_offset = 0.f;
- const F32 noise_magnitude = 2.f; // Degree to which noise modulates composition layer (versus
- // simple height)
-
- const F32 xyScaleInv = (1.f / xyScale);
- const F32 zScaleInv = (1.f / zScale);
-
- const F32 inv_width = 1.f/mWidth;
-
- // OK, for now, just have the composition value equal the height at the point.
- for (S32 j = y_begin; j < y_end; j++)
+BOOL LLTerrainMaterials::materialsReady(BOOL boost)
+{
+ for (S32 i = 0; i < ASSET_COUNT; i++)
{
- for (S32 i = x_begin; i < x_end; i++)
- {
-
- F32 vec[3];
- F32 vec1[3];
- F32 twiddle;
-
- // Bilinearly interpolate the start height and height range of the textures
- F32 start_height = bilinear(mStartHeight[SOUTHWEST],
- mStartHeight[SOUTHEAST],
- mStartHeight[NORTHWEST],
- mStartHeight[NORTHEAST],
- i*inv_width, j*inv_width); // These will be bilinearly interpolated
- F32 height_range = bilinear(mHeightRange[SOUTHWEST],
- mHeightRange[SOUTHEAST],
- mHeightRange[NORTHWEST],
- mHeightRange[NORTHEAST],
- i*inv_width, j*inv_width); // These will be bilinearly interpolated
-
- LLVector3 location(i*mScale, j*mScale, 0.f);
-
- F32 height = mSurfacep->resolveHeightRegion(location) + z_offset;
-
- // Step 0: Measure the exact height at this texel
- vec[0] = (F32)(origin_global.mdV[VX]+location.mV[VX])*xyScaleInv; // Adjust to non-integer lattice
- vec[1] = (F32)(origin_global.mdV[VY]+location.mV[VY])*xyScaleInv;
- vec[2] = height*zScaleInv;
- //
- // Choose material value by adding to the exact height a random value
- //
- vec1[0] = vec[0]*(0.2222222222f);
- vec1[1] = vec[1]*(0.2222222222f);
- vec1[2] = vec[2]*(0.2222222222f);
- twiddle = noise2(vec1)*6.5f; // Low freq component for large divisions
-
- twiddle += turbulence2(vec, 2)*slope_squared; // High frequency component
- twiddle *= noise_magnitude;
-
- F32 scaled_noisy_height = (height + twiddle - start_height) * F32(ASSET_COUNT) / height_range;
-
- scaled_noisy_height = llmax(0.f, scaled_noisy_height);
- scaled_noisy_height = llmin(3.f, scaled_noisy_height);
- *(mDatap + i + j*mWidth) = scaled_noisy_height;
- }
- }
- return TRUE;
+ if (!materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost))
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
}
-static const U32 BASE_SIZE = 128;
-
// Boost the texture loading priority
// Return true when ready to use (i.e. texture is sufficiently loaded)
// static
-BOOL LLVLComposition::textureReady(LLPointer<LLViewerFetchedTexture>& tex, BOOL boost)
+BOOL LLTerrainMaterials::textureReady(LLPointer<LLViewerFetchedTexture>& tex, BOOL boost)
{
llassert(tex.notNull());
@@ -266,9 +193,9 @@ BOOL LLVLComposition::textureReady(LLPointer<LLViewerFetchedTexture>& tex, BOOL
// 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)
+BOOL LLTerrainMaterials::materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, BOOL boost)
{
- if (!mat->isLoaded())
+ if (!mat || !mat->isLoaded())
{
return FALSE;
}
@@ -308,37 +235,140 @@ BOOL LLVLComposition::materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool&
return TRUE;
}
-BOOL LLVLComposition::useTextures()
+
+LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale) :
+ LLTerrainMaterials(),
+ LLViewerLayer(width, scale)
+{
+ // Load Terrain Textures - Original ones
+ setDetailAssetID(0, TERRAIN_DIRT_DETAIL);
+ setDetailAssetID(1, TERRAIN_GRASS_DETAIL);
+ setDetailAssetID(2, TERRAIN_MOUNTAIN_DETAIL);
+ setDetailAssetID(3, TERRAIN_ROCK_DETAIL);
+
+ mSurfacep = surfacep;
+
+ // Initialize the texture matrix to defaults.
+ for (S32 i = 0; i < CORNER_COUNT; ++i)
+ {
+ mStartHeight[i] = gSavedSettings.getF32("TerrainColorStartHeight");
+ mHeightRange[i] = gSavedSettings.getF32("TerrainColorHeightRange");
+ }
+}
+
+
+LLVLComposition::~LLVLComposition()
{
- LL_PROFILE_ZONE_SCOPED;
+ LLTerrainMaterials::~LLTerrainMaterials();
+}
- return texturesReady() || !materialsReady();
+
+void LLVLComposition::setSurface(LLSurface *surfacep)
+{
+ mSurfacep = surfacep;
}
-BOOL LLVLComposition::texturesReady(BOOL boost)
+BOOL LLVLComposition::generateHeights(const F32 x, const F32 y,
+ const F32 width, const F32 height)
{
- for (S32 i = 0; i < ASSET_COUNT; i++)
+ if (!mParamsReady)
{
- if (!textureReady(mDetailTextures[i], boost))
- {
- return FALSE;
- }
+ // All the parameters haven't been set yet (we haven't gotten the message from the sim)
+ return FALSE;
}
- return TRUE;
-}
-BOOL LLVLComposition::materialsReady(BOOL boost)
-{
- for (S32 i = 0; i < ASSET_COUNT; i++)
+ llassert(mSurfacep);
+
+ if (!mSurfacep || !mSurfacep->getRegion())
{
- if (!materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost))
- {
- return FALSE;
- }
- }
- return TRUE;
+ // We don't always have the region yet here....
+ return FALSE;
+ }
+
+ S32 x_begin, y_begin, x_end, y_end;
+
+ x_begin = ll_round( x * mScaleInv );
+ y_begin = ll_round( y * mScaleInv );
+ x_end = ll_round( (x + width) * mScaleInv );
+ y_end = ll_round( (y + width) * mScaleInv );
+
+ if (x_end > mWidth)
+ {
+ x_end = mWidth;
+ }
+ if (y_end > mWidth)
+ {
+ y_end = mWidth;
+ }
+
+ LLVector3d origin_global = from_region_handle(mSurfacep->getRegion()->getHandle());
+
+ // For perlin noise generation...
+ const F32 slope_squared = 1.5f*1.5f;
+ const F32 xyScale = 4.9215f; //0.93284f;
+ const F32 zScale = 4; //0.92165f;
+ const F32 z_offset = 0.f;
+ const F32 noise_magnitude = 2.f; // Degree to which noise modulates composition layer (versus
+ // simple height)
+
+ const F32 xyScaleInv = (1.f / xyScale);
+ const F32 zScaleInv = (1.f / zScale);
+
+ const F32 inv_width = 1.f/mWidth;
+
+ // OK, for now, just have the composition value equal the height at the point.
+ for (S32 j = y_begin; j < y_end; j++)
+ {
+ for (S32 i = x_begin; i < x_end; i++)
+ {
+
+ F32 vec[3];
+ F32 vec1[3];
+ F32 twiddle;
+
+ // Bilinearly interpolate the start height and height range of the textures
+ F32 start_height = bilinear(mStartHeight[SOUTHWEST],
+ mStartHeight[SOUTHEAST],
+ mStartHeight[NORTHWEST],
+ mStartHeight[NORTHEAST],
+ i*inv_width, j*inv_width); // These will be bilinearly interpolated
+ F32 height_range = bilinear(mHeightRange[SOUTHWEST],
+ mHeightRange[SOUTHEAST],
+ mHeightRange[NORTHWEST],
+ mHeightRange[NORTHEAST],
+ i*inv_width, j*inv_width); // These will be bilinearly interpolated
+
+ LLVector3 location(i*mScale, j*mScale, 0.f);
+
+ F32 height = mSurfacep->resolveHeightRegion(location) + z_offset;
+
+ // Step 0: Measure the exact height at this texel
+ vec[0] = (F32)(origin_global.mdV[VX]+location.mV[VX])*xyScaleInv; // Adjust to non-integer lattice
+ vec[1] = (F32)(origin_global.mdV[VY]+location.mV[VY])*xyScaleInv;
+ vec[2] = height*zScaleInv;
+ //
+ // Choose material value by adding to the exact height a random value
+ //
+ vec1[0] = vec[0]*(0.2222222222f);
+ vec1[1] = vec[1]*(0.2222222222f);
+ vec1[2] = vec[2]*(0.2222222222f);
+ twiddle = noise2(vec1)*6.5f; // Low freq component for large divisions
+
+ twiddle += turbulence2(vec, 2)*slope_squared; // High frequency component
+ twiddle *= noise_magnitude;
+
+ F32 scaled_noisy_height = (height + twiddle - start_height) * F32(ASSET_COUNT) / height_range;
+
+ scaled_noisy_height = llmax(0.f, scaled_noisy_height);
+ scaled_noisy_height = llmin(3.f, scaled_noisy_height);
+ *(mDatap + i + j*mWidth) = scaled_noisy_height;
+ }
+ }
+ return TRUE;
}
+LLTerrainMaterials gLocalTerrainMaterials;
+
BOOL LLVLComposition::generateComposition()
{
if (!mParamsReady)
@@ -347,17 +377,7 @@ BOOL LLVLComposition::generateComposition()
return FALSE;
}
- if (texturesReady(TRUE))
- {
- return TRUE;
- }
-
- if (materialsReady(TRUE))
- {
- return TRUE;
- }
-
- return FALSE;
+ return LLTerrainMaterials::generateMaterials();
}
// TODO: Re-evaluate usefulness of this function in the PBR case. There is currently a hack here to treat the material base color like a legacy terrain texture, but I'm not sure if that's useful.
@@ -592,18 +612,19 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
return TRUE;
}
-LLUUID LLVLComposition::getDetailAssetID(S32 corner)
+F32 LLVLComposition::getStartHeight(S32 corner)
{
- 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();
+ return mStartHeight[corner];
}
-F32 LLVLComposition::getStartHeight(S32 corner)
+void LLVLComposition::setDetailAssetID(S32 asset, const LLUUID& id)
{
- return mStartHeight[corner];
+ if (id.isNull())
+ {
+ return;
+ }
+ LLTerrainMaterials::setDetailAssetID(asset, id);
+ mRawImages[asset] = NULL;
}
void LLVLComposition::setStartHeight(S32 corner, const F32 start_height)