diff --git a/doc/testplans/pbr_terrain_composition.md b/doc/testplans/pbr_terrain_composition.md index 1cd26a0ded..aadd97a94b 100644 --- a/doc/testplans/pbr_terrain_composition.md +++ b/doc/testplans/pbr_terrain_composition.md @@ -12,6 +12,13 @@ All tests in this section assume the PBR terrain feature flag is enabled, and th ### Feature Availability +On the client, the advanced setting `RenderTerrainPBREnabled` is the PBR terrain feature flag. + +The PBR terrain feature flag should be set automatically when logging in/teleporting to a new region. + +- The flag should be enabled on regions where the PBR terrain feature is enabled +- Otherwise the flag should be disabled + When the PBR terrain feature flag is disabled: - The "PBR Metallic Roughness" checkbox should not be visible diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp index 9375b4e1aa..4a295fea5b 100644 --- a/indra/llinventory/llsettingssky.cpp +++ b/indra/llinventory/llsettingssky.cpp @@ -411,7 +411,6 @@ LLSettingsSky::LLSettingsSky(const LLSD &data) : mNextRainbowTextureId(), mNextHaloTextureId() { - mCanAutoAdjust = !data.has(SETTING_REFLECTION_PROBE_AMBIANCE); } LLSettingsSky::LLSettingsSky(): @@ -434,8 +433,6 @@ void LLSettingsSky::replaceSettings(LLSD settings) mNextBloomTextureId.setNull(); mNextRainbowTextureId.setNull(); mNextHaloTextureId.setNull(); - - mCanAutoAdjust = !settings.has(SETTING_REFLECTION_PROBE_AMBIANCE); } void LLSettingsSky::replaceWithSky(LLSettingsSky::ptr_t pother) @@ -448,7 +445,6 @@ void LLSettingsSky::replaceWithSky(LLSettingsSky::ptr_t pother) mNextBloomTextureId = pother->mNextBloomTextureId; mNextRainbowTextureId = pother->mNextRainbowTextureId; mNextHaloTextureId = pother->mNextHaloTextureId; - mCanAutoAdjust = pother->mCanAutoAdjust; } void LLSettingsSky::blend(const LLSettingsBase::ptr_t &end, F64 blendf) @@ -1150,7 +1146,6 @@ void LLSettingsSky::setSkyIceLevel(F32 ice_level) void LLSettingsSky::setReflectionProbeAmbiance(F32 ambiance) { - mCanAutoAdjust = false; // we've now touched this sky in a "new" way, it can no longer auto adjust setValue(SETTING_REFLECTION_PROBE_AMBIANCE, ambiance); } @@ -1452,24 +1447,6 @@ F32 LLSettingsSky::getReflectionProbeAmbiance(bool auto_adjust) const return mSettings[SETTING_REFLECTION_PROBE_AMBIANCE].asReal(); } -F32 LLSettingsSky::getTotalReflectionProbeAmbiance(F32 cloud_shadow_scale, bool auto_adjust) const -{ -#if 0 - // feed cloud shadow back into reflection probe ambiance to mimic pre-reflection-probe behavior - // without brightening dark/interior spaces - F32 probe_ambiance = getReflectionProbeAmbiance(auto_adjust); - - if (probe_ambiance > 0.f && probe_ambiance < 1.f) - { - probe_ambiance += (1.f - probe_ambiance) * getCloudShadow() * cloud_shadow_scale; - } - - return probe_ambiance; -#else - return getReflectionProbeAmbiance(auto_adjust); -#endif -} - F32 LLSettingsSky::getSkyBottomRadius() const { return mSettings[SETTING_SKY_BOTTOM_RADIUS].asReal(); @@ -1814,3 +1791,8 @@ LLUUID LLSettingsSky::getNextBloomTextureId() const return mNextBloomTextureId; } +// if true, this sky is a candidate for auto-adjustment +bool LLSettingsSky::canAutoAdjust() const +{ + return !mSettings.has(SETTING_REFLECTION_PROBE_AMBIANCE); +} diff --git a/indra/llinventory/llsettingssky.h b/indra/llinventory/llsettingssky.h index 7ba7a9ba06..222ab040cb 100644 --- a/indra/llinventory/llsettingssky.h +++ b/indra/llinventory/llsettingssky.h @@ -139,10 +139,6 @@ public: // auto_adjust - if true and canAutoAdjust() is true, return 1.0 F32 getReflectionProbeAmbiance(bool auto_adjust = false) const; - // get the probe ambiance setting to use for rendering (adjusted by cloud shadow, aka cloud coverage) - // auto_adjust - if true and canAutoAdjust() is true, return 1.0 - F32 getTotalReflectionProbeAmbiance(F32 cloud_shadow_scale, bool auto_adjust = false) const; - // Return first (only) profile layer represented in LLSD LLSD getRayleighConfig() const; LLSD getMieConfig() const; @@ -340,7 +336,7 @@ public: virtual void updateSettings() SETTINGS_OVERRIDE; // if true, this sky is a candidate for auto-adjustment - bool canAutoAdjust() const { return mCanAutoAdjust; } + bool canAutoAdjust() const; protected: static const std::string SETTING_LEGACY_EAST_ANGLE; @@ -385,9 +381,6 @@ private: mutable LLColor4 mTotalAmbient; mutable LLColor4 mHazeColor; - // if true, this sky is a candidate for auto adjustment - bool mCanAutoAdjust = true; - typedef std::map mapNameToUniformId_t; static mapNameToUniformId_t sNameToUniformMapping; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 38611ea3e0..ff60a1306f 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -11596,17 +11596,6 @@ Change of this parameter will affect the layout of buttons in notification toast Value 32.0 - RenderCloudShadowAmbianceFactor - - Comment - Amount that cloud shadow (aka cloud coverage) contributes to reflection probe ambiance - Persist - 1 - Type - F32 - Value - 0.1 - RenderCPUBasis Comment @@ -12208,6 +12197,17 @@ Change of this parameter will affect the layout of buttons in notification toast Value 1.0 + RenderHDRIIrradianceOnly + + Comment + Only use HDRI sky for irradiance map when RenderHDRISplitScreen is 0 + Persist + 1 + Type + Boolean + Value + 0 + RenderMaxOpenGLVersion Comment @@ -13865,7 +13865,7 @@ Change of this parameter will affect the layout of buttons in notification toast RenderTerrainPBREnabled Comment - EXPERIMENTAL: Enable PBR Terrain features. Requires restart. + EXPERIMENTAL: Enable PBR Terrain features. Persist 1 Type 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 gEXRImage; +static bool use_hdri_sky() +{ + static LLCachedControl hdri_split(gSavedSettings, "RenderHDRISplitScreen", 1.f); + static LLCachedControl 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/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 cloud_shadow_scale(gSavedSettings, "RenderCloudShadowAmbianceFactor", 0.125f); static LLCachedControl 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 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/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 32cad8dc81..8e9e16ece8 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -46,21 +46,40 @@ extern LLColor4U MAX_WATER_COLOR; static const U32 BASE_SIZE = 128; -F32 bilinear(const F32 v00, const F32 v01, const F32 v10, const F32 v11, const F32 x_frac, const F32 y_frac) +namespace { - // Not sure if this is the right math... - // Take weighted average of all four points (bilinear interpolation) - F32 result; + F32 bilinear(const F32 v00, const F32 v01, const F32 v10, const F32 v11, const F32 x_frac, const F32 y_frac) + { + // Not sure if this is the right math... + // Take weighted average of all four points (bilinear interpolation) + F32 result; - const F32 inv_x_frac = 1.f - x_frac; - const F32 inv_y_frac = 1.f - y_frac; - result = inv_x_frac*inv_y_frac*v00 - + x_frac*inv_y_frac*v10 - + inv_x_frac*y_frac*v01 - + x_frac*y_frac*v11; + const F32 inv_x_frac = 1.f - x_frac; + const F32 inv_y_frac = 1.f - y_frac; + result = inv_x_frac*inv_y_frac*v00 + + x_frac*inv_y_frac*v10 + + inv_x_frac*y_frac*v01 + + x_frac*y_frac*v11; - return result; -} + return result; + } + + void unboost_minimap_texture(LLPointer& tex) + { + if (!tex) { return; } + tex->setBoostLevel(LLGLTexture::BOOST_NONE); + tex->setMinDiscardLevel(MAX_DISCARD_LEVEL + 1); + } + + void unboost_minimap_material(LLPointer& mat) + { + if (!mat) { return; } + unboost_minimap_texture(mat->mBaseColorTexture); + unboost_minimap_texture(mat->mNormalTexture); + unboost_minimap_texture(mat->mMetallicRoughnessTexture); + unboost_minimap_texture(mat->mEmissiveTexture); + } +}; LLTerrainMaterials::LLTerrainMaterials() { @@ -517,21 +536,47 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, if (!tex) { tex = LLViewerFetchedTexture::sWhiteImagep; } // tex_emissive can be null, and then will be ignored - S32 min_dim = llmin(tex->getFullWidth(), tex->getFullHeight()); - S32 ddiscard = 0; - while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) - { - ddiscard++; - min_dim /= 2; + S32 ddiscard = 0; + { + S32 min_dim = llmin(tex->getFullWidth(), tex->getFullHeight()); + while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) + { + ddiscard++; + min_dim /= 2; + } + } + + S32 ddiscard_emissive = 0; + if (tex_emissive) + { + S32 min_dim_emissive = llmin(tex_emissive->getFullWidth(), tex_emissive->getFullHeight()); + while (min_dim_emissive > BASE_SIZE && ddiscard_emissive < MAX_DISCARD_LEVEL) + { + ddiscard_emissive++; + min_dim_emissive /= 2; + } } - BOOL delete_raw = (tex->reloadRawImage(ddiscard) != NULL) ; + // *NOTE: It is probably safe to call destroyRawImage no matter + // what, as LLViewerFetchedTexture::mRawImage is managed by + // LLPointer and not modified with the rare exception of + // icons (see BOOST_ICON). Nevertheless, gate this fix for now, as + // it may have unintended consequences on texture loading. + // We may want to also set the boost level in setDetailAssetID, but + // that is not guaranteed to work if a texture is loaded on an object + // before being loaded as terrain, so we will need this fix + // regardless. + static LLCachedControl sRenderTerrainPBREnabled(gSavedSettings, "RenderTerrainPBREnabled", false); + BOOL delete_raw = (tex->reloadRawImage(ddiscard) != NULL || sRenderTerrainPBREnabled); + BOOL delete_raw_emissive = (tex_emissive && + (tex_emissive->reloadRawImage(ddiscard_emissive) != NULL || sRenderTerrainPBREnabled)); + if(tex->getRawImageLevel() != ddiscard) { // Raw image is not ready, will enter here again later. if (tex->getFetchPriority() <= 0.0f && !tex->hasSavedRawImage()) { - tex->setBoostLevel(LLGLTexture::BOOST_MAP); + tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); tex->forceToRefetchTexture(ddiscard); } @@ -543,16 +588,16 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, } if (tex_emissive) { - if(tex_emissive->getRawImageLevel() != ddiscard) + if(tex_emissive->getRawImageLevel() != ddiscard_emissive) { // Raw image is not ready, will enter here again later. if (tex_emissive->getFetchPriority() <= 0.0f && !tex_emissive->hasSavedRawImage()) { - tex_emissive->setBoostLevel(LLGLTexture::BOOST_MAP); - tex_emissive->forceToRefetchTexture(ddiscard); + tex_emissive->setBoostLevel(LLGLTexture::BOOST_TERRAIN); + tex_emissive->forceToRefetchTexture(ddiscard_emissive); } - if(delete_raw) + if(delete_raw_emissive) { tex_emissive->destroyRawImage() ; } @@ -580,8 +625,8 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, { raw_emissive = tex_emissive->getRawImage(); if (has_emissive_factor || - tex_emissive->getWidth(ddiscard) != BASE_SIZE || - tex_emissive->getHeight(ddiscard) != BASE_SIZE || + tex_emissive->getWidth(tex_emissive->getRawImageLevel()) != BASE_SIZE || + tex_emissive->getHeight(tex_emissive->getRawImageLevel()) != BASE_SIZE || tex_emissive->getComponents() != 4) { LLPointer newraw_emissive = new LLImageRaw(BASE_SIZE, BASE_SIZE, 4); @@ -591,14 +636,14 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, { newraw_emissive->tint(emissive_factor); } - raw_emissive = newraw_emissive; // deletes old + raw_emissive = newraw_emissive; } } if (has_base_color_factor || raw_emissive || has_alpha || - tex->getWidth(ddiscard) != BASE_SIZE || - tex->getHeight(ddiscard) != BASE_SIZE || + tex->getWidth(tex->getRawImageLevel()) != BASE_SIZE || + tex->getHeight(tex->getRawImageLevel()) != BASE_SIZE || tex->getComponents() != 3) { LLPointer newraw = new LLImageRaw(BASE_SIZE, BASE_SIZE, 3); @@ -629,8 +674,14 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, { newraw->composite(raw_emissive); } + mRawImages[i] = newraw; // deletes old } + + if (delete_raw_emissive) + { + tex_emissive->destroyRawImage(); + } } st_data[i] = mRawImages[i]->getData(); st_data_size[i] = mRawImages[i]->getDataSize(); @@ -776,12 +827,17 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, } texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin); - for (S32 i = 0; i < ASSET_COUNT; i++) - { - // Un-boost detatil textures (will get re-boosted if rendering in high detail) - mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_NONE); - mDetailTextures[i]->setMinDiscardLevel(MAX_DISCARD_LEVEL + 1); - } + // Un-boost detail textures (will get re-boosted if rendering in high detail) + for (S32 i = 0; i < ASSET_COUNT; i++) + { + unboost_minimap_texture(mDetailTextures[i]); + } + + // Un-boost textures for each detail material (will get re-boosted if rendering in high detail) + for (S32 i = 0; i < ASSET_COUNT; i++) + { + unboost_minimap_material(mDetailMaterials[i]); + } return TRUE; } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index da0449b2a8..106e803525 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -5348,7 +5348,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); }