diff --git a/doc/changelog.dox b/doc/changelog.dox index a602153dd..946c68808 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -485,7 +485,8 @@ See also: @ref Trade::PbrMetallicRoughnessMaterialData, @ref Trade::PbrSpecularGlossinessMaterialData and @ref Trade::PbrClearCoatMaterialData convenience accessor APIs similar to - @ref Trade::PhongMaterialData. See [mosra/magnum#459](https://github.com/mosra/magnum/pull/459). + @ref Trade::PhongMaterialData. See also [mosra/magnum#459](https://github.com/mosra/magnum/pull/459) + and [mosra/magnum#662](https://github.com/mosra/magnum/issues/662). - Added @ref Trade::PhongMaterialData::hasSpecularTexture(), @ref Trade::PhongMaterialData::specularTextureSwizzle(), @ref Trade::PhongMaterialData::normalTextureScale() and diff --git a/src/Magnum/Trade/PbrMetallicRoughnessMaterialData.cpp b/src/Magnum/Trade/PbrMetallicRoughnessMaterialData.cpp index 5291a0b7f..2438e36b2 100644 --- a/src/Magnum/Trade/PbrMetallicRoughnessMaterialData.cpp +++ b/src/Magnum/Trade/PbrMetallicRoughnessMaterialData.cpp @@ -56,15 +56,21 @@ bool PbrMetallicRoughnessMaterialData::hasNoneRoughnessMetallicTexture() const { } bool PbrMetallicRoughnessMaterialData::hasOcclusionRoughnessMetallicTexture() const { - if(!hasAttribute(MaterialAttribute::OcclusionTexture) || - !hasAttribute(MaterialAttribute::RoughnessTexture) || - !hasAttribute(MaterialAttribute::MetalnessTexture)) + if(!hasAttribute(MaterialAttribute::OcclusionTexture)) return false; const UnsignedInt occlusionTexture = attribute(MaterialAttribute::OcclusionTexture); - if(attribute(MaterialAttribute::RoughnessTexture) != occlusionTexture || - attribute(MaterialAttribute::MetalnessTexture) != occlusionTexture || - occlusionTextureSwizzle() != MaterialTextureSwizzle::R || + if(hasAttribute(MaterialAttribute::NoneRoughnessMetallicTexture)) { + if(attribute(MaterialAttribute::NoneRoughnessMetallicTexture) != occlusionTexture) + return false; + } else if(hasAttribute(MaterialAttribute::MetalnessTexture) && + hasAttribute(MaterialAttribute::RoughnessTexture)) { + if(attribute(MaterialAttribute::RoughnessTexture) != occlusionTexture || + attribute(MaterialAttribute::MetalnessTexture) != occlusionTexture) + return false; + } else return false; + + if(occlusionTextureSwizzle() != MaterialTextureSwizzle::R || roughnessTextureSwizzle() != MaterialTextureSwizzle::G || metalnessTextureSwizzle() != MaterialTextureSwizzle::B) return false; diff --git a/src/Magnum/Trade/PbrMetallicRoughnessMaterialData.h b/src/Magnum/Trade/PbrMetallicRoughnessMaterialData.h index 3aa267c02..52468c100 100644 --- a/src/Magnum/Trade/PbrMetallicRoughnessMaterialData.h +++ b/src/Magnum/Trade/PbrMetallicRoughnessMaterialData.h @@ -124,13 +124,15 @@ class MAGNUM_TRADE_EXPORT PbrMetallicRoughnessMaterialData: public MaterialData /** * @brief Whether the material has a combined occlusion/roughness/metallic texture * - * Returns @cpp true @ce if @ref MaterialAttribute::OcclusionTexture, - * @ref MaterialAttribute::RoughnessTexture and - * @ref MaterialAttribute::MetalnessTexture are all present, point to - * the same texture ID, @ref MaterialAttribute::OcclusionTextureSwizzle - * is set to @ref MaterialTextureSwizzle::R (or omitted, in which case - * it's the default), @ref MaterialAttribute::RoughnessTextureSwizzle - * is set to @ref MaterialTextureSwizzle::G and + * Returns @cpp true @ce if @ref MaterialAttribute::OcclusionTexture + * and either the @ref MaterialAttribute::NoneRoughnessMetallicTexture + * attribute is present or both @ref MaterialAttribute::RoughnessTexture + * and @ref MaterialAttribute::MetalnessTexture are present and they + * point to the same texture ID, + * @ref MaterialAttribute::OcclusionTextureSwizzle is set to + * @ref MaterialTextureSwizzle::R (or omitted, in which case it's the + * default), @ref MaterialAttribute::RoughnessTextureSwizzle is set to + * @ref MaterialTextureSwizzle::G and * @ref MaterialAttribute::MetalnessTextureSwizzle is set to * @ref MaterialTextureSwizzle::B, and additionally * @ref MaterialAttribute::OcclusionTextureMatrix, diff --git a/src/Magnum/Trade/Test/PbrMetallicRoughnessMaterialDataTest.cpp b/src/Magnum/Trade/Test/PbrMetallicRoughnessMaterialDataTest.cpp index e3cfab937..e0ef6f5d5 100644 --- a/src/Magnum/Trade/Test/PbrMetallicRoughnessMaterialDataTest.cpp +++ b/src/Magnum/Trade/Test/PbrMetallicRoughnessMaterialDataTest.cpp @@ -40,6 +40,7 @@ struct PbrMetallicRoughnessMaterialDataTest: TestSuite::Tester { void defaults(); void textured(); void texturedDefaults(); + void texturedImplicitPackedNoneRoughnessMetallic(); void texturedExplicitPackedNoneRoughnessMetallic(); void texturedImplicitPackedOcclusionRoughnessMetallic(); void texturedExplicitPackedOcclusionRoughnessMetallic(); @@ -68,6 +69,7 @@ PbrMetallicRoughnessMaterialDataTest::PbrMetallicRoughnessMaterialDataTest() { &PbrMetallicRoughnessMaterialDataTest::defaults, &PbrMetallicRoughnessMaterialDataTest::textured, &PbrMetallicRoughnessMaterialDataTest::texturedDefaults, + &PbrMetallicRoughnessMaterialDataTest::texturedImplicitPackedNoneRoughnessMetallic, &PbrMetallicRoughnessMaterialDataTest::texturedExplicitPackedNoneRoughnessMetallic, &PbrMetallicRoughnessMaterialDataTest::texturedImplicitPackedOcclusionRoughnessMetallic, &PbrMetallicRoughnessMaterialDataTest::texturedExplicitPackedOcclusionRoughnessMetallic, @@ -475,6 +477,106 @@ void PbrMetallicRoughnessMaterialDataTest::texturedExplicitPackedNoneRoughnessMe } } +void PbrMetallicRoughnessMaterialDataTest::texturedImplicitPackedOcclusionRoughnessMetallic() { + /* Just the texture IDs, the rest is implicit */ + { + PbrMetallicRoughnessMaterialData data{{}, { + {MaterialAttribute::OcclusionTexture, 2u}, + {MaterialAttribute::NoneRoughnessMetallicTexture, 2u}, + }}; + CORRADE_VERIFY(data.hasOcclusionRoughnessMetallicTexture()); + CORRADE_VERIFY(!data.hasRoughnessMetallicOcclusionTexture()); + /* This is a superset */ + CORRADE_VERIFY(data.hasNoneRoughnessMetallicTexture()); + + /* Explicit parameters for everything, but all the same */ + } { + PbrMetallicRoughnessMaterialData data{{}, { + {MaterialAttribute::OcclusionTexture, 2u}, + {MaterialAttribute::NoneRoughnessMetallicTexture, 2u}, + {MaterialAttribute::OcclusionTextureSwizzle, MaterialTextureSwizzle::R}, + {MaterialAttribute::OcclusionTextureMatrix, Matrix3::scaling({0.5f, 0.5f})}, + {MaterialAttribute::OcclusionTextureCoordinates, 3u}, + {MaterialAttribute::OcclusionTextureLayer, 17u}, + {MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::G}, + {MaterialAttribute::RoughnessTextureMatrix, Matrix3::scaling({0.5f, 0.5f})}, + {MaterialAttribute::RoughnessTextureCoordinates, 3u}, + {MaterialAttribute::RoughnessTextureLayer, 17u}, + {MaterialAttribute::MetalnessTextureMatrix, Matrix3::scaling({0.5f, 0.5f})}, + {MaterialAttribute::MetalnessTextureSwizzle, MaterialTextureSwizzle::B}, + {MaterialAttribute::MetalnessTextureCoordinates, 3u}, + {MaterialAttribute::MetalnessTextureLayer, 17u} + }}; + CORRADE_VERIFY(data.hasOcclusionRoughnessMetallicTexture()); + CORRADE_VERIFY(!data.hasRoughnessMetallicOcclusionTexture()); + /* This is a superset */ + CORRADE_VERIFY(data.hasNoneRoughnessMetallicTexture()); + + /* Different texture ID */ + } { + PbrMetallicRoughnessMaterialData data{{}, { + {MaterialAttribute::OcclusionTexture, 2u}, + {MaterialAttribute::NoneRoughnessMetallicTexture, 3u}, + {MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::G}, + {MaterialAttribute::MetalnessTextureSwizzle, MaterialTextureSwizzle::B}, + }}; + CORRADE_VERIFY(!data.hasOcclusionRoughnessMetallicTexture()); + + /* One texture missing */ + } { + PbrMetallicRoughnessMaterialData data{{}, { + {MaterialAttribute::NoneRoughnessMetallicTexture, 2u}, + {MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::G}, + {MaterialAttribute::MetalnessTextureSwizzle, MaterialTextureSwizzle::B}, + }}; + CORRADE_VERIFY(!data.hasOcclusionRoughnessMetallicTexture()); + + /* Unexpected swizzle */ + } { + PbrMetallicRoughnessMaterialData data{{}, { + {MaterialAttribute::OcclusionTexture, 2u}, + {MaterialAttribute::NoneRoughnessMetallicTexture, 2u}, + {MaterialAttribute::OcclusionTextureSwizzle, MaterialTextureSwizzle::A}, + {MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::G}, + {MaterialAttribute::MetalnessTextureSwizzle, MaterialTextureSwizzle::B}, + }}; + CORRADE_VERIFY(!data.hasOcclusionRoughnessMetallicTexture()); + + /* Unexpected texture matrix */ + } { + PbrMetallicRoughnessMaterialData data{{}, { + {MaterialAttribute::OcclusionTexture, 2u}, + {MaterialAttribute::NoneRoughnessMetallicTexture, 2u}, + {MaterialAttribute::OcclusionTextureMatrix, Matrix3::scaling({0.5f, 1.0f})}, + {MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::G}, + {MaterialAttribute::MetalnessTextureSwizzle, MaterialTextureSwizzle::B}, + }}; + CORRADE_VERIFY(!data.hasOcclusionRoughnessMetallicTexture()); + + /* Unexpected texture coordinates */ + } { + PbrMetallicRoughnessMaterialData data{{}, { + {MaterialAttribute::OcclusionTexture, 2u}, + {MaterialAttribute::NoneRoughnessMetallicTexture, 2u}, + {MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::G}, + {MaterialAttribute::MetalnessTextureSwizzle, MaterialTextureSwizzle::B}, + {MaterialAttribute::MetalnessTextureCoordinates, 1u}, + }}; + CORRADE_VERIFY(!data.hasOcclusionRoughnessMetallicTexture()); + + /* Unexpected array texture layer */ + } { + PbrMetallicRoughnessMaterialData data{{}, { + {MaterialAttribute::OcclusionTexture, 2u}, + {MaterialAttribute::NoneRoughnessMetallicTexture, 2u}, + {MaterialAttribute::OcclusionTextureLayer, 1u}, + {MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::G}, + {MaterialAttribute::MetalnessTextureSwizzle, MaterialTextureSwizzle::B}, + }}; + CORRADE_VERIFY(!data.hasOcclusionRoughnessMetallicTexture()); + } +} + void PbrMetallicRoughnessMaterialDataTest::texturedExplicitPackedOcclusionRoughnessMetallic() { /* Just the texture IDs and swizzles, the rest is implicit */ { @@ -713,14 +815,17 @@ void PbrMetallicRoughnessMaterialDataTest::texturedExplicitPackedNormalRoughness {MaterialAttribute::NormalTextureSwizzle, MaterialTextureSwizzle::RG}, {MaterialAttribute::NormalTextureMatrix, Matrix3::scaling({0.5f, 0.5f})}, {MaterialAttribute::NormalTextureCoordinates, 3u}, + {MaterialAttribute::NormalTextureLayer, 17u}, {MaterialAttribute::RoughnessTexture, 2u}, {MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::B}, {MaterialAttribute::RoughnessTextureMatrix, Matrix3::scaling({0.5f, 0.5f})}, {MaterialAttribute::RoughnessTextureCoordinates, 3u}, + {MaterialAttribute::RoughnessTextureLayer, 17u}, {MaterialAttribute::MetalnessTexture, 2u}, {MaterialAttribute::MetalnessTextureMatrix, Matrix3::scaling({0.5f, 0.5f})}, {MaterialAttribute::MetalnessTextureSwizzle, MaterialTextureSwizzle::A}, - {MaterialAttribute::MetalnessTextureCoordinates, 3u} + {MaterialAttribute::MetalnessTextureCoordinates, 3u}, + {MaterialAttribute::MetalnessTextureLayer, 17u} }}; CORRADE_VERIFY(data.hasNormalRoughnessMetallicTexture());