diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp
index c9ff8e681b..855a5965ad 100644
--- a/libraries/model-networking/src/model-networking/ModelCache.cpp
+++ b/libraries/model-networking/src/model-networking/ModelCache.cpp
@@ -147,11 +147,12 @@ bool NetworkGeometry::isLoadedWithTextures() const {
                 (material->lightmapTexture && !material->lightmapTexture->isLoaded())) {
                 return false;
             }
-            if (material->albedoTexture && material->albedoTexture->getGPUTexture()) {
+            if (material->useAlbedoMapOpacity && material->albedoTexture && material->albedoTexture->getGPUTexture()) {
+                material->_material->setTextureMap(model::MaterialKey::ALBEDO_MAP, material->_material->getTextureMap(model::MaterialKey::ALBEDO_MAP));
                 // Reset the materialKey transparentTexture key only, as it is albedoTexture-dependent
                 const auto& usage = material->albedoTexture->getGPUTexture()->getUsage();
                 bool isTransparentTexture = usage.isAlpha() && !usage.isAlphaMask();
-                material->_material->setTransparentTexture(isTransparentTexture);
+              //  material->_material->setTransparentTexture(isTransparentTexture);
                 // FIXME: Materials with *some* transparent textures seem to give all *other* textures alphas of 0.
                 _hasTransparentTextures = isTransparentTexture && _hasTransparentTextures;
             }
@@ -376,9 +377,21 @@ static NetworkMaterial* buildNetworkMaterial(NetworkGeometry* geometry, const FB
         auto albedoMap = setupNetworkTextureMap(geometry, textureBaseUrl, material.albedoTexture, DEFAULT_TEXTURE,
             networkMaterial->albedoTexture, networkMaterial->albedoTextureName);
         albedoMap->setTextureTransform(material.albedoTexture.transform);
+
+        if (!material.opacityTexture.filename.isEmpty()) {
+            if (material.albedoTexture.filename == material.opacityTexture.filename) {
+                // Best case scenario, just indicating that the albedo map contains transparency
+                networkMaterial->useAlbedoMapOpacity;
+                albedoMap->setUseAlphaChannel(true);
+            } else {
+                // Opacity Map is different from the Abledo map, not supported
+            }
+        }
+
         material._material->setTextureMap(model::MaterialKey::ALBEDO_MAP, albedoMap);
     }
 
+
     if (!material.normalTexture.filename.isEmpty()) {
         auto normalMap = setupNetworkTextureMap(geometry, textureBaseUrl, material.normalTexture,
             (material.normalTexture.isBumpmap ? BUMP_TEXTURE : NORMAL_TEXTURE),
diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h
index 7f01bdafaa..b172bb70b4 100644
--- a/libraries/model-networking/src/model-networking/ModelCache.h
+++ b/libraries/model-networking/src/model-networking/ModelCache.h
@@ -199,6 +199,7 @@ public:
     QSharedPointer<NetworkTexture> occlusionTexture;
     QString lightmapTextureName;
     QSharedPointer<NetworkTexture> lightmapTexture;
+    bool useAlbedoMapOpacity{ false };
 
 };
 
diff --git a/libraries/model/src/model/Material.cpp b/libraries/model/src/model/Material.cpp
index 306867c204..21fdab59a3 100755
--- a/libraries/model/src/model/Material.cpp
+++ b/libraries/model/src/model/Material.cpp
@@ -51,7 +51,7 @@ void Material::setEmissive(const Color&  emissive, bool isSRGB) {
 }
 
 void Material::setOpacity(float opacity) {
-    _key.setTransparent((opacity < 1.0f));
+    _key.setTransparentFactor((opacity < 1.0f));
     _schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
     _schemaBuffer.edit<Schema>()._opacity = opacity;
 }
@@ -80,19 +80,52 @@ void Material::setMetallic(float metallic) {
     _schemaBuffer.edit<Schema>()._metallic = metallic;
 }
 
-void Material::setTransparentTexture(bool isTransparent) {
-    _key.setTransparentTexture(isTransparent);
-    _schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
-}
 
 void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textureMap) {
     if (textureMap) {
         _key.setMapChannel(channel, (true));
+
+        if (channel == MaterialKey::ALBEDO_MAP) {
+            if (textureMap->useAlphaChannel()) {
+                if (textureMap->isDefined()) {
+                    if (textureMap->getTextureView().isValid()) {
+                        auto usage = textureMap->getTextureView()._texture->getUsage();
+                        if (usage.isAlpha()) {
+                            // Texture has alpha, is nut just a mask or a true transparent channel
+                            if (!usage.isAlphaMask()) {
+                                _key.setOpacityMaskMap(true);
+                                _key.setTransparentMap(false);
+                            } else {
+                                _key.setOpacityMaskMap(false);
+                                _key.setTransparentMap(true);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
         _schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
         _textureMaps[channel] = textureMap;
     } else {
         _key.setMapChannel(channel, (false));
+
+        if (channel == MaterialKey::ALBEDO_MAP) {
+            _key.setOpacityMaskMap(false);
+            _key.setTransparentMap(false);
+        }
+
         _schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
         _textureMaps.erase(channel);
     }
 }
+
+
+const TextureMapPointer Material::getTextureMap(MapChannel channel) const {
+    auto result = _textureMaps.find(channel);
+    if (result != _textureMaps.end()) {
+        return (result->second);
+    } else {
+        return TextureMapPointer();
+    }
+}
\ No newline at end of file
diff --git a/libraries/model/src/model/Material.h b/libraries/model/src/model/Material.h
index 078fc6499a..0cef46f788 100755
--- a/libraries/model/src/model/Material.h
+++ b/libraries/model/src/model/Material.h
@@ -31,14 +31,14 @@ public:
         ALBEDO_VAL_BIT,
         METALLIC_VAL_BIT,
         GLOSSY_VAL_BIT,
-        TRANSPARENT_VAL_BIT,
-        TRANSPARENT_TEX_VAL_BIT,
+        OPACITY_VAL_BIT,
 
         EMISSIVE_MAP_BIT,
         ALBEDO_MAP_BIT,
+        OPACITY_MASK_MAP_BIT,           // OPacity Map and Opacity MASK map are mutually exclusive
+        OPACITY_TRANSPARENT_MAP_BIT,
         METALLIC_MAP_BIT,
         ROUGHNESS_MAP_BIT,
-        TRANSPARENT_MAP_BIT,
         NORMAL_MAP_BIT,
         OCCLUSION_MAP_BIT,
         LIGHTMAP_MAP_BIT,
@@ -52,7 +52,6 @@ public:
         ALBEDO_MAP,
         METALLIC_MAP,
         ROUGHNESS_MAP,
-        TRANSPARENT_MAP,
         NORMAL_MAP,
         OCCLUSION_MAP,
         LIGHTMAP_MAP,
@@ -77,13 +76,15 @@ public:
         Builder& withAlbedo() { _flags.set(ALBEDO_VAL_BIT); return (*this); }
         Builder& withMetallic() { _flags.set(METALLIC_VAL_BIT); return (*this); }
         Builder& withGlossy() { _flags.set(GLOSSY_VAL_BIT); return (*this); }
-        Builder& withTransparent() { _flags.set(TRANSPARENT_VAL_BIT); return (*this); }
+        Builder& withOpacity() { _flags.set(OPACITY_VAL_BIT); return (*this); }
 
         Builder& withEmissiveMap() { _flags.set(EMISSIVE_MAP_BIT); return (*this); }
         Builder& withAlbedoMap() { _flags.set(ALBEDO_MAP_BIT); return (*this); }
         Builder& withMetallicMap() { _flags.set(METALLIC_MAP_BIT); return (*this); }
         Builder& withRoughnessMap() { _flags.set(ROUGHNESS_MAP_BIT); return (*this); }
-        Builder& withTransparentMap() { _flags.set(TRANSPARENT_MAP_BIT); return (*this); }
+
+        Builder& withTransparentMap() { _flags.set(OPACITY_TRANSPARENT_MAP_BIT); return (*this); }
+        Builder& withMaskMap() { _flags.set(OPACITY_MASK_MAP_BIT); return (*this); }
 
         Builder& withNormalMap() { _flags.set(NORMAL_MAP_BIT); return (*this); }
         Builder& withOcclusionMap() { _flags.set(OCCLUSION_MAP_BIT); return (*this); }
@@ -102,9 +103,6 @@ public:
     void setAlbedo(bool value) { _flags.set(ALBEDO_VAL_BIT, value); }
     bool isAlbedo() const { return _flags[ALBEDO_VAL_BIT]; }
 
-    void setTransparentTexture(bool value) { _flags.set(TRANSPARENT_TEX_VAL_BIT, value); }
-    bool isTransparentTexture() const { return _flags[TRANSPARENT_TEX_VAL_BIT]; }
-
     void setAlbedoMap(bool value) { _flags.set(ALBEDO_MAP_BIT, value); }
     bool isAlbedoMap() const { return _flags[ALBEDO_MAP_BIT]; }
 
@@ -121,13 +119,16 @@ public:
     void setRoughnessMap(bool value) { _flags.set(ROUGHNESS_MAP_BIT, value); }
     bool isRoughnessMap() const { return _flags[ROUGHNESS_MAP_BIT]; }
 
-    void setTransparent(bool value) { _flags.set(TRANSPARENT_VAL_BIT, value); }
-    bool isTransparent() const { return _flags[TRANSPARENT_VAL_BIT]; }
-    bool isOpaque() const { return !_flags[TRANSPARENT_VAL_BIT]; }
+    void setTransparentFactor(bool value) { _flags.set(OPACITY_VAL_BIT, value); }
+    bool isTransparentFactor() const { return _flags[OPACITY_VAL_BIT]; }
+    bool isOpaqueFactor() const { return !_flags[OPACITY_VAL_BIT]; }
 
-    void setTransparentMap(bool value) { _flags.set(TRANSPARENT_MAP_BIT, value); }
-    bool isTransparentMap() const { return _flags[TRANSPARENT_MAP_BIT]; }
+    void setTransparentMap(bool value) { _flags.set(OPACITY_TRANSPARENT_MAP_BIT, value); }
+    bool isTransparentMap() const { return _flags[OPACITY_TRANSPARENT_MAP_BIT]; }
 
+    void setOpacityMaskMap(bool value) { _flags.set(OPACITY_MASK_MAP_BIT, value); }
+    bool isOpacityMaskMap() const { return _flags[OPACITY_MASK_MAP_BIT]; }
+    
     void setNormalMap(bool value) { _flags.set(NORMAL_MAP_BIT, value); }
     bool isNormalMap() const { return _flags[NORMAL_MAP_BIT]; }
 
@@ -168,9 +169,6 @@ public:
         Builder& withoutAlbedo()       { _value.reset(MaterialKey::ALBEDO_VAL_BIT); _mask.set(MaterialKey::ALBEDO_VAL_BIT); return (*this); }
         Builder& withAlbedo()        { _value.set(MaterialKey::ALBEDO_VAL_BIT);  _mask.set(MaterialKey::ALBEDO_VAL_BIT); return (*this); }
 
-        Builder& withoutTransparentTexture()       { _value.reset(MaterialKey::TRANSPARENT_TEX_VAL_BIT); _mask.set(MaterialKey::TRANSPARENT_TEX_VAL_BIT); return (*this); }
-        Builder& withTransparentTexture()        { _value.set(MaterialKey::TRANSPARENT_TEX_VAL_BIT);  _mask.set(MaterialKey::TRANSPARENT_TEX_VAL_BIT); return (*this); }
-
         Builder& withoutAlbedoMap()       { _value.reset(MaterialKey::ALBEDO_MAP_BIT); _mask.set(MaterialKey::ALBEDO_MAP_BIT); return (*this); }
         Builder& withAlbedoMap()        { _value.set(MaterialKey::ALBEDO_MAP_BIT);  _mask.set(MaterialKey::ALBEDO_MAP_BIT); return (*this); }
 
@@ -186,11 +184,15 @@ public:
         Builder& withoutRoughnessMap()       { _value.reset(MaterialKey::ROUGHNESS_MAP_BIT); _mask.set(MaterialKey::ROUGHNESS_MAP_BIT); return (*this); }
         Builder& withRoughnessMap()        { _value.set(MaterialKey::ROUGHNESS_MAP_BIT);  _mask.set(MaterialKey::ROUGHNESS_MAP_BIT); return (*this); }
 
-        Builder& withoutTransparent()       { _value.reset(MaterialKey::TRANSPARENT_VAL_BIT); _mask.set(MaterialKey::TRANSPARENT_VAL_BIT); return (*this); }
-        Builder& withTransparent()        { _value.set(MaterialKey::TRANSPARENT_VAL_BIT);  _mask.set(MaterialKey::TRANSPARENT_VAL_BIT); return (*this); }
+        Builder& withoutTransparentFactor()       { _value.reset(MaterialKey::OPACITY_VAL_BIT); _mask.set(MaterialKey::OPACITY_VAL_BIT); return (*this); }
+        Builder& withTransparentFactor()        { _value.set(MaterialKey::OPACITY_VAL_BIT);  _mask.set(MaterialKey::OPACITY_VAL_BIT); return (*this); }
+        Builder& withOpaqueFactor()        { return withoutTransparentFactor(); }
 
-        Builder& withoutTransparentMap()       { _value.reset(MaterialKey::TRANSPARENT_MAP_BIT); _mask.set(MaterialKey::TRANSPARENT_MAP_BIT); return (*this); }
-        Builder& withTransparentMap()        { _value.set(MaterialKey::TRANSPARENT_MAP_BIT);  _mask.set(MaterialKey::TRANSPARENT_MAP_BIT); return (*this); }
+        Builder& withoutTransparentMap()       { _value.reset(MaterialKey::OPACITY_TRANSPARENT_MAP_BIT); _mask.set(MaterialKey::OPACITY_TRANSPARENT_MAP_BIT); return (*this); }
+        Builder& withTransparentMap()        { _value.set(MaterialKey::OPACITY_TRANSPARENT_MAP_BIT);  _mask.set(MaterialKey::OPACITY_TRANSPARENT_MAP_BIT); return (*this); }
+
+        Builder& withoutMaskMap()       { _value.reset(MaterialKey::OPACITY_MASK_MAP_BIT); _mask.set(MaterialKey::OPACITY_MASK_MAP_BIT); return (*this); }
+        Builder& withMaskMap()        { _value.set(MaterialKey::OPACITY_MASK_MAP_BIT);  _mask.set(MaterialKey::OPACITY_MASK_MAP_BIT); return (*this); }
 
         Builder& withoutNormalMap()       { _value.reset(MaterialKey::NORMAL_MAP_BIT); _mask.set(MaterialKey::NORMAL_MAP_BIT); return (*this); }
         Builder& withNormalMap()        { _value.set(MaterialKey::NORMAL_MAP_BIT);  _mask.set(MaterialKey::NORMAL_MAP_BIT); return (*this); }
@@ -202,7 +204,7 @@ public:
         Builder& withLightmapMap()        { _value.set(MaterialKey::LIGHTMAP_MAP_BIT);  _mask.set(MaterialKey::LIGHTMAP_MAP_BIT); return (*this); }
 
         // Convenient standard keys that we will keep on using all over the place
-        static MaterialFilter opaqueAlbedo() { return Builder().withAlbedo().withoutTransparent().build(); }
+        static MaterialFilter opaqueAlbedo() { return Builder().withAlbedo().withOpaqueFactor().build(); }
     };
 
     // Item Filter operator testing if a key pass the filter
@@ -255,7 +257,6 @@ public:
     void setRoughness(float roughness);
     float getRoughness() const { return _schemaBuffer.get<Schema>()._roughness; }
 
-    void setTransparentTexture(bool isTransparent);
 
     // Schema to access the attribute values of the material
     class Schema {
@@ -283,6 +284,7 @@ public:
     // The texture map to channel association
     void setTextureMap(MapChannel channel, const TextureMapPointer& textureMap);
     const TextureMaps& getTextureMaps() const { return _textureMaps; }
+    const TextureMapPointer getTextureMap(MapChannel channel) const;
 
     // conversion from legacy material properties to PBR equivalent
     static float shininessToRoughness(float shininess) { return 1.0f - shininess / 100.0f; }
diff --git a/libraries/model/src/model/TextureMap.h b/libraries/model/src/model/TextureMap.h
index 228adb25e6..e845aebb81 100755
--- a/libraries/model/src/model/TextureMap.h
+++ b/libraries/model/src/model/TextureMap.h
@@ -56,6 +56,9 @@ public:
     void setTextureTransform(const Transform& texcoordTransform);
     const Transform& getTextureTransform() const { return _texcoordTransform; }
 
+    void setUseAlphaChannel(bool useAlpha) { _useAlphaChannel = useAlpha; }
+    bool useAlphaChannel() const { return _useAlphaChannel; }
+
     void setLightmapOffsetScale(float offset, float scale);
     const glm::vec2& getLightmapOffsetScale() const { return _lightmapOffsetScale; }
 
@@ -64,6 +67,8 @@ protected:
 
     Transform _texcoordTransform;
     glm::vec2 _lightmapOffsetScale{ 0.0f, 1.0f };
+
+    bool _useAlphaChannel{ false };
 };
 typedef std::shared_ptr< TextureMap > TextureMapPointer;
 
diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp
index 4ae5b4532a..2e66fe43f2 100644
--- a/libraries/render-utils/src/MeshPartPayload.cpp
+++ b/libraries/render-utils/src/MeshPartPayload.cpp
@@ -81,7 +81,7 @@ ItemKey MeshPartPayload::getKey() const {
 
     if (_drawMaterial) {
         auto matKey = _drawMaterial->getKey();
-        if (matKey.isTransparent() || matKey.isTransparentTexture() || matKey.isTransparentMap()) {
+        if (matKey.isTransparentFactor() || matKey.isTransparentMap()) {
             builder.withTransparent();
         }
     }
@@ -100,7 +100,7 @@ ShapeKey MeshPartPayload::getShapeKey() const {
     }
 
     ShapeKey::Builder builder;
-    if (drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentTexture() || drawMaterialKey.isTransparentMap()) {
+    if (drawMaterialKey.isTransparentFactor() || drawMaterialKey.isTransparentMap()) {
         builder.withTranslucent();
     }
     if (drawMaterialKey.isNormalMap()) {
@@ -365,7 +365,7 @@ ItemKey ModelMeshPartPayload::getKey() const {
 
     if (_drawMaterial) {
         auto matKey = _drawMaterial->getKey();
-        if (matKey.isTransparent() || matKey.isTransparentTexture() || matKey.isTransparentMap()) {
+        if (matKey.isTransparentFactor() || matKey.isTransparentMap()) {
             builder.withTransparent();
         }
     }
@@ -413,7 +413,7 @@ ShapeKey ModelMeshPartPayload::getShapeKey() const {
     }
 
     bool isTranslucent =
-        drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentTexture() || drawMaterialKey.isTransparentMap();
+        drawMaterialKey.isTransparentFactor() || drawMaterialKey.isTransparentMap();
     bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty();
     bool hasSpecular = drawMaterialKey.isMetallicMap();
     bool hasLightmap = drawMaterialKey.isLightmapMap();