From ee1fb698a4656b7b22fb87b5a9d79a8f26a7428a Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 8 Mar 2016 12:50:21 -0800 Subject: [PATCH 1/5] Add texture transparency to material key --- libraries/model/src/model/Material.cpp | 7 +++--- libraries/model/src/model/Material.h | 12 ++++++++-- libraries/model/src/model/Material.slh | 24 +++++++++---------- .../render-utils/src/MeshPartPayload.cpp | 9 +++---- 4 files changed, 30 insertions(+), 22 deletions(-) diff --git a/libraries/model/src/model/Material.cpp b/libraries/model/src/model/Material.cpp index 10fa15edd5..306867c204 100755 --- a/libraries/model/src/model/Material.cpp +++ b/libraries/model/src/model/Material.cpp @@ -80,6 +80,10 @@ void Material::setMetallic(float metallic) { _schemaBuffer.edit()._metallic = metallic; } +void Material::setTransparentTexture(bool isTransparent) { + _key.setTransparentTexture(isTransparent); + _schemaBuffer.edit()._key = (uint32)_key._flags.to_ulong(); +} void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textureMap) { if (textureMap) { @@ -92,6 +96,3 @@ void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textur _textureMaps.erase(channel); } } - - - diff --git a/libraries/model/src/model/Material.h b/libraries/model/src/model/Material.h index b22f8a3f42..078fc6499a 100755 --- a/libraries/model/src/model/Material.h +++ b/libraries/model/src/model/Material.h @@ -32,6 +32,7 @@ public: METALLIC_VAL_BIT, GLOSSY_VAL_BIT, TRANSPARENT_VAL_BIT, + TRANSPARENT_TEX_VAL_BIT, EMISSIVE_MAP_BIT, ALBEDO_MAP_BIT, @@ -101,6 +102,9 @@ 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]; } @@ -164,6 +168,9 @@ 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); } @@ -248,6 +255,8 @@ public: void setRoughness(float roughness); float getRoughness() const { return _schemaBuffer.get()._roughness; } + void setTransparentTexture(bool isTransparent); + // Schema to access the attribute values of the material class Schema { public: @@ -260,8 +269,7 @@ public: glm::vec3 _fresnel{ 0.03f }; // Fresnel value for a default non metallic float _metallic{ 0.0f }; // Not Metallic - - glm::vec3 _spare0{ 0.0f }; + glm::vec3 _spare{ 0.0f }; uint32_t _key{ 0 }; // a copy of the materialKey diff --git a/libraries/model/src/model/Material.slh b/libraries/model/src/model/Material.slh index d75f3df5e0..da185ddf0b 100644 --- a/libraries/model/src/model/Material.slh +++ b/libraries/model/src/model/Material.slh @@ -15,7 +15,7 @@ struct Material { vec4 _emissiveOpacity; vec4 _albedoRoughness; vec4 _fresnelMetallic; - vec4 _spare; + vec4 _spareKey; }; uniform materialBuffer { @@ -37,25 +37,23 @@ float getMaterialMetallic(Material m) { return m._fresnelMetallic.a; } float getMaterialShininess(Material m) { return 1.0 - getMaterialRoughness(m); } -int getMaterialKey(Material m) { return floatBitsToInt(m._spare.w); } +int getMaterialKey(Material m) { return floatBitsToInt(m._spareKey.w); } const int EMISSIVE_VAL_BIT = 0x00000001; const int ALBEDO_VAL_BIT = 0x00000002; const int METALLIC_VAL_BIT = 0x00000004; const int GLOSSY_VAL_BIT = 0x00000008; const int TRANSPARENT_VAL_BIT = 0x00000010; +const int TRANSPARENT_TEX_VAL_BIT = 0x00000020; +const int EMISSIVE_MAP_BIT = 0x00000040; +const int ALBEDO_MAP_BIT = 0x00000080; +const int METALLIC_MAP_BIT = 0x00000100; +const int ROUGHNESS_MAP_BIT = 0x00000200; +const int TRANSPARENT_MAP_BIT = 0x00000400; +const int NORMAL_MAP_BIT = 0x00000800; +const int OCCLUSION_MAP_BIT = 0x00001000; -const int EMISSIVE_MAP_BIT = 0x00000020; -const int ALBEDO_MAP_BIT = 0x00000040; -const int METALLIC_MAP_BIT = 0x00000080; -const int ROUGHNESS_MAP_BIT = 0x00000100; -const int TRANSPARENT_MAP_BIT = 0x00000200; -const int NORMAL_MAP_BIT = 0x00000400; -const int OCCLUSION_MAP_BIT = 0x00000800; - -const int LIGHTMAP_MAP_BIT = 0x00001000; - - +const int LIGHTMAP_MAP_BIT = 0x00002000; <@endif@> diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 166b14333f..4ae5b4532a 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.isTransparentMap()) { + if (matKey.isTransparent() || matKey.isTransparentTexture() || matKey.isTransparentMap()) { builder.withTransparent(); } } @@ -100,7 +100,7 @@ ShapeKey MeshPartPayload::getShapeKey() const { } ShapeKey::Builder builder; - if (drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentMap()) { + if (drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentTexture() || 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.isTransparentMap()) { + if (matKey.isTransparent() || matKey.isTransparentTexture() || matKey.isTransparentMap()) { builder.withTransparent(); } } @@ -412,7 +412,8 @@ ShapeKey ModelMeshPartPayload::getShapeKey() const { drawMaterialKey = _drawMaterial->getKey(); } - bool isTranslucent = drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentMap(); + bool isTranslucent = + drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentTexture() || drawMaterialKey.isTransparentMap(); bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty(); bool hasSpecular = drawMaterialKey.isMetallicMap(); bool hasLightmap = drawMaterialKey.isLightmapMap(); From 22d41c833f8b8b7bde69994ebd521b48badc48dd Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Mon, 29 Feb 2016 19:26:18 -0800 Subject: [PATCH 2/5] Update loaded models with texture transparency --- .../model-networking/src/model-networking/ModelCache.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 21eed5f59f..29c517594a 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -145,7 +145,13 @@ bool NetworkGeometry::isLoadedWithTextures() const { (material->lightmapTexture && !material->lightmapTexture->isLoaded())) { return false; } + if (material->albedoTexture) { + // Reset the materialKey transparentTexture key only, as it is albedoTexture-dependent + const auto& usage = material->albedoTexture->getGPUTexture()->getUsage(); + material->_material->setTransparentTexture(usage.isAlpha() && !usage.isAlphaMask()); + } } + _isLoadedWithTextures = true; } return true; From 3b62e203f754717c49ea256c425642801d251759 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Fri, 11 Mar 2016 14:25:21 -0800 Subject: [PATCH 3/5] Cache NetworkGeometry::_hasTransparentTextures --- .../model-networking/src/model-networking/ModelCache.cpp | 6 +++++- .../model-networking/src/model-networking/ModelCache.h | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 29c517594a..af9fe97e93 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -135,6 +135,8 @@ bool NetworkGeometry::isLoadedWithTextures() const { } if (!_isLoadedWithTextures) { + _hasTransparentTextures = false; + for (auto&& material : _materials) { if ((material->albedoTexture && !material->albedoTexture->isLoaded()) || (material->normalTexture && !material->normalTexture->isLoaded()) || @@ -148,7 +150,9 @@ bool NetworkGeometry::isLoadedWithTextures() const { if (material->albedoTexture) { // Reset the materialKey transparentTexture key only, as it is albedoTexture-dependent const auto& usage = material->albedoTexture->getGPUTexture()->getUsage(); - material->_material->setTransparentTexture(usage.isAlpha() && !usage.isAlphaMask()); + bool isTransparentTexture = usage.isAlpha() && !usage.isAlphaMask(); + material->_material->setTransparentTexture(isTransparentTexture); + _hasTransparentTextures = _hasTransparentTextures || isTransparentTexture; } } diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h index 60f185f691..7f01bdafaa 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.h +++ b/libraries/model-networking/src/model-networking/ModelCache.h @@ -75,6 +75,10 @@ public: // true when the requested geometry and its textures are loaded. bool isLoadedWithTextures() const; + // true if the albedo texture has a non-masking alpha channel. + // This can only be known after isLoadedWithTextures(). + bool hasTransparentTextures() const { return _hasTransparentTextures; } + // WARNING: only valid when isLoaded returns true. const FBXGeometry& getFBXGeometry() const { return *_geometry; } const std::vector>& getMeshes() const { return _meshes; } @@ -151,6 +155,7 @@ protected: // cache for isLoadedWithTextures() mutable bool _isLoadedWithTextures = false; + mutable bool _hasTransparentTextures = false; }; /// Reads geometry in a worker thread. From a89a76dc4b8034833bea89fa6c011ffd91eb62bd Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Fri, 11 Mar 2016 14:25:39 -0800 Subject: [PATCH 4/5] Require model fixup if tex is transparent --- libraries/render-utils/src/Model.cpp | 17 +++++++++++++++++ libraries/render-utils/src/Model.h | 12 +++++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index ce6dfd6849..8b6cc41f35 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -74,6 +74,21 @@ Model::~Model() { AbstractViewStateInterface* Model::_viewState = NULL; +bool Model::needsFixupInScene() { + if (readyToAddToScene()) { + // Once textures are loaded, fixup if they are now transparent + if (!_needsReload && _needsUpdateTransparentTextures && _geometry->isLoadedWithTextures()) { + _needsUpdateTransparentTextures = false; + if (_hasTransparentTextures != _geometry->hasTransparentTextures()) { + return true; + } + } + if (!_readyWhenAdded) { + return true; + } + } + return false; +} void Model::setTranslation(const glm::vec3& translation) { _translation = translation; @@ -728,6 +743,8 @@ void Model::setURL(const QUrl& url) { } _needsReload = true; + _needsUpdateTransparentTextures = true; + _hasTransparentTextures = false; _meshGroupsKnown = false; invalidCalculatedMeshBoxes(); deleteGeometry(); diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 424eed1e66..e90d51813b 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -70,7 +70,7 @@ public: // new Scene/Engine rendering support void setVisibleInScene(bool newValue, std::shared_ptr scene); - bool needsFixupInScene() { return !_readyWhenAdded && readyToAddToScene(); } + bool needsFixupInScene(); bool readyToAddToScene(RenderArgs* renderArgs = nullptr) { return !_needsReload && isRenderable() && isActive() && isLoaded(); } @@ -365,10 +365,12 @@ protected: QSet> _renderItemsSet; QMap _renderItems; - bool _readyWhenAdded = false; - bool _needsReload = true; - bool _needsUpdateClusterMatrices = true; - bool _showCollisionHull = false; + bool _readyWhenAdded { false }; + bool _needsReload { true }; + bool _needsUpdateClusterMatrices { true }; + bool _needsUpdateTransparentTextures { true }; + bool _hasTransparentTextures { false }; + bool _showCollisionHull { false }; friend class ModelMeshPartPayload; RigPointer _rig; From 9dcdf26567f5829b9973ede55b5c27b47988eb05 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Fri, 11 Mar 2016 15:15:30 -0800 Subject: [PATCH 5/5] Only consider model transparent if all texs are --- .../model-networking/src/model-networking/ModelCache.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index af9fe97e93..3f7e0405d4 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -135,7 +135,7 @@ bool NetworkGeometry::isLoadedWithTextures() const { } if (!_isLoadedWithTextures) { - _hasTransparentTextures = false; + _hasTransparentTextures = true; for (auto&& material : _materials) { if ((material->albedoTexture && !material->albedoTexture->isLoaded()) || @@ -152,7 +152,8 @@ bool NetworkGeometry::isLoadedWithTextures() const { const auto& usage = material->albedoTexture->getGPUTexture()->getUsage(); bool isTransparentTexture = usage.isAlpha() && !usage.isAlphaMask(); material->_material->setTransparentTexture(isTransparentTexture); - _hasTransparentTextures = _hasTransparentTextures || isTransparentTexture; + // FIXME: Materials with *some* transparent textures seem to give all *other* textures alphas of 0. + _hasTransparentTextures = isTransparentTexture && _hasTransparentTextures; } }