From 225b330d416a70e6ed1b8f1b8cc82d22d6400622 Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 18 Mar 2016 12:47:33 -0700 Subject: [PATCH 1/8] Trying to better load aand detect the case for transparent textures oor opacity mask --- .../src/model-networking/ModelCache.cpp | 17 ++++++- .../src/model-networking/ModelCache.h | 1 + libraries/model/src/model/Material.cpp | 43 +++++++++++++++-- libraries/model/src/model/Material.h | 48 ++++++++++--------- libraries/model/src/model/TextureMap.h | 5 ++ .../render-utils/src/MeshPartPayload.cpp | 8 ++-- 6 files changed, 88 insertions(+), 34 deletions(-) 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 occlusionTexture; QString lightmapTextureName; QSharedPointer 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()._key = (uint32)_key._flags.to_ulong(); _schemaBuffer.edit()._opacity = opacity; } @@ -80,19 +80,52 @@ 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) { _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()._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()._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()._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(); From f7847f656163b7c2c9fc54f8a8157d269367b4ef Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 18 Mar 2016 17:32:00 -0700 Subject: [PATCH 2/8] Trying to fix names --- libraries/model/src/model/Material.h | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/libraries/model/src/model/Material.h b/libraries/model/src/model/Material.h index 0cef46f788..f590b73b85 100755 --- a/libraries/model/src/model/Material.h +++ b/libraries/model/src/model/Material.h @@ -36,7 +36,7 @@ public: EMISSIVE_MAP_BIT, ALBEDO_MAP_BIT, OPACITY_MASK_MAP_BIT, // OPacity Map and Opacity MASK map are mutually exclusive - OPACITY_TRANSPARENT_MAP_BIT, + OPACITY_TRANSLUCENT_MAP_BIT, METALLIC_MAP_BIT, ROUGHNESS_MAP_BIT, NORMAL_MAP_BIT, @@ -83,7 +83,7 @@ public: Builder& withMetallicMap() { _flags.set(METALLIC_MAP_BIT); return (*this); } Builder& withRoughnessMap() { _flags.set(ROUGHNESS_MAP_BIT); return (*this); } - Builder& withTransparentMap() { _flags.set(OPACITY_TRANSPARENT_MAP_BIT); return (*this); } + Builder& withTransparentMap() { _flags.set(OPACITY_TRANSLUCENT_MAP_BIT); return (*this); } Builder& withMaskMap() { _flags.set(OPACITY_MASK_MAP_BIT); return (*this); } Builder& withNormalMap() { _flags.set(NORMAL_MAP_BIT); return (*this); } @@ -119,12 +119,11 @@ public: void setRoughnessMap(bool value) { _flags.set(ROUGHNESS_MAP_BIT, value); } bool isRoughnessMap() const { return _flags[ROUGHNESS_MAP_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 setTranslucentFactor(bool value) { _flags.set(OPACITY_VAL_BIT, value); } + bool isTranslucentFactor() const { return _flags[OPACITY_VAL_BIT]; } - void setTransparentMap(bool value) { _flags.set(OPACITY_TRANSPARENT_MAP_BIT, value); } - bool isTransparentMap() const { return _flags[OPACITY_TRANSPARENT_MAP_BIT]; } + void setTransparentMap(bool value) { _flags.set(OPACITY_TRANSLUCENT_MAP_BIT, value); } + bool isOpacityMap() const { return _flags[OPACITY_TRANSLUCENT_MAP_BIT]; } void setOpacityMaskMap(bool value) { _flags.set(OPACITY_MASK_MAP_BIT, value); } bool isOpacityMaskMap() const { return _flags[OPACITY_MASK_MAP_BIT]; } @@ -188,8 +187,8 @@ public: 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::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& withoutTransparentMap() { _value.reset(MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT); _mask.set(MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT); return (*this); } + Builder& withTransparentMap() { _value.set(MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT); _mask.set(MaterialKey::OPACITY_TRANSLUCENT_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); } From 227ddb12a6f0af743fa29263625e0fdb22a8e098 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 21 Mar 2016 12:14:59 -0700 Subject: [PATCH 3/8] Trying to clen up the way the opacity final value comes to the fragment shader --- libraries/model/src/model/Material.cpp | 8 +++--- libraries/model/src/model/Material.h | 25 +++++++++++-------- libraries/model/src/model/Material.slh | 20 +++++++-------- .../render-utils/src/MaterialTextures.slh | 19 +++++++++++++- .../render-utils/src/MeshPartPayload.cpp | 9 +++---- libraries/render-utils/src/model.slf | 6 ++++- .../render-utils/src/model_normal_map.slf | 6 ++++- .../src/model_normal_specular_map.slf | 6 ++++- .../render-utils/src/model_specular_map.slf | 6 ++++- .../render-utils/src/model_translucent.slf | 8 +++--- 10 files changed, 76 insertions(+), 37 deletions(-) diff --git a/libraries/model/src/model/Material.cpp b/libraries/model/src/model/Material.cpp index 21fdab59a3..5f5c93eb61 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.setTransparentFactor((opacity < 1.0f)); + _key.setTranslucentFactor((opacity < 1.0f)); _schemaBuffer.edit()._key = (uint32)_key._flags.to_ulong(); _schemaBuffer.edit()._opacity = opacity; } @@ -94,10 +94,10 @@ void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textur // Texture has alpha, is nut just a mask or a true transparent channel if (!usage.isAlphaMask()) { _key.setOpacityMaskMap(true); - _key.setTransparentMap(false); + _key.setTranslucentMap(false); } else { _key.setOpacityMaskMap(false); - _key.setTransparentMap(true); + _key.setTranslucentMap(true); } } } @@ -112,7 +112,7 @@ void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textur if (channel == MaterialKey::ALBEDO_MAP) { _key.setOpacityMaskMap(false); - _key.setTransparentMap(false); + _key.setTranslucentMap(false); } _schemaBuffer.edit()._key = (uint32)_key._flags.to_ulong(); diff --git a/libraries/model/src/model/Material.h b/libraries/model/src/model/Material.h index f590b73b85..2527c8e1e1 100755 --- a/libraries/model/src/model/Material.h +++ b/libraries/model/src/model/Material.h @@ -76,14 +76,14 @@ 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& withOpacity() { _flags.set(OPACITY_VAL_BIT); return (*this); } + Builder& withTranslucentFactor() { _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(OPACITY_TRANSLUCENT_MAP_BIT); return (*this); } + Builder& withTranslucentMap() { _flags.set(OPACITY_TRANSLUCENT_MAP_BIT); return (*this); } Builder& withMaskMap() { _flags.set(OPACITY_MASK_MAP_BIT); return (*this); } Builder& withNormalMap() { _flags.set(NORMAL_MAP_BIT); return (*this); } @@ -122,8 +122,8 @@ public: void setTranslucentFactor(bool value) { _flags.set(OPACITY_VAL_BIT, value); } bool isTranslucentFactor() const { return _flags[OPACITY_VAL_BIT]; } - void setTransparentMap(bool value) { _flags.set(OPACITY_TRANSLUCENT_MAP_BIT, value); } - bool isOpacityMap() const { return _flags[OPACITY_TRANSLUCENT_MAP_BIT]; } + void setTranslucentMap(bool value) { _flags.set(OPACITY_TRANSLUCENT_MAP_BIT, value); } + bool isTranslucentMap() const { return _flags[OPACITY_TRANSLUCENT_MAP_BIT]; } void setOpacityMaskMap(bool value) { _flags.set(OPACITY_MASK_MAP_BIT, value); } bool isOpacityMaskMap() const { return _flags[OPACITY_MASK_MAP_BIT]; } @@ -140,6 +140,12 @@ public: void setMapChannel(MapChannel channel, bool value) { _flags.set(EMISSIVE_MAP_BIT + channel, value); } bool isMapChannel(MapChannel channel) const { return _flags[EMISSIVE_MAP_BIT + channel]; } + + // Translucency and Opacity Heuristics are combining several flags: + bool isTranslucent() const { return isTranslucentFactor() || isTranslucentMap(); } + bool isOpaque() const { return !isTranslucent(); } + bool isSurfaceOpaque() const { return isOpaque() && !isOpacityMaskMap(); } + bool isTexelOpaque() const { return isOpaque() && isOpacityMaskMap(); } }; @@ -183,12 +189,11 @@ 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& 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& withoutTranslucentFactor() { _value.reset(MaterialKey::OPACITY_VAL_BIT); _mask.set(MaterialKey::OPACITY_VAL_BIT); return (*this); } + Builder& withTranslucentFactor() { _value.set(MaterialKey::OPACITY_VAL_BIT); _mask.set(MaterialKey::OPACITY_VAL_BIT); return (*this); } - Builder& withoutTransparentMap() { _value.reset(MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT); _mask.set(MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT); return (*this); } - Builder& withTransparentMap() { _value.set(MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT); _mask.set(MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT); return (*this); } + Builder& withoutTranslucentMap() { _value.reset(MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT); _mask.set(MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT); return (*this); } + Builder& withTranslucentMap() { _value.set(MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT); _mask.set(MaterialKey::OPACITY_TRANSLUCENT_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); } @@ -203,7 +208,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().withOpaqueFactor().build(); } + static MaterialFilter opaqueAlbedo() { return Builder().withAlbedo().withoutTranslucentFactor().build(); } }; // Item Filter operator testing if a key pass the filter diff --git a/libraries/model/src/model/Material.slh b/libraries/model/src/model/Material.slh index da185ddf0b..e8c9d3d6bc 100644 --- a/libraries/model/src/model/Material.slh +++ b/libraries/model/src/model/Material.slh @@ -43,17 +43,17 @@ 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 OPACITY_VAL_BIT = 0x00000010; -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 OPACITY_MASK_MAP_BIT = 0x00000080; +const int OPACITY_TRANSLUCENT_MAP_BIT = 0x00000100; +const int METALLIC_MAP_BIT = 0x00000200; +const int ROUGHNESS_MAP_BIT = 0x00000400; +const int NORMAL_MAP_BIT = 0x00001000; +const int OCCLUSION_MAP_BIT = 0x00002000; +const int LIGHTMAP_MAP_BIT = 0x00004000; -const int LIGHTMAP_MAP_BIT = 0x00002000; <@endif@> diff --git a/libraries/render-utils/src/MaterialTextures.slh b/libraries/render-utils/src/MaterialTextures.slh index 8904ae34b2..ef8c30a97f 100644 --- a/libraries/render-utils/src/MaterialTextures.slh +++ b/libraries/render-utils/src/MaterialTextures.slh @@ -59,7 +59,7 @@ float fetchOcclusionMap(vec2 uv) { <@func fetchMaterialTextures(matKey, texcoord0, albedo, roughness, normal, metallic, emissive, occlusion)@> <@if albedo@> - vec4 <$albedo$> = (((<$matKey$> & ALBEDO_MAP_BIT) != 0) ? fetchAlbedoMap(<$texcoord0$>) : vec4(1.0)); + vec4 <$albedo$> = (((<$matKey$> & (ALBEDO_MAP_BIT | OPACITY_MASK_MAP_BIT | OPACITY_TRANSLUCENT_MAP_BIT)) != 0) ? fetchAlbedoMap(<$texcoord0$>) : vec4(1.0)); <@endif@> <@if roughness@> float <$roughness$> = (((<$matKey$> & ROUGHNESS_MAP_BIT) != 0) ? fetchRoughnessMap(<$texcoord0$>) : 1.0); @@ -112,6 +112,23 @@ vec3 fetchLightmapMap(vec2 uv) { } <@endfunc@> +<@func evalMaterialOpacity(fetchedOpacity, materialOpacity, matKey, opacity)@> +{ + const float OPACITY_MASK_THRESHOLD = 0.5; + <$opacity$> = (((<$matKey$> & (OPACITY_TRANSLUCENCY_MAP_BIT | OPACITY_MASK_MAP_BIT)) != 0) ? + (((<$matKey$> & OPACITY_MASK_MAP_BIT) != 0) ? step(OPACITY_MASK_THRESHOLD, <$fetchedOpacity$>) : <$fetchedOpacity$>) : + 1.0) * <$materialOpacity$>; +} +<@endfunc@> + +<@func $discardTransparent(opacity)@> +{ + if (<$opacity$> < 1.0) { + discard; + } +} +<@endfunc@> + <@func evalMaterialRoughness(fetchedRoughness, materialRoughness, matKey, roughness)@> { <$roughness$> = (((<$matKey$> & ROUGHNESS_MAP_BIT) != 0) ? <$fetchedRoughness$> : <$materialRoughness$>); diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 2e66fe43f2..aca9774221 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.isTransparentFactor() || matKey.isTransparentMap()) { + if (matKey.isTranslucentFactor() || matKey.isTranslucentMap()) { builder.withTransparent(); } } @@ -100,7 +100,7 @@ ShapeKey MeshPartPayload::getShapeKey() const { } ShapeKey::Builder builder; - if (drawMaterialKey.isTransparentFactor() || drawMaterialKey.isTransparentMap()) { + if (drawMaterialKey.isTranslucent()) { builder.withTranslucent(); } if (drawMaterialKey.isNormalMap()) { @@ -365,7 +365,7 @@ ItemKey ModelMeshPartPayload::getKey() const { if (_drawMaterial) { auto matKey = _drawMaterial->getKey(); - if (matKey.isTransparentFactor() || matKey.isTransparentMap()) { + if (matKey.isTranslucent()) { builder.withTransparent(); } } @@ -412,8 +412,7 @@ ShapeKey ModelMeshPartPayload::getShapeKey() const { drawMaterialKey = _drawMaterial->getKey(); } - bool isTranslucent = - drawMaterialKey.isTransparentFactor() || drawMaterialKey.isTransparentMap(); + bool isTranslucent = drawMaterialKey.isTranslucent(); bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty(); bool hasSpecular = drawMaterialKey.isMetallicMap(); bool hasLightmap = drawMaterialKey.isLightmapMap(); diff --git a/libraries/render-utils/src/model.slf b/libraries/render-utils/src/model.slf index c9ca6d9eb7..ddfd83d1d4 100755 --- a/libraries/render-utils/src/model.slf +++ b/libraries/render-utils/src/model.slf @@ -29,6 +29,10 @@ void main(void) { int matKey = getMaterialKey(mat); <$fetchMaterialTextures(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, _SCRIBE_NULL, emissiveTex, occlusionTex)$> + float opacity = 1.0; + <$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)&>; + <$discardTransparent(opacity)$>; + vec3 albedo = getMaterialAlbedo(mat); <$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>; albedo *= _color; @@ -41,7 +45,7 @@ void main(void) { packDeferredFragment( normalize(_normal.xyz), - evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedoTex.a), + opacity, albedo, roughness, getMaterialMetallic(mat), diff --git a/libraries/render-utils/src/model_normal_map.slf b/libraries/render-utils/src/model_normal_map.slf index a584427005..10ae6ee880 100755 --- a/libraries/render-utils/src/model_normal_map.slf +++ b/libraries/render-utils/src/model_normal_map.slf @@ -30,6 +30,10 @@ void main(void) { int matKey = getMaterialKey(mat); <$fetchMaterialTextures(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, _SCRIBE_NULL, emissiveTex, occlusionTex)$> + float opacity = 1.0; + <$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)&>; + <$discardTransparent(opacity)$>; + vec3 albedo = getMaterialAlbedo(mat); <$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>; albedo *= _color; @@ -45,7 +49,7 @@ void main(void) { packDeferredFragment( viewNormal, - evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedoTex.a), + opacity, albedo, roughness, getMaterialMetallic(mat), diff --git a/libraries/render-utils/src/model_normal_specular_map.slf b/libraries/render-utils/src/model_normal_specular_map.slf index cf461db7ef..2529596818 100755 --- a/libraries/render-utils/src/model_normal_specular_map.slf +++ b/libraries/render-utils/src/model_normal_specular_map.slf @@ -30,6 +30,10 @@ void main(void) { int matKey = getMaterialKey(mat); <$fetchMaterialTextures(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, occlusionTex)$> + float opacity = 1.0; + <$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)&>; + <$discardTransparent(opacity)$>; + vec3 albedo = getMaterialAlbedo(mat); <$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>; albedo *= _color; @@ -49,7 +53,7 @@ void main(void) { packDeferredFragment( normalize(viewNormal.xyz), - evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedoTex.a), + opacity, albedo, roughness, metallic, diff --git a/libraries/render-utils/src/model_specular_map.slf b/libraries/render-utils/src/model_specular_map.slf index 32e5823430..9b2f4ae640 100755 --- a/libraries/render-utils/src/model_specular_map.slf +++ b/libraries/render-utils/src/model_specular_map.slf @@ -30,6 +30,10 @@ void main(void) { int matKey = getMaterialKey(mat); <$fetchMaterialTextures(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, occlusionTex)$> + float opacity = 1.0; + <$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)&>; + <$discardTransparent(opacity)$>; + vec3 albedo = getMaterialAlbedo(mat); <$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>; albedo *= _color; @@ -45,7 +49,7 @@ void main(void) { packDeferredFragment( normalize(_normal), - evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedoTex.a), + opacity, albedo, roughness, metallic, diff --git a/libraries/render-utils/src/model_translucent.slf b/libraries/render-utils/src/model_translucent.slf index b99b5c8a2a..12a7b9299f 100755 --- a/libraries/render-utils/src/model_translucent.slf +++ b/libraries/render-utils/src/model_translucent.slf @@ -36,6 +36,10 @@ void main(void) { int matKey = getMaterialKey(mat); <$fetchMaterialTextures(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, _SCRIBE_NULL, emissiveTex, occlusionTex)$> + float opacity = getMaterialOpacity(mat) * _alpha; + <$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)&>; + <$discardTransparent(opacity)$>; + vec3 albedo = getMaterialAlbedo(mat); <$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>; albedo *= _color; @@ -52,8 +56,6 @@ void main(void) { vec3 fragPosition = _position.xyz; vec3 fragNormal = normalize(_normal); - float fragOpacity = getMaterialOpacity(mat) * albedoTex.a * _alpha; - TransformCamera cam = getTransformCamera(); _fragColor = vec4(evalAmbientSphereGlobalColor( @@ -66,5 +68,5 @@ void main(void) { metallic, emissive, roughness), - fragOpacity); + opacity); } From d189dc4af2f42da7d2f1b6226a8897d162542c13 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 21 Mar 2016 13:30:08 -0700 Subject: [PATCH 4/8] Problem not fixed yet, need to merge with upstream --- libraries/render-utils/src/MaterialTextures.slh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/render-utils/src/MaterialTextures.slh b/libraries/render-utils/src/MaterialTextures.slh index ef8c30a97f..b25876af63 100644 --- a/libraries/render-utils/src/MaterialTextures.slh +++ b/libraries/render-utils/src/MaterialTextures.slh @@ -114,9 +114,9 @@ vec3 fetchLightmapMap(vec2 uv) { <@func evalMaterialOpacity(fetchedOpacity, materialOpacity, matKey, opacity)@> { - const float OPACITY_MASK_THRESHOLD = 0.5; - <$opacity$> = (((<$matKey$> & (OPACITY_TRANSLUCENCY_MAP_BIT | OPACITY_MASK_MAP_BIT)) != 0) ? - (((<$matKey$> & OPACITY_MASK_MAP_BIT) != 0) ? step(OPACITY_MASK_THRESHOLD, <$fetchedOpacity$>) : <$fetchedOpacity$>) : + const float OPACITY_MASK_THRESHOLD = 0.95; + <$opacity$> = (((<$matKey$> & (OPACITY_TRANSLUCENT_MAP_BIT | OPACITY_MASK_MAP_BIT)) != 0) ? + (((<$matKey$> & OPACITY_MASK_MAP_BIT) != 0) ? step(<$fetchedOpacity$>, OPACITY_MASK_THRESHOLD) : <$fetchedOpacity$>) : 1.0) * <$materialOpacity$>; } <@endfunc@> From 695e558851adbb7a12bae26a5ecc614e9cac1446 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 21 Mar 2016 16:36:47 -0700 Subject: [PATCH 5/8] Trying to clena up the problem? --- .../src/model-networking/ModelCache.cpp | 2 +- libraries/model/src/model/Material.cpp | 18 +++++++++++- libraries/model/src/model/Material.slh | 28 +++++++++---------- .../render-utils/src/MaterialTextures.slh | 4 +-- 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 7d5c6964e8..9c2725a919 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -151,7 +151,7 @@ bool NetworkGeometry::isLoadedWithTextures() const { (material->lightmapTexture && !material->lightmapTexture->isLoaded())) { return false; } - if (material->useAlbedoMapOpacity && 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(); diff --git a/libraries/model/src/model/Material.cpp b/libraries/model/src/model/Material.cpp index 5f5c93eb61..eaabda8f07 100755 --- a/libraries/model/src/model/Material.cpp +++ b/libraries/model/src/model/Material.cpp @@ -92,7 +92,23 @@ void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textur 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()) { + if (usage.isAlphaMask()) { + _key.setOpacityMaskMap(true); + _key.setTranslucentMap(false); + } else { + _key.setOpacityMaskMap(false); + _key.setTranslucentMap(true); + } + } + } + } + } else { + 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.setTranslucentMap(false); } else { diff --git a/libraries/model/src/model/Material.slh b/libraries/model/src/model/Material.slh index e8c9d3d6bc..a5b58e2aa0 100644 --- a/libraries/model/src/model/Material.slh +++ b/libraries/model/src/model/Material.slh @@ -39,21 +39,21 @@ float getMaterialShininess(Material m) { return 1.0 - getMaterialRoughness(m); } 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 OPACITY_VAL_BIT = 0x00000010; +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 OPACITY_VAL_BIT = 0x00000010; -const int EMISSIVE_MAP_BIT = 0x00000020; -const int ALBEDO_MAP_BIT = 0x00000040; -const int OPACITY_MASK_MAP_BIT = 0x00000080; -const int OPACITY_TRANSLUCENT_MAP_BIT = 0x00000100; -const int METALLIC_MAP_BIT = 0x00000200; -const int ROUGHNESS_MAP_BIT = 0x00000400; -const int NORMAL_MAP_BIT = 0x00001000; -const int OCCLUSION_MAP_BIT = 0x00002000; -const int LIGHTMAP_MAP_BIT = 0x00004000; +const int EMISSIVE_MAP_BIT = 0x00000020; +const int ALBEDO_MAP_BIT = 0x00000040; +const int OPACITY_MASK_MAP_BIT = 0x00000080; +const int OPACITY_TRANSLUCENT_MAP_BIT = 0x00000100; +const int METALLIC_MAP_BIT = 0x00000200; +const int ROUGHNESS_MAP_BIT = 0x00000400; +const int NORMAL_MAP_BIT = 0x00000800; +const int OCCLUSION_MAP_BIT = 0x00001000; +const int LIGHTMAP_MAP_BIT = 0x00002000; <@endif@> diff --git a/libraries/render-utils/src/MaterialTextures.slh b/libraries/render-utils/src/MaterialTextures.slh index b25876af63..34bb7c429b 100644 --- a/libraries/render-utils/src/MaterialTextures.slh +++ b/libraries/render-utils/src/MaterialTextures.slh @@ -114,9 +114,9 @@ vec3 fetchLightmapMap(vec2 uv) { <@func evalMaterialOpacity(fetchedOpacity, materialOpacity, matKey, opacity)@> { - const float OPACITY_MASK_THRESHOLD = 0.95; + const float OPACITY_MASK_THRESHOLD = 0.5; <$opacity$> = (((<$matKey$> & (OPACITY_TRANSLUCENT_MAP_BIT | OPACITY_MASK_MAP_BIT)) != 0) ? - (((<$matKey$> & OPACITY_MASK_MAP_BIT) != 0) ? step(<$fetchedOpacity$>, OPACITY_MASK_THRESHOLD) : <$fetchedOpacity$>) : + (((<$matKey$> & OPACITY_MASK_MAP_BIT) != 0) ? step(OPACITY_MASK_THRESHOLD, <$fetchedOpacity$>) : <$fetchedOpacity$>) : 1.0) * <$materialOpacity$>; } <@endfunc@> From de374c0cacf6b342227e2b8e40a0ac096eeb4f1a Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 21 Mar 2016 17:51:57 -0700 Subject: [PATCH 6/8] Switching emissive and lightmap somewhere but not big issue --- .../model-networking/src/model-networking/ModelCache.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 9c2725a919..2b142d95d5 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -213,10 +213,10 @@ void NetworkGeometry::setTextureWithNameToURL(const QString& name, const QUrl& u networkMaterial->setTextureMap(model::MaterialKey::EMISSIVE_MAP, emissiveMap); } else if (material->lightmapTextureName == name) { - material->emissiveTexture = textureCache->getTexture(url, LIGHTMAP_TEXTURE); + material->lightmapTexture = textureCache->getTexture(url, LIGHTMAP_TEXTURE); auto lightmapMap = model::TextureMapPointer(new model::TextureMap()); - lightmapMap->setTextureSource(material->emissiveTexture->_textureSource); + lightmapMap->setTextureSource(material->lightmapTexture->_textureSource); lightmapMap->setTextureTransform( oldTextureMaps[model::MaterialKey::LIGHTMAP_MAP]->getTextureTransform()); glm::vec2 oldOffsetScale = From 3c075532f8cd3670eb51766f49e1a690ed813e2c Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 22 Mar 2016 15:14:01 -0700 Subject: [PATCH 7/8] Good to go for merge --- .../src/model-networking/ModelCache.cpp | 7 ++----- .../src/model-networking/ModelCache.h | 2 -- libraries/model/src/model/Material.cpp | 18 +----------------- libraries/model/src/model/Material.h | 7 ++++--- libraries/model/src/model/Material.slh | 8 ++++---- 5 files changed, 11 insertions(+), 31 deletions(-) diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 2b142d95d5..5eb961ef98 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -151,13 +151,11 @@ bool NetworkGeometry::isLoadedWithTextures() const { (material->lightmapTexture && !material->lightmapTexture->isLoaded())) { return false; } - if (/*material->useAlbedoMapOpacity && */ material->albedoTexture && material->albedoTexture->getGPUTexture()) { + if (material->albedoTexture && material->albedoTexture->getGPUTexture()) { + // Reassign the texture to make sure that itsalbedo alpha channel material key is detected correctly 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); - // FIXME: Materials with *some* transparent textures seem to give all *other* textures alphas of 0. _hasTransparentTextures = isTransparentTexture && _hasTransparentTextures; } } @@ -385,7 +383,6 @@ static NetworkMaterial* buildNetworkMaterial(NetworkGeometry* geometry, const FB 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 diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h index b172bb70b4..1c76a0b878 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.h +++ b/libraries/model-networking/src/model-networking/ModelCache.h @@ -199,8 +199,6 @@ public: QSharedPointer occlusionTexture; QString lightmapTextureName; QSharedPointer lightmapTexture; - bool useAlbedoMapOpacity{ false }; - }; diff --git a/libraries/model/src/model/Material.cpp b/libraries/model/src/model/Material.cpp index eaabda8f07..f1e6b8c2ef 100755 --- a/libraries/model/src/model/Material.cpp +++ b/libraries/model/src/model/Material.cpp @@ -91,23 +91,7 @@ void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textur 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.setTranslucentMap(false); - } else { - _key.setOpacityMaskMap(false); - _key.setTranslucentMap(true); - } - } - } - } - } else { - 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 + // Texture has alpha, is not just a mask or a true transparent channel if (usage.isAlphaMask()) { _key.setOpacityMaskMap(true); _key.setTranslucentMap(false); diff --git a/libraries/model/src/model/Material.h b/libraries/model/src/model/Material.h index 2527c8e1e1..5a7b919994 100755 --- a/libraries/model/src/model/Material.h +++ b/libraries/model/src/model/Material.h @@ -32,11 +32,12 @@ public: METALLIC_VAL_BIT, GLOSSY_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_TRANSLUCENT_MAP_BIT, + + // THe map bits must be in the smae sequence as the enum names for the map channels + EMISSIVE_MAP_BIT, + ALBEDO_MAP_BIT, METALLIC_MAP_BIT, ROUGHNESS_MAP_BIT, NORMAL_MAP_BIT, diff --git a/libraries/model/src/model/Material.slh b/libraries/model/src/model/Material.slh index a5b58e2aa0..28f9769a8b 100644 --- a/libraries/model/src/model/Material.slh +++ b/libraries/model/src/model/Material.slh @@ -44,11 +44,11 @@ const int ALBEDO_VAL_BIT = 0x00000002; const int METALLIC_VAL_BIT = 0x00000004; const int GLOSSY_VAL_BIT = 0x00000008; const int OPACITY_VAL_BIT = 0x00000010; +const int OPACITY_MASK_MAP_BIT = 0x00000020; +const int OPACITY_TRANSLUCENT_MAP_BIT = 0x00000040; -const int EMISSIVE_MAP_BIT = 0x00000020; -const int ALBEDO_MAP_BIT = 0x00000040; -const int OPACITY_MASK_MAP_BIT = 0x00000080; -const int OPACITY_TRANSLUCENT_MAP_BIT = 0x00000100; +const int EMISSIVE_MAP_BIT = 0x00000080; +const int ALBEDO_MAP_BIT = 0x00000100; const int METALLIC_MAP_BIT = 0x00000200; const int ROUGHNESS_MAP_BIT = 0x00000400; const int NORMAL_MAP_BIT = 0x00000800; From 3274df9923a4c70b96262778cbfb8178c18ee138 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 22 Mar 2016 16:18:51 -0700 Subject: [PATCH 8/8] Fixing the missing field for blender translucent map --- libraries/fbx/src/FBXReader.cpp | 5 +++-- libraries/fbx/src/FBXReader_Material.cpp | 8 ++++++-- libraries/model/src/model/Material.cpp | 6 +++++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index b2ede33e01..c3364f90f8 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -1098,8 +1098,9 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS diffuseTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1)); } else if (type.contains("tex_color_map")) { diffuseTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1)); - } else if (type.contains("transparentcolor")) { // it should be TransparentColor... - // THis is how Maya assign a texture that affect diffuse color AND transparency ? + } else if (type.contains("transparentcolor")) { // Maya way of passing TransparentMap + transparentTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1)); + } else if (type.contains("transparencyfactor")) { // Blender way of passing TransparentMap transparentTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1)); } else if (type.contains("bump")) { bumpTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1)); diff --git a/libraries/fbx/src/FBXReader_Material.cpp b/libraries/fbx/src/FBXReader_Material.cpp index fb272a1af9..11c6dad2f2 100644 --- a/libraries/fbx/src/FBXReader_Material.cpp +++ b/libraries/fbx/src/FBXReader_Material.cpp @@ -102,16 +102,20 @@ void FBXReader::consolidateFBXMaterials() { detectDifferentUVs = (diffuseTexture.texcoordSet != 0) || (!diffuseTexture.transform.isIdentity()); } - FBXTexture transparentTexture; QString transparentTextureID = transparentTextures.value(material.materialID); + // If PBS Material, systematically bind the albedo texture as transparency texture and check for the alpha channel + if (material.isPBSMaterial) { + transparentTextureID = diffuseTextureID; + } if (!transparentTextureID.isNull()) { transparentTexture = getTexture(transparentTextureID); - material.opacityTexture = transparentTexture; detectDifferentUVs |= (transparentTexture.texcoordSet != 0) || (!transparentTexture.transform.isIdentity()); } + + FBXTexture normalTexture; QString bumpTextureID = bumpTextures.value(material.materialID); QString normalTextureID = normalTextures.value(material.materialID); diff --git a/libraries/model/src/model/Material.cpp b/libraries/model/src/model/Material.cpp index f1e6b8c2ef..81bc9b40a6 100755 --- a/libraries/model/src/model/Material.cpp +++ b/libraries/model/src/model/Material.cpp @@ -84,8 +84,12 @@ void Material::setMetallic(float metallic) { void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textureMap) { if (textureMap) { _key.setMapChannel(channel, (true)); - + if (channel == MaterialKey::ALBEDO_MAP) { + // clear the previous flags whatever they were: + _key.setOpacityMaskMap(false); + _key.setTranslucentMap(false); + if (textureMap->useAlphaChannel()) { if (textureMap->isDefined()) { if (textureMap->getTextureView().isValid()) {