summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan "Geenz" Goodman <geenz@geenzo.com>2024-02-23 15:27:29 -0800
committerJonathan "Geenz" Goodman <geenz@geenzo.com>2024-02-23 15:27:29 -0800
commit0d38d1bbd659206454d261193857d6fbb91387fa (patch)
tree046acde9a0a7aca5970f24729df7702bf6450f19
parente68735ad3a6da635a447eb9ed1981e5c360fd2f2 (diff)
parent8415461d2dc21b0e7453860f41bfd955f6e194cd (diff)
Merge remote-tracking branch 'origin/release/materials_featurette' into geenz/mirrors-optimization-pass-1
-rw-r--r--doc/testplans/material_preview.md83
-rw-r--r--doc/testplans/terrain_loading.md4
-rw-r--r--indra/llcommon/indra_constants.cpp2
-rw-r--r--indra/llrender/llrendertarget.cpp27
-rw-r--r--indra/llrender/llrendertarget.h3
-rw-r--r--indra/newview/app_settings/settings.xml15
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl4
-rw-r--r--indra/newview/lldrawpoolterrain.cpp80
-rw-r--r--indra/newview/lldynamictexture.cpp3
-rw-r--r--indra/newview/llfloaterregioninfo.cpp32
-rw-r--r--indra/newview/llfloaterregioninfo.h3
-rw-r--r--indra/newview/llgltfmaterialpreviewmgr.cpp36
-rw-r--r--indra/newview/llgltfmaterialpreviewmgr.h8
-rw-r--r--indra/newview/llpanelface.cpp15
-rw-r--r--indra/newview/llpanelface.h1
-rw-r--r--indra/newview/llselectmgr.cpp3
-rw-r--r--indra/newview/lltexturectrl.cpp36
-rw-r--r--indra/newview/lltexturectrl.h42
-rw-r--r--indra/newview/lltooldraganddrop.cpp220
-rw-r--r--indra/newview/lltooldraganddrop.h5
-rw-r--r--indra/newview/llviewermenu.cpp5
-rwxr-xr-xindra/newview/llviewerregion.cpp28
-rw-r--r--indra/newview/llviewershadermgr.cpp17
-rw-r--r--indra/newview/llviewershadermgr.h1
-rw-r--r--indra/newview/llvlcomposition.cpp130
-rw-r--r--indra/newview/llvlcomposition.h16
-rw-r--r--indra/newview/llvovolume.cpp17
-rw-r--r--indra/newview/pipeline.cpp71
-rw-r--r--indra/newview/pipeline.h2
32 files changed, 686 insertions, 244 deletions
diff --git a/doc/testplans/material_preview.md b/doc/testplans/material_preview.md
new file mode 100644
index 0000000000..6d2768f72a
--- /dev/null
+++ b/doc/testplans/material_preview.md
@@ -0,0 +1,83 @@
+# Material Preview
+
+## Overview
+
+Material preview is a UI feature which displays a lit spherical preview of a PBR material. It can be found in the following UIs:
+
+- The material picker swatch
+ - In the build floater, in the Texture tab, when applying a PBR material
+ - (If the feature is enabled) In the Region/Estate floater, in the Terrain tab, when applying PBR materials to terrain
+- In the floater to select a material from inventory, which can be opened by clicking the material picker swatch
+
+## Known Issues
+
+These are known issues that the current implementation of this feature does not address:
+
+- The material preview in the build floater is a preview of the base material ID only, and ignores other properties on the prim face like material overrides (https://github.com/secondlife/viewer/issues/865)
+- Alpha mask previews as alpha blend (https://github.com/secondlife/viewer/issues/866)
+- Double-sided previews as single-sided (https://github.com/secondlife/viewer/issues/867)
+- Material preview inherits some of its lighting from the current environment, and reflections from the default reflection probe (https://github.com/secondlife/viewer/issues/868)
+
+## General Regression Testing
+
+- Check that the material preview swatch looks OK with different materials selected
+- Check that the material preview swatch runs reasonably well on different systems, especially when the select material from inventory floater is also open
+ - In particular: AMD, MacOS, minimum spec machines
+- Watch out for regressions in rendering caused by opening a floater with a material preview swatch
+
+## Bug Fixes
+
+### Disappearing Objects Fix Test
+
+This test is recommended for verifying that https://github.com/secondlife/viewer-issues/issues/72 is fixed.
+
+#### Symptoms
+
+When the bug occurs, one or more of following types of objects could randomly disappear in the world, permanently until relog:
+
+- Objects
+- Water level in current region
+- Adjacent region/void water
+
+Note: Disappearing objects in reflections have a different root cause and are not covered by the fix.
+
+#### Bug Reproduction Steps
+
+Verify the disappearing objects bug does not reproduce, given the following steps:
+
+- Runtime prerequisites: Material preview swatch may not be available in your viewer or region if this feature is still behind a feature flag. It is safe to enable this feature manually by setting, "UIPreviewMaterial" to True in the advanced settings. The setting will persist for the current session.
+- Region prerequisites: Unknown, but a region with lots of objects in it seems to increase repro rate. The following locations have been known to easily reproduce the bug, as of 2024-02-16:
+ - http://maps.secondlife.com/secondlife/LindenWorld%20B/161/75/47
+ - [secondlife://Aditi/secondlife/Rumpus%20Room%202048/128/128/24](secondlife://Aditi/secondlife/Rumpus%20Room%202048/128/128/24)
+- Right click an object and select, "Edit item"
+- Go to texture tab, select PBR Metallic Roughness from dropdown, and click the button to select material from inventory
+- Ensure "Apply now" is checked in the inventory selection floater
+- Alternate between different materials from the inventory selection floater
+- Look around the world and check for permanently disappeared objects.
+
+### Dynamic Exposure Influence Fix Test
+
+This test is recommended for verifying that https://github.com/secondlife/viewer-issues/issues/72 is fixed.
+
+#### Symptoms
+
+Dynamic exposure in the world could be influenced by the material preview being displayed. If a material preview was being generated in a given frame, then, depending on the current environment, the user would observe an unpleasant flashing effect in the environment:
+
+- The world view could suddenly get darker and then fade back to normal exposure levels
+- The world view could suddenly get brighter and then fade back to normal exposure levels
+
+#### Bug Reproduction Steps
+
+Verify the dynamic exposure influence bug does not reproduce. Test using a few environment presets such as Default Midday, Sunset, and Midnight.
+
+- Right click an object and select, "Edit item"
+- Go to texture tab, select PBR Metallic Roughness from dropdown, and click the button to select material from inventory
+- Alternate between different materials from the inventory selection floater
+
+#### Regression Testing
+
+Dynamic exposure in the world should continue to work correctly. In particular:
+
+- Exposure should fade gradually from high exposure to low exposure and back as needed
+- Exposure should decrease in brighter environments
+- Exposure should increase in darker environments
diff --git a/doc/testplans/terrain_loading.md b/doc/testplans/terrain_loading.md
new file mode 100644
index 0000000000..b84daf6f73
--- /dev/null
+++ b/doc/testplans/terrain_loading.md
@@ -0,0 +1,4 @@
+- Texture terrain should load
+- PBR terrain should load if enabled
+- Related subsystem: A change to the PBR terrain loading system may affect the texture terrain loading system and vice-versa
+- Related subsystem: Minimaps should load if terrain loads (may take longer)
diff --git a/indra/llcommon/indra_constants.cpp b/indra/llcommon/indra_constants.cpp
index 473b3ebdc9..9a0c565b06 100644
--- a/indra/llcommon/indra_constants.cpp
+++ b/indra/llcommon/indra_constants.cpp
@@ -50,7 +50,7 @@ const LLUUID IMG_FIRE ("aca40aa8-44cf-44ca-a0fa-93e1a2986f82"); // dataserver
const LLUUID IMG_FACE_SELECT ("a85ac674-cb75-4af6-9499-df7c5aaf7a28"); // face selector
const LLUUID IMG_DEFAULT_AVATAR ("c228d1cf-4b5d-4ba8-84f4-899a0796aa97"); // dataserver
const LLUUID IMG_INVISIBLE ("3a367d1c-bef1-6d43-7595-e88c1e3aadb3"); // dataserver
-const LLUUID IMG_WHITE ("3a367d1c-bef1-6d43-7595-e88c1e3aadb3"); // dataserver
+const LLUUID IMG_WHITE ("5748decc-f629-461c-9a36-a35a221fe21f"); // dataserver
const LLUUID IMG_EXPLOSION ("68edcf47-ccd7-45b8-9f90-1649d7f12806"); // On dataserver
const LLUUID IMG_EXPLOSION_2 ("21ce046c-83fe-430a-b629-c7660ac78d7c"); // On dataserver
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index 88c48e5166..9cd7527d3e 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -567,4 +567,31 @@ bool LLRenderTarget::isBoundInStack() const
return cur == this;
}
+void LLRenderTarget::swapFBORefs(LLRenderTarget& other)
+{
+ // Must be initialized
+ llassert(mFBO);
+ llassert(other.mFBO);
+ // Must be unbound
+ // *NOTE: mPreviousRT can be non-null even if this target is unbound - presumably for debugging purposes?
+ llassert(sCurFBO != mFBO);
+ llassert(sCurFBO != other.mFBO);
+ llassert(!isBoundInStack());
+ llassert(!other.isBoundInStack());
+
+ // Must be same type
+ llassert(sUseFBO == other.sUseFBO);
+ llassert(mResX == other.mResX);
+ llassert(mResY == other.mResY);
+ llassert(mInternalFormat == other.mInternalFormat);
+ llassert(mTex.size() == other.mTex.size());
+ llassert(mDepth == other.mDepth);
+ llassert(mUseDepth == other.mUseDepth);
+ llassert(mGenerateMipMaps == other.mGenerateMipMaps);
+ llassert(mMipLevels == other.mMipLevels);
+ llassert(mUsage == other.mUsage);
+
+ std::swap(mFBO, other.mFBO);
+ std::swap(mTex, other.mTex);
+}
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index 9fcea35e3d..da401572d1 100644
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -169,6 +169,9 @@ public:
static LLRenderTarget* getCurrentBoundTarget() { return sBoundTarget; }
+ // *HACK
+ void swapFBORefs(LLRenderTarget& other);
+
protected:
U32 mResX;
U32 mResY;
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 7e4058cc6e..6a84f64030 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -8699,7 +8699,7 @@
<key>OctreeAlphaDistanceFactor</key>
<map>
<key>Comment</key>
- <string>Multiplier on alpha object distance for determining octree node size </string>
+ <string>Multiplier on alpha object distance for determining octree node size. First two parameters are currently unused. Third parameter is distance at which to perform detailed alpha sorting.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -8708,7 +8708,7 @@
<array>
<real>0.1</real>
<real>0.0</real>
- <real>0.0</real>
+ <real>64.0</real>
</array>
</map>
@@ -13840,6 +13840,17 @@
<key>Value</key>
<integer>2</integer>
</map>
+ <key>UIPreviewMaterial</key>
+ <map>
+ <key>Comment</key>
+ <string>Whether or not PBR material swatch is enabled</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <real>0</real>
+ </map>
<key>UIResizeBarHeight</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl
index 83b0ba096c..43863dd37a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl
@@ -26,6 +26,7 @@
uniform mat3 normal_matrix;
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
+uniform mat4 modelview_matrix;
in vec3 position;
in vec3 normal;
@@ -35,10 +36,12 @@ in vec2 texcoord0;
out vec3 vary_normal;
out vec4 vertex_color;
out vec2 vary_texcoord0;
+out vec3 vary_position;
void main()
{
//transform vertex
+ vary_position = (modelview_matrix * vec4(position.xyz, 1.0)).xyz;
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl b/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl
index 9ac4ceb37e..eff7221ae7 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl
@@ -28,7 +28,9 @@
out vec4 frag_color;
uniform sampler2D emissiveRect;
+#ifdef USE_LAST_EXPOSURE
uniform sampler2D exposureMap;
+#endif
uniform float dt;
uniform vec2 noiseVec;
@@ -51,10 +53,12 @@ void main()
L /= max_L;
L = pow(L, 2.0);
float s = mix(dynamic_exposure_params.z, dynamic_exposure_params.y, L);
-
+
+#ifdef USE_LAST_EXPOSURE
float prev = texture(exposureMap, vec2(0.5,0.5)).r;
s = mix(prev, s, min(dt*2.0*abs(prev-s), 0.04));
+#endif
frag_color = max(vec4(s, s, s, dt), vec4(0.0));
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl b/indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl
index ea04ce1cae..51d05cd507 100644
--- a/indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl
@@ -32,15 +32,15 @@
out vec4 vertex_color;
in vec4 normal_g[];
-#if HAS_ATTRIBUTE_TANGENT == 1
+#ifdef HAS_ATTRIBUTE_TANGENT
in vec4 tangent_g[];
#endif
-layout(TRIANGLES) in;
-#if HAS_ATTRIBUTE_TANGENT == 1
-layout(LINE_STRIP, max_vertices = 12) out;
+layout(triangles) in;
+#ifdef HAS_ATTRIBUTE_TANGENT
+layout(line_strip, max_vertices = 12) out;
#else
-layout(LINE_STRIP, max_vertices = 6) out;
+layout(line_strip, max_vertices = 6) out;
#endif
void triangle_normal_debug(int i)
@@ -55,7 +55,7 @@ void triangle_normal_debug(int i)
EmitVertex();
EndPrimitive();
-#if HAS_ATTRIBUTE_TANGENT == 1
+#ifdef HAS_ATTRIBUTE_TANGENT
// Tangent
vec4 tangent_color = vec4(0.0, 1.0, 1.0, 1.0);
gl_Position = gl_in[i].gl_Position;
diff --git a/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl b/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl
index d1596b9d2a..b198bc2485 100644
--- a/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl
@@ -26,7 +26,7 @@
in vec3 position;
in vec3 normal;
out vec4 normal_g;
-#if HAS_ATTRIBUTE_TANGENT == 1
+#ifdef HAS_ATTRIBUTE_TANGENT
in vec4 tangent;
out vec4 tangent_g;
#endif
@@ -67,7 +67,7 @@ void main()
gl_Position = projection_matrix * world_pos;
normal_g = get_screen_normal(position.xyz, world_pos, normal.xyz, mat);
-#if HAS_ATTRIBUTE_TANGENT == 1
+#ifdef HAS_ATTRIBUTE_TANGENT
tangent_g = get_screen_normal(position.xyz, world_pos, tangent.xyz, mat);
#endif
}
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index 3a943f27f6..2d198c5b4b 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -125,27 +125,29 @@ void LLDrawPoolTerrain::boostTerrainDetailTextures()
tex->setBoostLevel(level);
tex->addTextureStats(stats);
- LLPointer<LLFetchedGLTFMaterial>& mat = compp->mDetailMaterials[i];
- llassert(mat.notNull());
- if (mat->mBaseColorTexture)
+ LLPointer<LLFetchedGLTFMaterial>& fetched_material = compp->mDetailMaterials[i];
+ if (fetched_material)
{
- mat->mBaseColorTexture->setBoostLevel(level);
- mat->mBaseColorTexture->addTextureStats(stats);
- }
- if (mat->mNormalTexture)
- {
- mat->mNormalTexture->setBoostLevel(level);
- mat->mNormalTexture->addTextureStats(stats);
- }
- if (mat->mMetallicRoughnessTexture)
- {
- mat->mMetallicRoughnessTexture->setBoostLevel(level);
- mat->mMetallicRoughnessTexture->addTextureStats(stats);
- }
- if (mat->mEmissiveTexture)
- {
- mat->mEmissiveTexture->setBoostLevel(level);
- mat->mEmissiveTexture->addTextureStats(stats);
+ if (fetched_material->mBaseColorTexture)
+ {
+ fetched_material->mBaseColorTexture->setBoostLevel(level);
+ fetched_material->mBaseColorTexture->addTextureStats(stats);
+ }
+ if (fetched_material->mNormalTexture)
+ {
+ fetched_material->mNormalTexture->setBoostLevel(level);
+ fetched_material->mNormalTexture->addTextureStats(stats);
+ }
+ if (fetched_material->mMetallicRoughnessTexture)
+ {
+ fetched_material->mMetallicRoughnessTexture->setBoostLevel(level);
+ fetched_material->mMetallicRoughnessTexture->addTextureStats(stats);
+ }
+ if (fetched_material->mEmissiveTexture)
+ {
+ fetched_material->mEmissiveTexture->setBoostLevel(level);
+ fetched_material->mEmissiveTexture->addTextureStats(stats);
+ }
}
}
}
@@ -234,7 +236,7 @@ void LLDrawPoolTerrain::drawLoop()
void LLDrawPoolTerrain::renderFullShader()
{
- const BOOL use_local_materials = gLocalTerrainMaterials.materialsReady(TRUE);
+ const BOOL use_local_materials = gLocalTerrainMaterials.materialsReady(true, false);
// Hack! Get the region that this draw pool is rendering from!
LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
LLVLComposition *compp = regionp->getComposition();
@@ -362,15 +364,26 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials)
// Hack! Get the region that this draw pool is rendering from!
LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
LLVLComposition *compp = regionp->getComposition();
- LLPointer<LLFetchedGLTFMaterial> (*materials)[LLVLComposition::ASSET_COUNT] = &compp->mDetailMaterials;
+ LLPointer<LLFetchedGLTFMaterial> (*fetched_materials)[LLVLComposition::ASSET_COUNT] = &compp->mDetailMaterials;
+
+ constexpr U32 terrain_material_count = LLVLComposition::ASSET_COUNT;
+#ifdef SHOW_ASSERT
+ constexpr U32 shader_material_count = 1 + LLViewerShaderMgr::TERRAIN_DETAIL3_BASE_COLOR - LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR;
+ llassert(shader_material_count == terrain_material_count);
+#endif
if (local_materials)
{
// Override region terrain with the global local override terrain
- materials = &gLocalTerrainMaterials.mDetailMaterials;
+ fetched_materials = &gLocalTerrainMaterials.mDetailMaterials;
}
+ const LLGLTFMaterial* materials[terrain_material_count];
+ for (U32 i = 0; i < terrain_material_count; ++i)
+ {
+ materials[i] = (*fetched_materials)[i].get();
+ if (!materials[i]) { materials[i] = &LLGLTFMaterial::sDefault; }
+ }
- constexpr U32 terrain_material_count = 1 + LLViewerShaderMgr::TERRAIN_DETAIL3_BASE_COLOR - LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR;
S32 detail_basecolor[terrain_material_count];
S32 detail_normal[terrain_material_count];
S32 detail_metalrough[terrain_material_count];
@@ -378,12 +391,19 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials)
for (U32 i = 0; i < terrain_material_count; ++i)
{
- const LLFetchedGLTFMaterial* material = (*materials)[i].get();
+ LLViewerTexture* detail_basecolor_texturep = nullptr;
+ LLViewerTexture* detail_normal_texturep = nullptr;
+ LLViewerTexture* detail_metalrough_texturep = nullptr;
+ LLViewerTexture* detail_emissive_texturep = nullptr;
- LLViewerTexture *detail_basecolor_texturep = material->mBaseColorTexture;
- LLViewerTexture *detail_normal_texturep = material->mNormalTexture;
- LLViewerTexture *detail_metalrough_texturep = material->mMetallicRoughnessTexture;
- LLViewerTexture *detail_emissive_texturep = material->mEmissiveTexture;
+ const LLFetchedGLTFMaterial* fetched_material = (*fetched_materials)[i].get();
+ if (fetched_material)
+ {
+ detail_basecolor_texturep = fetched_material->mBaseColorTexture;
+ detail_normal_texturep = fetched_material->mNormalTexture;
+ detail_metalrough_texturep = fetched_material->mMetallicRoughnessTexture;
+ detail_emissive_texturep = fetched_material->mEmissiveTexture;
+ }
detail_basecolor[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR + i);
if (detail_basecolor_texturep)
@@ -483,7 +503,7 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials)
F32 minimum_alphas[terrain_material_count];
for (U32 i = 0; i < terrain_material_count; ++i)
{
- const LLFetchedGLTFMaterial* material = (*materials)[i].get();
+ const LLGLTFMaterial* material = materials[i];
base_color_factors[i] = material->mBaseColor;
metallic_factors[i] = material->mMetallicFactor;
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index a66c3876fc..24818241ab 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -118,6 +118,8 @@ BOOL LLViewerDynamicTexture::render()
//-----------------------------------------------------------------------------
void LLViewerDynamicTexture::preRender(BOOL clear_depth)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
+
//use the bottom left corner
mOrigin.set(0, 0);
@@ -219,7 +221,6 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
llassert(dynamicTexture->getFullHeight() <= LLPipeline::MAX_BAKE_WIDTH);
glClear(GL_DEPTH_BUFFER_BIT);
- gDepthDirty = TRUE;
gGL.color4f(1,1,1,1);
dynamicTexture->setBoundTarget(&bake_target);
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 2c743d596e..8b335d57d7 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -1441,6 +1441,11 @@ BOOL LLPanelRegionTerrainInfo::postBuild()
mAskedTextureHeights = false;
mConfirmedTextureHeights = false;
+ if (!mRegionChangedSlot.connected())
+ {
+ mRegionChangedSlot = gAgent.addRegionChangedCallback(boost::bind(&LLPanelRegionTerrainInfo::onRegionChanged,this));
+ }
+
refresh();
return LLPanelRegionInfo::postBuild();
@@ -1449,8 +1454,7 @@ BOOL LLPanelRegionTerrainInfo::postBuild()
// virtual
void LLPanelRegionTerrainInfo::refresh()
{
- // For simplicity, require restart
- static BOOL feature_pbr_terrain_enabled = gSavedSettings.getBOOL("RenderTerrainPBREnabled");
+ static LLCachedControl<bool> feature_pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false);
LLTextBox* texture_text = getChild<LLTextBox>("detail_texture_text");
if (texture_text) { texture_text->setVisible(!feature_pbr_terrain_enabled); }
@@ -1512,6 +1516,27 @@ void LLPanelRegionTerrainInfo::onSelectMaterialType()
}
}
+void LLPanelRegionTerrainInfo::onRegionChanged()
+{
+ LLViewerRegion *region = gAgent.getRegion();
+ if (!region) { return; }
+
+ if (region->simulatorFeaturesReceived())
+ {
+ onSimulatorFeaturesReceived(region->getRegionID(), region);
+ }
+ else
+ {
+ // See "RenderTerrainPBREnabled" in LLViewerRegion::setSimulatorFeatures
+ region->setSimulatorFeaturesReceivedCallback(boost::bind(&LLPanelRegionTerrainInfo::onSimulatorFeaturesReceived,this,_1, _2));
+ }
+}
+
+void LLPanelRegionTerrainInfo::onSimulatorFeaturesReceived(const LLUUID& region_id, LLViewerRegion* regionp)
+{
+ refresh();
+}
+
// virtual
bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region)
{
@@ -1568,6 +1593,9 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region)
LL_DEBUGS() << "no region set" << LL_ENDL;
getChild<LLUICtrl>("region_text")->setValue(LLSD(""));
}
+
+ // Update visibility of terrain swatches, etc
+ refresh();
getChildView("download_raw_btn")->setEnabled(owner_or_god);
getChildView("upload_raw_btn")->setEnabled(owner_or_god);
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index 91fd54fcf9..91e1f5b058 100644
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -248,6 +248,8 @@ public:
BOOL postBuild() override;
+ void onRegionChanged();
+ void onSimulatorFeaturesReceived(const LLUUID& region_id, LLViewerRegion* regionp);
bool refreshFromRegion(LLViewerRegion* region) override; // refresh local settings from region update from simulator
void setEnvControls(bool available); // Whether environment settings are available for this region
@@ -271,6 +273,7 @@ protected:
private:
bool mConfirmedTextureHeights;
bool mAskedTextureHeights;
+ boost::signals2::connection mRegionChangedSlot;
};
/////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llgltfmaterialpreviewmgr.cpp b/indra/newview/llgltfmaterialpreviewmgr.cpp
index 53d9d7d0ba..1c39f1ae7d 100644
--- a/indra/newview/llgltfmaterialpreviewmgr.cpp
+++ b/indra/newview/llgltfmaterialpreviewmgr.cpp
@@ -58,6 +58,15 @@ LLGLTFPreviewTexture::MaterialLoadLevels::MaterialLoadLevels()
}
}
+bool LLGLTFPreviewTexture::MaterialLoadLevels::isFullyLoaded()
+{
+ for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
+ {
+ if (levels[i] != FULLY_LOADED) { return false; }
+ }
+ return true;
+}
+
S32& LLGLTFPreviewTexture::MaterialLoadLevels::operator[](size_t i)
{
llassert(i >= 0 && i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT);
@@ -187,17 +196,26 @@ LLPointer<LLGLTFPreviewTexture> LLGLTFPreviewTexture::create(LLPointer<LLFetched
return new LLGLTFPreviewTexture(material, LLPipeline::MAX_BAKE_WIDTH);
}
-void LLGLTFPreviewTexture::preRender(BOOL clear_depth)
+BOOL LLGLTFPreviewTexture::needsRender()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
+ if (!mShouldRender && mBestLoad.isFullyLoaded()) { return false; }
MaterialLoadLevels current_load = get_material_load_levels(*mGLTFMaterial.get());
if (current_load < mBestLoad)
{
mShouldRender = true;
mBestLoad = current_load;
+ return true;
}
+ return false;
+}
+void LLGLTFPreviewTexture::preRender(BOOL clear_depth)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
+
+ llassert(mShouldRender);
if (!mShouldRender) { return; }
LLViewerDynamicTexture::preRender(clear_depth);
@@ -499,9 +517,12 @@ BOOL LLGLTFPreviewTexture::render()
screen.flush();
}
+ // *HACK: Hide mExposureMap from generateExposure
+ gPipeline.mExposureMap.swapFBORefs(gPipeline.mLastExposure);
+
gPipeline.copyScreenSpaceReflections(&screen, &gPipeline.mSceneMap);
gPipeline.generateLuminance(&screen, &gPipeline.mLuminanceMap);
- gPipeline.generateExposure(&gPipeline.mLuminanceMap, &gPipeline.mExposureMap);
+ gPipeline.generateExposure(&gPipeline.mLuminanceMap, &gPipeline.mExposureMap, /*use_history = */ false);
gPipeline.gammaCorrect(&screen, &gPipeline.mPostMap);
LLVertexBuffer::unbind();
gPipeline.generateGlow(&gPipeline.mPostMap);
@@ -509,6 +530,9 @@ BOOL LLGLTFPreviewTexture::render()
gPipeline.renderDoF(&screen, &gPipeline.mPostMap);
gPipeline.applyFXAA(&gPipeline.mPostMap, &screen);
+ // *HACK: Restore mExposureMap (it will be consumed by generateExposure next frame)
+ gPipeline.mExposureMap.swapFBORefs(gPipeline.mLastExposure);
+
// Final render
gDeferredPostNoDoFProgram.bind();
@@ -543,7 +567,6 @@ void LLGLTFPreviewTexture::postRender(BOOL success)
LLViewerDynamicTexture::postRender(success);
}
-// static
LLPointer<LLViewerTexture> LLGLTFMaterialPreviewMgr::getPreview(LLPointer<LLFetchedGLTFMaterial> &material)
{
if (!material)
@@ -551,6 +574,13 @@ LLPointer<LLViewerTexture> LLGLTFMaterialPreviewMgr::getPreview(LLPointer<LLFetc
return nullptr;
}
+ static LLCachedControl<bool> sUIPreviewMaterial(gSavedSettings, "UIPreviewMaterial", false);
+ if (!sUIPreviewMaterial)
+ {
+ fetch_texture_for_ui(material->mBaseColorTexture, material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]);
+ return material->mBaseColorTexture;
+ }
+
if (!is_material_loaded_enough_for_ui(*material))
{
return nullptr;
diff --git a/indra/newview/llgltfmaterialpreviewmgr.h b/indra/newview/llgltfmaterialpreviewmgr.h
index cc40a6f2e2..981c8b0592 100644
--- a/indra/newview/llgltfmaterialpreviewmgr.h
+++ b/indra/newview/llgltfmaterialpreviewmgr.h
@@ -40,7 +40,7 @@ public:
// Width scales with size of material's textures
static LLPointer<LLGLTFPreviewTexture> create(LLPointer<LLFetchedGLTFMaterial> material);
- BOOL needsRender() override { return mNeedsRender; }
+ BOOL needsRender() override;
void preRender(BOOL clear_depth = TRUE) override;
BOOL render() override;
void postRender(BOOL success) override;
@@ -50,15 +50,12 @@ public:
S32 levels[LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT];
MaterialLoadLevels();
-
+ bool isFullyLoaded();
S32& operator[](size_t i);
-
const S32& operator[](size_t i) const;
-
// Less is better
// Returns false if lhs is not strictly less or equal for all levels
bool operator<(const MaterialLoadLevels& other) const;
-
// Less is better
// Returns false if lhs is not strictly greater or equal for all levels
bool operator>(const MaterialLoadLevels& other) const;
@@ -66,7 +63,6 @@ public:
private:
LLPointer<LLFetchedGLTFMaterial> mGLTFMaterial;
- bool mNeedsRender = true;
bool mShouldRender = true;
MaterialLoadLevels mBestLoad;
};
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 753601d98e..4f3b233218 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -227,6 +227,17 @@ LLRender::eTexIndex LLPanelFace::getTextureDropChannel()
return LLRender::eTexIndex(MATTYPE_DIFFUSE);
}
+LLGLTFMaterial::TextureInfo LLPanelFace::getPBRDropChannel()
+{
+ if (mComboMatMedia && mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR)
+ {
+ LLRadioGroup* radio_pbr_type = getChild<LLRadioGroup>("radio_pbr_type");
+ return texture_info_from_pbrtype(radio_pbr_type->getSelectedIndex());
+ }
+
+ return texture_info_from_pbrtype(PBRTYPE_BASE_COLOR);
+}
+
// Things the UI provides...
//
LLUUID LLPanelFace::getCurrentNormalMap() { return getChild<LLTextureCtrl>("bumpytexture control")->getImageAssetID(); }
@@ -4654,7 +4665,8 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te)
LLToolDragAndDrop::dropTextureAllFaces(objectp,
itemp_res,
from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT,
- LLUUID::null);
+ LLUUID::null,
+ false);
}
else // one face
{
@@ -4663,6 +4675,7 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te)
itemp_res,
from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT,
LLUUID::null,
+ false,
0);
}
}
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index 774a32efb4..05860b995f 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -126,6 +126,7 @@ public:
LLRender::eTexIndex getTextureChannelToEdit();
LLRender::eTexIndex getTextureDropChannel();
+ LLGLTFMaterial::TextureInfo getPBRDropChannel();
protected:
void navigateToTitleMedia(const std::string url);
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index c2e3857af0..30e12faca5 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -1879,7 +1879,8 @@ bool LLSelectMgr::selectionSetImage(const LLUUID& imageid)
te,
mItem,
LLToolDragAndDrop::SOURCE_AGENT,
- LLUUID::null);
+ LLUUID::null,
+ false);
}
else // not an inventory item
{
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 0439b0b115..d9001bc16a 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -538,6 +538,8 @@ void LLFloaterTexturePicker::onClose(bool app_quitting)
}
stopUsingPipette();
sLastPickerMode = mModeSelector->getValue().asInteger();
+ // *NOTE: Vertex buffer for sphere preview is still cached
+ mGLTFPreview = nullptr;
}
// virtual
@@ -680,6 +682,10 @@ void LLFloaterTexturePicker::draw()
mGLTFPreview = gGLTFMaterialPreviewMgr.getPreview(mGLTFMaterial);
}
}
+ if (mGLTFPreview)
+ {
+ mGLTFPreview->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+ }
}
else
{
@@ -735,7 +741,7 @@ void LLFloaterTexturePicker::draw()
// If the floater is focused, don't apply its alpha to the texture (STORM-677).
const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
- LLViewerTexture* preview = nullptr;
+ LLViewerTexture* preview;
if (mGLTFMaterial)
{
preview = mGLTFPreview.get();
@@ -743,15 +749,11 @@ void LLFloaterTexturePicker::draw()
else
{
preview = mTexturep.get();
- if (mTexturep)
- {
- // Pump the priority
- mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
- }
}
if( preview )
{
+ preview->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
if( preview->getComponents() == 4 )
{
gl_rect_2d_checkerboard( interior, alpha );
@@ -1760,6 +1762,19 @@ void LLTextureCtrl::setFilterPermissionMasks(PermissionMask mask)
setDnDFilterPermMask(mask);
}
+void LLTextureCtrl::onVisibilityChange(BOOL new_visibility)
+{
+ if (!new_visibility)
+ {
+ // *NOTE: Vertex buffer for sphere preview is still cached
+ mGLTFPreview = nullptr;
+ }
+ else
+ {
+ llassert(!mGLTFPreview);
+ }
+}
+
void LLTextureCtrl::setVisible( BOOL visible )
{
if( !visible )
@@ -2219,6 +2234,10 @@ void LLTextureCtrl::draw()
mGLTFPreview = gGLTFMaterialPreviewMgr.getPreview(mGLTFMaterial);
}
}
+ if (mGLTFPreview)
+ {
+ mGLTFPreview->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+ }
preview = mGLTFPreview;
}
@@ -2257,10 +2276,7 @@ void LLTextureCtrl::draw()
}
gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), preview, UI_VERTEX_COLOR % alpha);
- if (mTexturep)
- {
- mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
- }
+ preview->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
}
else if (!mFallbackImage.isNull())
{
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index 05ea185b1b..f193b0c083 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -148,26 +148,28 @@ public:
// LLView interface
- virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
- virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
- BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
- EAcceptance *accept,
- std::string& tooltip_msg);
- virtual BOOL handleHover(S32 x, S32 y, MASK mask);
- virtual BOOL handleUnicodeCharHere(llwchar uni_char);
-
- virtual void draw();
- virtual void setVisible( BOOL visible );
- virtual void setEnabled( BOOL enabled );
-
- void setValid(BOOL valid);
-
- // LLUICtrl interface
- virtual void clear();
-
- // Takes a UUID, wraps get/setImageAssetID
- virtual void setValue(const LLSD& value);
- virtual LLSD getValue() const;
+ BOOL handleMouseDown(S32 x, S32 y, MASK mask) override;
+ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
+ BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
+ EAcceptance *accept,
+ std::string& tooltip_msg) override;
+ BOOL handleHover(S32 x, S32 y, MASK mask) override;
+ BOOL handleUnicodeCharHere(llwchar uni_char) override;
+
+ void draw() override;
+ void setVisible( BOOL visible ) override;
+ void setEnabled( BOOL enabled ) override;
+
+ void onVisibilityChange(BOOL new_visibility) override;
+
+ void setValid(BOOL valid);
+
+ // LLUICtrl interface
+ void clear() override;
+
+ // Takes a UUID, wraps get/setImageAssetID
+ void setValue(const LLSD& value) override;
+ LLSD getValue() const override;
// LLTextureCtrl interface
void showPicker(BOOL take_focus);
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index e7f96239fd..bfa9386cd4 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -1071,10 +1071,64 @@ BOOL LLToolDragAndDrop::handleDropMaterialProtections(LLViewerObject* hit_obj,
return TRUE;
}
+void set_texture_to_material(LLViewerObject* hit_obj,
+ S32 hit_face,
+ const LLUUID& asset_id,
+ LLGLTFMaterial::TextureInfo drop_channel)
+{
+ LLTextureEntry* te = hit_obj->getTE(hit_face);
+ if (te)
+ {
+ LLPointer<LLGLTFMaterial> material = te->getGLTFMaterialOverride();
+
+ // make a copy to not invalidate existing
+ // material for multiple objects
+ if (material.isNull())
+ {
+ // Start with a material override which does not make any changes
+ material = new LLGLTFMaterial();
+ }
+ else
+ {
+ material = new LLGLTFMaterial(*material);
+ }
+
+ switch (drop_channel)
+ {
+ case LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR:
+ default:
+ {
+ material->setBaseColorId(asset_id);
+ }
+ break;
+
+ case LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS:
+ {
+ material->setOcclusionRoughnessMetallicId(asset_id);
+ }
+ break;
+
+ case LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE:
+ {
+ material->setEmissiveId(asset_id);
+ }
+ break;
+
+ case LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL:
+ {
+ material->setNormalId(asset_id);
+ }
+ break;
+ }
+ LLGLTFMaterialList::queueModify(hit_obj, hit_face, material);
+ }
+}
+
void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj,
LLInventoryItem* item,
LLToolDragAndDrop::ESource source,
- const LLUUID& src_id)
+ const LLUUID& src_id,
+ bool remove_pbr)
{
if (!item)
{
@@ -1091,28 +1145,46 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj,
break;
}
}
- if (!has_non_pbr_faces)
+
+ if (has_non_pbr_faces || remove_pbr)
{
- return;
+ BOOL res = handleDropMaterialProtections(hit_obj, item, source, src_id);
+ if (!res)
+ {
+ return;
+ }
}
LLUUID asset_id = item->getAssetUUID();
- BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id);
- if (!success)
- {
- return;
- }
+
+ // Overrides require textures to be copy and transfer free
+ LLPermissions item_permissions = item->getPermissions();
+ bool allow_adding_to_override = item_permissions.allowOperationBy(PERM_COPY, gAgent.getID());
+ allow_adding_to_override &= item_permissions.allowOperationBy(PERM_TRANSFER, gAgent.getID());
+
LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id);
add(LLStatViewer::EDIT_TEXTURE, 1);
for( S32 face = 0; face < num_faces; face++ )
{
- if (hit_obj->getRenderMaterialID(face).isNull())
+ if (remove_pbr)
+ {
+ hit_obj->setRenderMaterialID(face, LLUUID::null);
+ hit_obj->setTEImage(face, image);
+ dialog_refresh_all();
+ }
+ else if (hit_obj->getRenderMaterialID(face).isNull())
{
- // update viewer side image in anticipation of update from simulator
+ // update viewer side
hit_obj->setTEImage(face, image);
dialog_refresh_all();
}
+ else if (allow_adding_to_override)
+ {
+ set_texture_to_material(hit_obj, face, asset_id, LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR);
+ }
}
+
// send the update to the simulator
+ LLGLTFMaterialList::flushUpdates(nullptr);
hit_obj->sendTEUpdate();
}
@@ -1260,21 +1332,13 @@ void LLToolDragAndDrop::dropMesh(LLViewerObject* hit_obj,
dialog_refresh_all();
}
-/*
-void LLToolDragAndDrop::dropTextureOneFaceAvatar(LLVOAvatar* avatar, S32 hit_face, LLInventoryItem* item)
-{
- if (hit_face == -1) return;
- LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(item->getAssetUUID());
-
- avatar->userSetOptionalTE( hit_face, image);
-}
-*/
void LLToolDragAndDrop::dropTexture(LLViewerObject* hit_obj,
S32 hit_face,
LLInventoryItem* item,
ESource source,
const LLUUID& src_id,
bool all_faces,
+ bool remove_pbr,
S32 tex_channel)
{
LLSelectNode* nodep = nullptr;
@@ -1286,13 +1350,15 @@ void LLToolDragAndDrop::dropTexture(LLViewerObject* hit_obj,
if (all_faces)
{
- dropTextureAllFaces(hit_obj, item, source, src_id);
+ dropTextureAllFaces(hit_obj, item, source, src_id, remove_pbr);
// If user dropped a texture onto face it implies
// applying texture now without cancel, save to selection
if (nodep)
{
uuid_vec_t texture_ids;
+ uuid_vec_t material_ids;
+ gltf_materials_vec_t override_materials;
S32 num_faces = hit_obj->getNumTEs();
for (S32 face = 0; face < num_faces; face++)
{
@@ -1305,13 +1371,35 @@ void LLToolDragAndDrop::dropTexture(LLViewerObject* hit_obj,
{
texture_ids.push_back(LLUUID::null);
}
+
+ // either removed or modified materials
+ if (remove_pbr)
+ {
+ material_ids.push_back(LLUUID::null);
+ }
+ else
+ {
+ material_ids.push_back(hit_obj->getRenderMaterialID(face));
+ }
+
+ LLTextureEntry* te = hit_obj->getTE(hit_face);
+ if (te && !remove_pbr)
+ {
+ override_materials.push_back(te->getGLTFMaterialOverride());
+ }
+ else
+ {
+ override_materials.push_back(nullptr);
+ }
}
+
nodep->saveTextures(texture_ids);
+ nodep->saveGLTFMaterials(material_ids, override_materials);
}
}
else
{
- dropTextureOneFace(hit_obj, hit_face, item, source, src_id);
+ dropTextureOneFace(hit_obj, hit_face, item, source, src_id, remove_pbr, tex_channel);
// If user dropped a texture onto face it implies
// applying texture now without cancel, save to selection
@@ -1331,6 +1419,16 @@ void LLToolDragAndDrop::dropTexture(LLViewerObject* hit_obj,
{
nodep->mSavedTextures[hit_face] = LLUUID::null;
}
+
+ LLTextureEntry* te = hit_obj->getTE(hit_face);
+ if (te && !remove_pbr)
+ {
+ nodep->mSavedGLTFOverrideMaterials[hit_face] = te->getGLTFMaterialOverride();
+ }
+ else
+ {
+ nodep->mSavedGLTFOverrideMaterials[hit_face] = nullptr;
+ }
}
}
}
@@ -1340,6 +1438,7 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
LLInventoryItem* item,
LLToolDragAndDrop::ESource source,
const LLUUID& src_id,
+ bool remove_pbr,
S32 tex_channel)
{
if (hit_face == -1) return;
@@ -1348,21 +1447,44 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
LL_WARNS() << "LLToolDragAndDrop::dropTextureOneFace no texture item." << LL_ENDL;
return;
}
- if (hit_obj->getRenderMaterialID(hit_face).notNull())
+
+ LLUUID asset_id = item->getAssetUUID();
+
+ if (hit_obj->getRenderMaterialID(hit_face).notNull() && !remove_pbr)
{
+ // Overrides require textures to be copy and transfer free
+ LLPermissions item_permissions = item->getPermissions();
+ bool allow_adding_to_override = item_permissions.allowOperationBy(PERM_COPY, gAgent.getID());
+ allow_adding_to_override &= item_permissions.allowOperationBy(PERM_TRANSFER, gAgent.getID());
+
+ if (allow_adding_to_override)
+ {
+ LLGLTFMaterial::TextureInfo drop_channel = LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR;
+ LLPanelFace* panel_face = gFloaterTools->getPanelFace();
+ if (gFloaterTools->getVisible() && panel_face)
+ {
+ drop_channel = panel_face->getPBRDropChannel();
+ }
+ set_texture_to_material(hit_obj, hit_face, asset_id, drop_channel);
+ LLGLTFMaterialList::flushUpdates(nullptr);
+ }
return;
}
- LLUUID asset_id = item->getAssetUUID();
BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id);
if (!success)
{
return;
}
+ if (remove_pbr)
+ {
+ hit_obj->setRenderMaterialID(hit_face, LLUUID::null);
+ }
+
// update viewer side image in anticipation of update from simulator
LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id);
add(LLStatViewer::EDIT_TEXTURE, 1);
- LLTextureEntry* tep = hit_obj ? (hit_obj->getTE(hit_face)) : NULL;
+ LLTextureEntry* tep = hit_obj->getTE(hit_face);
LLPanelFace* panel_face = gFloaterTools->getPanelFace();
@@ -1380,6 +1502,7 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
break;
case 1:
+ if (tep)
{
LLMaterialPtr old_mat = tep->getMaterialParams();
LLMaterialPtr new_mat = panel_face->createDefaultMaterial(old_mat);
@@ -1391,6 +1514,7 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
break;
case 2:
+ if (tep)
{
LLMaterialPtr old_mat = tep->getMaterialParams();
LLMaterialPtr new_mat = panel_face->createDefaultMaterial(old_mat);
@@ -2200,6 +2324,7 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject(
LLViewerInventoryCategory* cat;
locateInventory(item, cat);
if (!item || !item->isFinished()) return ACCEPT_NO;
+ LLPermissions item_permissions = item->getPermissions();
EAcceptance rv = willObjectAcceptInventory(obj, item);
if((mask & MASK_CONTROL))
{
@@ -2214,12 +2339,12 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject(
return ACCEPT_NO_LOCKED;
}
- if (cargo_type == DAD_TEXTURE)
+ if (cargo_type == DAD_TEXTURE && (mask & MASK_ALT) == 0)
{
+ bool has_non_pbr_faces = false;
if ((mask & MASK_SHIFT))
{
S32 num_faces = obj->getNumTEs();
- bool has_non_pbr_faces = false;
for (S32 face = 0; face < num_faces; face++)
{
if (obj->getRenderMaterialID(face).isNull())
@@ -2228,14 +2353,19 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject(
break;
}
}
- if (!has_non_pbr_faces)
- {
- return ACCEPT_NO;
- }
}
- else if (obj->getRenderMaterialID(face).notNull())
+ else
+ {
+ has_non_pbr_faces = obj->getRenderMaterialID(face).isNull();
+ }
+
+ if (!has_non_pbr_faces)
{
- return ACCEPT_NO;
+ // Only pbr faces selected, texture will be added to an override
+ // Overrides require textures to be copy and transfer free
+ bool allow_adding_to_override = item_permissions.allowOperationBy(PERM_COPY, gAgent.getID());
+ allow_adding_to_override &= item_permissions.allowOperationBy(PERM_TRANSFER, gAgent.getID());
+ if (!allow_adding_to_override) return ACCEPT_NO;
}
}
@@ -2244,15 +2374,16 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject(
if (cargo_type == DAD_TEXTURE)
{
bool all_faces = mask & MASK_SHIFT;
- if (item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
+ bool remove_pbr = mask & MASK_ALT;
+ if (item_permissions.allowOperationBy(PERM_COPY, gAgent.getID()))
{
- dropTexture(obj, face, item, mSource, mSourceID, all_faces);
+ dropTexture(obj, face, item, mSource, mSourceID, all_faces, remove_pbr);
}
else
{
ESource source = mSource;
LLUUID source_id = mSourceID;
- LLNotificationsUtil::add("ApplyInventoryToObject", LLSD(), LLSD(), [obj, face, item, source, source_id, all_faces](const LLSD& notification, const LLSD& response)
+ LLNotificationsUtil::add("ApplyInventoryToObject", LLSD(), LLSD(), [obj, face, item, source, source_id, all_faces, remove_pbr](const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
// if Cancel pressed
@@ -2260,7 +2391,7 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject(
{
return;
}
- dropTexture(obj, face, item, source, source_id, all_faces);
+ dropTexture(obj, face, item, source, source_id, all_faces, remove_pbr);
});
}
}
@@ -2327,23 +2458,6 @@ EAcceptance LLToolDragAndDrop::dad3dMeshObject(
return dad3dApplyToObject(obj, face, mask, drop, DAD_MESH);
}
-
-/*
-EAcceptance LLToolDragAndDrop::dad3dTextureSelf(
- LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
-{
- LL_DEBUGS() << "LLToolDragAndDrop::dad3dTextureAvatar()" << LL_ENDL;
- if(drop)
- {
- if( !(mask & MASK_SHIFT) )
- {
- dropTextureOneFaceAvatar( (LLVOAvatar*)obj, face, (LLInventoryItem*)mCargoData);
- }
- }
- return (mask & MASK_SHIFT) ? ACCEPT_NO : ACCEPT_YES_SINGLE;
-}
-*/
-
EAcceptance LLToolDragAndDrop::dad3dWearItem(
LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
{
diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h
index 7bdd2d1a49..db2fe87f20 100644
--- a/indra/newview/lltooldraganddrop.h
+++ b/indra/newview/lltooldraganddrop.h
@@ -249,17 +249,20 @@ public:
ESource source,
const LLUUID& src_id,
bool all_faces,
+ bool replace_pbr,
S32 tex_channel = -1);
static void dropTextureOneFace(LLViewerObject* hit_obj,
S32 hit_face,
LLInventoryItem* item,
ESource source,
const LLUUID& src_id,
+ bool remove_pbr,
S32 tex_channel = -1);
static void dropTextureAllFaces(LLViewerObject* hit_obj,
LLInventoryItem* item,
ESource source,
- const LLUUID& src_id);
+ const LLUUID& src_id,
+ bool remove_pbr);
static void dropMaterial(LLViewerObject* hit_obj,
S32 hit_face,
LLInventoryItem* item,
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index da7b1131a3..981984db6a 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -9506,10 +9506,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedClickRenderProfile(), "Advanced.ClickRenderProfile");
view_listener_t::addMenu(new LLAdvancedClickRenderBenchmark(), "Advanced.ClickRenderBenchmark");
view_listener_t::addMenu(new LLAdvancedPurgeShaderCache(), "Advanced.ClearShaderCache");
- if (gSavedSettings.get<bool>("RenderTerrainPBREnabled"))
- {
- view_listener_t::addMenu(new LLAdvancedRebuildTerrain(), "Advanced.RebuildTerrain");
- }
+ view_listener_t::addMenu(new LLAdvancedRebuildTerrain(), "Advanced.RebuildTerrain");
#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
view_listener_t::addMenu(new LLAdvancedHandleToggleHackedGodmode(), "Advanced.HandleToggleHackedGodmode");
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index cea083e07d..d887a579e4 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1610,8 +1610,8 @@ void LLViewerRegion::idleUpdate(F32 max_update_time)
mLastUpdate = LLViewerOctreeEntryData::getCurrentFrame();
- static bool pbr_terrain_enabled = gSavedSettings.get<bool>("RenderTerrainPBREnabled");
- static LLCachedControl<bool> pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", FALSE);
+ static LLCachedControl<bool> pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false);
+ static LLCachedControl<bool> pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", false);
bool pbr_material = mImpl->mCompositionp && (mImpl->mCompositionp->getMaterialType() == LLTerrainMaterials::Type::PBR);
bool pbr_land = pbr_material && pbr_terrain_enabled && pbr_terrain_experimental_normals;
@@ -1925,8 +1925,8 @@ void LLViewerRegion::forceUpdate()
{
constexpr F32 max_update_time = 0.f;
- static bool pbr_terrain_enabled = gSavedSettings.get<BOOL>("RenderTerrainPBREnabled");
- static LLCachedControl<BOOL> pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", FALSE);
+ static LLCachedControl<bool> pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false);
+ static LLCachedControl<bool> pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", false);
bool pbr_material = mImpl->mCompositionp && (mImpl->mCompositionp->getMaterialType() == LLTerrainMaterials::Type::PBR);
bool pbr_land = pbr_material && pbr_terrain_enabled && pbr_terrain_experimental_normals;
@@ -2459,6 +2459,26 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features)
}
gSavedSettings.setBOOL("RenderMirrors", mirrors_enabled);
+
+ if (mSimulatorFeatures.has("PBRTerrainEnabled"))
+ {
+ bool enabled = mSimulatorFeatures["PBRTerrainEnabled"];
+ gSavedSettings.setBOOL("RenderTerrainPBREnabled", enabled);
+ }
+ else
+ {
+ gSavedSettings.setBOOL("RenderTerrainPBREnabled", false);
+ }
+
+ if (mSimulatorFeatures.has("PBRMaterialSwatchEnabled"))
+ {
+ bool enabled = mSimulatorFeatures["PBRMaterialSwatchEnabled"];
+ gSavedSettings.setBOOL("UIPreviewMaterial", enabled);
+ }
+ else
+ {
+ gSavedSettings.setBOOL("UIPreviewMaterial", false);
+ }
}
//this is called when the parent is not cacheable.
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 4eb934114d..354cc79036 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -196,6 +196,7 @@ LLGLSLShader gDeferredPostGammaCorrectProgram;
LLGLSLShader gNoPostGammaCorrectProgram;
LLGLSLShader gLegacyPostGammaCorrectProgram;
LLGLSLShader gExposureProgram;
+LLGLSLShader gExposureProgramNoFade;
LLGLSLShader gLuminanceProgram;
LLGLSLShader gFXAAProgram;
LLGLSLShader gDeferredPostNoDoFProgram;
@@ -980,6 +981,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredCoFProgram.unload();
gDeferredDoFCombineProgram.unload();
gExposureProgram.unload();
+ gExposureProgramNoFade.unload();
gLuminanceProgram.unload();
gDeferredPostGammaCorrectProgram.unload();
gNoPostGammaCorrectProgram.unload();
@@ -2127,6 +2129,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gExposureProgram.mFeatures.isDeferred = true;
gExposureProgram.mShaderFiles.clear();
gExposureProgram.clearPermutations();
+ gExposureProgram.addPermutation("USE_LAST_EXPOSURE", "1");
gExposureProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
gExposureProgram.mShaderFiles.push_back(make_pair("deferred/exposureF.glsl", GL_FRAGMENT_SHADER));
gExposureProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
@@ -2136,6 +2139,20 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
+ gExposureProgramNoFade.mName = "Exposure (no fade)";
+ gExposureProgramNoFade.mFeatures.hasSrgb = true;
+ gExposureProgramNoFade.mFeatures.isDeferred = true;
+ gExposureProgramNoFade.mShaderFiles.clear();
+ gExposureProgramNoFade.clearPermutations();
+ gExposureProgramNoFade.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gExposureProgramNoFade.mShaderFiles.push_back(make_pair("deferred/exposureF.glsl", GL_FRAGMENT_SHADER));
+ gExposureProgramNoFade.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gExposureProgramNoFade.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
gLuminanceProgram.mName = "Luminance";
gLuminanceProgram.mShaderFiles.clear();
gLuminanceProgram.clearPermutations();
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 57fc66ce0d..2502be6bb1 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -249,6 +249,7 @@ extern LLGLSLShader gDeferredPostGammaCorrectProgram;
extern LLGLSLShader gNoPostGammaCorrectProgram;
extern LLGLSLShader gLegacyPostGammaCorrectProgram;
extern LLGLSLShader gExposureProgram;
+extern LLGLSLShader gExposureProgramNoFade;
extern LLGLSLShader gLuminanceProgram;
extern LLGLSLShader gDeferredAvatarShadowProgram;
extern LLGLSLShader gDeferredAvatarAlphaShadowProgram;
diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp
index 7c16ee4f61..09b21e4e0a 100644
--- a/indra/newview/llvlcomposition.cpp
+++ b/indra/newview/llvlcomposition.cpp
@@ -75,12 +75,12 @@ LLTerrainMaterials::~LLTerrainMaterials()
BOOL LLTerrainMaterials::generateMaterials()
{
- if (texturesReady(TRUE))
+ if (texturesReady(true, true))
{
return TRUE;
}
- if (materialsReady(TRUE))
+ if (materialsReady(true, true))
{
return TRUE;
}
@@ -123,27 +123,43 @@ LLTerrainMaterials::Type LLTerrainMaterials::getMaterialType()
{
LL_PROFILE_ZONE_SCOPED;
- const BOOL use_textures = texturesReady() || !materialsReady();
+ const BOOL use_textures = texturesReady(false, false) || !materialsReady(false, false);
return use_textures ? Type::TEXTURE : Type::PBR;
}
-BOOL LLTerrainMaterials::texturesReady(BOOL boost)
+bool LLTerrainMaterials::texturesReady(bool boost, bool strict)
{
- BOOL ready = TRUE;
- for (S32 i = 0; i < ASSET_COUNT; i++)
- {
- if (!textureReady(mDetailTextures[i], boost))
+ bool ready[ASSET_COUNT];
+ // *NOTE: Calls to textureReady may boost textures. Do not early-return.
+ for (S32 i = 0; i < ASSET_COUNT; i++)
+ {
+ ready[i] = textureReady(mDetailTextures[i], boost);
+ }
+
+ bool one_ready = false;
+ for (S32 i = 0; i < ASSET_COUNT; i++)
+ {
+ const bool current_ready = ready[i];
+ one_ready = one_ready || current_ready;
+ if (!current_ready && strict)
{
- ready = FALSE;
+ return false;
}
- }
- return ready;
+ }
+ return one_ready;
}
-BOOL LLTerrainMaterials::materialsReady(BOOL boost)
+bool LLTerrainMaterials::materialsReady(bool boost, bool strict)
{
+ bool ready[ASSET_COUNT];
+ // *NOTE: Calls to materialReady may boost materials/textures. Do not early-return.
+ for (S32 i = 0; i < ASSET_COUNT; i++)
+ {
+ ready[i] = materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost, strict);
+ }
+
#if 1
- static bool sRenderTerrainPBREnabled = gSavedSettings.get<bool>("RenderTerrainPBREnabled");
+ static LLCachedControl<bool> sRenderTerrainPBREnabled(gSavedSettings, "RenderTerrainPBREnabled", false);
static LLCachedControl<bool> sRenderTerrainPBRForce(gSavedSettings, "RenderTerrainPBRForce", false);
if (sRenderTerrainPBREnabled && sRenderTerrainPBRForce)
{
@@ -158,28 +174,31 @@ BOOL LLTerrainMaterials::materialsReady(BOOL boost)
}
if (defined)
{
- return TRUE;
+ return true;
}
}
#endif
- BOOL ready = TRUE;
- for (S32 i = 0; i < ASSET_COUNT; i++)
- {
- if (!materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost))
+ bool one_ready = false;
+ for (S32 i = 0; i < ASSET_COUNT; i++)
+ {
+ const bool current_ready = ready[i];
+ one_ready = one_ready || current_ready;
+ if (!current_ready && strict)
{
- ready = FALSE;
+ return false;
}
}
- return ready;
+ return one_ready;
}
// Boost the texture loading priority
// Return true when ready to use (i.e. texture is sufficiently loaded)
// static
-BOOL LLTerrainMaterials::textureReady(LLPointer<LLViewerFetchedTexture>& tex, BOOL boost)
+bool LLTerrainMaterials::textureReady(LLPointer<LLViewerFetchedTexture>& tex, bool boost)
{
- llassert(tex.notNull());
+ llassert(tex);
+ if (!tex) { return false; }
if (tex->getDiscardLevel() < 0)
{
@@ -188,7 +207,7 @@ BOOL LLTerrainMaterials::textureReady(LLPointer<LLViewerFetchedTexture>& tex, BO
tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail
tex->addTextureStats(BASE_SIZE*BASE_SIZE);
}
- return FALSE;
+ return false;
}
if ((tex->getDiscardLevel() != 0 &&
(tex->getWidth() < BASE_SIZE ||
@@ -209,23 +228,23 @@ BOOL LLTerrainMaterials::textureReady(LLPointer<LLViewerFetchedTexture>& tex, BO
tex->setMinDiscardLevel(ddiscard);
tex->addTextureStats(BASE_SIZE*BASE_SIZE); // priority
}
- return FALSE;
+ return false;
}
if (tex->getComponents() == 0)
{
- 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)
+// Return true when ready to use
// static
-BOOL LLTerrainMaterials::materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, BOOL boost)
+bool LLTerrainMaterials::materialReady(LLPointer<LLFetchedGLTFMaterial> &mat, bool &textures_set, bool boost, bool strict)
{
if (!mat || !mat->isLoaded())
{
- return FALSE;
+ return false;
}
// Material is loaded, but textures may not be
@@ -234,33 +253,39 @@ BOOL LLTerrainMaterials::materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bo
// *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->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;
+ mat->mEmissiveTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]);
+ textures_set = true;
- return FALSE;
+ 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))
+ // *NOTE: Calls to textureReady may boost textures. Do not early-return.
+ bool ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT];
+ ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] =
+ mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].isNull() || textureReady(mat->mBaseColorTexture, boost);
+ ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] =
+ mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].isNull() || textureReady(mat->mNormalTexture, boost);
+ ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] =
+ mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].isNull() ||
+ textureReady(mat->mMetallicRoughnessTexture, boost);
+ ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] =
+ mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].isNull() || textureReady(mat->mEmissiveTexture, boost);
+
+ if (strict)
{
- return FALSE;
- }
- if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].notNull() && !textureReady(mat->mEmissiveTexture, boost))
- {
- return FALSE;
+ for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
+ {
+ if (!ready[i])
+ {
+ return false;
+ }
+ }
}
- return TRUE;
+ return true;
}
@@ -427,16 +452,13 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y,
S32 st_data_size[ASSET_COUNT]; // for debugging
const bool use_textures = getMaterialType() != LLTerrainMaterials::Type::PBR;
- // *TODO: Remove this as it is reduandant computation (first and foremost
- // because getMaterialType() does something similar, but also... shouldn't
- // the textures/materials already be loaded by now?)
if (use_textures)
{
- if (!texturesReady()) { return FALSE; }
+ if (!texturesReady(true, true)) { return FALSE; }
}
else
{
- if (!materialsReady()) { return FALSE; }
+ if (!materialsReady(true, true)) { return FALSE; }
}
for (S32 i = 0; i < ASSET_COUNT; i++)
diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h
index d59c0f95bb..73bfca6ed4 100644
--- a/indra/newview/llvlcomposition.h
+++ b/indra/newview/llvlcomposition.h
@@ -61,12 +61,16 @@ public:
LLUUID getDetailAssetID(S32 asset);
virtual void setDetailAssetID(S32 asset, const LLUUID& id);
Type getMaterialType();
- BOOL texturesReady(BOOL boost = FALSE);
- BOOL materialsReady(BOOL boost = FALSE);
+ bool texturesReady(bool boost, bool strict);
+ // strict = true -> all materials must be sufficiently loaded
+ // strict = false -> at least one material must be loaded
+ bool materialsReady(bool boost, bool strict);
protected:
- static BOOL textureReady(LLPointer<LLViewerFetchedTexture>& tex, BOOL boost = FALSE);
- static BOOL materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, BOOL boost = FALSE);
+ static bool textureReady(LLPointer<LLViewerFetchedTexture>& tex, bool boost);
+ // strict = true -> all materials must be sufficiently loaded
+ // strict = false -> at least one material must be loaded
+ static bool materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, bool boost, bool strict);
LLPointer<LLViewerFetchedTexture> mDetailTextures[ASSET_COUNT];
LLPointer<LLFetchedGLTFMaterial> mDetailMaterials[ASSET_COUNT];
bool mMaterialTexturesSet[ASSET_COUNT];
@@ -116,8 +120,8 @@ public:
BOOL getParamsReady() const { return mParamsReady; }
protected:
- static BOOL textureReady(LLPointer<LLViewerFetchedTexture>& tex, BOOL boost = FALSE);
- static BOOL materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, BOOL boost = FALSE);
+ 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;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 54e0a0113d..27d2e6af71 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -5304,8 +5304,9 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
//drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD)));
- U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? facep->getTextureEntry()->getBumpmap() : 0;
- U8 shiny = facep->getTextureEntry()->getShiny();
+ const LLTextureEntry* te = facep->getTextureEntry();
+ U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? te->getBumpmap() : 0;
+ U8 shiny = te->getShiny();
LLViewerTexture* tex = facep->getTexture();
@@ -5315,22 +5316,22 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
LLUUID mat_id;
- auto* gltf_mat = (LLFetchedGLTFMaterial*) facep->getTextureEntry()->getGLTFRenderMaterial();
- llassert(gltf_mat == nullptr || dynamic_cast<LLFetchedGLTFMaterial*>(facep->getTextureEntry()->getGLTFRenderMaterial()) != nullptr);
+ auto* gltf_mat = (LLFetchedGLTFMaterial*)te->getGLTFRenderMaterial();
+ llassert(gltf_mat == nullptr || dynamic_cast<LLFetchedGLTFMaterial*>(te->getGLTFRenderMaterial()) != nullptr);
if (gltf_mat != nullptr)
{
mat_id = gltf_mat->getHash(); // TODO: cache this hash
- if (!facep->hasMedia())
+ if (!facep->hasMedia() || (tex && tex->getType() != LLViewerTexture::MEDIA_TEXTURE))
{ // no media texture, face texture will be unused
tex = nullptr;
}
}
else
{
- mat = facep->getTextureEntry()->getMaterialParams().get();
+ mat = te->getMaterialParams().get();
if (mat)
{
- mat_id = facep->getTextureEntry()->getMaterialParams()->getHash();
+ mat_id = te->getMaterialParams()->getHash();
}
}
@@ -5340,7 +5341,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
if (mat)
{
- BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) || (facep->getTextureEntry()->getColor().mV[3] < 0.999f) ? TRUE : FALSE;
+ BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) || (te->getColor().mV[3] < 0.999f) ? TRUE : FALSE;
if (type == LLRenderPass::PASS_ALPHA)
{
shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND, is_alpha);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 269b40a6c5..e3e2da3b30 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6779,11 +6779,12 @@ void LLPipeline::generateLuminance(LLRenderTarget* src, LLRenderTarget* dst)
}
}
-void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst) {
+void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool use_history) {
// exposure sample
{
LL_PROFILE_GPU_ZONE("exposure sample");
+ if (use_history)
{
// copy last frame's exposure into mLastExposure
mLastExposure.bindTarget();
@@ -6800,51 +6801,67 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst) {
LLGLDepthTest depth(GL_FALSE, GL_FALSE);
- gExposureProgram.bind();
+ LLGLSLShader* shader;
+ if (use_history)
+ {
+ shader = &gExposureProgram;
+ }
+ else
+ {
+ shader = &gExposureProgramNoFade;
+ }
+
+ shader->bind();
- S32 channel = gExposureProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
if (channel > -1)
{
- mLuminanceMap.bindTexture(0, channel, LLTexUnit::TFO_TRILINEAR);
+ src->bindTexture(0, channel, LLTexUnit::TFO_TRILINEAR);
}
- channel = gExposureProgram.enableTexture(LLShaderMgr::EXPOSURE_MAP);
- if (channel > -1)
+ if (use_history)
{
- mLastExposure.bindTexture(0, channel);
+ channel = shader->enableTexture(LLShaderMgr::EXPOSURE_MAP);
+ if (channel > -1)
+ {
+ mLastExposure.bindTexture(0, channel);
+ }
}
static LLStaticHashedString dt("dt");
static LLStaticHashedString noiseVec("noiseVec");
static LLStaticHashedString dynamic_exposure_params("dynamic_exposure_params");
static LLCachedControl<F32> dynamic_exposure_coefficient(gSavedSettings, "RenderDynamicExposureCoefficient", 0.175f);
- static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
+ static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
- LLSettingsSky::ptr_t sky = LLEnvironment::instance().getCurrentSky();
+ LLSettingsSky::ptr_t sky = LLEnvironment::instance().getCurrentSky();
- F32 probe_ambiance = LLEnvironment::instance().getCurrentSky()->getReflectionProbeAmbiance(should_auto_adjust);
- F32 exp_min = 1.f;
- F32 exp_max = 1.f;
-
- if (probe_ambiance > 0.f)
- {
- F32 hdr_scale = sqrtf(LLEnvironment::instance().getCurrentSky()->getGamma())*2.f;
+ F32 probe_ambiance = LLEnvironment::instance().getCurrentSky()->getReflectionProbeAmbiance(should_auto_adjust);
+ F32 exp_min = 1.f;
+ F32 exp_max = 1.f;
- if (hdr_scale > 1.f)
- {
- exp_min = 1.f / hdr_scale;
- exp_max = hdr_scale;
- }
- }
- gExposureProgram.uniform1f(dt, gFrameIntervalSeconds);
- gExposureProgram.uniform2f(noiseVec, ll_frand() * 2.0 - 1.0, ll_frand() * 2.0 - 1.0);
- gExposureProgram.uniform3f(dynamic_exposure_params, dynamic_exposure_coefficient, exp_min, exp_max);
+ if (probe_ambiance > 0.f)
+ {
+ F32 hdr_scale = sqrtf(LLEnvironment::instance().getCurrentSky()->getGamma()) * 2.f;
+
+ if (hdr_scale > 1.f)
+ {
+ exp_min = 1.f / hdr_scale;
+ exp_max = hdr_scale;
+ }
+ }
+ shader->uniform1f(dt, gFrameIntervalSeconds);
+ shader->uniform2f(noiseVec, ll_frand() * 2.0 - 1.0, ll_frand() * 2.0 - 1.0);
+ shader->uniform3f(dynamic_exposure_params, dynamic_exposure_coefficient, exp_min, exp_max);
mScreenTriangleVB->setBuffer();
mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- gGL.getTexUnit(channel)->unbind(mLastExposure.getUsage());
- gExposureProgram.unbind();
+ if (use_history)
+ {
+ gGL.getTexUnit(channel)->unbind(mLastExposure.getUsage());
+ }
+ shader->unbind();
dst->flush();
}
}
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 2937b1fa1a..fe00c52e6d 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -154,7 +154,7 @@ public:
void renderFinalize();
void copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst);
void generateLuminance(LLRenderTarget* src, LLRenderTarget* dst);
- void generateExposure(LLRenderTarget* src, LLRenderTarget* dst);
+ void generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool use_history = true);
void gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst);
void generateGlow(LLRenderTarget* src);
void applyFXAA(LLRenderTarget* src, LLRenderTarget* dst);