From d54ca435545f04007916e9f4d4862eea0de73084 Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Fri, 22 Nov 2019 00:37:27 -0800 Subject: [PATCH] properly implement alphaModes --- libraries/fbx/src/GLTFSerializer.cpp | 85 ++++++++++--------- libraries/fbx/src/GLTFSerializer.h | 20 ++--- libraries/graphics/src/graphics/Material.cpp | 3 +- .../src/graphics/MaterialTextures.slh | 17 ++-- libraries/hfm/src/hfm/HFM.h | 47 +++++----- .../render-utils/src/RenderPipelines.cpp | 4 +- libraries/render-utils/src/model.slf | 10 +-- 7 files changed, 94 insertions(+), 92 deletions(-) diff --git a/libraries/fbx/src/GLTFSerializer.cpp b/libraries/fbx/src/GLTFSerializer.cpp index 5d4daf53f7..34a610c921 100755 --- a/libraries/fbx/src/GLTFSerializer.cpp +++ b/libraries/fbx/src/GLTFSerializer.cpp @@ -225,18 +225,17 @@ int GLTFSerializer::getAccessorType(const QString& type) return GLTFAccessorType::SCALAR; } -int GLTFSerializer::getMaterialAlphaMode(const QString& type) -{ +graphics::MaterialKey::OpacityMapMode GLTFSerializer::getMaterialAlphaMode(const QString& type) { if (type == "OPAQUE") { - return GLTFMaterialAlphaMode::OPAQUE; + return graphics::MaterialKey::OPACITY_MAP_OPAQUE; } if (type == "MASK") { - return GLTFMaterialAlphaMode::MASK; + return graphics::MaterialKey::OPACITY_MAP_MASK; } if (type == "BLEND") { - return GLTFMaterialAlphaMode::BLEND; + return graphics::MaterialKey::OPACITY_MAP_BLEND; } - return GLTFMaterialAlphaMode::OPAQUE; + return graphics::MaterialKey::OPACITY_MAP_BLEND; } int GLTFSerializer::getCameraType(const QString& type) @@ -484,9 +483,9 @@ bool GLTFSerializer::addMaterial(const QJsonObject& object) { getIndexFromObject(object, "normalTexture", material.normalTexture, material.defined); getIndexFromObject(object, "occlusionTexture", material.occlusionTexture, material.defined); getBoolVal(object, "doubleSided", material.doubleSided, material.defined); - QString alphamode; - if (getStringVal(object, "alphaMode", alphamode, material.defined)) { - material.alphaMode = getMaterialAlphaMode(alphamode); + QString alphaMode; + if (getStringVal(object, "alphaMode", alphaMode, material.defined)) { + material.alphaMode = getMaterialAlphaMode(alphaMode); } getDoubleVal(object, "alphaCutoff", material.alphaCutoff, material.defined); QJsonObject jsMetallicRoughness; @@ -1764,62 +1763,68 @@ HFMTexture GLTFSerializer::getHFMTexture(const GLTFTexture& texture) { return fbxtex; } -void GLTFSerializer::setHFMMaterial(HFMMaterial& fbxmat, const GLTFMaterial& material) { +void GLTFSerializer::setHFMMaterial(HFMMaterial& hfmMat, const GLTFMaterial& material) { + if (material.defined["alphaMode"]) { + hfmMat._material->setOpacityMapMode(material.alphaMode); + } else { + hfmMat._material->setOpacityMapMode(graphics::MaterialKey::OPACITY_MAP_OPAQUE); // GLTF defaults to opaque + } + if (material.defined["alphaCutoff"]) { + hfmMat._material->setOpacityCutoff(material.alphaCutoff); + } if (material.defined["emissiveFactor"] && material.emissiveFactor.size() == 3) { - glm::vec3 emissive = glm::vec3(material.emissiveFactor[0], - material.emissiveFactor[1], - material.emissiveFactor[2]); - fbxmat._material->setEmissive(emissive); + glm::vec3 emissive = glm::vec3(material.emissiveFactor[0], material.emissiveFactor[1], material.emissiveFactor[2]); + hfmMat._material->setEmissive(emissive); } if (material.defined["emissiveTexture"]) { - fbxmat.emissiveTexture = getHFMTexture(_file.textures[material.emissiveTexture]); - fbxmat.useEmissiveMap = true; + hfmMat.emissiveTexture = getHFMTexture(_file.textures[material.emissiveTexture]); + hfmMat.useEmissiveMap = true; } if (material.defined["normalTexture"]) { - fbxmat.normalTexture = getHFMTexture(_file.textures[material.normalTexture]); - fbxmat.useNormalMap = true; + hfmMat.normalTexture = getHFMTexture(_file.textures[material.normalTexture]); + hfmMat.useNormalMap = true; } if (material.defined["occlusionTexture"]) { - fbxmat.occlusionTexture = getHFMTexture(_file.textures[material.occlusionTexture]); - fbxmat.useOcclusionMap = true; + hfmMat.occlusionTexture = getHFMTexture(_file.textures[material.occlusionTexture]); + hfmMat.useOcclusionMap = true; } if (material.defined["pbrMetallicRoughness"]) { - fbxmat.isPBSMaterial = true; - + hfmMat.isPBSMaterial = true; + if (material.pbrMetallicRoughness.defined["metallicFactor"]) { - fbxmat.metallic = material.pbrMetallicRoughness.metallicFactor; + hfmMat.metallic = material.pbrMetallicRoughness.metallicFactor; } if (material.pbrMetallicRoughness.defined["baseColorTexture"]) { - fbxmat.opacityTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]); - fbxmat.albedoTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]); - fbxmat.useAlbedoMap = true; + hfmMat.opacityTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]); + hfmMat.albedoTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]); + hfmMat.useAlbedoMap = true; } if (material.pbrMetallicRoughness.defined["metallicRoughnessTexture"]) { - fbxmat.roughnessTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]); - fbxmat.roughnessTexture.sourceChannel = image::ColorChannel::GREEN; - fbxmat.useRoughnessMap = true; - fbxmat.metallicTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]); - fbxmat.metallicTexture.sourceChannel = image::ColorChannel::BLUE; - fbxmat.useMetallicMap = true; + hfmMat.roughnessTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]); + hfmMat.roughnessTexture.sourceChannel = image::ColorChannel::GREEN; + hfmMat.useRoughnessMap = true; + hfmMat.metallicTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]); + hfmMat.metallicTexture.sourceChannel = image::ColorChannel::BLUE; + hfmMat.useMetallicMap = true; } if (material.pbrMetallicRoughness.defined["roughnessFactor"]) { - fbxmat._material->setRoughness(material.pbrMetallicRoughness.roughnessFactor); + hfmMat._material->setRoughness(material.pbrMetallicRoughness.roughnessFactor); } if (material.pbrMetallicRoughness.defined["baseColorFactor"] && material.pbrMetallicRoughness.baseColorFactor.size() == 4) { - glm::vec3 dcolor = glm::vec3(material.pbrMetallicRoughness.baseColorFactor[0], - material.pbrMetallicRoughness.baseColorFactor[1], - material.pbrMetallicRoughness.baseColorFactor[2]); - fbxmat.diffuseColor = dcolor; - fbxmat._material->setAlbedo(dcolor); - fbxmat._material->setOpacity(material.pbrMetallicRoughness.baseColorFactor[3]); - } + glm::vec3 dcolor = + glm::vec3(material.pbrMetallicRoughness.baseColorFactor[0], material.pbrMetallicRoughness.baseColorFactor[1], + material.pbrMetallicRoughness.baseColorFactor[2]); + hfmMat.diffuseColor = dcolor; + hfmMat._material->setAlbedo(dcolor); + hfmMat._material->setOpacity(material.pbrMetallicRoughness.baseColorFactor[3]); + } } } diff --git a/libraries/fbx/src/GLTFSerializer.h b/libraries/fbx/src/GLTFSerializer.h index 4d72805863..b1020f7154 100755 --- a/libraries/fbx/src/GLTFSerializer.h +++ b/libraries/fbx/src/GLTFSerializer.h @@ -416,21 +416,13 @@ struct GLTFpbrMetallicRoughness { } }; -namespace GLTFMaterialAlphaMode { - enum Values { - OPAQUE = 0, - MASK, - BLEND - }; -}; - struct GLTFMaterial { QString name; QVector emissiveFactor; int emissiveTexture; int normalTexture; int occlusionTexture; - int alphaMode; + graphics::MaterialKey::OpacityMapMode alphaMode; double alphaCutoff; bool doubleSided; GLTFpbrMetallicRoughness pbrMetallicRoughness; @@ -451,6 +443,12 @@ struct GLTFMaterial { if (defined["emissiveFactor"]) { qCDebug(modelformat) << "emissiveFactor: " << emissiveFactor; } + if (defined["alphaMode"]) { + qCDebug(modelformat) << "alphaMode: " << alphaMode; + } + if (defined["alphaCutoff"]) { + qCDebug(modelformat) << "alphaCutoff: " << alphaCutoff; + } if (defined["pbrMetallicRoughness"]) { pbrMetallicRoughness.dump(); } @@ -800,7 +798,7 @@ private: hifi::ByteArray setGLBChunks(const hifi::ByteArray& data); - int getMaterialAlphaMode(const QString& type); + graphics::MaterialKey::OpacityMapMode getMaterialAlphaMode(const QString& type); int getAccessorType(const QString& type); int getAnimationSamplerInterpolation(const QString& interpolation); int getCameraType(const QString& type); @@ -854,7 +852,7 @@ private: bool doesResourceExist(const QString& url); - void setHFMMaterial(HFMMaterial& fbxmat, const GLTFMaterial& material); + void setHFMMaterial(HFMMaterial& hfmMat, const GLTFMaterial& material); HFMTexture getHFMTexture(const GLTFTexture& texture); void glTFDebugDump(); void hfmDebugDump(const HFMModel& hfmModel); diff --git a/libraries/graphics/src/graphics/Material.cpp b/libraries/graphics/src/graphics/Material.cpp index d80c3adfbc..1b96ed433b 100755 --- a/libraries/graphics/src/graphics/Material.cpp +++ b/libraries/graphics/src/graphics/Material.cpp @@ -209,8 +209,7 @@ bool Material::resetOpacityMap() const { } } } - auto newious = _key.getOpacityMapMode(); - if (previous != newious) { + if (previous != _key.getOpacityMapMode()) { //opacity change detected for this material return true; } diff --git a/libraries/graphics/src/graphics/MaterialTextures.slh b/libraries/graphics/src/graphics/MaterialTextures.slh index 2a291e5d57..534e1ae869 100644 --- a/libraries/graphics/src/graphics/MaterialTextures.slh +++ b/libraries/graphics/src/graphics/MaterialTextures.slh @@ -214,22 +214,19 @@ vec3 fetchLightMap(vec2 uv) { } <@endfunc@> -<@func evalMaterialOpacityMask(fetchedOpacity, materialOpacityCutoff, opacity)@> +<@func evalMaterialOpacityMask(fetchedOpacity, materialOpacityCutoff, materialOpacity, matKey, opacity)@> { - // This path only valid for opaque or texel opaque material - <$opacity$> = step(<$materialOpacityCutoff$>, <$fetchedOpacity$>); + // This path only valid for opaque or texel opaque material + <$opacity$> = mix(<$materialOpacity$>, + step(<$materialOpacityCutoff$>, <$fetchedOpacity$>), + float((<$matKey$> & OPACITY_MASK_MAP_BIT) != 0)); } <@endfunc@> - -<@func evalMaterialOpacity(fetchedOpacity, materialOpacityCutoff, materialOpacity, matKey, opacity)@> +<@func evalMaterialOpacity(fetchedOpacity, materialOpacity, opacity)@> { // This path only valid for transparent material - // Assert that float((<$matKey$> & (OPACITY_TRANSLUCENT_MAP_BIT | OPACITY_MASK_MAP_BIT)) != 0)) == 1.0 - <$opacity$> = mix(<$fetchedOpacity$>, - step(<$materialOpacityCutoff$>, <$fetchedOpacity$>), - float((<$matKey$> & OPACITY_MASK_MAP_BIT) != 0)) - * <$materialOpacity$>; + <$opacity$> = <$materialOpacity$> * <$fetchedOpacity$>; } <@endfunc@> diff --git a/libraries/hfm/src/hfm/HFM.h b/libraries/hfm/src/hfm/HFM.h index 888e562bca..7111ad2e65 100644 --- a/libraries/hfm/src/hfm/HFM.h +++ b/libraries/hfm/src/hfm/HFM.h @@ -173,24 +173,27 @@ public: void getTextureNames(QSet& textureList) const; void setMaxNumPixelsPerTexture(int maxNumPixels); - glm::vec3 diffuseColor{ 1.0f }; - float diffuseFactor{ 1.0f }; - glm::vec3 specularColor{ 0.02f }; - float specularFactor{ 1.0f }; + glm::vec3 diffuseColor { 1.0f }; + float diffuseFactor { 1.0f }; + glm::vec3 specularColor { 0.02f }; + float specularFactor { 1.0f }; - glm::vec3 emissiveColor{ 0.0f }; - float emissiveFactor{ 0.0f }; + glm::vec3 emissiveColor { 0.0f }; + float emissiveFactor { 0.0f }; - float shininess{ 23.0f }; - float opacity{ 1.0f }; + float shininess { 23.0f }; + float opacity { 1.0f }; - float metallic{ 0.0f }; - float roughness{ 1.0f }; - float emissiveIntensity{ 1.0f }; - float ambientFactor{ 1.0f }; + float metallic { 0.0f }; + float roughness { 1.0f }; + float emissiveIntensity { 1.0f }; + float ambientFactor { 1.0f }; float bumpMultiplier { 1.0f }; // TODO: to be implemented + graphics::MaterialKey::OpacityMapMode alphaMode { graphics::MaterialKey::OPACITY_MAP_BLEND }; + float alphaCutoff { 0.5f }; + QString materialID; QString name; QString shadingModel; @@ -207,19 +210,19 @@ public: Texture occlusionTexture; Texture scatteringTexture; Texture lightmapTexture; - glm::vec2 lightmapParams{ 0.0f, 1.0f }; + glm::vec2 lightmapParams { 0.0f, 1.0f }; - bool isPBSMaterial{ false }; + 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 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/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index 2b0d197819..ff2e3610c2 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -387,8 +387,10 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial std::call_once(once, [] { for (int i = 0; i < graphics::Material::NUM_TOTAL_FLAGS; i++) { // The opacity mask/map are derived from the albedo map + // FIXME: OPACITY_MAP_MODE_BIT is supposed to support fallthrough if (i != graphics::MaterialKey::OPACITY_MASK_MAP_BIT && - i != graphics::MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT) { + i != graphics::MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT && + i != graphics::MaterialKey::OPACITY_MAP_MODE_BIT) { allFlags.insert(i); } } diff --git a/libraries/render-utils/src/model.slf b/libraries/render-utils/src/model.slf index bacc6b0ab1..229a6b1907 100644 --- a/libraries/render-utils/src/model.slf +++ b/libraries/render-utils/src/model.slf @@ -103,14 +103,13 @@ void main(void) { <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex)$> <@if HIFI_USE_TRANSLUCENT@> - float cutoff = getMaterialOpacityCutoff(mat); float opacity = getMaterialOpacity(mat) * _color.a; - <$evalMaterialOpacity(albedoTex.a, cutoff, opacity, matKey, opacity)$>; + <$evalMaterialOpacity(albedoTex.a, opacity, opacity)$>; <$discardInvisible(opacity)$>; <@else@> float cutoff = getMaterialOpacityCutoff(mat); float opacity = 1.0; - <$evalMaterialOpacityMask(albedoTex.a, cutoff, opacity)$>; + <$evalMaterialOpacityMask(albedoTex.a, cutoff, opacity, matKey, opacity)$>; <$discardTransparent(opacity)$>; <@endif@> @@ -155,14 +154,13 @@ void main(void) { <@endif@> <@if HIFI_USE_TRANSLUCENT@> - float cutoff = getMaterialOpacityCutoff(mat); float opacity = getMaterialOpacity(mat) * _color.a; - <$evalMaterialOpacity(albedoTex.a, cutoff, opacity, matKey, opacity)$>; + <$evalMaterialOpacity(albedoTex.a, opacity, opacity)$>; <$discardInvisible(opacity)$>; <@else@> float cutoff = getMaterialOpacityCutoff(mat); float opacity = 1.0; - <$evalMaterialOpacityMask(albedoTex.a, cutoff, opacity)$>; + <$evalMaterialOpacityMask(albedoTex.a, cutoff, opacity, matKey, opacity)$>; <$discardTransparent(opacity)$>; <@endif@>