From a0649375e1652061610d626c958ee7488fad140d Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 20 Mar 2024 10:22:29 -0700 Subject: secondlife/viewer-issues#83: Disallow alpha blend/double sided from PBR terrain --- indra/newview/llfloaterregioninfo.cpp | 62 ++++++++++++++++++++++ indra/newview/llfloaterregioninfo.h | 1 + .../newview/skins/default/xui/en/notifications.xml | 40 ++++++++++++++ 3 files changed, 103 insertions(+) (limited to 'indra') diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 706f7cf943..65b4feba11 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1392,6 +1392,62 @@ BOOL LLPanelRegionTerrainInfo::validateTextureSizes() return TRUE; } +bool LLPanelRegionTerrainInfo::validateMaterials() +{ + if (mMaterialTypeCtrl) + { + const LLTerrainMaterials::Type material_type = material_type_from_ctrl(mMaterialTypeCtrl); + const bool is_texture_selected = material_type == LLTerrainMaterials::Type::TEXTURE; + if (is_texture_selected) { return true; } + } + + for (S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) + { + LLTextureCtrl* material_ctrl = mMaterialDetailCtrl[i]; + if (!material_ctrl) { continue; } + + const LLUUID& material_asset_id = material_ctrl->getImageAssetID(); + llassert(material_asset_id.notNull()); + if (material_asset_id.isNull()) { return false; } + const LLFetchedGLTFMaterial* material = gGLTFMaterialList.getMaterial(material_asset_id); + if (!material->isLoaded()) + { + if (material->isFetching()) + { + LLSD args; + args["MATERIAL_NUM"] = i + 1; + LLNotificationsUtil::add("InvalidTerrainMaterialNotLoaded", args); + } + else // Loading failed + { + LLSD args; + args["MATERIAL_NUM"] = i + 1; + LLNotificationsUtil::add("InvalidTerrainMaterialLoadFailed", args); + } + return false; + } + + if (material->mDoubleSided) + { + LLSD args; + args["MATERIAL_NUM"] = i + 1; + LLNotificationsUtil::add("InvalidTerrainMaterialDoubleSided", args); + return false; + } + if (material->mAlphaMode != LLGLTFMaterial::ALPHA_MODE_OPAQUE && material->mAlphaMode != LLGLTFMaterial::ALPHA_MODE_MASK) + { + LLSD args; + args["MATERIAL_NUM"] = i + 1; + const char* alpha_mode = material->getAlphaMode(); + args["MATERIAL_ALPHA_MODE"] = alpha_mode; + LLNotificationsUtil::add("InvalidTerrainMaterialAlphaMode", args); + return false; + } + } + + return true; +} + BOOL LLPanelRegionTerrainInfo::validateTextureHeights() { for (S32 i = 0; i < CORNER_COUNT; ++i) @@ -1668,6 +1724,12 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() return FALSE; } + // Prevent applying unsupported alpha blend/double-sided materials + if (!validateMaterials()) + { + return FALSE; + } + // Check if terrain Elevation Ranges are correct if (gSavedSettings.getBOOL("RegionCheckTextureHeights") && !validateTextureHeights()) { diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index 99774e5db3..ac3a8fc717 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -254,6 +254,7 @@ public: void setEnvControls(bool available); // Whether environment settings are available for this region BOOL validateTextureSizes(); + bool validateMaterials(); BOOL validateTextureHeights(); //static void onChangeAnything(LLUICtrl* ctrl, void* userData); // callback for any change, to enable commit button diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index c1e6e7b9f0..44807aa6c7 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -4044,6 +4044,46 @@ Terrain texture [TEXTURE_NUM] is too large at [TEXTURE_SIZE_X]x[TEXTURE_SIZE_Y]. Replace texture [TEXTURE_NUM] with an RGB [MAX_SIZE]x[MAX_SIZE] or smaller image then click "Apply" again. + +Couldn'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. + + + +Couldn't set region materials: +Terrain material [MATERIAL_NUM] failed to load. + +Replace material [TEXTURE_NUM] with a valid material. + + + +Couldn't set region materials: +Terrain material [MATERIAL_NUM] is double-sided. Double-sided materials are not currently supported for PBR terrain. + +Replace material [MATERIAL_NUM] with a material with doubleSided=false. + + + +Couldn't set region materials: +Terrain material [MATERIAL_NUM] is using the unsupported alphaMode="[MATERIAL_ALPHA_MODE]". + +Replace material [MATERIAL_NUM] with a material with alphaMode="OPAQUE" or alphaMode="MASK". + + Date: Wed, 20 Mar 2024 12:51:58 -0700 Subject: secondlife/viewer-issues#83, secondlife/viewer-issues#82: Mark texture/material terrain save notifications as unique, to prevent duplicates --- indra/newview/skins/default/xui/en/notifications.xml | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'indra') diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 44807aa6c7..9f99a76bd0 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -4001,6 +4001,7 @@ Are you sure you want to return objects owned by [USER_NAME]? icon="alertmodal.tga" name="InvalidTerrainBitDepth" type="alertmodal"> + Couldn't set region textures: Terrain texture [TEXTURE_NUM] has an invalid bit depth of [TEXTURE_BIT_DEPTH]. @@ -4012,6 +4013,7 @@ Replace texture [TEXTURE_NUM] with an RGB [MAX_SIZE]x[MAX_SIZE] or smaller image icon="alertmodal.tga" name="InvalidTerrainAlphaNotFullyLoaded" type="alertmodal"> + Couldn't set region textures: Terrain texture [TEXTURE_NUM] is not fully loaded, but is assumed to contain transparency due to a bit depth of [TEXTURE_BIT_DEPTH]. Transparency is not currently supported for terrain textures. @@ -4025,6 +4027,7 @@ Alpha is only supported for terrain materials (PBR Metallic Roughness), when alp icon="alertmodal.tga" name="InvalidTerrainAlpha" type="alertmodal"> + Couldn't set region textures: Terrain texture [TEXTURE_NUM] contains transparency. Transparency is not currently supported for terrain textures. @@ -4038,6 +4041,7 @@ Alpha is only supported for terrain materials (PBR Metallic Roughness), when alp icon="alertmodal.tga" name="InvalidTerrainSize" type="alertmodal"> + Couldn't set region textures: Terrain texture [TEXTURE_NUM] is too large at [TEXTURE_SIZE_X]x[TEXTURE_SIZE_Y]. @@ -4048,6 +4052,7 @@ Replace texture [TEXTURE_NUM] with an RGB [MAX_SIZE]x[MAX_SIZE] or smaller image icon="alertmodal.tga" name="InvalidTerrainMaterialNotLoaded" type="alertmodal"> + Couldn't set region materials: Terrain material [MATERIAL_NUM] is not loaded. @@ -4058,6 +4063,7 @@ Wait for the material to load, or replace material [TEXTURE_NUM] with a valid ma icon="alertmodal.tga" name="InvalidTerrainMaterialLoadFailed" type="alertmodal"> + Couldn't set region materials: Terrain material [MATERIAL_NUM] failed to load. @@ -4068,6 +4074,7 @@ Replace material [TEXTURE_NUM] with a valid material. icon="alertmodal.tga" name="InvalidTerrainMaterialDoubleSided" type="alertmodal"> + Couldn't set region materials: Terrain material [MATERIAL_NUM] is double-sided. Double-sided materials are not currently supported for PBR terrain. @@ -4078,6 +4085,7 @@ Replace material [MATERIAL_NUM] with a material with doubleSided=false. icon="alertmodal.tga" name="InvalidTerrainMaterialAlphaMode" type="alertmodal"> + Couldn't set region materials: Terrain material [MATERIAL_NUM] is using the unsupported alphaMode="[MATERIAL_ALPHA_MODE]". -- cgit v1.2.3 From d21813786ae51ba62b906e648908f7feaf6bcb32 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 20 Mar 2024 13:14:43 -0700 Subject: secondlife/viewer-issues#83, secondlife/viewer-issues#82: Combine terrain save error notifications --- indra/newview/llfloaterregioninfo.cpp | 50 ++++++++++++++++++++--------------- indra/newview/llfloaterregioninfo.h | 2 +- 2 files changed, 29 insertions(+), 23 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 65b4feba11..aaae43bdc9 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1313,15 +1313,16 @@ void LLPanelRegionDebugInfo::onClickDebugConsole(void* data) LLFloaterReg::showInstance("region_debug_console"); } -BOOL LLPanelRegionTerrainInfo::validateTextureSizes() +bool LLPanelRegionTerrainInfo::validateTextureSizes() { if (mMaterialTypeCtrl) { const LLTerrainMaterials::Type material_type = material_type_from_ctrl(mMaterialTypeCtrl); const bool is_material_selected = material_type == LLTerrainMaterials::Type::PBR; - if (is_material_selected) { return TRUE; } + if (is_material_selected) { return true; } } + bool valid = true; static LLCachedControl max_texture_resolution(gSavedSettings, "RenderMaxTextureResolution", 2048); const S32 max_terrain_texture_size = (S32)max_texture_resolution; for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) @@ -1345,7 +1346,8 @@ BOOL LLPanelRegionTerrainInfo::validateTextureSizes() args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8); args["MAX_SIZE"] = max_terrain_texture_size; LLNotificationsUtil::add("InvalidTerrainBitDepth", args); - return FALSE; + valid = false; + continue; } if (components == 4) @@ -1358,21 +1360,24 @@ BOOL LLPanelRegionTerrainInfo::validateTextureSizes() args["TEXTURE_NUM"] = i+1; args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8); LLNotificationsUtil::add("InvalidTerrainAlphaNotFullyLoaded", args); - return FALSE; + valid = false; } - // Slower path: Calculate alpha from raw image pixels (not needed - // for GLTF materials, which use alphaMode to determine - // transparency) - // Raw image is pretty much guaranteed to be saved due to the texture swatches - LLImageRaw* raw = img->getSavedRawImage(); - if (raw->checkHasTransparentPixels()) + else { - LLSD args; - args["TEXTURE_NUM"] = i+1; - LLNotificationsUtil::add("InvalidTerrainAlpha", args); - return FALSE; + // Slower path: Calculate alpha from raw image pixels (not needed + // for GLTF materials, which use alphaMode to determine + // transparency) + // Raw image is pretty much guaranteed to be saved due to the texture swatches + LLImageRaw* raw = img->getSavedRawImage(); + if (raw->checkHasTransparentPixels()) + { + LLSD args; + args["TEXTURE_NUM"] = i+1; + LLNotificationsUtil::add("InvalidTerrainAlpha", args); + valid = false; + } + LL_WARNS() << "Terrain texture image in slot " << i << " with ID " << image_asset_id << " has alpha channel, but pixels are opaque. Is alpha being optimized away in the texture uploader?" << LL_ENDL; } - LL_WARNS() << "Terrain texture image in slot " << i << " with ID " << image_asset_id << " has alpha channel, but pixels are opaque. Is alpha being optimized away in the texture uploader?" << LL_ENDL; } if (width > max_terrain_texture_size || height > max_terrain_texture_size) @@ -1384,12 +1389,11 @@ BOOL LLPanelRegionTerrainInfo::validateTextureSizes() args["TEXTURE_SIZE_Y"] = height; args["MAX_SIZE"] = max_terrain_texture_size; LLNotificationsUtil::add("InvalidTerrainSize", args); - return FALSE; - + valid = false; } } - return TRUE; + return valid; } bool LLPanelRegionTerrainInfo::validateMaterials() @@ -1401,6 +1405,7 @@ bool LLPanelRegionTerrainInfo::validateMaterials() if (is_texture_selected) { return true; } } + bool valid = true; for (S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { LLTextureCtrl* material_ctrl = mMaterialDetailCtrl[i]; @@ -1424,7 +1429,8 @@ bool LLPanelRegionTerrainInfo::validateMaterials() args["MATERIAL_NUM"] = i + 1; LLNotificationsUtil::add("InvalidTerrainMaterialLoadFailed", args); } - return false; + valid = false; + continue; } if (material->mDoubleSided) @@ -1432,7 +1438,7 @@ bool LLPanelRegionTerrainInfo::validateMaterials() LLSD args; args["MATERIAL_NUM"] = i + 1; LLNotificationsUtil::add("InvalidTerrainMaterialDoubleSided", args); - return false; + valid = false; } if (material->mAlphaMode != LLGLTFMaterial::ALPHA_MODE_OPAQUE && material->mAlphaMode != LLGLTFMaterial::ALPHA_MODE_MASK) { @@ -1441,11 +1447,11 @@ bool LLPanelRegionTerrainInfo::validateMaterials() const char* alpha_mode = material->getAlphaMode(); args["MATERIAL_ALPHA_MODE"] = alpha_mode; LLNotificationsUtil::add("InvalidTerrainMaterialAlphaMode", args); - return false; + valid = false; } } - return true; + return valid; } BOOL LLPanelRegionTerrainInfo::validateTextureHeights() diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index ac3a8fc717..da17212016 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -253,7 +253,7 @@ public: 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 - BOOL validateTextureSizes(); + bool validateTextureSizes(); bool validateMaterials(); BOOL validateTextureHeights(); -- cgit v1.2.3 From 294eaa3c57d97c74074330e1c4ac4d2903619757 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 20 Mar 2024 13:36:20 -0700 Subject: secondlife/viewer-issues#83: Add TODO/assert for deciding when to allow candidate future extensions on PBR terrain --- indra/llprimitive/llgltfmaterial.h | 11 +++++++++++ indra/newview/llfloaterregioninfo.cpp | 14 ++++++++++++++ 2 files changed, 25 insertions(+) (limited to 'indra') diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 02f62fb08c..d14ae6970b 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -129,6 +129,17 @@ public: bool mOverrideDoubleSided = false; bool mOverrideAlphaMode = false; + // *TODO: If/when we implement additional GLTF extensions, they may not be + // compatible with our GLTF terrain implementation. We may want to disallow + // materials with some features from being set on terrain, if their + // implementation on terrain is not compliant with the spec: + // - KHR_materials_transmission: Probably OK? + // - KHR_materials_ior: Probably OK? + // - KHR_materials_volume: Likely incompatible, as our terrain + // heightmaps cannot currently be described as finite enclosed + // volumes. + // See also LLPanelRegionTerrainInfo::validateMaterials + // get a UUID based on a hash of this LLGLTFMaterial LLUUID getHash() const; diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index aaae43bdc9..98656d6a58 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1405,6 +1405,20 @@ bool LLPanelRegionTerrainInfo::validateMaterials() if (is_texture_selected) { return true; } } + // *TODO: If/when we implement additional GLTF extensions, they may not be + // compatible with our GLTF terrain implementation. We may want to disallow + // materials with some features from being set on terrain, if their + // implementation on terrain is not compliant with the spec: + // - KHR_materials_transmission: Probably OK? + // - KHR_materials_ior: Probably OK? + // - KHR_materials_volume: Likely incompatible, as our terrain + // heightmaps cannot currently be described as finite enclosed + // volumes. + // See also LLGLTFMaterial +#ifdef LL_WINDOWS + llassert(sizeof(LLGLTFMaterial) == 232); +#endif + bool valid = true; for (S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { -- cgit v1.2.3