diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index 5371d5a41d..3fefd837f3 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -111,7 +111,6 @@ public: QString texcoordSetName; bool isBumpmap{ false }; - bool isGlossmap{ true }; bool isNull() const { return name.isEmpty() && filename.isEmpty() && content.isEmpty(); } }; @@ -151,21 +150,13 @@ public: float roughness{ 1.0f }; float emissiveIntensity{ 1.0f }; - bool useNormalMap{ false }; - bool useAlbedoMap{ false }; - bool useOpacityMap{ false }; - bool useRoughnessMap{ false }; - bool useSpecularMap{ false }; - bool useMetallicMap{ false }; - bool useEmissiveMap{ false }; - bool useOcclusionMap{ false }; - QString materialID; model::MaterialPointer _material; FBXTexture normalTexture; FBXTexture albedoTexture; FBXTexture opacityTexture; + FBXTexture glossTexture; FBXTexture roughnessTexture; FBXTexture specularTexture; FBXTexture metallicTexture; @@ -176,6 +167,16 @@ public: bool isPBSMaterial{ false }; + // THe use XXXMap are not really used to drive which map are going or not, debug only + bool useNormalMap{ false }; + bool useAlbedoMap{ false }; + bool useOpacityMap{ false }; + bool useRoughnessMap{ false }; + bool useSpecularMap{ false }; + bool useMetallicMap{ false }; + bool useEmissiveMap{ false }; + bool useOcclusionMap{ false }; + bool needTangentSpace() const; }; diff --git a/libraries/fbx/src/FBXReader_Material.cpp b/libraries/fbx/src/FBXReader_Material.cpp index cc6452c620..d87eac405f 100644 --- a/libraries/fbx/src/FBXReader_Material.cpp +++ b/libraries/fbx/src/FBXReader_Material.cpp @@ -128,19 +128,20 @@ void FBXReader::consolidateFBXMaterials() { FBXTexture roughnessTexture; QString roughnessTextureID = roughnessTextures.value(material.materialID); - QString shininessTextureID = shininessTextures.value(material.materialID); if (!roughnessTextureID.isNull()) { roughnessTexture = getTexture(roughnessTextureID); - roughnessTexture.isGlossmap = false; - material.roughnessTexture = roughnessTexture; - detectDifferentUVs |= (roughnessTexture.texcoordSet != 0) || (!roughnessTexture.transform.isIdentity()); - } else if (!shininessTextureID.isNull()) { - roughnessTexture = getTexture(roughnessTextureID); - roughnessTexture.isGlossmap = true; material.roughnessTexture = roughnessTexture; detectDifferentUVs |= (roughnessTexture.texcoordSet != 0) || (!roughnessTexture.transform.isIdentity()); } + FBXTexture shininessTexture; + QString shininessTextureID = shininessTextures.value(material.materialID); + if (!shininessTextureID.isNull()) { + shininessTexture = getTexture(shininessTextureID); + material.glossTexture = shininessTexture; + detectDifferentUVs |= (shininessTexture.texcoordSet != 0) || (!shininessTexture.transform.isIdentity()); + } + FBXTexture emissiveTexture; QString emissiveTextureID = emissiveTextures.value(material.materialID); if (!emissiveTextureID.isNull()) { diff --git a/libraries/gpu/src/gpu/GLBackendTexture.cpp b/libraries/gpu/src/gpu/GLBackendTexture.cpp index 8efb4736c1..efcafc9d60 100755 --- a/libraries/gpu/src/gpu/GLBackendTexture.cpp +++ b/libraries/gpu/src/gpu/GLBackendTexture.cpp @@ -199,7 +199,7 @@ public: } case gpu::NUINT8: { if ((dstFormat.getSemantic() == gpu::SRGB || dstFormat.getSemantic() == gpu::SRGBA)) { - texel.internalFormat = GL_SLUMINANCE8; + texel.internalFormat = GL_SLUMINANCE; } else { texel.internalFormat = GL_R8; } diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index d944b0c686..f795472137 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -138,7 +138,9 @@ bool NetworkGeometry::isLoadedWithTextures() const { for (auto&& material : _materials) { if ((material->albedoTexture && !material->albedoTexture->isLoaded()) || (material->normalTexture && !material->normalTexture->isLoaded()) || - (material->specularTexture && !material->specularTexture->isLoaded()) || + (material->roughnessTexture && !material->roughnessTexture->isLoaded()) || + (material->metallicTexture && !material->metallicTexture->isLoaded()) || + (material->occlusionTexture && !material->occlusionTexture->isLoaded()) || (material->emissiveTexture && !material->emissiveTexture->isLoaded()) || (material->lightmapTexture && !material->lightmapTexture->isLoaded())) { return false; @@ -171,22 +173,31 @@ void NetworkGeometry::setTextureWithNameToURL(const QString& name, const QUrl& u normalMap->setTextureSource(material->normalTexture->_textureSource); networkMaterial->setTextureMap(model::MaterialKey::NORMAL_MAP, normalMap); - } else if (material->specularTextureName == name) { - material->specularTexture = textureCache->getTexture(url); + } else if (material->roughnessTextureName == name) { + // FIXME: If passing a gloss map instead of a roughmap how to say that ? looking for gloss in the name ? + material->roughnessTexture = textureCache->getTexture(url, ROUGHNESS_TEXTURE); + + auto roughnessMap = model::TextureMapPointer(new model::TextureMap()); + roughnessMap->setTextureSource(material->roughnessTexture->_textureSource); + + networkMaterial->setTextureMap(model::MaterialKey::ROUGHNESS_MAP, roughnessMap); + } else if (material->metallicTextureName == name) { + // FIXME: If passing a specular map instead of a metallic how to say that ? looking for wtf in the name ? + material->metallicTexture = textureCache->getTexture(url, METALLIC_TEXTURE); auto glossMap = model::TextureMapPointer(new model::TextureMap()); - glossMap->setTextureSource(material->specularTexture->_textureSource); + glossMap->setTextureSource(material->metallicTexture->_textureSource); - networkMaterial->setTextureMap(model::MaterialKey::ROUGHNESS_MAP, glossMap); + networkMaterial->setTextureMap(model::MaterialKey::METALLIC_MAP, glossMap); } else if (material->emissiveTextureName == name) { - material->emissiveTexture = textureCache->getTexture(url); + material->emissiveTexture = textureCache->getTexture(url, EMISSIVE_TEXTURE); auto emissiveMap = model::TextureMapPointer(new model::TextureMap()); emissiveMap->setTextureSource(material->emissiveTexture->_textureSource); networkMaterial->setTextureMap(model::MaterialKey::EMISSIVE_MAP, emissiveMap); } else if (material->lightmapTextureName == name) { - material->emissiveTexture = textureCache->getTexture(url); + material->emissiveTexture = textureCache->getTexture(url, LIGHTMAP_TEXTURE); auto lightmapMap = model::TextureMapPointer(new model::TextureMap()); lightmapMap->setTextureSource(material->emissiveTexture->_textureSource); @@ -208,6 +219,11 @@ void NetworkGeometry::setTextureWithNameToURL(const QString& name, const QUrl& u QStringList NetworkGeometry::getTextureNames() const { QStringList result; for (auto&& material : _materials) { + if (!material->emissiveTextureName.isEmpty() && material->emissiveTexture) { + QString textureURL = material->emissiveTexture->getURL().toString(); + result << material->emissiveTextureName + ":\"" + textureURL + "\""; + } + if (!material->albedoTextureName.isEmpty() && material->albedoTexture) { QString textureURL = material->albedoTexture->getURL().toString(); result << material->albedoTextureName + ":\"" + textureURL + "\""; @@ -218,15 +234,21 @@ QStringList NetworkGeometry::getTextureNames() const { result << material->normalTextureName + ":\"" + textureURL + "\""; } - if (!material->specularTextureName.isEmpty() && material->specularTexture) { - QString textureURL = material->specularTexture->getURL().toString(); - result << material->specularTextureName + ":\"" + textureURL + "\""; + if (!material->roughnessTextureName.isEmpty() && material->roughnessTexture) { + QString textureURL = material->roughnessTexture->getURL().toString(); + result << material->roughnessTextureName + ":\"" + textureURL + "\""; } - if (!material->emissiveTextureName.isEmpty() && material->emissiveTexture) { - QString textureURL = material->emissiveTexture->getURL().toString(); - result << material->emissiveTextureName + ":\"" + textureURL + "\""; + if (!material->metallicTextureName.isEmpty() && material->metallicTexture) { + QString textureURL = material->metallicTexture->getURL().toString(); + result << material->metallicTextureName + ":\"" + textureURL + "\""; } + + if (!material->occlusionTextureName.isEmpty() && material->occlusionTexture) { + QString textureURL = material->occlusionTexture->getURL().toString(); + result << material->occlusionTextureName + ":\"" + textureURL + "\""; + } + if (!material->lightmapTextureName.isEmpty() && material->lightmapTexture) { QString textureURL = material->lightmapTexture->getURL().toString(); result << material->lightmapTextureName + ":\"" + textureURL + "\""; @@ -335,6 +357,7 @@ static NetworkMaterial* buildNetworkMaterial(NetworkGeometry* geometry, const FB material._material->setTextureMap(model::MaterialKey::ALBEDO_MAP, albedoMap); } + if (!material.normalTexture.filename.isEmpty()) { networkMaterial->normalTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.normalTexture.filename)), (material.normalTexture.isBumpmap ? BUMP_TEXTURE : NORMAL_TEXTURE), material.normalTexture.content); networkMaterial->normalTextureName = material.normalTexture.name; @@ -344,29 +367,18 @@ static NetworkMaterial* buildNetworkMaterial(NetworkGeometry* geometry, const FB material._material->setTextureMap(model::MaterialKey::NORMAL_MAP, normalMap); } - if (!material.specularTexture.filename.isEmpty()) { - networkMaterial->specularTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.specularTexture.filename)), SPECULAR_TEXTURE, material.specularTexture.content); - networkMaterial->specularTextureName = material.specularTexture.name; - auto specularMap = model::TextureMapPointer(new model::TextureMap()); - specularMap->setTextureSource(networkMaterial->specularTexture->_textureSource); - - material._material->setTextureMap(model::MaterialKey::METALLIC_MAP, specularMap); - } - if (!material.metallicTexture.filename.isEmpty()) { - networkMaterial->specularTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.metallicTexture.filename)), SPECULAR_TEXTURE, material.metallicTexture.content); - networkMaterial->specularTextureName = material.metallicTexture.name; - - auto metallicMap = model::TextureMapPointer(new model::TextureMap()); - metallicMap->setTextureSource(networkMaterial->specularTexture->_textureSource); - - material._material->setTextureMap(model::MaterialKey::METALLIC_MAP, metallicMap); - } + // Roughness first or gloss maybe if (!material.roughnessTexture.filename.isEmpty()) { - // FIXME: COnvert from gloss to roughness if material.roughnessTexture.isGlossmap; - networkMaterial->roughnessTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.roughnessTexture.filename)), - (material.roughnessTexture.isGlossmap ? GLOSS_TEXTURE : ROUGHNESS_TEXTURE), - material.roughnessTexture.content); + networkMaterial->roughnessTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.roughnessTexture.filename)), ROUGHNESS_TEXTURE, material.roughnessTexture.content); + networkMaterial->roughnessTextureName = material.roughnessTexture.name; + + auto roughnessMap = model::TextureMapPointer(new model::TextureMap()); + roughnessMap->setTextureSource(networkMaterial->roughnessTexture->_textureSource); + + material._material->setTextureMap(model::MaterialKey::ROUGHNESS_MAP, roughnessMap); + } else if (!material.glossTexture.filename.isEmpty()) { + networkMaterial->roughnessTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.glossTexture.filename)), GLOSS_TEXTURE, material.glossTexture.content); networkMaterial->roughnessTextureName = material.roughnessTexture.name; auto roughnessMap = model::TextureMapPointer(new model::TextureMap()); @@ -374,6 +386,37 @@ static NetworkMaterial* buildNetworkMaterial(NetworkGeometry* geometry, const FB material._material->setTextureMap(model::MaterialKey::ROUGHNESS_MAP, roughnessMap); } + + // Metallic first or specular maybe + + if (!material.metallicTexture.filename.isEmpty()) { + networkMaterial->metallicTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.metallicTexture.filename)), METALLIC_TEXTURE, material.metallicTexture.content); + networkMaterial->metallicTextureName = material.metallicTexture.name; + + auto metallicMap = model::TextureMapPointer(new model::TextureMap()); + metallicMap->setTextureSource(networkMaterial->metallicTexture->_textureSource); + + material._material->setTextureMap(model::MaterialKey::METALLIC_MAP, metallicMap); + } else if (!material.specularTexture.filename.isEmpty()) { + networkMaterial->metallicTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.specularTexture.filename)), SPECULAR_TEXTURE, material.specularTexture.content); + networkMaterial->metallicTextureName = material.specularTexture.name; + + auto metallicMap = model::TextureMapPointer(new model::TextureMap()); + metallicMap->setTextureSource(networkMaterial->metallicTexture->_textureSource); + + material._material->setTextureMap(model::MaterialKey::METALLIC_MAP, metallicMap); + } + + if (!material.occlusionTexture.filename.isEmpty()) { + networkMaterial->occlusionTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.occlusionTexture.filename)), OCCLUSION_TEXTURE, material.occlusionTexture.content); + networkMaterial->occlusionTextureName = material.occlusionTexture.name; + + auto occlusionMap = model::TextureMapPointer(new model::TextureMap()); + occlusionMap->setTextureSource(networkMaterial->occlusionTexture->_textureSource); + + material._material->setTextureMap(model::MaterialKey::OCCLUSION_MAP, occlusionMap); + } + if (!material.emissiveTexture.filename.isEmpty()) { networkMaterial->emissiveTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.emissiveTexture.filename)), EMISSIVE_TEXTURE, material.emissiveTexture.content); networkMaterial->emissiveTextureName = material.emissiveTexture.name; @@ -383,6 +426,7 @@ static NetworkMaterial* buildNetworkMaterial(NetworkGeometry* geometry, const FB material._material->setTextureMap(model::MaterialKey::EMISSIVE_MAP, emissiveMap); } + if (!material.lightmapTexture.filename.isEmpty()) { networkMaterial->lightmapTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.lightmapTexture.filename)), LIGHTMAP_TEXTURE, material.lightmapTexture.content); networkMaterial->lightmapTextureName = material.lightmapTexture.name; @@ -395,15 +439,7 @@ static NetworkMaterial* buildNetworkMaterial(NetworkGeometry* geometry, const FB material._material->setTextureMap(model::MaterialKey::LIGHTMAP_MAP, lightmapMap); } - if (!material.occlusionTexture.filename.isEmpty()) { - networkMaterial->occlusionTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.occlusionTexture.filename)), OCCLUSION_TEXTURE, material.occlusionTexture.content); - networkMaterial->occlusionTextureName = material.occlusionTexture.name; - auto occlusionMap = model::TextureMapPointer(new model::TextureMap()); - occlusionMap->setTextureSource(networkMaterial->occlusionTexture->_textureSource); - - material._material->setTextureMap(model::MaterialKey::OCCLUSION_MAP, occlusionMap); - } return networkMaterial; } diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h index b517cc67ca..60f185f691 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.h +++ b/libraries/model-networking/src/model-networking/ModelCache.h @@ -180,16 +180,16 @@ class NetworkMaterial { public: model::MaterialPointer _material; + QString emissiveTextureName; + QSharedPointer emissiveTexture; QString albedoTextureName; QSharedPointer albedoTexture; QString normalTextureName; QSharedPointer normalTexture; - QString specularTextureName; - QSharedPointer specularTexture; QString roughnessTextureName; QSharedPointer roughnessTexture; - QString emissiveTextureName; - QSharedPointer emissiveTexture; + QString metallicTextureName; + QSharedPointer metallicTexture; QString occlusionTextureName; QSharedPointer occlusionTexture; QString lightmapTextureName; diff --git a/libraries/model-networking/src/model-networking/TextureCache.h b/libraries/model-networking/src/model-networking/TextureCache.h index ded90e7780..af82d2a1ad 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.h +++ b/libraries/model-networking/src/model-networking/TextureCache.h @@ -34,6 +34,7 @@ enum TextureType { NORMAL_TEXTURE, BUMP_TEXTURE, SPECULAR_TEXTURE, + METALLIC_TEXTURE = SPECULAR_TEXTURE, // for now spec and metallic texture are the same, converted to grey ROUGHNESS_TEXTURE, GLOSS_TEXTURE, EMISSIVE_TEXTURE, diff --git a/libraries/model/src/model/TextureMap.cpp b/libraries/model/src/model/TextureMap.cpp index 41be048440..c775443425 100755 --- a/libraries/model/src/model/TextureMap.cpp +++ b/libraries/model/src/model/TextureMap.cpp @@ -291,6 +291,9 @@ gpu::Texture* TextureUsage::createRoughnessTextureFromGlossImage(const QImage& s image = image.convertToFormat(QImage::Format_ARGB32); } } + + // Gloss turned into Rough + image.invertPixels(QImage::InvertRgba); image = image.convertToFormat(QImage::Format_Grayscale8);