summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcosmic-linden <111533034+cosmic-linden@users.noreply.github.com>2024-03-20 08:58:58 -0700
committerGitHub <noreply@github.com>2024-03-20 08:58:58 -0700
commit93231d4eed69f7b869d4d10855a7ce6809b4a033 (patch)
tree671182f101d48e852d277f501c6adfe7964d3784
parent052a8a78e8b024bda1db6e5359c0d091b2a72d06 (diff)
parente2a3edf6daed276d82767ce070dbbaf1d42dc427 (diff)
Merge pull request #1019 from secondlife/vi-82
secondlife/viewer-issues#82: Don't allow transparent texture terrain
-rw-r--r--doc/testplans/pbr_terrain_composition.md2
-rw-r--r--indra/llimage/llimage.cpp22
-rw-r--r--indra/llimage/llimage.h2
-rw-r--r--indra/newview/llfloaterregioninfo.cpp29
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml26
5 files changed, 79 insertions, 2 deletions
diff --git a/doc/testplans/pbr_terrain_composition.md b/doc/testplans/pbr_terrain_composition.md
index 0e721c064a..87c1d47780 100644
--- a/doc/testplans/pbr_terrain_composition.md
+++ b/doc/testplans/pbr_terrain_composition.md
@@ -60,6 +60,6 @@ Unlike a viewer without PBR terrain support, the new viewer will no longer treat
## Graphics Features
-Texture terrain with transparency will render as opaque. Parts of the texture that would be partially transparent will instead display as a mix of the color and black, depending on how transparent the texture is.
+Texture terrain with transparency is not permitted to be applied in the viewer.
See [PBR Terrain Appearance](./pbr_terrain_appearance.md) for supported PBR terrain features.
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index acfc254b65..16609b60be 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -990,6 +990,28 @@ void LLImageRaw::verticalFlip()
}
+bool LLImageRaw::checkHasTransparentPixels()
+{
+ if (getComponents() != 4)
+ {
+ return false;
+ }
+
+ U8* data = getData();
+ U32 pixels = getWidth() * getHeight();
+
+ // check alpha channel for all 255
+ for (U32 i = 0; i < pixels; ++i)
+ {
+ if (data[i * 4 + 3] != 255)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
bool LLImageRaw::optimizeAwayAlpha()
{
if (getComponents() == 4)
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index fc8d62cc96..93b58b2356 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -210,6 +210,8 @@ public:
void verticalFlip();
+ // Returns true if the image is not fully opaque
+ bool checkHasTransparentPixels();
// if the alpha channel is all 100% opaque, delete it
// returns true if alpha channel was deleted
bool optimizeAwayAlpha();
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 2ed0e4195a..f7a8826400 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -1330,7 +1330,7 @@ BOOL LLPanelRegionTerrainInfo::validateTextureSizes()
if (!texture_ctrl) continue;
LLUUID image_asset_id = texture_ctrl->getImageAssetID();
- LLViewerTexture* img = LLViewerTextureManager::getFetchedTexture(image_asset_id);
+ LLViewerFetchedTexture* img = LLViewerTextureManager::getFetchedTexture(image_asset_id);
S32 components = img->getComponents();
// Must ask for highest resolution version's width. JC
S32 width = img->getFullWidth();
@@ -1348,6 +1348,33 @@ BOOL LLPanelRegionTerrainInfo::validateTextureSizes()
return FALSE;
}
+ if (components == 4)
+ {
+ if (!img->hasSavedRawImage())
+ {
+ // Raw image isn't loaded yet
+ // Assume it's invalid due to presence of alpha channel
+ LLSD args;
+ args["TEXTURE_NUM"] = i+1;
+ args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8);
+ LLNotificationsUtil::add("InvalidTerrainAlphaNotFullyLoaded", 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);
+ return 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;
+ }
+
if (width > max_terrain_texture_size || height > max_terrain_texture_size)
{
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 1a6cadf43e..c1e6e7b9f0 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -4010,6 +4010,32 @@ Replace texture [TEXTURE_NUM] with an RGB [MAX_SIZE]x[MAX_SIZE] or smaller image
<notification
icon="alertmodal.tga"
+ name="InvalidTerrainAlphaNotFullyLoaded"
+ type="alertmodal">
+Couldn&apos;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.
+
+If texture [TEXTURE_NUM] is opaque, wait for the texture to fully load and then click &quot;Apply&quot; again.
+
+Alpha is only supported for terrain materials (PBR Metallic Roughness), when alphaMode="MASK" and doubleSided=false.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="InvalidTerrainAlpha"
+ type="alertmodal">
+Couldn&apos;t set region textures:
+Terrain texture [TEXTURE_NUM] contains transparency. Transparency is not currently supported for terrain textures.
+
+Replace texture [TEXTURE_NUM] with an opaque RGB image, then click &quot;Apply&quot; again.
+
+Alpha is only supported for terrain materials (PBR Metallic Roughness), when alphaMode="MASK" and doubleSided=false.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="InvalidTerrainSize"
type="alertmodal">
Couldn&apos;t set region textures: