From 5371fd613afded803e4ab52da30304b3ef0c3315 Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Fri, 22 Nov 2019 00:37:27 -0800 Subject: [PATCH 1/2] properly implement alphaModes --- libraries/fbx/src/GLTFSerializer.cpp | 72 +++++++++++-------- 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, 90 insertions(+), 83 deletions(-) diff --git a/libraries/fbx/src/GLTFSerializer.cpp b/libraries/fbx/src/GLTFSerializer.cpp index a48631e360..c75e717609 100755 --- a/libraries/fbx/src/GLTFSerializer.cpp +++ b/libraries/fbx/src/GLTFSerializer.cpp @@ -265,17 +265,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) { @@ -523,9 +523,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; @@ -1704,57 +1704,67 @@ 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); + 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]); + 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 edecde6985..d59df615e5 100755 --- a/libraries/fbx/src/GLTFSerializer.h +++ b/libraries/fbx/src/GLTFSerializer.h @@ -418,21 +418,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; @@ -453,6 +445,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(); } @@ -850,7 +848,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); @@ -907,7 +905,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 c7b6789094..ca73676f86 100644 --- a/libraries/hfm/src/hfm/HFM.h +++ b/libraries/hfm/src/hfm/HFM.h @@ -176,24 +176,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; @@ -210,19 +213,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@> From f55c4b8b127065132b2a8630e6c0fcdd27b2c993 Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Sun, 24 Nov 2019 12:44:42 -0800 Subject: [PATCH 2/2] put back stepping in translucent case --- libraries/graphics/src/graphics/MaterialTextures.slh | 7 +++++-- libraries/render-utils/src/model.slf | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/libraries/graphics/src/graphics/MaterialTextures.slh b/libraries/graphics/src/graphics/MaterialTextures.slh index 534e1ae869..cb83f7d9cf 100644 --- a/libraries/graphics/src/graphics/MaterialTextures.slh +++ b/libraries/graphics/src/graphics/MaterialTextures.slh @@ -223,10 +223,13 @@ vec3 fetchLightMap(vec2 uv) { } <@endfunc@> -<@func evalMaterialOpacity(fetchedOpacity, materialOpacity, opacity)@> +<@func evalMaterialOpacity(fetchedOpacity, materialOpacityCutoff, materialOpacity, matKey, opacity)@> { // This path only valid for transparent material - <$opacity$> = <$materialOpacity$> * <$fetchedOpacity$>; + <$opacity$> = mix(<$fetchedOpacity$>, + step(<$materialOpacityCutoff$>, <$fetchedOpacity$>), + float((<$matKey$> & OPACITY_MASK_MAP_BIT) != 0)) + * <$materialOpacity$>; } <@endfunc@> diff --git a/libraries/render-utils/src/model.slf b/libraries/render-utils/src/model.slf index 229a6b1907..a6cc82e335 100644 --- a/libraries/render-utils/src/model.slf +++ b/libraries/render-utils/src/model.slf @@ -103,8 +103,9 @@ void main(void) { <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex)$> <@if HIFI_USE_TRANSLUCENT@> + float cutoff = getMaterialOpacityCutoff(mat); float opacity = getMaterialOpacity(mat) * _color.a; - <$evalMaterialOpacity(albedoTex.a, opacity, opacity)$>; + <$evalMaterialOpacity(albedoTex.a, cutoff, opacity, matKey, opacity)$>; <$discardInvisible(opacity)$>; <@else@> float cutoff = getMaterialOpacityCutoff(mat); @@ -154,8 +155,9 @@ void main(void) { <@endif@> <@if HIFI_USE_TRANSLUCENT@> + float cutoff = getMaterialOpacityCutoff(mat); float opacity = getMaterialOpacity(mat) * _color.a; - <$evalMaterialOpacity(albedoTex.a, opacity, opacity)$>; + <$evalMaterialOpacity(albedoTex.a, cutoff, opacity, matKey, opacity)$>; <$discardInvisible(opacity)$>; <@else@> float cutoff = getMaterialOpacityCutoff(mat);