diff --git a/src/Magnum/Trade/PbrClearCoatMaterialData.cpp b/src/Magnum/Trade/PbrClearCoatMaterialData.cpp index 87761a247..73bd1bd88 100644 --- a/src/Magnum/Trade/PbrClearCoatMaterialData.cpp +++ b/src/Magnum/Trade/PbrClearCoatMaterialData.cpp @@ -27,6 +27,16 @@ namespace Magnum { namespace Trade { +bool PbrClearCoatMaterialData::hasLayerFactorRoughnessTexture() const { + return hasAttribute(MaterialAttribute::LayerFactorTexture) && + hasAttribute(MaterialAttribute::RoughnessTexture) && + attribute(MaterialAttribute::LayerFactorTexture) == attribute(MaterialAttribute::RoughnessTexture) && + layerFactorTextureSwizzle() == MaterialTextureSwizzle::R && + roughnessTextureSwizzle() == MaterialTextureSwizzle::G && + layerFactorTextureMatrix() == roughnessTextureMatrix() && + layerFactorTextureCoordinates() == roughnessTextureCoordinates(); +} + bool PbrClearCoatMaterialData::hasTextureTransformation() const { return hasAttribute(MaterialAttribute::LayerFactorTextureMatrix) || hasAttribute(MaterialAttribute::RoughnessTextureMatrix) || diff --git a/src/Magnum/Trade/PbrClearCoatMaterialData.h b/src/Magnum/Trade/PbrClearCoatMaterialData.h index 9323581e8..9622599ce 100644 --- a/src/Magnum/Trade/PbrClearCoatMaterialData.h +++ b/src/Magnum/Trade/PbrClearCoatMaterialData.h @@ -56,6 +56,36 @@ class MAGNUM_TRADE_EXPORT PbrClearCoatMaterialData: public MaterialLayerData::MaterialLayerData; #endif + /** + * @brief Whether the material has a combined layer factor / roughness texture + * + * Returns @cpp true @ce if both + * @ref MaterialAttribute::LayerFactorTexture and + * @ref MaterialAttribute::RoughnessTexture attributes are present, + * point to the same texture ID, + * @ref MaterialAttribute::LayerFactorTextureSwizzle is either not + * present or set to @ref MaterialTextureSwizzle::R and + * @ref MaterialAttribute::RoughnessTextureSwizzle is set to + * @ref MaterialTextureSwizzle::G, and additionally + * @ref MaterialAttribute::LayerFactorTextureMatrix and + * @ref MaterialAttribute::RoughnessTextureMatrix are both either not + * present or have the same value, and + * @ref MaterialAttribute::LayerFactorTextureCoordinates and + * @ref MaterialAttribute::RoughnessTextureCoordinates are both either + * not present or have the smae value; @cpp false @ce otherwise. + * + * In other words, if this function returns @cpp true @ce, + * @ref layerFactorTexture(), @ref layerFactorTextureMatrix() and + * @ref layerFactorTextureCoordinates() return values common for both + * layer factor and roughness texture, and the two are packed together + * with layer factor occupying the R channel and roughness the G + * channel. This check is present in order to provide support for the + * [KHR_materials_clearcoat](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat/README.md) + * glTF extension. + * @see @ref hasAttribute() + */ + bool hasLayerFactorRoughnessTexture() const; + /** * @brief Whether the material has texture transformation * diff --git a/src/Magnum/Trade/Test/MaterialDataTest.cpp b/src/Magnum/Trade/Test/MaterialDataTest.cpp index 0e712b21c..e469b782e 100644 --- a/src/Magnum/Trade/Test/MaterialDataTest.cpp +++ b/src/Magnum/Trade/Test/MaterialDataTest.cpp @@ -207,6 +207,7 @@ class MaterialDataTest: public TestSuite::Tester { void pbrClearCoatAccessDefaults(); void pbrClearCoatAccessTextured(); void pbrClearCoatAccessTexturedDefaults(); + void pbrClearCoatAccessTexturedExplicitPackedLayerFactorRoughness(); void pbrClearCoatAccessTexturedSingleMatrixCoordinates(); void pbrClearCoatAccessTexturedBaseMaterialMatrixCoordinates(); void pbrClearCoatAccessInvalidTextures(); @@ -465,6 +466,7 @@ MaterialDataTest::MaterialDataTest() { &MaterialDataTest::pbrClearCoatAccessDefaults, &MaterialDataTest::pbrClearCoatAccessTextured, &MaterialDataTest::pbrClearCoatAccessTexturedDefaults, + &MaterialDataTest::pbrClearCoatAccessTexturedExplicitPackedLayerFactorRoughness, &MaterialDataTest::pbrClearCoatAccessTexturedSingleMatrixCoordinates, &MaterialDataTest::pbrClearCoatAccessTexturedBaseMaterialMatrixCoordinates, &MaterialDataTest::pbrClearCoatAccessInvalidTextures, @@ -4619,6 +4621,101 @@ void MaterialDataTest::pbrClearCoatAccessTexturedDefaults() { CORRADE_COMPARE(data.normalTextureCoordinates(), 0u); } +void MaterialDataTest::pbrClearCoatAccessTexturedExplicitPackedLayerFactorRoughness() { + /* Just the texture ID and swizzles, the rest is implicit */ + { + PbrClearCoatMaterialData data{{}, { + {MaterialLayer::ClearCoat}, + {MaterialAttribute::LayerFactorTexture, 2u}, + {MaterialAttribute::RoughnessTexture, 2u}, + {MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::G} + }, {0, 4}}; + CORRADE_VERIFY(data.hasLayerFactorRoughnessTexture()); + CORRADE_COMPARE(data.layerFactorTexture(), 2); + CORRADE_COMPARE(data.layerFactorTextureMatrix(), Matrix3{}); + CORRADE_COMPARE(data.layerFactorTextureCoordinates(), 0); + CORRADE_COMPARE(data.roughnessTexture(), 2); + CORRADE_COMPARE(data.roughnessTextureSwizzle(), MaterialTextureSwizzle::G); + CORRADE_COMPARE(data.roughnessTextureMatrix(), Matrix3{}); + CORRADE_COMPARE(data.roughnessTextureCoordinates(), 0); + + /* Explicit parameters for everything, but all the same */ + } { + PbrClearCoatMaterialData data{{}, { + {MaterialLayer::ClearCoat}, + {MaterialAttribute::LayerFactorTexture, 2u}, + {MaterialAttribute::LayerFactorTextureSwizzle, MaterialTextureSwizzle::R}, + {MaterialAttribute::LayerFactorTextureMatrix, Matrix3::scaling({0.5f, 0.5f})}, + {MaterialAttribute::LayerFactorTextureCoordinates, 3u}, + {MaterialAttribute::RoughnessTexture, 2u}, + {MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::G}, + {MaterialAttribute::RoughnessTextureMatrix, Matrix3::scaling({0.5f, 0.5f})}, + {MaterialAttribute::RoughnessTextureCoordinates, 3u} + }, {0, 9}}; + CORRADE_VERIFY(data.hasLayerFactorRoughnessTexture()); + CORRADE_COMPARE(data.layerFactorTexture(), 2); + CORRADE_COMPARE(data.layerFactorTextureMatrix(), Matrix3::scaling({0.5f, 0.5f})); + CORRADE_COMPARE(data.layerFactorTextureCoordinates(), 3); + CORRADE_COMPARE(data.roughnessTexture(), 2); + CORRADE_COMPARE(data.roughnessTextureSwizzle(), MaterialTextureSwizzle::G); + CORRADE_COMPARE(data.roughnessTextureMatrix(), Matrix3::scaling({0.5f, 0.5f})); + CORRADE_COMPARE(data.roughnessTextureCoordinates(), 3); + + /* Different texture ID */ + } { + PbrClearCoatMaterialData data{{}, { + {MaterialLayer::ClearCoat}, + {MaterialAttribute::LayerFactorTexture, 2u}, + {MaterialAttribute::RoughnessTexture, 3u}, + {MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::G}, + }, {0, 4}}; + CORRADE_VERIFY(!data.hasLayerFactorRoughnessTexture()); + + /* Unexpected swizzle 1 */ + } { + PbrClearCoatMaterialData data{{}, { + {MaterialLayer::ClearCoat}, + {MaterialAttribute::LayerFactorTexture, 2u}, + {MaterialAttribute::LayerFactorTextureSwizzle, MaterialTextureSwizzle::B}, + {MaterialAttribute::RoughnessTexture, 2u}, + {MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::G}, + }, {0, 5}}; + CORRADE_VERIFY(!data.hasLayerFactorRoughnessTexture()); + + /* Unexpected swizzle 2 */ + } { + PbrClearCoatMaterialData data{{}, { + {MaterialLayer::ClearCoat}, + {MaterialAttribute::LayerFactorTexture, 2u}, + {MaterialAttribute::RoughnessTexture, 2u}, + {MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::B} + }, {0, 4}}; + CORRADE_VERIFY(!data.hasLayerFactorRoughnessTexture()); + + /* Unexpected texture matrix */ + } { + PbrClearCoatMaterialData data{{}, { + {MaterialLayer::ClearCoat}, + {MaterialAttribute::LayerFactorTexture, 2u}, + {MaterialAttribute::LayerFactorTextureMatrix, Matrix3::scaling({0.5f, 1.0f})}, + {MaterialAttribute::RoughnessTexture, 2u}, + {MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::G} + }, {0, 5}}; + CORRADE_VERIFY(!data.hasLayerFactorRoughnessTexture()); + + /* Unexpected texture coordinates */ + } { + PbrClearCoatMaterialData data{{}, { + {MaterialLayer::ClearCoat}, + {MaterialAttribute::LayerFactorTexture, 2u}, + {MaterialAttribute::RoughnessTexture, 2u}, + {MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::G}, + {MaterialAttribute::RoughnessTextureCoordinates, 1u} + }, {0, 5}}; + CORRADE_VERIFY(!data.hasLayerFactorRoughnessTexture()); + } +} + void MaterialDataTest::pbrClearCoatAccessTexturedSingleMatrixCoordinates() { PbrClearCoatMaterialData data{{}, { {MaterialLayer::ClearCoat},