summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/app_settings/settings.xml35
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl18
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/skyV.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl2
-rw-r--r--indra/newview/llagentbenefits.cpp11
-rw-r--r--indra/newview/llagentbenefits.h4
-rw-r--r--indra/newview/lldrawpoolwlsky.cpp23
-rw-r--r--indra/newview/llfetchedgltfmaterial.cpp9
-rw-r--r--indra/newview/llfloaterimagepreview.cpp21
-rw-r--r--indra/newview/llfloaterimagepreview.h26
-rw-r--r--indra/newview/llfloaternamedesc.h2
-rw-r--r--indra/newview/llmaterialeditor.cpp74
-rw-r--r--indra/newview/llpanelmaininventory.cpp4
-rw-r--r--indra/newview/llreflectionmapmanager.cpp3
-rw-r--r--indra/newview/llsettingsvo.cpp3
-rw-r--r--indra/newview/llviewermenu.cpp4
-rw-r--r--indra/newview/llviewermenufile.cpp142
-rw-r--r--indra/newview/llviewershadermgr.cpp1
-rw-r--r--indra/newview/llvoavatar.cpp2
-rw-r--r--indra/newview/pipeline.cpp12
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml18
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory_add.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml2
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml4
26 files changed, 330 insertions, 108 deletions
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index b7f8ee41e6..69adf3456f 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-7.1.4
+7.1.5
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index a28ea7294c..0ed4b629bb 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -8828,17 +8828,6 @@
<key>Value</key>
<real>32.0</real>
</map>
- <key>RenderCloudShadowAmbianceFactor</key>
- <map>
- <key>Comment</key>
- <string>Amount that cloud shadow (aka cloud coverage) contributes to reflection probe ambiance</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>0.1</real>
- </map>
<key>RenderCPUBasis</key>
<map>
<key>Comment</key>
@@ -9384,6 +9373,17 @@
<key>Value</key>
<real>1.0</real>
</map>
+ <key>RenderHDRIIrradianceOnly</key>
+ <map>
+ <key>Comment</key>
+ <string>Only use HDRI sky for irradiance map when RenderHDRISplitScreen is 0</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>RenderMaxOpenGLVersion</key>
<map>
<key>Comment</key>
@@ -10833,6 +10833,17 @@
<key>Value</key>
<real>0.5</real>
</map>
+ <key>RenderDiffuseLuminanceScale</key>
+ <map>
+ <key>Comment</key>
+ <string>Luminance adjustment for diffuse surfaces to aid auto-exposure behavior</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.5</real>
+ </map>
<key>RenderShaderLODThreshold</key>
<map>
<key>Comment</key>
@@ -10902,7 +10913,7 @@
<key>RenderTerrainPBREnabled</key>
<map>
<key>Comment</key>
- <string>EXPERIMENTAL: Enable PBR Terrain features. Requires restart.</string>
+ <string>EXPERIMENTAL: Enable PBR Terrain features.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
index c8afacf9bb..95b2f80e06 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
@@ -34,6 +34,8 @@ in vec2 vary_fragcoord;
uniform sampler2D diffuseRect;
uniform sampler2D emissiveRect;
+uniform sampler2D normalMap;
+uniform float diffuse_luminance_scale;
float lum(vec3 col)
{
@@ -45,7 +47,21 @@ void main()
{
vec2 tc = vary_fragcoord*0.6+0.2;
tc.y -= 0.1; // HACK - nudge exposure sample down a little bit to favor ground over sky
- vec3 c = texture(diffuseRect, tc).rgb + texture(emissiveRect, tc).rgb;
+ vec3 c = texture(diffuseRect, tc).rgb;
+
+ vec4 norm = texture(normalMap, tc);
+
+ if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_HDRI) &&
+ !GET_GBUFFER_FLAG(GBUFFER_FLAG_SKIP_ATMOS))
+ {
+ // Apply the diffuse luminance scale to objects but not the sky
+ // Prevents underexposing when looking at bright environments
+ // while still allowing for realistically bright skies.
+ c *= diffuse_luminance_scale;
+ }
+
+ c += texture(emissiveRect, tc).rgb;
+
float L = lum(c);
frag_color = vec4(max(L, 0.0));
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
index d89377326e..1629ed91c8 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
@@ -153,6 +153,15 @@ float noise(vec2 x) {
//=============================
+void debugExposure(inout vec3 color)
+{
+ float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r;
+ exp_scale *= 0.5;
+ if (abs(vary_fragcoord.y-exp_scale) < 0.01 && vary_fragcoord.x < 0.1)
+ {
+ color = vec3(1,0,0);
+ }
+}
vec3 legacyGamma(vec3 color)
{
@@ -181,7 +190,8 @@ void main()
vec3 seed = (diff.rgb+vec3(1.0))*vec3(tc.xy, tc.x+tc.y);
vec3 nz = vec3(noise(seed.rg), noise(seed.gb), noise(seed.rb));
diff.rgb += nz*0.003;
-
+
+ //debugExposure(diff.rgb);
frag_color = max(diff, vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
index e48f69dab5..24d2db2183 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
@@ -108,7 +108,7 @@ void main()
vec3 light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
// Calculate relative weights
- vec3 combined_haze = abs(blue_density) + vec3(abs(haze_density));
+ vec3 combined_haze = max(abs(blue_density) + vec3(abs(haze_density)), vec3(1e-6));
vec3 blue_weight = blue_density / combined_haze;
vec3 haze_weight = haze_density / combined_haze;
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
index 8769cc0239..40b7f9cf0e 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
@@ -66,7 +66,7 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou
// I had thought blue_density and haze_density should have equal weighting,
// but attenuation due to haze_density tends to seem too strong
- vec3 combined_haze = blue_density + vec3(haze_density);
+ vec3 combined_haze = max(blue_density + vec3(haze_density), vec3(1e-6));
vec3 blue_weight = blue_density / combined_haze;
vec3 haze_weight = vec3(haze_density) / combined_haze;
diff --git a/indra/newview/llagentbenefits.cpp b/indra/newview/llagentbenefits.cpp
index 2d219735a0..7362082029 100644
--- a/indra/newview/llagentbenefits.cpp
+++ b/indra/newview/llagentbenefits.cpp
@@ -34,7 +34,8 @@ LLAgentBenefits::LLAgentBenefits():
m_group_membership_limit(-1),
m_picks_limit(-1),
m_sound_upload_cost(-1),
- m_texture_upload_cost(-1)
+ m_texture_upload_cost(-1),
+ m_2k_texture_upload_cost(-1)
{
}
@@ -94,6 +95,7 @@ bool LLAgentBenefits::init(const LLSD& benefits_sd)
{
return false;
}
+ get_required_S32(benefits_sd, "large_texture_upload_cost", m_2k_texture_upload_cost);
// FIXME PREMIUM - either use this field or get rid of it
m_initalized = true;
@@ -140,12 +142,17 @@ S32 LLAgentBenefits::getTextureUploadCost() const
return m_texture_upload_cost;
}
+S32 LLAgentBenefits::get2KTextureUploadCost() const
+{
+ return m_2k_texture_upload_cost;
+}
+
bool LLAgentBenefits::findUploadCost(LLAssetType::EType& asset_type, S32& cost) const
{
bool succ = false;
if (asset_type == LLAssetType::AT_TEXTURE)
{
- cost = getTextureUploadCost();
+ cost = getTextureUploadCost();
succ = true;
}
else if (asset_type == LLAssetType::AT_SOUND)
diff --git a/indra/newview/llagentbenefits.h b/indra/newview/llagentbenefits.h
index 48aa6bd869..e48cedd95c 100644
--- a/indra/newview/llagentbenefits.h
+++ b/indra/newview/llagentbenefits.h
@@ -33,6 +33,8 @@
class LLAgentBenefits
{
public:
+ static constexpr S32 MIN_2K_TEXTURE_AREA = 1024 * 1024 + 1;
+
LLAgentBenefits();
~LLAgentBenefits();
LOG_CLASS(LLAgentBenefits);
@@ -47,6 +49,7 @@ public:
S32 getPicksLimit() const;
S32 getSoundUploadCost() const;
S32 getTextureUploadCost() const;
+ S32 get2KTextureUploadCost() const;
bool findUploadCost(LLAssetType::EType& asset_type, S32& cost) const;
@@ -59,6 +62,7 @@ private:
S32 m_picks_limit;
S32 m_sound_upload_cost;
S32 m_texture_upload_cost;
+ S32 m_2k_texture_upload_cost;
bool m_initalized;
};
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index 323ab5fc07..68be354533 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -130,6 +130,17 @@ void LLDrawPoolWLSky::renderDome(const LLVector3& camPosLocal, F32 camHeightLoca
extern LLPointer<LLImageGL> gEXRImage;
+static bool use_hdri_sky()
+{
+ static LLCachedControl<F32> hdri_split(gSavedSettings, "RenderHDRISplitScreen", 1.f);
+ static LLCachedControl<bool> irradiance_only(gSavedSettings, "RenderHDRIIrradianceOnly", false);
+
+ return gCubeSnapshot && (!irradiance_only || !gPipeline.mReflectionMapManager.isRadiancePass()) ? gEXRImage.notNull() : // always use HDRI for reflection probes when available
+ gEXRImage.notNull() ? hdri_split > 0.f : // fallback to EEP sky when split screen is zero
+ false; // no HDRI available, always use EEP sky
+
+}
+
void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 camHeightLocal) const
{
if (!gSky.mVOSkyp)
@@ -141,7 +152,7 @@ void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 ca
if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
{
- if (gEXRImage.notNull())
+ if (use_hdri_sky())
{
sky_shader = &gEnvironmentMapProgram;
sky_shader->bind();
@@ -161,7 +172,7 @@ void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 ca
sky_shader->uniform1f(LLShaderMgr::SKY_HDR_SCALE, powf(2.f, hdri_exposure));
sky_shader->uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, GL_FALSE, (F32*) rot.mMatrix);
- sky_shader->uniform1f(hdri_split_screen, hdri_split);
+ sky_shader->uniform1f(hdri_split_screen, gCubeSnapshot ? 1.f : hdri_split);
}
else
{
@@ -170,8 +181,6 @@ void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 ca
LLGLSPipelineDepthTestSkyBox sky(true, true);
-
-
sky_shader->uniform1i(LLShaderMgr::CUBE_SNAPSHOT, gCubeSnapshot ? 1 : 0);
LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
@@ -210,7 +219,7 @@ void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 ca
void LLDrawPoolWLSky::renderStarsDeferred(const LLVector3& camPosLocal) const
{
- if (!gSky.mVOSkyp || gEXRImage.notNull())
+ if (!gSky.mVOSkyp || use_hdri_sky())
{
return;
}
@@ -281,7 +290,7 @@ void LLDrawPoolWLSky::renderStarsDeferred(const LLVector3& camPosLocal) const
void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const
{
- if (gEXRImage.notNull())
+ if (use_hdri_sky())
{
return;
}
@@ -345,7 +354,7 @@ void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32
void LLDrawPoolWLSky::renderHeavenlyBodies()
{
- if (!gSky.mVOSkyp || gEXRImage.notNull()) return;
+ if (!gSky.mVOSkyp || use_hdri_sky()) return;
LLGLSPipelineBlendSkyBox gls_skybox(true, true); // SL-14113 we need moon to write to depth to clip stars behind
diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp
index 97b959e5cb..1ca7ffaec1 100644
--- a/indra/newview/llfetchedgltfmaterial.cpp
+++ b/indra/newview/llfetchedgltfmaterial.cpp
@@ -76,7 +76,14 @@ void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_tex)
{
// dividing the alpha cutoff by transparency here allows the shader to compare against
// the alpha value of the texture without needing the transparency value
- min_alpha = mAlphaCutoff/mBaseColor.mV[3];
+ if (mBaseColor.mV[3] > 0.f)
+ {
+ min_alpha = mAlphaCutoff / mBaseColor.mV[3];
+ }
+ else
+ {
+ min_alpha = 1024.f;
+ }
}
shader->uniform1f(LLShaderMgr::MINIMUM_ALPHA, min_alpha);
}
diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index ba0f97e2e1..87fe0a4dd6 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -34,6 +34,7 @@
#include "llimagepng.h"
#include "llagent.h"
+#include "llagentbenefits.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
@@ -144,6 +145,26 @@ BOOL LLFloaterImagePreview::postBuild()
return TRUE;
}
+
+//-----------------------------------------------------------------------------
+// getExpectedUploadCost()
+//-----------------------------------------------------------------------------
+S32 LLFloaterImagePreview::getExpectedUploadCost() const
+{
+ if (mRawImagep.notNull())
+ {
+ if (mRawImagep->getWidth() * mRawImagep->getHeight() >= LLAgentBenefits::MIN_2K_TEXTURE_AREA)
+ {
+ return LLAgentBenefitsMgr::current().get2KTextureUploadCost();
+ }
+ else
+ {
+ return LLAgentBenefitsMgr::current().getTextureUploadCost();
+ }
+ }
+ return 0;
+}
+
//-----------------------------------------------------------------------------
// LLFloaterImagePreview()
//-----------------------------------------------------------------------------
diff --git a/indra/newview/llfloaterimagepreview.h b/indra/newview/llfloaterimagepreview.h
index d034622c35..426dd926ae 100644
--- a/indra/newview/llfloaterimagepreview.h
+++ b/indra/newview/llfloaterimagepreview.h
@@ -48,17 +48,17 @@ protected:
public:
LLImagePreviewSculpted(S32 width, S32 height);
- /*virtual*/ S8 getType() const ;
+ S8 getType() const override;
void setPreviewTarget(LLImageRaw *imagep, F32 distance);
void setTexture(U32 name) { mTextureName = name; }
- BOOL render();
+ BOOL render() override;
void refresh();
void rotate(F32 yaw_radians, F32 pitch_radians);
void zoom(F32 zoom_amt);
void pan(F32 right, F32 up);
- virtual BOOL needsRender() { return mNeedsUpdate; }
+ virtual BOOL needsRender() override { return mNeedsUpdate; }
protected:
BOOL mNeedsUpdate;
@@ -81,18 +81,18 @@ protected:
public:
LLImagePreviewAvatar(S32 width, S32 height);
- /*virtual*/ S8 getType() const ;
+ S8 getType() const override;
void setPreviewTarget(const std::string& joint_name, const std::string& mesh_name, LLImageRaw* imagep, F32 distance, BOOL male);
void setTexture(U32 name) { mTextureName = name; }
void clearPreviewTexture(const std::string& mesh_name);
- BOOL render();
+ BOOL render() override;
void refresh();
void rotate(F32 yaw_radians, F32 pitch_radians);
void zoom(F32 zoom_amt);
void pan(F32 right, F32 up);
- virtual BOOL needsRender() { return mNeedsUpdate; }
+ virtual BOOL needsRender() override { return mNeedsUpdate; }
protected:
BOOL mNeedsUpdate;
@@ -113,12 +113,14 @@ public:
LLFloaterImagePreview(const std::string& filename);
virtual ~LLFloaterImagePreview();
- virtual BOOL postBuild();
+ BOOL postBuild() override;
+
+ S32 getExpectedUploadCost() const override;
- BOOL handleMouseDown(S32 x, S32 y, MASK mask);
- BOOL handleMouseUp(S32 x, S32 y, MASK mask);
- BOOL handleHover(S32 x, S32 y, MASK mask);
- BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+ BOOL handleMouseDown(S32 x, S32 y, MASK mask) override;
+ BOOL handleMouseUp(S32 x, S32 y, MASK mask) override;
+ BOOL handleHover(S32 x, S32 y, MASK mask) override;
+ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) override;
static void onMouseCaptureLostImagePreview(LLMouseHandler*);
@@ -126,7 +128,7 @@ public:
protected:
static void onPreviewTypeCommit(LLUICtrl*,void*);
- void draw();
+ void draw() override;
bool loadImage(const std::string& filename);
LLPointer<LLImageRaw> mRawImagep;
diff --git a/indra/newview/llfloaternamedesc.h b/indra/newview/llfloaternamedesc.h
index 589f470e82..cf3b512fab 100644
--- a/indra/newview/llfloaternamedesc.h
+++ b/indra/newview/llfloaternamedesc.h
@@ -47,7 +47,7 @@ public:
void onBtnCancel();
void doCommit();
- S32 getExpectedUploadCost() const;
+ virtual S32 getExpectedUploadCost() const;
protected:
virtual void onCommit();
diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
index b54617870c..1783621530 100644
--- a/indra/newview/llmaterialeditor.cpp
+++ b/indra/newview/llmaterialeditor.cpp
@@ -489,11 +489,20 @@ BOOL LLMaterialEditor::postBuild()
}
else
{
- S32 upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
- getChild<LLUICtrl>("base_color_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost));
- getChild<LLUICtrl>("metallic_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost));
- getChild<LLUICtrl>("emissive_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost));
- getChild<LLUICtrl>("normal_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost));
+ S32 upload_cost_base = LLAgentBenefitsMgr::current().getTextureUploadCost();
+ S32 upload_cost_2k = LLAgentBenefitsMgr::current().get2KTextureUploadCost();
+
+ bool large_texture = mBaseColorFetched && (mBaseColorFetched->getFullHeight() * mBaseColorFetched->getFullWidth() >= LLAgentBenefits::MIN_2K_TEXTURE_AREA);
+ getChild<LLUICtrl>("base_color_upload_fee")->setTextArg("[FEE]", llformat("%d", large_texture ? upload_cost_2k : upload_cost_base));
+
+ large_texture = mMetallicRoughnessFetched && (mMetallicRoughnessFetched->getFullHeight() * mMetallicRoughnessFetched->getFullWidth() >= LLAgentBenefits::MIN_2K_TEXTURE_AREA);
+ getChild<LLUICtrl>("metallic_upload_fee")->setTextArg("[FEE]", llformat("%d", large_texture ? upload_cost_2k : upload_cost_base));
+
+ large_texture = mEmissiveFetched && (mEmissiveFetched->getFullHeight() * mEmissiveFetched->getFullWidth() >= LLAgentBenefits::MIN_2K_TEXTURE_AREA);
+ getChild<LLUICtrl>("emissive_upload_fee")->setTextArg("[FEE]", llformat("%d", large_texture ? upload_cost_2k : upload_cost_base));
+
+ large_texture = mNormalFetched && (mNormalFetched->getFullHeight() * mNormalFetched->getFullWidth() >= LLAgentBenefits::MIN_2K_TEXTURE_AREA);
+ getChild<LLUICtrl>("normal_upload_fee")->setTextArg("[FEE]", llformat("%d", large_texture ? upload_cost_2k : upload_cost_base));
}
boost::function<void(LLUICtrl*, void*)> changes_callback = [this](LLUICtrl * ctrl, void* userData)
@@ -843,24 +852,59 @@ void LLMaterialEditor::markChangesUnsaved(U32 dirty_flag)
}
S32 upload_texture_count = 0;
- if (mBaseColorTextureUploadId.notNull() && mBaseColorTextureUploadId == getBaseColorId())
+ S32 upload_2k_texture_count = 0;
+ if (mBaseColorTextureUploadId.notNull() && mBaseColorTextureUploadId == getBaseColorId() && mBaseColorFetched)
{
- upload_texture_count++;
+ if (mBaseColorFetched->getFullHeight() * mBaseColorFetched->getFullWidth() >= LLAgentBenefits::MIN_2K_TEXTURE_AREA)
+ {
+ upload_2k_texture_count++;
+ }
+ else
+ {
+ upload_texture_count++;
+ }
}
- if (mMetallicTextureUploadId.notNull() && mMetallicTextureUploadId == getMetallicRoughnessId())
+ if (mMetallicTextureUploadId.notNull() && mMetallicTextureUploadId == getMetallicRoughnessId() && mMetallicRoughnessFetched)
{
- upload_texture_count++;
+ if (mMetallicRoughnessFetched->getFullHeight() * mMetallicRoughnessFetched->getFullWidth() >= LLAgentBenefits::MIN_2K_TEXTURE_AREA)
+ {
+ upload_2k_texture_count++;
+ }
+ else
+ {
+ upload_texture_count++;
+ }
}
- if (mEmissiveTextureUploadId.notNull() && mEmissiveTextureUploadId == getEmissiveId())
+ if (mEmissiveTextureUploadId.notNull() && mEmissiveTextureUploadId == getEmissiveId() && mEmissiveFetched)
{
- upload_texture_count++;
+ if (mEmissiveFetched->getFullHeight() * mEmissiveFetched->getFullWidth() >= LLAgentBenefits::MIN_2K_TEXTURE_AREA)
+ {
+ upload_2k_texture_count++;
+ }
+ else
+ {
+ upload_texture_count++;
+ }
}
- if (mNormalTextureUploadId.notNull() && mNormalTextureUploadId == getNormalId())
+ if (mNormalTextureUploadId.notNull() && mNormalTextureUploadId == getNormalId() && mNormalFetched)
{
- upload_texture_count++;
+ if (mNormalFetched->getFullHeight() * mNormalFetched->getFullWidth() >= LLAgentBenefits::MIN_2K_TEXTURE_AREA)
+ {
+ upload_2k_texture_count++;
+ }
+ else
+ {
+ upload_texture_count++;
+ }
}
mExpectedUploadCost = upload_texture_count * LLAgentBenefitsMgr::current().getTextureUploadCost();
+ S32 cost_2k = LLAgentBenefitsMgr::current().get2KTextureUploadCost();
+ if (cost_2k < 0)
+ {
+ cost_2k = 0;
+ }
+ mExpectedUploadCost += upload_2k_texture_count * cost_2k;
getChild<LLUICtrl>("total_upload_fee")->setTextArg("[FEE]", llformat("%d", mExpectedUploadCost));
}
@@ -3496,6 +3540,10 @@ void LLMaterialEditor::saveTexture(LLImageJ2C* img, const std::string& name, con
buffer.assign((const char*) img->getData(), img->getDataSize());
U32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
+ if (img->getWidth() * img->getHeight() >= LLAgentBenefits::MIN_2K_TEXTURE_AREA)
+ {
+ expected_upload_cost = LLAgentBenefitsMgr::current().get2KTextureUploadCost();
+ }
LLSD key = getKey();
std::function<bool(LLUUID itemId, LLSD response, std::string reason)> failed_upload([key](LLUUID assetId, LLSD response, std::string reason)
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 20241aac24..2db431d165 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -276,14 +276,12 @@ BOOL LLPanelMainInventory::postBuild()
initListCommandsHandlers();
- const std::string texture_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost());
const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost());
const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost());
LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
if (menu)
{
- menu->getChild<LLMenuItemGL>("Upload Image")->setLabelArg("[COST]", texture_upload_cost_str);
menu->getChild<LLMenuItemGL>("Upload Sound")->setLabelArg("[COST]", sound_upload_cost_str);
menu->getChild<LLMenuItemGL>("Upload Animation")->setLabelArg("[COST]", animation_upload_cost_str);
}
@@ -2229,11 +2227,9 @@ void LLPanelMainInventory::setUploadCostIfNeeded()
LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
if(mNeedUploadCost && menu)
{
- const std::string texture_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost());
const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost());
const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost());
- menu->getChild<LLView>("Upload Image")->setLabelArg("[COST]", texture_upload_cost_str);
menu->getChild<LLView>("Upload Sound")->setLabelArg("[COST]", sound_upload_cost_str);
menu->getChild<LLView>("Upload Animation")->setLabelArg("[COST]", animation_upload_cost_str);
}
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index f9c5421866..3e4992e4e7 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -1092,9 +1092,8 @@ void LLReflectionMapManager::updateUniforms()
LLEnvironment& environment = LLEnvironment::instance();
LLSettingsSky::ptr_t psky = environment.getCurrentSky();
- static LLCachedControl<F32> cloud_shadow_scale(gSavedSettings, "RenderCloudShadowAmbianceFactor", 0.125f);
static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
- F32 minimum_ambiance = psky->getTotalReflectionProbeAmbiance(cloud_shadow_scale, should_auto_adjust);
+ F32 minimum_ambiance = psky->getReflectionProbeAmbiance(should_auto_adjust);
bool is_ambiance_pass = gCubeSnapshot && !isRadiancePass();
F32 ambscale = is_ambiance_pass ? 0.f : 1.f;
diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp
index afae5f140b..ff9332aeee 100644
--- a/indra/newview/llsettingsvo.cpp
+++ b/indra/newview/llsettingsvo.cpp
@@ -745,8 +745,7 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
shader->uniform1f(LLShaderMgr::SKY_SUNLIGHT_SCALE, sunlight_scale);
shader->uniform1f(LLShaderMgr::SKY_AMBIENT_SCALE, ambient_scale);
- static LLCachedControl<F32> cloud_shadow_scale(gSavedSettings, "RenderCloudShadowAmbianceFactor", 0.125f);
- F32 probe_ambiance = getTotalReflectionProbeAmbiance(cloud_shadow_scale);
+ F32 probe_ambiance = getReflectionProbeAmbiance();
if (irradiance_pass)
{ // during an irradiance map update, disable ambient lighting (direct lighting only) and desaturate sky color (avoid tinting the world blue)
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index c50ae2e153..52e5c5ff12 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -526,10 +526,8 @@ void init_menus()
LLGridManager::getInstance()->isInProductionGrid());
// *TODO:Also fix cost in llfolderview.cpp for Inventory menus
- const std::string texture_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost());
const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost());
const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost());
- gMenuHolder->childSetLabelArg("Upload Image", "[COST]", texture_upload_cost_str);
gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", sound_upload_cost_str);
gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", animation_upload_cost_str);
@@ -9245,6 +9243,8 @@ void LLUploadCostCalculator::calculateCost(const std::string& asset_type_str)
if (asset_type_str == "texture")
{
+ // This use minimal texture cost to allow bulk and
+ // texture upload menu options to be visible
upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
}
else if (asset_type_str == "animation")
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 5461e0f362..6fe5ef00ab 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -546,21 +546,50 @@ void do_bulk_upload(std::vector<std::string> filenames, const LLSD& notification
std::string ext = gDirUtilp->getExtension(filename);
LLAssetType::EType asset_type;
U32 codec;
- S32 expected_upload_cost;
- if (LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(ext, asset_type, codec) &&
- LLAgentBenefitsMgr::current().findUploadCost(asset_type, expected_upload_cost))
- {
- LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo(
- filename,
- asset_name,
- asset_name, 0,
- LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
- LLFloaterPerms::getNextOwnerPerms("Uploads"),
- LLFloaterPerms::getGroupPerms("Uploads"),
- LLFloaterPerms::getEveryonePerms("Uploads"),
- expected_upload_cost));
-
- upload_new_resource(uploadInfo);
+ S32 expected_upload_cost = 0;
+
+ if (LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(ext, asset_type, codec))
+ {
+ bool resource_upload = false;
+ if (asset_type == LLAssetType::AT_TEXTURE)
+ {
+ LLPointer<LLImageFormatted> image_frmted = LLImageFormatted::createFromType(codec);
+ if (gDirUtilp->fileExists(filename) && image_frmted->load(filename))
+ {
+ if (image_frmted->getWidth() * image_frmted->getHeight() >= LLAgentBenefits::MIN_2K_TEXTURE_AREA)
+ {
+ expected_upload_cost = LLAgentBenefitsMgr::current().get2KTextureUploadCost();
+ if (expected_upload_cost >= 0)
+ {
+ resource_upload = true;
+ }
+ }
+ else
+ {
+ expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
+ resource_upload = true;
+ }
+ }
+ }
+ else if (LLAgentBenefitsMgr::current().findUploadCost(asset_type, expected_upload_cost))
+ {
+ resource_upload = true;
+ }
+
+ if (resource_upload)
+ {
+ LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo(
+ filename,
+ asset_name,
+ asset_name, 0,
+ LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
+ LLFloaterPerms::getNextOwnerPerms("Uploads"),
+ LLFloaterPerms::getGroupPerms("Uploads"),
+ LLFloaterPerms::getEveryonePerms("Uploads"),
+ expected_upload_cost));
+
+ upload_new_resource(uploadInfo);
+ }
}
// gltf does not use normal upload procedure
@@ -588,6 +617,8 @@ bool get_bulk_upload_expected_cost(const std::vector<std::string>& filenames, S3
total_cost = 0;
file_count = 0;
bvh_count = 0;
+ S32 texture_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
+ S32 texture_2k_upload_cost = LLAgentBenefitsMgr::current().get2KTextureUploadCost();
for (std::vector<std::string>::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter)
{
std::string filename = (*in_iter);
@@ -602,17 +633,37 @@ bool get_bulk_upload_expected_cost(const std::vector<std::string>& filenames, S3
U32 codec;
S32 cost;
- if (LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(ext, asset_type, codec) &&
- LLAgentBenefitsMgr::current().findUploadCost(asset_type, cost))
+ if (LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(ext, asset_type, codec))
{
- total_cost += cost;
- file_count++;
- }
+ if (asset_type == LLAssetType::AT_TEXTURE)
+ {
+ LLPointer<LLImageFormatted> image_frmted = LLImageFormatted::createFromType(codec);
+ if (gDirUtilp->fileExists(filename) && image_frmted->load(filename))
+ {
+ if (image_frmted->getWidth() * image_frmted->getHeight() >= LLAgentBenefits::MIN_2K_TEXTURE_AREA)
+ {
+ if (texture_2k_upload_cost >= 0)
+ {
+ total_cost += texture_2k_upload_cost;
+ file_count++;
+ }
+ }
+ else
+ {
+ total_cost += texture_upload_cost;
+ file_count++;
+ }
+ }
+ }
+ else if (LLAgentBenefitsMgr::current().findUploadCost(asset_type, cost))
+ {
+ total_cost += cost;
+ file_count++;
+ }
+ }
if (ext == "gltf" || ext == "glb")
{
- S32 texture_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
-
tinygltf::Model model;
if (LLTinyGLTFHelper::loadModel(filename, model))
@@ -630,23 +681,52 @@ bool get_bulk_upload_expected_cost(const std::vector<std::string>& filenames, S3
// Todo: make it account for possibility of same texture in different
// materials and even in scope of same material
S32 texture_count = 0;
- if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].notNull())
+ S32 texture_2k_count = 0;
+ if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].notNull() && material->mBaseColorTexture)
{
- texture_count++;
+ if (material->mBaseColorTexture->getFullHeight() * material->mBaseColorTexture->getFullWidth() >= LLAgentBenefits::MIN_2K_TEXTURE_AREA)
+ {
+ texture_2k_count++;
+ }
+ else
+ {
+ texture_count++;
+ }
}
- if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].notNull())
+ if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].notNull() && material->mMetallicRoughnessTexture)
{
- texture_count++;
+ if (material->mMetallicRoughnessTexture->getFullHeight() * material->mMetallicRoughnessTexture->getFullWidth() >= LLAgentBenefits::MIN_2K_TEXTURE_AREA)
+ {
+ texture_2k_count++;
+ }
+ else
+ {
+ texture_count++;
+ }
}
- if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].notNull())
+ if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].notNull() && material->mNormalTexture)
{
- texture_count++;
+ if (material->mNormalTexture->getFullHeight() * material->mNormalTexture->getFullWidth() >= LLAgentBenefits::MIN_2K_TEXTURE_AREA)
+ {
+ texture_2k_count++;
+ }
+ else
+ {
+ texture_count++;
+ }
}
- if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].notNull())
+ if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].notNull() && material->mEmissiveTexture)
{
- texture_count++;
+ if (material->mEmissiveTexture->getFullHeight() * material->mEmissiveTexture->getFullWidth() >= LLAgentBenefits::MIN_2K_TEXTURE_AREA)
+ {
+ texture_2k_count++;
+ }
+ else
+ {
+ texture_count++;
+ }
}
- total_cost += texture_count * texture_upload_cost;
+ total_cost += texture_count * texture_upload_cost + texture_2k_count * texture_2k_upload_cost;
file_count++;
}
}
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index dc20f035c9..65b1fee54b 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -331,6 +331,7 @@ void LLViewerShaderMgr::finalizeShaderList()
mShaderList.push_back(&gDeferredPBROpaqueProgram);
mShaderList.push_back(&gDeferredAvatarProgram);
mShaderList.push_back(&gDeferredTerrainProgram);
+ mShaderList.push_back(&gDeferredPBRTerrainProgram);
mShaderList.push_back(&gDeferredDiffuseAlphaMaskProgram);
mShaderList.push_back(&gDeferredNonIndexedDiffuseAlphaMaskProgram);
mShaderList.push_back(&gDeferredTreeProgram);
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 35e45c6cd9..aae13e3327 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -4681,7 +4681,7 @@ bool LLVOAvatar::updateCharacter(LLAgent &agent)
mSpeed = speed;
// update animations
- if (!visible)
+ if (!visible && !isSelf()) // NOTE: never do a "hidden update" for self avatar as it interrupts controller processing
{
updateMotions(LLCharacter::HIDDEN_UPDATE);
}
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 7809129743..ef6e7c3994 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6759,6 +6759,8 @@ void LLPipeline::generateLuminance(LLRenderTarget* src, LLRenderTarget* dst)
gLuminanceProgram.bind();
+ static LLCachedControl<F32> diffuse_luminance_scale(gSavedSettings, "RenderDiffuseLuminanceScale", 1.0f);
+
S32 channel = 0;
channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE);
if (channel > -1)
@@ -6772,6 +6774,16 @@ void LLPipeline::generateLuminance(LLRenderTarget* src, LLRenderTarget* dst)
mGlow[1].bindTexture(0, channel);
}
+ channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_NORMAL);
+ if (channel > -1)
+ {
+ // bind the normal map to get the environment mask
+ mRT->deferredScreen.bindTexture(2, channel, LLTexUnit::TFO_POINT);
+ }
+
+ static LLStaticHashedString diffuse_luminance_scale_s("diffuse_luminance_scale");
+ gLuminanceProgram.uniform1f(diffuse_luminance_scale_s, diffuse_luminance_scale);
+
mScreenTriangleVB->setBuffer();
mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
dst->flush();
diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
index bc237322af..a3b18563d0 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
@@ -534,7 +534,7 @@
layout="topleft"
left="420"
name="TransparentWater"
- top_delta="16"
+ top_delta="18"
width="300">
<check_box.commit_callback
function="Pref.RenderOptionUpdate" />
@@ -555,7 +555,7 @@
max_val="128"
name="SkyMeshDetail"
show_text="false"
- top_delta="16"
+ top_delta="22"
width="260">
<slider.commit_callback
function="Pref.UpdateSliderText"
@@ -583,7 +583,7 @@
layout="topleft"
left="420"
name="UseSSAO"
- top_delta="16"
+ top_delta="22"
width="240">
<check_box.commit_callback
function="Pref.RenderOptionUpdate" />
@@ -597,7 +597,7 @@
layout="topleft"
left="420"
name="UseDoF"
- top_delta="16"
+ top_delta="20"
width="240">
<check_box.commit_callback
function="Pref.RenderOptionUpdate" />
@@ -612,7 +612,7 @@
left="420"
name="RenderShadowDetailText"
text_readonly_color="LabelDisabledColor"
- top_delta="16"
+ top_delta="22"
width="128">
Shadows:
</text>
@@ -646,7 +646,7 @@
layout="topleft"
left="420"
name="ScreenSpaceReflections"
- top_delta="16"
+ top_delta="24"
width="240">
<check_box.commit_callback
function="Pref.RenderOptionUpdate" />
@@ -661,7 +661,7 @@
left="420"
name="ReflectionDetailText"
text_readonly_color="LabelDisabledColor"
- top_delta="16"
+ top_delta="22"
width="128">
Reflection Detail:
</text>
@@ -697,7 +697,7 @@
left="420"
name="ReflectionProbeText"
text_readonly_color="LabelDisabledColor"
- top_delta="16"
+ top_delta="22"
width="128">
Reflection Coverage:
</text>
@@ -743,7 +743,7 @@
max_val="1.5"
name="RenderExposure"
show_text="true"
- top_delta="20"
+ top_delta="24"
width="260">
</slider>
diff --git a/indra/newview/skins/default/xui/en/menu_inventory_add.xml b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
index 284dd8d9fc..5bf26b41c6 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
@@ -13,7 +13,7 @@
name="upload"
tear_off="true">
<menu_item_call
- label="Image (L$[COST])..."
+ label="Image..."
layout="topleft"
name="Upload Image"
shortcut="control|U">
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 591b5537c7..992b3b2023 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1612,7 +1612,7 @@ function="World.EnvPreset"
name="Upload"
tear_off="true">
<menu_item_call
- label="Image (L$[COST])..."
+ label="Image..."
layout="topleft"
name="Upload Image"
shortcut="control|U">
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 9f99a76bd0..8769ac9b95 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -4056,7 +4056,7 @@ Replace texture [TEXTURE_NUM] with an RGB [MAX_SIZE]x[MAX_SIZE] or smaller image
Couldn&apos;t set region materials:
Terrain material [MATERIAL_NUM] is not loaded.
-Wait for the material to load, or replace material [TEXTURE_NUM] with a valid material.
+Wait for the material to load, or replace material [MATERIAL_NUM] with a valid material.
</notification>
<notification
@@ -4067,7 +4067,7 @@ Wait for the material to load, or replace material [TEXTURE_NUM] with a valid ma
Couldn&apos;t set region materials:
Terrain material [MATERIAL_NUM] failed to load.
-Replace material [TEXTURE_NUM] with a valid material.
+Replace material [MATERIAL_NUM] with a valid material.
</notification>
<notification