Browse Source

Trade: rework metallic/roughness packing.

Turns out glTF doesn't actually put metalness into R and roughness into
G, even though the naming suggests that. This was done originally, but
then they changed that in order to be compatible with UE4 and allow for
a more efficient storage of an occlusion map.

Because this feels extremely arbitrary, the docs have added rationale
for each of the packing variants, and I'm also renaming the packed
attribute and checks to imply the red channel isn't used.
pull/459/head
Vladimír Vondruš 6 years ago
parent
commit
f9edbcdd24
  1. 22
      doc/snippets/MagnumTrade.cpp
  2. 2
      src/Magnum/Trade/Implementation/materialAttributeProperties.hpp
  3. 61
      src/Magnum/Trade/MaterialData.h
  4. 26
      src/Magnum/Trade/PbrMetallicRoughnessMaterialData.cpp
  5. 91
      src/Magnum/Trade/PbrMetallicRoughnessMaterialData.h
  6. 104
      src/Magnum/Trade/Test/MaterialDataTest.cpp

22
doc/snippets/MagnumTrade.cpp

@ -310,24 +310,26 @@ if(data.types() & Trade::MaterialType::PbrSpecularGlossiness) {
{
/* [MaterialData-usage-packing] */
Trade::PbrMetallicRoughnessMaterialData data = DOXYGEN_IGNORE(Trade::PbrMetallicRoughnessMaterialData{{}, {}});
Trade::PbrSpecularGlossinessMaterialData data = DOXYGEN_IGNORE(Trade::PbrSpecularGlossinessMaterialData{{}, {}});
/* Use a shader that accepts a single packed metallic/roughness texture.
Querying any texture attributes will give the same values for both metalness
and roughness. */
if(data.hasMetallicRoughnessTexture()) {
UnsignedInt metallicRoughness = data.metalnessTexture();
if(data.hasSpecularGlossinessTexture()) {
UnsignedInt specularGlossiness = data.specularTexture();
DOXYGEN_IGNORE(static_cast<void>(metallicRoughness);)
DOXYGEN_IGNORE(static_cast<void>(specularGlossiness);)
/* Supply texture channels separately */
} else {
UnsignedInt metalness = data.metalnessTexture();
UnsignedInt roughness = data.roughnessTexture();
Trade::MaterialTextureSwizzle metalnessSwizzle = data.metalnessTextureSwizzle();
Trade::MaterialTextureSwizzle roughnessSwizzle = data.roughnessTextureSwizzle();
UnsignedInt specular = data.specularTexture();
UnsignedInt glossiness = data.glossinessTexture();
Trade::MaterialTextureSwizzle specularSwizzle =
data.specularTextureSwizzle();
Trade::MaterialTextureSwizzle glossinessSwizzle =
data.glossinessTextureSwizzle();
DOXYGEN_IGNORE(static_cast<void>(metalness), static_cast<void>(roughness), static_cast<void>(metalnessSwizzle), static_cast<void>(roughnessSwizzle);)
DOXYGEN_IGNORE(static_cast<void>(specular), static_cast<void>(glossiness), static_cast<void>(specularSwizzle), static_cast<void>(glossinessSwizzle);)
}
/* [MaterialData-usage-packing] */
}
@ -413,7 +415,7 @@ Trade::MaterialData data{
Trade::MaterialType::PbrMetallicRoughness|Trade::MaterialType::PbrClearCoat,
{
{Trade::MaterialAttribute::BaseColor, 0xffcc33_srgbf},
{Trade::MaterialAttribute::MetallicRoughnessTexture, 0u},
{Trade::MaterialAttribute::NoneRoughnessMetallicTexture, 0u},
{Trade::MaterialLayer::ClearCoat},
{Trade::MaterialAttribute::LayerFactorTexture, 1u},

2
src/Magnum/Trade/Implementation/materialAttributeProperties.hpp

@ -57,7 +57,7 @@ _c(RoughnessTexture,UnsignedInt)
_ct(RoughnessTextureSwizzle,TextureSwizzle,MaterialTextureSwizzle)
_c(RoughnessTextureMatrix,Matrix3x3)
_c(RoughnessTextureCoordinates,UnsignedInt)
_c(MetallicRoughnessTexture,UnsignedInt)
_c(NoneRoughnessMetallicTexture,UnsignedInt)
_c(Glossiness,Float)
_c(GlossinessTexture,UnsignedInt)
_ct(GlossinessTextureSwizzle,TextureSwizzle,MaterialTextureSwizzle)

61
src/Magnum/Trade/MaterialData.h

@ -356,7 +356,7 @@ enum class MaterialAttribute: UnsignedInt {
* @ref MaterialAttributeType::Float.
*
* If @ref MaterialAttribute::MetalnessTexture or
* @ref MaterialAttribute::MetallicRoughnessTexture is present as well,
* @ref MaterialAttribute::NoneRoughnessMetallicTexture is present as well,
* these two are multiplied together.
* @see @ref PbrMetallicRoughnessMaterialData::metalness()
*/
@ -368,9 +368,9 @@ enum class MaterialAttribute: UnsignedInt {
*
* If @ref MaterialAttribute::Metalness is present as well, these two are
* multiplied together. Can be alternatively supplied as a packed
* @ref MaterialAttribute::MetallicRoughnessTexture.
* @ref MaterialAttribute::NoneRoughnessMetallicTexture.
* @see @ref PbrMetallicRoughnessMaterialData::hasMetalnessTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasMetallicRoughnessTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasNoneRoughnessMetallicTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasOcclusionRoughnessMetallicTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasNormalRoughnessMetallicTexture()
* @ref PbrMetallicRoughnessMaterialData::metalnessTexture()
@ -385,9 +385,10 @@ enum class MaterialAttribute: UnsignedInt {
* @ref MaterialAttribute::MetalnessTexture together with other maps in a
* single texture. A single-channel swizzle value is expected. If not
* present, @ref MaterialTextureSwizzle::R is assumed. Does not apply to
* @ref MaterialAttribute::MetallicRoughnessTexture --- in that case, the
* metalness is implicitly in the red channel regardless of this attribute.
* @see @ref PbrMetallicRoughnessMaterialData::hasMetallicRoughnessTexture(),
* @ref MaterialAttribute::NoneRoughnessMetallicTexture --- in that case,
* the metalness is implicitly in the red channel regardless of this
* attribute.
* @see @ref PbrMetallicRoughnessMaterialData::hasNoneRoughnessMetallicTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasOcclusionRoughnessMetallicTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasNormalRoughnessMetallicTexture()
* @ref PbrMetallicRoughnessMaterialData::metalnessTextureSwizzle()
@ -419,7 +420,7 @@ enum class MaterialAttribute: UnsignedInt {
* @ref MaterialAttributeType::Float.
*
* If @ref MaterialAttribute::RoughnessTexture or
* @ref MaterialAttribute::MetallicRoughnessTexture is present as well,
* @ref MaterialAttribute::NoneRoughnessMetallicTexture is present as well,
* these two are multiplied together.
* @see @ref PbrMetallicRoughnessMaterialData::roughness()
*/
@ -431,9 +432,9 @@ enum class MaterialAttribute: UnsignedInt {
*
* If @ref MaterialAttribute::Roughness is present as well, these two are
* multiplied together. Can be alternatively supplied as a packed
* @ref MaterialAttribute::MetallicRoughnessTexture.
* @ref MaterialAttribute::NoneRoughnessMetallicTexture.
* @see @ref PbrMetallicRoughnessMaterialData::hasRoughnessTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasMetallicRoughnessTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasNoneRoughnessMetallicTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasOcclusionRoughnessMetallicTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasNormalRoughnessMetallicTexture()
* @ref PbrMetallicRoughnessMaterialData::roughnessTexture()
@ -448,10 +449,10 @@ enum class MaterialAttribute: UnsignedInt {
* @ref MaterialAttribute::RoughnessTexture together with other maps in a
* single texture. A single-channel swizzle value is expected. If not
* present, @ref MaterialTextureSwizzle::R is assumed. Does not apply to
* @ref MaterialAttribute::MetallicRoughnessTexture --- in that case, the
* metalness is implicitly in the green channel regardless of this
* @ref MaterialAttribute::NoneRoughnessMetallicTexture --- in that case,
* the metalness is implicitly in the green channel regardless of this
* attribute.
* @see @ref PbrMetallicRoughnessMaterialData::hasMetallicRoughnessTexture(),
* @see @ref PbrMetallicRoughnessMaterialData::hasNoneRoughnessMetallicTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasOcclusionRoughnessMetallicTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasNormalRoughnessMetallicTexture()
* @ref PbrMetallicRoughnessMaterialData::roughnessTextureSwizzle()
@ -479,32 +480,36 @@ enum class MaterialAttribute: UnsignedInt {
RoughnessTextureCoordinates,
/**
* Combined metallic/roughness texture index for PBR metallic/roughness
* materials with metalness in the red channel and roughness in the green
* Combined roughness/metallic texture index for PBR metallic/roughness
* materials with metalness in the blue channel and roughness in the green
* channel, @ref MaterialAttributeType::UnsignedInt.
*
* If @ref MaterialAttribute::Metalness / @ref MaterialAttribute::Roughness
* is present as well, these two are multiplied together. Can be
* alternatively specified as a pair of @ref MaterialAttribute::MetalnessTexture
* / @ref MaterialAttribute::RoughnessTexture attributes together with
* @ref MaterialAttribute::MetalnessTextureSwizzle set to
* @ref MaterialTextureSwizzle::R (or omitted, since that's the default)
* and @ref MaterialAttribute::RoughnessTextureSwizzle set to
* @ref MaterialTextureSwizzle::G. Texture transformation and coordinate
* is present as well, these two are multiplied together.
*
* This is a convenience alias to simplify representation of glTF and UE4
* materials, which is where this packing is used ([rationale](https://github.com/KhronosGroup/glTF/issues/857)).
* This packing (and other variants) can be alternatively specified as a
* pair of @ref MaterialAttribute::RoughnessTexture /
* @ref MaterialAttribute::MetalnessTexture attributes together with
* @ref MaterialAttribute::RoughnessTextureSwizzle set to
* @ref MaterialTextureSwizzle::G
* and @ref MaterialAttribute::MetalnessTextureSwizzle set to
* @ref MaterialTextureSwizzle::B. Texture transformation and coordinate
* set, if needed, have to be specified either using the global
* @ref MaterialAttribute::TextureMatrix and
* @ref MaterialAttribute::TextureCoordinates attributes or the per-texture
* @ref MaterialAttribute::MetalnessTextureMatrix,
* @ref MaterialAttribute::RoughnessTextureMatrix,
* @ref MaterialAttribute::MetalnessTextureCoordinates and
* @ref MaterialAttribute::RoughnessTextureCoordinates variants.
* @see @ref PbrMetallicRoughnessMaterialData::hasMetallicRoughnessTexture(),
* @ref MaterialAttribute::MetalnessTextureMatrix,
* @ref MaterialAttribute::RoughnessTextureCoordinates and
* @ref MaterialAttribute::MetalnessTextureCoordinates variants.
* @see @ref PbrMetallicRoughnessMaterialData::hasNoneRoughnessMetallicTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasOcclusionRoughnessMetallicTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasNormalRoughnessMetallicTexture()
* @ref PbrMetallicRoughnessMaterialData::metalnessTexture(),
* @ref PbrMetallicRoughnessMaterialData::roughnessTexture()
*/
MetallicRoughnessTexture,
NoneRoughnessMetallicTexture,
/* DiffuseColor, DiffuseTexture, DiffuseTextureMatrix,
DiffuseTextureCoordinates, SpecularColor, SpecularTexture,
@ -1441,8 +1446,8 @@ various @ref MaterialTextureSwizzle attributes such as
@ref MaterialAttribute::MetalnessTextureSwizzle. While this provides an almost
endless variability, real-world textures are in just a few common packing
schemes. For convenience these have dedicated attributes such as
@ref MaterialAttribute::MetallicRoughnessTexture and can also be checked for
with for example @ref PbrMetallicRoughnessMaterialData::hasMetallicRoughnessTexture():
@ref MaterialAttribute::SpecularGlossinessTexture and can also be checked
for with for example @ref PbrSpecularGlossinessMaterialData::hasSpecularGlossinessTexture():
@snippet MagnumTrade.cpp MaterialData-usage-packing

26
src/Magnum/Trade/PbrMetallicRoughnessMaterialData.cpp

@ -34,22 +34,22 @@ using namespace Math::Literals;
bool PbrMetallicRoughnessMaterialData::hasMetalnessTexture() const {
return hasAttribute(MaterialAttribute::MetalnessTexture) ||
hasAttribute(MaterialAttribute::MetallicRoughnessTexture);
hasAttribute(MaterialAttribute::NoneRoughnessMetallicTexture);
}
bool PbrMetallicRoughnessMaterialData::hasRoughnessTexture() const {
return hasAttribute(MaterialAttribute::RoughnessTexture) ||
hasAttribute(MaterialAttribute::MetallicRoughnessTexture);
hasAttribute(MaterialAttribute::NoneRoughnessMetallicTexture);
}
bool PbrMetallicRoughnessMaterialData::hasMetallicRoughnessTexture() const {
return (hasAttribute(MaterialAttribute::MetallicRoughnessTexture) ||
bool PbrMetallicRoughnessMaterialData::hasNoneRoughnessMetallicTexture() const {
return (hasAttribute(MaterialAttribute::NoneRoughnessMetallicTexture) ||
(hasAttribute(MaterialAttribute::MetalnessTexture) &&
hasAttribute(MaterialAttribute::RoughnessTexture) &&
metalnessTextureSwizzle() == MaterialTextureSwizzle::R &&
roughnessTextureSwizzle() == MaterialTextureSwizzle::G)) &&
metalnessTextureMatrix() == roughnessTextureMatrix() &&
metalnessTextureCoordinates() == roughnessTextureCoordinates();
roughnessTextureSwizzle() == MaterialTextureSwizzle::G &&
metalnessTextureSwizzle() == MaterialTextureSwizzle::B)) &&
roughnessTextureMatrix() == metalnessTextureMatrix() &&
roughnessTextureCoordinates() == metalnessTextureCoordinates();
}
bool PbrMetallicRoughnessMaterialData::hasRoughnessMetallicOcclusionTexture() const {
@ -156,7 +156,7 @@ UnsignedInt PbrMetallicRoughnessMaterialData::metalnessTexture() const {
would be misleading as it can be also MetallicRoughnessTexture */
CORRADE_ASSERT(hasMetalnessTexture(),
"Trade::PbrMetallicRoughnessMaterialData::metalnessTexture(): the material doesn't have a metalness texture", {});
if(Containers::Optional<UnsignedInt> value = tryAttribute<UnsignedInt>(MaterialAttribute::MetallicRoughnessTexture))
if(Containers::Optional<UnsignedInt> value = tryAttribute<UnsignedInt>(MaterialAttribute::NoneRoughnessMetallicTexture))
return *value;
return attribute<UnsignedInt>(MaterialAttribute::MetalnessTexture);
}
@ -164,8 +164,8 @@ UnsignedInt PbrMetallicRoughnessMaterialData::metalnessTexture() const {
MaterialTextureSwizzle PbrMetallicRoughnessMaterialData::metalnessTextureSwizzle() const {
CORRADE_ASSERT(hasMetalnessTexture(),
"Trade::PbrMetallicRoughnessMaterialData::metalnessTextureSwizzle(): the material doesn't have a metalness texture", {});
if(hasAttribute(MaterialAttribute::MetallicRoughnessTexture))
return MaterialTextureSwizzle::R;
if(hasAttribute(MaterialAttribute::NoneRoughnessMetallicTexture))
return MaterialTextureSwizzle::B;
return attributeOr(MaterialAttribute::MetalnessTextureSwizzle, MaterialTextureSwizzle::R);
}
@ -194,7 +194,7 @@ UnsignedInt PbrMetallicRoughnessMaterialData::roughnessTexture() const {
would be misleading as it can be also MetallicRoughnessTexture */
CORRADE_ASSERT(hasRoughnessTexture(),
"Trade::PbrMetallicRoughnessMaterialData::roughnessTexture(): the material doesn't have a roughness texture", {});
if(Containers::Optional<UnsignedInt> value = tryAttribute<UnsignedInt>(MaterialAttribute::MetallicRoughnessTexture))
if(Containers::Optional<UnsignedInt> value = tryAttribute<UnsignedInt>(MaterialAttribute::NoneRoughnessMetallicTexture))
return *value;
return attribute<UnsignedInt>(MaterialAttribute::RoughnessTexture);
}
@ -202,7 +202,7 @@ UnsignedInt PbrMetallicRoughnessMaterialData::roughnessTexture() const {
MaterialTextureSwizzle PbrMetallicRoughnessMaterialData::roughnessTextureSwizzle() const {
CORRADE_ASSERT(hasRoughnessTexture(),
"Trade::PbrMetallicRoughnessMaterialData::roughnessTextureSwizzle(): the material doesn't have a roughness texture", {});
if(hasAttribute(MaterialAttribute::MetallicRoughnessTexture))
if(hasAttribute(MaterialAttribute::NoneRoughnessMetallicTexture))
return MaterialTextureSwizzle::G;
return attributeOr(MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::R);
}

91
src/Magnum/Trade/PbrMetallicRoughnessMaterialData.h

@ -60,9 +60,9 @@ class MAGNUM_TRADE_EXPORT PbrMetallicRoughnessMaterialData: public MaterialData
*
* Returns @cpp true @ce if any of the
* @ref MaterialAttribute::MetalnessTexture or
* @ref MaterialAttribute::MetallicRoughnessTexture attributes is
* @ref MaterialAttribute::NoneRoughnessMetallicTexture attributes is
* present, @cpp false @ce otherwise.
* @see @ref hasRoughnessTexture(), @ref hasMetallicRoughnessTexture()
* @see @ref hasRoughnessTexture(), @ref hasNoneRoughnessMetallicTexture()
*/
bool hasMetalnessTexture() const;
@ -71,41 +71,48 @@ class MAGNUM_TRADE_EXPORT PbrMetallicRoughnessMaterialData: public MaterialData
*
* Returns @cpp true @ce if any of the
* @ref MaterialAttribute::RoughnessTexture or
* @ref MaterialAttribute::MetallicRoughnessTexture attributes is
* @ref MaterialAttribute::NoneRoughnessMetallicTexture attributes is
* present, @cpp false @ce otherwise.
* @see @ref hasMetalnessTexture(), @ref hasMetallicRoughnessTexture()
* @see @ref hasMetalnessTexture(), @ref hasNoneRoughnessMetallicTexture()
*/
bool hasRoughnessTexture() const;
/**
* @brief Whether the material has a combined metallic/roughness texture
* @brief Whether the material has a combined roughness/metallic texture
*
* Returns @cpp true @ce if either the
* @ref MaterialAttribute::MetallicRoughnessTexture attribute is
* present or both @ref MaterialAttribute::MetalnessTexture and
* @ref MaterialAttribute::RoughnessTexture are present, point to
* the same texture ID, @ref MaterialAttribute::MetalnessTextureSwizzle
* is set to @ref MaterialTextureSwizzle::R (or omitted, in which case
* it's the default) and @ref MaterialAttribute::RoughnessTextureSwizzle
* is set to @ref MaterialTextureSwizzle::G, and ddditionally
* @ref MaterialAttribute::MetalnessTextureMatrix and
* @ref MaterialAttribute::RoughnessTextureMatrix are both either not
* @ref MaterialAttribute::NoneRoughnessMetallicTexture attribute is
* present or both @ref MaterialAttribute::RoughnessTexture and
* @ref MaterialAttribute::MetalnessTexture are present, point to the
* same texture ID, @ref MaterialAttribute::RoughnessTextureSwizzle is
* set to @ref MaterialTextureSwizzle::G and
* @ref MaterialAttribute::MetalnessTextureSwizzle is set to
* @ref MaterialTextureSwizzle::B, and ddditionally
* @ref MaterialAttribute::RoughnessTextureMatrix and
* @ref MaterialAttribute::MetalnessTextureMatrix are both either not
* present or have the same value, and
* @ref MaterialAttribute::MetalnessTextureCoordinates and
* @ref MaterialAttribute::RoughnessTextureCoordinates are both either
* @ref MaterialAttribute::RoughnessTextureCoordinates and
* @ref MaterialAttribute::MetalnessTextureCoordinates are both either
* not present or have the same value; @cpp false @ce otherwise.
*
* In other words, if this function returns @cpp true @ce,
* @ref metalnessTexture(), @ref metalnessTextureMatrix() and
* @ref metalnessTextureCoordinates() return values common for both
* @ref roughnessTexture(), @ref roughnessTextureMatrix() and
* @ref roughnessTextureCoordinates() return values common for both
* metalness and roughness texture, and the two are packed together
* with metalness occupying the R channel and roughness the G channel.
* with roughness occupying the G channel and metalness the B channel.
* This packing is common in glTF metallic/roughness materials, which
* in turn is compatible with how UE4 assets are usually packed.
* Original rationale for this [can be seen here](https://github.com/KhronosGroup/glTF/issues/857).
*
* The red and alpha channels are ignored and can be repurposed for
* other maps such as occlusion or transmission. This check is a subset
* of @ref hasOcclusionRoughnessMetallicTexture() --- if that function
* returns @cpp true @ce, this will return @cpp true @ce as well.
* @see @ref hasMetalnessTexture(), @ref hasRoughnessTexture(),
* @ref hasOcclusionRoughnessMetallicTexture(),
* @ref hasRoughnessMetallicOcclusionTexture(),
* @ref hasNormalRoughnessMetallicTexture()
*/
bool hasMetallicRoughnessTexture() const;
bool hasNoneRoughnessMetallicTexture() const;
/**
* @brief Whether the material has a combined occlusion/roughness/metallic texture
@ -133,9 +140,19 @@ class MAGNUM_TRADE_EXPORT PbrMetallicRoughnessMaterialData: public MaterialData
* @ref occlusionTextureCoordinates() return values common for
* occlusion, roughness and metalness textures, and the three are
* packed together with occlusion occupying the R channel, roughness
* the G channel and metalness the B channel.
* the G channel and metalness the B channel. This packing is common in
* glTF metallic/roughness materials, which in turn is compatible with
* how UE4 assets are usually packed. Original rationale for this [can
* be seen here](https://github.com/KhronosGroup/glTF/issues/857),
* there's also a [MSFT_packing_occlusionRoughnessMetallic](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Vendor/MSFT_packing_occlusionRoughnessMetallic/README.md)
* glTF extension using this packing in a more explicit way.
*
* The alpha channel is ignored and can be repurposed for other maps
* such as transmission. This check is a superset of
* @ref hasNoneRoughnessMetallicTexture() --- if this function returns
* @cpp true @ce, that one will return @cpp true @ce as well.
* @see @ref hasMetalnessTexture(), @ref hasRoughnessTexture(),
* @ref hasMetallicRoughnessTexture(),
* @ref hasNoneRoughnessMetallicTexture(),
* @ref hasRoughnessMetallicOcclusionTexture(),
* @ref hasNormalRoughnessMetallicTexture()
*/
@ -167,9 +184,14 @@ class MAGNUM_TRADE_EXPORT PbrMetallicRoughnessMaterialData: public MaterialData
* @ref roughnessTextureCoordinates() return values common for
* roughness, metalness and occlusion textures, and the three are
* packed together with roughness occupying the R channel, metalness
* the G channel and occlusion the B channel.
* the G channel and occlusion the B channel. This check is present in
* order to provide support for the [MSFT_packing_occlusionRoughnessMetallic](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Vendor/MSFT_packing_occlusionRoughnessMetallic/README.md)
* glTF extension.
*
* The alpha channel is ignored and can be repurposed for other maps
* such as transmission.
* @see @ref hasMetalnessTexture(), @ref hasRoughnessTexture(),
* @ref hasMetallicRoughnessTexture(),
* @ref hasNoneRoughnessMetallicTexture(),
* @ref hasOcclusionRoughnessMetallicTexture(),
* @ref hasNormalRoughnessMetallicTexture()
*/
@ -201,9 +223,12 @@ class MAGNUM_TRADE_EXPORT PbrMetallicRoughnessMaterialData: public MaterialData
* @ref normalTextureCoordinates() return values common for normal,
* roughness and metalness textures, and the three are packed together
* with normals occupying the RG channel, roughness the B channel and
* metalness the A channel.
* metalness the A channel. This check is present in order to provide
* support for the [MSFT_packing_normalRoughnessMetallic](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Vendor/MSFT_packing_normalRoughnessMetallic/README.md)
* glTF extension.
*
* @see @ref hasMetalnessTexture(), @ref hasRoughnessTexture(),
* @ref hasMetallicRoughnessTexture(),
* @ref hasNoneRoughnessMetallicTexture(),
* @ref hasRoughnessMetallicOcclusionTexture(),
* @ref hasOcclusionRoughnessMetallicTexture()
*/
@ -297,8 +322,8 @@ class MAGNUM_TRADE_EXPORT PbrMetallicRoughnessMaterialData: public MaterialData
* @brief Metalness texture ID
*
* Available only if either @ref MaterialAttribute::MetalnessTexture or
* @ref MaterialAttribute::MetallicRoughnessTexture is present. Meant
* to be multiplied with @ref metalness().
* @ref MaterialAttribute::NoneRoughnessMetallicTexture is present.
* Meant to be multiplied with @ref metalness().
* @see @ref hasMetalnessTexture(), @ref AbstractImporter::texture()
*/
UnsignedInt metalnessTexture() const;
@ -306,8 +331,8 @@ class MAGNUM_TRADE_EXPORT PbrMetallicRoughnessMaterialData: public MaterialData
/**
* @brief Metalness texture swizzle
*
* If @ref MaterialAttribute::MetallicRoughnessTexture is present,
* returns always @ref MaterialTextureSwizzle::R. Otherwise returns the
* If @ref MaterialAttribute::NoneRoughnessMetallicTexture is present,
* returns always @ref MaterialTextureSwizzle::B. Otherwise returns the
* @ref MaterialAttribute::MetalnessTextureSwizzle attribute, or
* @ref MaterialTextureSwizzle::R, if it's not present. Available only
* if the material has a metalness texture.
@ -353,7 +378,7 @@ class MAGNUM_TRADE_EXPORT PbrMetallicRoughnessMaterialData: public MaterialData
* @brief Roughness texture ID
*
* Available only if either @ref MaterialAttribute::RoughnessTexture or
* @ref MaterialAttribute::MetallicRoughnessTexture is present. Meant
* @ref MaterialAttribute::NoneRoughnessMetallicTexture is present. Meant
* to be multiplied with @ref roughness().
* @see @ref hasRoughnessTexture(), @ref AbstractImporter::texture()
*/
@ -362,7 +387,7 @@ class MAGNUM_TRADE_EXPORT PbrMetallicRoughnessMaterialData: public MaterialData
/**
* @brief Roughness texture swizzle
*
* If @ref MaterialAttribute::MetallicRoughnessTexture is present,
* If @ref MaterialAttribute::NoneRoughnessMetallicTexture is present,
* returns always @ref MaterialTextureSwizzle::G. Otherwise returns the
* @ref MaterialAttribute::RoughnessTextureSwizzle attribute, or
* @ref MaterialTextureSwizzle::R, if it's not present. Available only

104
src/Magnum/Trade/Test/MaterialDataTest.cpp

@ -2679,7 +2679,7 @@ void MaterialDataTest::pbrMetallicRoughnessAccess() {
CORRADE_VERIFY(!data.hasMetalnessTexture());
CORRADE_VERIFY(!data.hasRoughnessTexture());
CORRADE_VERIFY(!data.hasMetallicRoughnessTexture());
CORRADE_VERIFY(!data.hasNoneRoughnessMetallicTexture());
CORRADE_VERIFY(!data.hasRoughnessMetallicOcclusionTexture());
CORRADE_VERIFY(!data.hasOcclusionRoughnessMetallicTexture());
CORRADE_VERIFY(!data.hasNormalRoughnessMetallicTexture());
@ -2700,7 +2700,7 @@ void MaterialDataTest::pbrMetallicRoughnessAccessDefaults() {
CORRADE_VERIFY(!data.hasMetalnessTexture());
CORRADE_VERIFY(!data.hasRoughnessTexture());
CORRADE_VERIFY(!data.hasMetallicRoughnessTexture());
CORRADE_VERIFY(!data.hasNoneRoughnessMetallicTexture());
CORRADE_VERIFY(!data.hasRoughnessMetallicOcclusionTexture());
CORRADE_VERIFY(!data.hasOcclusionRoughnessMetallicTexture());
CORRADE_VERIFY(!data.hasNormalRoughnessMetallicTexture());
@ -2747,7 +2747,7 @@ void MaterialDataTest::pbrMetallicRoughnessAccessTextured() {
CORRADE_VERIFY(data.hasMetalnessTexture());
CORRADE_VERIFY(data.hasRoughnessTexture());
CORRADE_VERIFY(!data.hasMetallicRoughnessTexture());
CORRADE_VERIFY(!data.hasNoneRoughnessMetallicTexture());
CORRADE_VERIFY(!data.hasRoughnessMetallicOcclusionTexture());
CORRADE_VERIFY(!data.hasOcclusionRoughnessMetallicTexture());
CORRADE_VERIFY(!data.hasNormalRoughnessMetallicTexture());
@ -2797,7 +2797,7 @@ void MaterialDataTest::pbrMetallicRoughnessAccessTexturedDefaults() {
CORRADE_VERIFY(data.hasMetalnessTexture());
CORRADE_VERIFY(data.hasRoughnessTexture());
CORRADE_VERIFY(!data.hasMetallicRoughnessTexture());
CORRADE_VERIFY(!data.hasNoneRoughnessMetallicTexture());
CORRADE_VERIFY(!data.hasRoughnessMetallicOcclusionTexture());
CORRADE_VERIFY(!data.hasOcclusionRoughnessMetallicTexture());
CORRADE_VERIFY(!data.hasNormalRoughnessMetallicTexture());
@ -2868,63 +2868,63 @@ void MaterialDataTest::pbrMetallicRoughnessAccessTexturedImplicitPackedMetallicR
/* Just the texture ID, the rest is implicit */
{
PbrMetallicRoughnessMaterialData data{{}, {
{MaterialAttribute::MetallicRoughnessTexture, 2u},
{MaterialAttribute::NoneRoughnessMetallicTexture, 2u},
}};
CORRADE_VERIFY(data.hasMetallicRoughnessTexture());
CORRADE_COMPARE(data.metalnessTexture(), 2);
CORRADE_COMPARE(data.metalnessTextureSwizzle(), MaterialTextureSwizzle::R);
CORRADE_COMPARE(data.metalnessTextureMatrix(), Matrix3{});
CORRADE_COMPARE(data.metalnessTextureCoordinates(), 0);
CORRADE_VERIFY(data.hasNoneRoughnessMetallicTexture());
CORRADE_COMPARE(data.roughnessTexture(), 2);
CORRADE_COMPARE(data.roughnessTextureSwizzle(), MaterialTextureSwizzle::G);
CORRADE_COMPARE(data.roughnessTextureMatrix(), Matrix3{});
CORRADE_COMPARE(data.roughnessTextureCoordinates(), 0);
CORRADE_COMPARE(data.metalnessTexture(), 2);
CORRADE_COMPARE(data.metalnessTextureSwizzle(), MaterialTextureSwizzle::B);
CORRADE_COMPARE(data.metalnessTextureMatrix(), Matrix3{});
CORRADE_COMPARE(data.metalnessTextureCoordinates(), 0);
/* Explicit parameters for everything, but all the same */
} {
PbrMetallicRoughnessMaterialData data{{}, {
{MaterialAttribute::MetallicRoughnessTexture, 2u},
{MaterialAttribute::MetalnessTextureMatrix, Matrix3::scaling({0.5f, 0.5f})},
{MaterialAttribute::MetalnessTextureSwizzle, MaterialTextureSwizzle::R},
{MaterialAttribute::MetalnessTextureCoordinates, 3u},
{MaterialAttribute::NoneRoughnessMetallicTexture, 2u},
{MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::G},
{MaterialAttribute::RoughnessTextureMatrix, Matrix3::scaling({0.5f, 0.5f})},
{MaterialAttribute::RoughnessTextureCoordinates, 3u}
{MaterialAttribute::RoughnessTextureCoordinates, 3u},
{MaterialAttribute::MetalnessTextureMatrix, Matrix3::scaling({0.5f, 0.5f})},
{MaterialAttribute::MetalnessTextureSwizzle, MaterialTextureSwizzle::B},
{MaterialAttribute::MetalnessTextureCoordinates, 3u}
}};
CORRADE_VERIFY(data.hasMetallicRoughnessTexture());
CORRADE_COMPARE(data.metalnessTexture(), 2);
CORRADE_COMPARE(data.metalnessTextureSwizzle(), MaterialTextureSwizzle::R);
CORRADE_COMPARE(data.metalnessTextureMatrix(), Matrix3::scaling({0.5f, 0.5f}));
CORRADE_COMPARE(data.metalnessTextureCoordinates(), 3);
CORRADE_VERIFY(data.hasNoneRoughnessMetallicTexture());
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);
CORRADE_COMPARE(data.metalnessTexture(), 2);
CORRADE_COMPARE(data.metalnessTextureSwizzle(), MaterialTextureSwizzle::B);
CORRADE_COMPARE(data.metalnessTextureMatrix(), Matrix3::scaling({0.5f, 0.5f}));
CORRADE_COMPARE(data.metalnessTextureCoordinates(), 3);
/* Swizzle is ignored when the combined texture is specified, so this is
fine */
} {
PbrMetallicRoughnessMaterialData data{{}, {
{MaterialAttribute::MetallicRoughnessTexture, 2u},
{MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::B},
{MaterialAttribute::NoneRoughnessMetallicTexture, 2u},
{MaterialAttribute::MetalnessTextureSwizzle, MaterialTextureSwizzle::G},
}};
CORRADE_VERIFY(data.hasMetallicRoughnessTexture());
CORRADE_VERIFY(data.hasNoneRoughnessMetallicTexture());
/* Unexpected texture matrix */
} {
PbrMetallicRoughnessMaterialData data{{}, {
{MaterialAttribute::MetallicRoughnessTexture, 2u},
{MaterialAttribute::NoneRoughnessMetallicTexture, 2u},
{MaterialAttribute::MetalnessTextureMatrix, Matrix3::scaling({0.5f, 1.0f})},
}};
CORRADE_VERIFY(!data.hasMetallicRoughnessTexture());
CORRADE_VERIFY(!data.hasNoneRoughnessMetallicTexture());
/* Unexpected texture coordinates */
} {
PbrMetallicRoughnessMaterialData data{{}, {
{MaterialAttribute::MetallicRoughnessTexture, 2u},
{MaterialAttribute::NoneRoughnessMetallicTexture, 2u},
{MaterialAttribute::RoughnessTextureCoordinates, 1u},
}};
CORRADE_VERIFY(!data.hasMetallicRoughnessTexture());
CORRADE_VERIFY(!data.hasNoneRoughnessMetallicTexture());
}
}
@ -2932,62 +2932,66 @@ void MaterialDataTest::pbrMetallicRoughnessAccessTexturedExplicitPackedMetallicR
/* Just the texture IDs and swizzles, the rest is implicit */
{
PbrMetallicRoughnessMaterialData data{{}, {
{MaterialAttribute::MetalnessTexture, 2u},
{MaterialAttribute::RoughnessTexture, 2u},
{MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::G}
{MaterialAttribute::MetalnessTexture, 2u},
{MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::G},
{MaterialAttribute::MetalnessTextureSwizzle, MaterialTextureSwizzle::B}
}};
CORRADE_VERIFY(data.hasMetallicRoughnessTexture());
CORRADE_VERIFY(data.hasNoneRoughnessMetallicTexture());
/* Explicit parameters for everything, but all the same */
} {
PbrMetallicRoughnessMaterialData data{{}, {
{MaterialAttribute::MetalnessTexture, 2u},
{MaterialAttribute::MetalnessTextureMatrix, Matrix3::scaling({0.5f, 0.5f})},
{MaterialAttribute::MetalnessTextureSwizzle, MaterialTextureSwizzle::R},
{MaterialAttribute::MetalnessTextureCoordinates, 3u},
{MaterialAttribute::RoughnessTexture, 2u},
{MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::G},
{MaterialAttribute::RoughnessTextureMatrix, Matrix3::scaling({0.5f, 0.5f})},
{MaterialAttribute::RoughnessTextureCoordinates, 3u}
{MaterialAttribute::RoughnessTextureCoordinates, 3u},
{MaterialAttribute::MetalnessTexture, 2u},
{MaterialAttribute::MetalnessTextureMatrix, Matrix3::scaling({0.5f, 0.5f})},
{MaterialAttribute::MetalnessTextureSwizzle, MaterialTextureSwizzle::B},
{MaterialAttribute::MetalnessTextureCoordinates, 3u}
}};
CORRADE_VERIFY(data.hasMetallicRoughnessTexture());
CORRADE_VERIFY(data.hasNoneRoughnessMetallicTexture());
/* One texture missing */
} {
PbrMetallicRoughnessMaterialData data{{}, {
{MaterialAttribute::RoughnessTexture, 2u},
{MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::B},
{MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::G},
}};
CORRADE_VERIFY(!data.hasMetallicRoughnessTexture());
CORRADE_VERIFY(!data.hasNoneRoughnessMetallicTexture());
/* Unexpected swizzle */
} {
PbrMetallicRoughnessMaterialData data{{}, {
{MaterialAttribute::MetalnessTexture, 2u},
{MaterialAttribute::RoughnessTexture, 2u},
{MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::B},
{MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::R},
{MaterialAttribute::MetalnessTexture, 2u},
{MaterialAttribute::MetalnessTextureSwizzle, MaterialTextureSwizzle::B},
}};
CORRADE_VERIFY(!data.hasMetallicRoughnessTexture());
CORRADE_VERIFY(!data.hasNoneRoughnessMetallicTexture());
/* Unexpected texture matrix */
} {
PbrMetallicRoughnessMaterialData data{{}, {
{MaterialAttribute::MetalnessTexture, 2u},
{MaterialAttribute::MetalnessTextureMatrix, Matrix3::scaling({0.5f, 1.0f})},
{MaterialAttribute::RoughnessTexture, 2u},
{MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::G},
{MaterialAttribute::MetalnessTexture, 2u},
{MaterialAttribute::MetalnessTextureSwizzle, MaterialTextureSwizzle::B},
{MaterialAttribute::MetalnessTextureMatrix, Matrix3::scaling({0.5f, 1.0f})},
}};
CORRADE_VERIFY(!data.hasMetallicRoughnessTexture());
CORRADE_VERIFY(!data.hasNoneRoughnessMetallicTexture());
/* Unexpected texture coordinates */
} {
PbrMetallicRoughnessMaterialData data{{}, {
{MaterialAttribute::MetalnessTexture, 2u},
{MaterialAttribute::RoughnessTexture, 2u},
{MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::G},
{MaterialAttribute::RoughnessTextureCoordinates, 1u},
{MaterialAttribute::MetalnessTexture, 2u},
{MaterialAttribute::MetalnessTextureSwizzle, MaterialTextureSwizzle::B},
}};
CORRADE_VERIFY(!data.hasMetallicRoughnessTexture());
CORRADE_VERIFY(!data.hasNoneRoughnessMetallicTexture());
}
}
@ -3002,6 +3006,8 @@ void MaterialDataTest::pbrMetallicRoughnessAccessTexturedExplicitPackedRoughness
{MaterialAttribute::OcclusionTextureSwizzle, MaterialTextureSwizzle::B},
}};
CORRADE_VERIFY(data.hasRoughnessMetallicOcclusionTexture());
/* This isn't a superset */
CORRADE_VERIFY(!data.hasNoneRoughnessMetallicTexture());
/* Explicit parameters for everything, but all the same */
} {
@ -3020,6 +3026,8 @@ void MaterialDataTest::pbrMetallicRoughnessAccessTexturedExplicitPackedRoughness
{MaterialAttribute::OcclusionTextureCoordinates, 3u}
}};
CORRADE_VERIFY(data.hasRoughnessMetallicOcclusionTexture());
/* This isn't a superset */
CORRADE_VERIFY(!data.hasNoneRoughnessMetallicTexture());
/* One texture missing */
} {
@ -3080,6 +3088,8 @@ void MaterialDataTest::pbrMetallicRoughnessAccessTexturedExplicitPackedOcclusion
{MaterialAttribute::MetalnessTextureSwizzle, MaterialTextureSwizzle::B},
}};
CORRADE_VERIFY(data.hasOcclusionRoughnessMetallicTexture());
/* This is a superset */
CORRADE_VERIFY(data.hasNoneRoughnessMetallicTexture());
/* Explicit parameters for everything, but all the same */
} {
@ -3098,6 +3108,8 @@ void MaterialDataTest::pbrMetallicRoughnessAccessTexturedExplicitPackedOcclusion
{MaterialAttribute::MetalnessTextureCoordinates, 3u}
}};
CORRADE_VERIFY(data.hasOcclusionRoughnessMetallicTexture());
/* This is a superset */
CORRADE_VERIFY(data.hasNoneRoughnessMetallicTexture());
/* One texture missing */
} {

Loading…
Cancel
Save