Browse Source

Trade: expose basic PBR material properties and helper classes.

Well, "basic". Practically mirrors glTF PBR materials:

 - builtin metallic/roughness
 - the KHR_materials_pbrSpecularGlossiness extension
 - extra normal/occlusion/emission maps
 - exposes the implicit metallic/roughness and specular/glossiness
   packing, but also allows separate maps with arbitrary packings as
   well as two-channel normal maps (instead of three-channel)
 - provides convenience checks for the most common packing schemes
   including MSFT_packing_normalRoughnessMetallic and the three variants
   of MSFT_packing_occlusionRoughnessMetallic
 - teaches PhongMaterialData to recognize packed specular/glossiness
   maps as well

Next up is exposing at least one layer extension, and then I'm done
here.
pull/459/head
Vladimír Vondruš 6 years ago
parent
commit
69f5f81110
  1. 9
      doc/changelog.dox
  2. 4
      src/Magnum/Trade/CMakeLists.txt
  3. 31
      src/Magnum/Trade/Implementation/materialAttributeProperties.hpp
  4. 6
      src/Magnum/Trade/MaterialData.cpp
  5. 519
      src/Magnum/Trade/MaterialData.h
  6. 302
      src/Magnum/Trade/PbrMetallicRoughnessMaterialData.cpp
  7. 566
      src/Magnum/Trade/PbrMetallicRoughnessMaterialData.h
  8. 251
      src/Magnum/Trade/PbrSpecularGlossinessMaterialData.cpp
  9. 460
      src/Magnum/Trade/PbrSpecularGlossinessMaterialData.h
  10. 29
      src/Magnum/Trade/PhongMaterialData.cpp
  11. 60
      src/Magnum/Trade/PhongMaterialData.h
  12. 1083
      src/Magnum/Trade/Test/MaterialDataTest.cpp
  13. 2
      src/Magnum/Trade/Trade.h

9
doc/changelog.dox

@ -76,7 +76,14 @@ See also:
- A new, redesigned @ref Trade::MaterialData class allowing to store custom
material attributes as well as more material types together in a single
instance. See [mosra/magnum#459](https://github.com/mosra/magnum/pull/459).
instance; plus new @ref Trade::PbrMetallicRoughnessMaterialData and
@ref Trade::PbrSpecularGlossinessMaterialData convenience accessor APIs
similar to @ref Trade::PhongMaterialData. See
[mosra/magnum#459](https://github.com/mosra/magnum/pull/459).
- Added @ref Trade::PhongMaterialData::hasSpecularTexture(),
@ref Trade::PhongMaterialData::specularTextureSwizzle() and
@ref Trade::PhongMaterialData::normalTextureSwizzle() to make new features
added for PBR materials recognizable also in classic Phong workflows.
@subsection changelog-latest-changes Changes and improvements

4
src/Magnum/Trade/CMakeLists.txt

@ -45,6 +45,8 @@ set(MagnumTrade_GracefulAssert_SRCS
MeshData.cpp
ObjectData2D.cpp
ObjectData3D.cpp
PbrMetallicRoughnessMaterialData.cpp
PbrSpecularGlossinessMaterialData.cpp
PhongMaterialData.cpp)
set(MagnumTrade_HEADERS
@ -63,6 +65,8 @@ set(MagnumTrade_HEADERS
MeshObjectData3D.h
ObjectData2D.h
ObjectData3D.h
PbrMetallicRoughnessMaterialData.h
PbrSpecularGlossinessMaterialData.h
PhongMaterialData.h
SceneData.h
TextureData.h

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

@ -39,12 +39,43 @@ _c(DiffuseTextureMatrix,Matrix3x3)
_c(DiffuseTextureCoordinates,UnsignedInt)
_c(SpecularColor,Vector4)
_c(SpecularTexture,UnsignedInt)
_ct(SpecularTextureSwizzle,TextureSwizzle,MaterialTextureSwizzle)
_c(SpecularTextureMatrix,Matrix3x3)
_c(SpecularTextureCoordinates,UnsignedInt)
_c(Shininess,Float)
_c(BaseColor,Vector4)
_c(BaseColorTexture,UnsignedInt)
_c(BaseColorTextureMatrix,Matrix3x3)
_c(BaseColorTextureCoordinates,UnsignedInt)
_c(Metalness,Float)
_c(MetalnessTexture,UnsignedInt)
_ct(MetalnessTextureSwizzle,TextureSwizzle,MaterialTextureSwizzle)
_c(MetalnessTextureMatrix,Matrix3x3)
_c(MetalnessTextureCoordinates,UnsignedInt)
_c(Roughness,Float)
_c(RoughnessTexture,UnsignedInt)
_ct(RoughnessTextureSwizzle,TextureSwizzle,MaterialTextureSwizzle)
_c(RoughnessTextureMatrix,Matrix3x3)
_c(RoughnessTextureCoordinates,UnsignedInt)
_c(MetallicRoughnessTexture,UnsignedInt)
_c(Glossiness,Float)
_c(GlossinessTexture,UnsignedInt)
_ct(GlossinessTextureSwizzle,TextureSwizzle,MaterialTextureSwizzle)
_c(GlossinessTextureMatrix,Matrix3x3)
_c(GlossinessTextureCoordinates,UnsignedInt)
_c(SpecularGlossinessTexture,UnsignedInt)
_c(NormalTexture,UnsignedInt)
_ct(NormalTextureSwizzle,TextureSwizzle,MaterialTextureSwizzle)
_c(NormalTextureMatrix,Matrix3x3)
_c(NormalTextureCoordinates,UnsignedInt)
_c(OcclusionTexture,UnsignedInt)
_ct(OcclusionTextureSwizzle,TextureSwizzle,MaterialTextureSwizzle)
_c(OcclusionTextureMatrix,Matrix3x3)
_c(OcclusionTextureCoordinates,UnsignedInt)
_c(EmissiveColor,Vector3)
_c(EmissiveTexture,UnsignedInt)
_c(EmissiveTextureMatrix,Matrix3x3)
_c(EmissiveTextureCoordinates,UnsignedInt)
_c(TextureMatrix,Matrix3x3)
_c(TextureCoordinates,UnsignedInt)
#endif

6
src/Magnum/Trade/MaterialData.cpp

@ -649,6 +649,8 @@ Debug& operator<<(Debug& debug, const MaterialType value) {
/* LCOV_EXCL_START */
#define _c(value) case MaterialType::value: return debug << "::" #value;
_c(Phong)
_c(PbrMetallicRoughness)
_c(PbrSpecularGlossiness)
#undef _c
/* LCOV_EXCL_STOP */
}
@ -658,7 +660,9 @@ Debug& operator<<(Debug& debug, const MaterialType value) {
Debug& operator<<(Debug& debug, const MaterialTypes value) {
return Containers::enumSetDebugOutput(debug, value, "Trade::MaterialTypes{}", {
MaterialType::Phong
MaterialType::Phong,
MaterialType::PbrMetallicRoughness,
MaterialType::PbrSpecularGlossiness
});
}

519
src/Magnum/Trade/MaterialData.h

@ -144,80 +144,113 @@ enum class MaterialAttribute: UnsignedInt {
AmbientTextureCoordinates,
/**
* Diffuse color for Phong materials, @ref MaterialAttributeType::Vector4.
* Diffuse color for Phong or PBR specular/glossiness materials,
* @ref MaterialAttributeType::Vector4.
*
* If @ref MaterialAttribute::DiffuseTexture is present as well, these two
* are multiplied together.
* @see @ref PhongMaterialData::diffuseColor()
* @see @ref PhongMaterialData::diffuseColor(),
* @ref PbrSpecularGlossinessMaterialData::diffuseColor()
*/
DiffuseColor,
/**
* Diffuse texture index for Phong materials,
* Diffuse texture index for Phong or PBR specular/glossiness materials,
* @ref MaterialAttributeType::UnsignedInt.
*
* If @ref MaterialAttribute::DiffuseColor is present as well, these two
* are multiplied together.
* @see @ref PhongMaterialData::diffuseTexture()
* @see @ref PhongMaterialData::diffuseTexture(),
* @ref PbrSpecularGlossinessMaterialData::diffuseTexture()
*/
DiffuseTexture,
/**
* Diffuse texture transformation matrix for Phong materials,
* @ref MaterialAttributeType::Matrix3x3.
* Diffuse texture transformation matrix for Phong or PBR
* specular/glossiness materials, @ref MaterialAttributeType::Matrix3x3.
*
* Has a precedence over @ref MaterialAttribute::TextureMatrix if both are
* present.
* @see @ref PhongMaterialData::diffuseTextureMatrix()
* @see @ref PhongMaterialData::diffuseTextureMatrix(),
* @ref PbrSpecularGlossinessMaterialData::diffuseTextureMatrix()
*/
DiffuseTextureMatrix,
/**
* Diffuse texture coordinate set index for Phong materials,
* @ref MaterialAttributeType::UnsignedInt.
* Diffuse texture coordinate set index for Phong or PBR
* specular/glossiness materials, @ref MaterialAttributeType::UnsignedInt.
*
* Has a precedence over @ref MaterialAttribute::TextureCoordinates if both
* are present.
* @see @ref PhongMaterialData::diffuseTextureCoordinates()
* @see @ref PhongMaterialData::diffuseTextureCoordinates(),
* @ref PbrSpecularGlossinessMaterialData::diffuseTextureCoordinates()
*/
DiffuseTextureCoordinates,
/**
* Specular color for Phong materials, @ref MaterialAttributeType::Vector4.
* Specular color for Phong or PBR specular/glossiness materials,
* @ref MaterialAttributeType::Vector4. Alpha is commonly zero to not
* interfere with alpha-masked objects, non-zero alpha can be for example
* used to render transparent material which are still expected to have
* specular highlights such as glass or soap bubbles.
*
* If @ref MaterialAttribute::SpecularTexture is present as well, these two
* are multiplied together.
* @see @ref PhongMaterialData::specularColor()
* If @ref MaterialAttribute::SpecularTexture or
* @ref MaterialAttribute::SpecularGlossinessTexture is present as well,
* these two are multiplied together.
* @see @ref PhongMaterialData::specularColor(),
* @ref PbrSpecularGlossinessMaterialData::specularColor()
*/
SpecularColor,
/**
* Specular texture index for Phong materials,
* Specular texture index for Phong or PBR specular/glossiness materials,
* @ref MaterialAttributeType::UnsignedInt.
*
* If @ref MaterialAttribute::SpecularColor is present as well, these two
* are multiplied together.
* @see @ref PhongMaterialData::specularTexture()
* are multiplied together. Can be alternatively supplied as a packed
* @ref MaterialAttribute::SpecularGlossinessTexture.
* @see @ref PhongMaterialData::hasSpecularTexture(),
* @ref PhongMaterialData::specularTexture(),
* @ref PbrSpecularGlossinessMaterialData::hasSpecularTexture(),
* @ref PbrSpecularGlossinessMaterialData::hasSpecularGlossinessTexture(),
* @ref PbrSpecularGlossinessMaterialData::specularTexture()
*/
SpecularTexture,
/**
* Specular texture transformation matrix for Phong materials,
* @ref MaterialAttributeType::Matrix3x3.
* Specular texture swizzle for Phong or PBR specular/glossiness materials,
* @ref MaterialAttributeType::TextureSwizzle.
*
* Can be used to describe whether the alpha channel of a
* @ref MaterialAttribute::SpecularTexture is used or not. Either
* @ref MaterialTextureSwizzle::RGBA or @ref MaterialTextureSwizzle::RGB
* (which is the default) is expected. Does not apply to
* @ref MaterialAttribute::SpecularGlossinessTexture --- in that case,
* the specular texture is always three-channel, regardless of this
* attribute.
* @see @ref PbrSpecularGlossinessMaterialData::specularTextureSwizzle()
*/
SpecularTextureSwizzle,
/**
* Specular texture transformation matrix for Phong or PBR
* specular/glossiness materials, @ref MaterialAttributeType::Matrix3x3.
*
* Has a precedence over @ref MaterialAttribute::TextureMatrix if both are
* present.
* @see @ref PhongMaterialData::specularTextureMatrix()
* @see @ref PhongMaterialData::specularTextureMatrix(),
* @ref PbrSpecularGlossinessMaterialData::glossinessTextureMatrix()
*/
SpecularTextureMatrix,
/**
* Specular texture coordinate set index for Phong materials,
* @ref MaterialAttributeType::UnsignedInt.
* Specular texture coordinate set index for Phong or PBR
* specular/glossiness materials, @ref MaterialAttributeType::UnsignedInt.
*
* Has a precedence over @ref MaterialAttribute::TextureCoordinates if both
* are present.
* @see @ref PhongMaterialData::specularTextureCoordinates()
* @see @ref PhongMaterialData::specularTextureCoordinates(),
* @ref PbrSpecularGlossinessMaterialData::specularTextureCoordinates()
*/
SpecularTextureCoordinates,
@ -228,20 +261,324 @@ enum class MaterialAttribute: UnsignedInt {
*/
Shininess,
/**
* Base color for PBR metallic/roughness materials,
* @ref MaterialAttributeType::Vector4.
*
* If @ref MaterialAttribute::BaseColorTexture is present as well, these
* two are multiplied together.
* @see @ref PbrMetallicRoughnessMaterialData::baseColor()
*/
BaseColor,
/**
* Base color texture index for PBR metallic/roughness materials,
* @ref MaterialAttributeType::UnsignedInt.
*
* If @ref MaterialAttribute::BaseColor is present as well, these two are
* multiplied together.
* @see @ref PbrMetallicRoughnessMaterialData::baseColorTexture()
*/
BaseColorTexture,
/**
* Base color texture transformation matrix for PBR metallic/roughness
* materials, @ref MaterialAttributeType::Matrix3x3.
*
* Has a precedence over @ref MaterialAttribute::TextureMatrix if both are
* present.
* @see @ref PbrMetallicRoughnessMaterialData::baseColorTextureMatrix()
*/
BaseColorTextureMatrix,
/**
* Base color texture coordinate set index for PBR metallic/roughness
* materials, @ref MaterialAttributeType::UnsignedInt.
*
* Has a precedence over @ref MaterialAttribute::TextureCoordinates if both
* are present.
* @see @ref PbrMetallicRoughnessMaterialData::baseColorTextureCoordinates()
*/
BaseColorTextureCoordinates,
/**
* Metalness for PBR metallic/roughness materials,
* @ref MaterialAttributeType::Float.
*
* If @ref MaterialAttribute::MetalnessTexture or
* @ref MaterialAttribute::MetallicRoughnessTexture is present as well,
* these two are multiplied together.
* @see @ref PbrMetallicRoughnessMaterialData::metalness()
*/
Metalness,
/**
* Metalness texture index for PBR metallic/roughness materials,
* @ref MaterialAttributeType::UnsignedInt.
*
* If @ref MaterialAttribute::Metalness is present as well, these two are
* multiplied together. Can be alternatively supplied as a packed
* @ref MaterialAttribute::MetallicRoughnessTexture.
* @see @ref PbrMetallicRoughnessMaterialData::hasMetalnessTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasMetallicRoughnessTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasOcclusionRoughnessMetallicTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasNormalRoughnessMetallicTexture()
* @ref PbrMetallicRoughnessMaterialData::metalnessTexture()
*/
MetalnessTexture,
/**
* Metalness texture swizzle for PBR metallic/roughness materials,
* @ref MaterialAttributeType::TextureSwizzle.
*
* Can be used to express arbitrary packing of
* @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 PbrMetallicRoughnessMaterialData::hasOcclusionRoughnessMetallicTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasNormalRoughnessMetallicTexture()
* @ref PbrMetallicRoughnessMaterialData::metalnessTextureSwizzle()
*/
MetalnessTextureSwizzle,
/**
* Metalness texture transformation matrix for PBR metallic/roughness
* materials, @ref MaterialAttributeType::Matrix3x3.
*
* Has a precedence over @ref MaterialAttribute::TextureMatrix if both are
* present.
* @see @ref PbrMetallicRoughnessMaterialData::metalnessTextureMatrix()
*/
MetalnessTextureMatrix,
/**
* Metalness texture coordinate set index for PBR metallic/roughness
* materials, @ref MaterialAttributeType::UnsignedInt.
*
* Has a precedence over @ref MaterialAttribute::TextureCoordinates if both
* are present.
* @see @ref PbrMetallicRoughnessMaterialData::metalnessTextureCoordinates()
*/
MetalnessTextureCoordinates,
/**
* Roughness for PBR metallic/roughness materials,
* @ref MaterialAttributeType::Float.
*
* If @ref MaterialAttribute::RoughnessTexture or
* @ref MaterialAttribute::MetallicRoughnessTexture is present as well,
* these two are multiplied together.
* @see @ref PbrMetallicRoughnessMaterialData::roughness()
*/
Roughness,
/**
* Roughness texture index for PBR metallic/roughness materials,
* @ref MaterialAttributeType::UnsignedInt.
*
* If @ref MaterialAttribute::Roughness is present as well, these two are
* multiplied together. Can be alternatively supplied as a packed
* @ref MaterialAttribute::MetallicRoughnessTexture.
* @see @ref PbrMetallicRoughnessMaterialData::hasRoughnessTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasMetallicRoughnessTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasOcclusionRoughnessMetallicTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasNormalRoughnessMetallicTexture()
* @ref PbrMetallicRoughnessMaterialData::roughnessTexture()
*/
RoughnessTexture,
/**
* Roughness texture swizzle for PBR metallic/roughness materials,
* @ref MaterialAttributeType::TextureSwizzle.
*
* Can be used to express arbitrary packing of
* @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
* attribute.
* @see @ref PbrMetallicRoughnessMaterialData::hasMetallicRoughnessTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasOcclusionRoughnessMetallicTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasNormalRoughnessMetallicTexture()
* @ref PbrMetallicRoughnessMaterialData::roughnessTextureSwizzle()
*/
RoughnessTextureSwizzle,
/**
* Roughness texture transformation matrix for PBR metallic/roughness
* materials, @ref MaterialAttributeType::Matrix3x3.
*
* Has a precedence over @ref MaterialAttribute::TextureMatrix if both are
* present.
* @see @ref PbrMetallicRoughnessMaterialData::roughnessTextureMatrix()
*/
RoughnessTextureMatrix,
/**
* Roughness texture coordinate set index for PBR metallic/roughness
* materials, @ref MaterialAttributeType::UnsignedInt.
*
* Has a precedence over @ref MaterialAttribute::TextureCoordinates if both
* are present.
* @see @ref PbrMetallicRoughnessMaterialData::roughnessTextureCoordinates()
*/
RoughnessTextureCoordinates,
/**
* Combined metallic/roughness texture index for PBR metallic/roughness
* materials with metalness in the red 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
* 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 PbrMetallicRoughnessMaterialData::hasOcclusionRoughnessMetallicTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasNormalRoughnessMetallicTexture()
* @ref PbrMetallicRoughnessMaterialData::metalnessTexture(),
* @ref PbrMetallicRoughnessMaterialData::roughnessTexture()
*/
MetallicRoughnessTexture,
/* DiffuseColor, DiffuseTexture, DiffuseTextureMatrix,
DiffuseTextureCoordinates, SpecularColor, SpecularTexture,
SpecularTextureSwizzle, SpecularTextureMatrix,
SpecularTextureCoordinates specified above for Phong already */
/**
* Glossiness for PBR specular/glossiness materials,
* @ref MaterialAttributeType::Float.
*
* If @ref MaterialAttribute::GlossinessTexture or
* @ref MaterialAttribute::SpecularGlossinessTexture is present as well,
* these two are multiplied together.
* @see @ref PbrSpecularGlossinessMaterialData::glossiness()
*/
Glossiness,
/**
* Glossiness texture index for PBR specular/glossiness materials,
* @ref MaterialAttributeType::UnsignedInt.
*
* If @ref MaterialAttribute::Glossiness is present as well, these two are
* multiplied together. Can be alternatively supplied as a packed
* @ref MaterialAttribute::SpecularGlossinessTexture.
* @see @ref PbrSpecularGlossinessMaterialData::hasGlossinessTexture(),
* @ref PbrSpecularGlossinessMaterialData::hasSpecularGlossinessTexture(),
* @ref PbrSpecularGlossinessMaterialData::glossinessTexture()
*/
GlossinessTexture,
/**
* Glossiness texture swizzle for PBR specular/glossiness materials,
* @ref MaterialAttributeType::TextureSwizzle.
*
* Can be used to express arbitrary packing of
* @ref MaterialAttribute::GlossinessTexture 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::SpecularGlossinessTexture --- in that case,
* the glossiness is implicitly in the alpha channel regardless of this
* attribute.
* @see @ref PbrSpecularGlossinessMaterialData::hasSpecularGlossinessTexture(),
* @ref PbrSpecularGlossinessMaterialData::glossinessTextureSwizzle()
*/
GlossinessTextureSwizzle,
/**
* Glossiness texture transformation matrix for PBR specular/glossiness
* materials, @ref MaterialAttributeType::Matrix3x3.
*
* Has a precedence over @ref MaterialAttribute::TextureMatrix if both are
* present.
* @see @ref PbrSpecularGlossinessMaterialData::glossinessTextureMatrix()
*/
GlossinessTextureMatrix,
/**
* Glossiness texture coordinate set index for PBR specular/glossiness
* materials, @ref MaterialAttributeType::UnsignedInt.
*
* Has a precedence over @ref MaterialAttribute::TextureCoordinates if both
* are present.
* @see @ref PbrSpecularGlossinessMaterialData::glossinessTextureCoordinates()
*/
GlossinessTextureCoordinates,
/**
* Combined specular/glossiness texture index for PBR specular/glossiness
* materials with specular color in the RGB channels and glossiness in
* alpha, @ref MaterialAttributeType::UnsignedInt.
*
* If @ref MaterialAttribute::SpecularColor / @ref MaterialAttribute::Glossiness
* is present as well, these two are multiplied together. Can be
* alternatively specified as a pair of @ref MaterialAttribute::SpecularTexture
* / @ref MaterialAttribute::GlossinessTexture attributes together with
* @ref MaterialAttribute::GlossinessTextureSwizzle set to
* @ref MaterialTextureSwizzle::A. 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::SpecularTextureMatrix,
* @ref MaterialAttribute::GlossinessTextureMatrix,
* @ref MaterialAttribute::SpecularTextureCoordinates and
* @ref MaterialAttribute::GlossinessTextureCoordinates variants.
* @see @ref PbrSpecularGlossinessMaterialData::hasSpecularGlossinessTexture(),
* @ref PbrSpecularGlossinessMaterialData::specularTexture(),
* @ref PbrSpecularGlossinessMaterialData::glossinessTexture()
*/
SpecularGlossinessTexture,
/**
* Tangent-space normal map texture index,
* @ref MaterialAttributeType::UnsignedInt.
* @see @ref PhongMaterialData::normalTexture()
* @see @ref PhongMaterialData::normalTexture(),
* @ref PbrMetallicRoughnessMaterialData::hasNormalRoughnessMetallicTexture(),
* @ref PbrMetallicRoughnessMaterialData::normalTexture(),
* @ref PbrSpecularGlossinessMaterialData::normalTexture()
*/
NormalTexture,
/**
* Normal texture swizzle, @ref MaterialAttributeType::TextureSwizzle.
*
* Can be used to express arbitrary packing together with other maps in a
* single texture. A two- or three-channel swizzle value is expected. If
* not present, @ref MaterialTextureSwizzle::RGB is assumed.
*
* If the texture is just two-component, the remaining component is
* implicit and calculated as @f$ z = \sqrt{1 - x^2 - y^2} @f$.
* @see @ref PbrMetallicRoughnessMaterialData::hasNormalRoughnessMetallicTexture(),
* @ref PbrMetallicRoughnessMaterialData::normalTextureSwizzle(),
* @ref PbrSpecularGlossinessMaterialData::normalTextureSwizzle()
*/
NormalTextureSwizzle,
/**
* Normal texture transformation matrix,
* @ref MaterialAttributeType::Matrix3x3.
*
* Has a precedence over @ref MaterialAttribute::TextureMatrix if both are
* present.
* @see @ref PhongMaterialData::normalTextureMatrix()
* @see @ref PhongMaterialData::normalTextureMatrix(),
* @ref PbrMetallicRoughnessMaterialData::normalTextureMatrix(),
* @ref PbrSpecularGlossinessMaterialData::normalTextureMatrix()
*/
NormalTextureMatrix,
@ -251,10 +588,102 @@ enum class MaterialAttribute: UnsignedInt {
*
* Has a precedence over @ref MaterialAttribute::TextureCoordinates if both
* are present.
* @see @ref PhongMaterialData::normalTextureCoordinates()
* @see @ref PhongMaterialData::normalTextureCoordinates(),
* @ref PbrMetallicRoughnessMaterialData::normalTextureCoordinates(),
* @ref PbrSpecularGlossinessMaterialData::normalTextureCoordinates()
*/
NormalTextureCoordinates,
/**
* Occlusion texture index,
* @ref MaterialAttributeType::UnsignedInt.
* @see @ref PbrMetallicRoughnessMaterialData::hasOcclusionRoughnessMetallicTexture(),
* @ref PbrMetallicRoughnessMaterialData::occlusionTexture(),
* @ref PbrSpecularGlossinessMaterialData::occlusionTexture()
*/
OcclusionTexture,
/**
* Occlusion texture swizzle, @ref MaterialAttributeType::TextureSwizzle.
*
* Can be used to express arbitrary packing together with other maps in a
* single texture. A single-channel swizzle value is expected. If
* not present, @ref MaterialTextureSwizzle::R is assumed.
* @see @ref PbrMetallicRoughnessMaterialData::hasOcclusionRoughnessMetallicTexture(),
* @ref PbrMetallicRoughnessMaterialData::occlusionTextureSwizzle(),
* @ref PbrSpecularGlossinessMaterialData::occlusionTextureSwizzle()
*/
OcclusionTextureSwizzle,
/**
* Occlusion texture transformation matrix,
* @ref MaterialAttributeType::Matrix3x3.
*
* Has a precedence over @ref MaterialAttribute::TextureMatrix if both are
* present.
* @see @ref PbrMetallicRoughnessMaterialData::occlusionTextureMatrix(),
* @ref PbrSpecularGlossinessMaterialData::occlusionTextureSwizzle()
*/
OcclusionTextureMatrix,
/**
* Occlusion texture coordinate set index,
* @ref MaterialAttributeType::UnsignedInt.
*
* Has a precedence over @ref MaterialAttribute::TextureCoordinates if both
* are present.
* @see @ref PbrMetallicRoughnessMaterialData::occlusionTextureCoordinates(),
* @ref PbrSpecularGlossinessMaterialData::occlusionTextureCoordinates()
*/
OcclusionTextureCoordinates,
/**
* Emissive color,
* @ref MaterialAttributeType::Vector3.
*
* If @ref MaterialAttribute::EmissiveTexture is present as well, these two
* are multiplied together.
* @see @ref PbrMetallicRoughnessMaterialData::emissiveColor(),
* @ref PbrSpecularGlossinessMaterialData::emissiveColor()
*/
EmissiveColor,
/**
* Emissive texture index,
* @ref MaterialAttributeType::UnsignedInt.
*
* If @ref MaterialAttribute::EmissiveColor is present as well, these two
* are multiplied together.
* @see @ref PbrMetallicRoughnessMaterialData::emissiveTexture(),
* @ref PbrSpecularGlossinessMaterialData::emissiveTexture()
*/
EmissiveTexture,
/** @todo EmissiveTextureSwizzle? It's a color and I'm not aware of any
existing packing schemes, so probably safe to assume it's always RGB */
/**
* Emissive texture transformation matrix,
* @ref MaterialAttributeType::Matrix3x3.
*
* Has a precedence over @ref MaterialAttribute::TextureMatrix if both are
* present.
* @see @ref PbrMetallicRoughnessMaterialData::emissiveTextureMatrix(),
* @ref PbrSpecularGlossinessMaterialData::emissiveTextureMatrix(),
*/
EmissiveTextureMatrix,
/**
* Emissive texture coordinate set index,
* @ref MaterialAttributeType::UnsignedInt.
*
* Has a precedence over @ref MaterialAttribute::TextureCoordinates if both
* are present.
* @see @ref PbrMetallicRoughnessMaterialData::emissiveTextureCoordinates(),
* @ref PbrSpecularGlossinessMaterialData::emissiveTextureCoordinates()
*/
EmissiveTextureCoordinates,
/**
* Common texture transformation matrix for all textures,
* @ref MaterialAttributeType::Matrix3x3.
@ -262,9 +691,16 @@ enum class MaterialAttribute: UnsignedInt {
* @ref MaterialAttribute::AmbientTextureMatrix /
* @ref MaterialAttribute::DiffuseTextureMatrix /
* @ref MaterialAttribute::SpecularTextureMatrix /
* @ref MaterialAttribute::NormalTextureMatrix have a precedence over this
* attribute for given texture, if present.
* @see @ref PhongMaterialData::textureMatrix()
* @ref MaterialAttribute::MetalnessTextureMatrix /
* @ref MaterialAttribute::RoughnessTextureMatrix /
* @ref MaterialAttribute::GlossinessTextureMatrix /
* @ref MaterialAttribute::NormalTextureMatrix /
* @ref MaterialAttribute::OcclusionTextureMatrix /
* @ref MaterialAttribute::EmissiveTextureMatrix have a precedence over
* this attribute for given texture, if present.
* @see @ref PhongMaterialData::textureMatrix(),
* @ref PbrMetallicRoughnessMaterialData::textureMatrix(),
* @ref PbrSpecularGlossinessMaterialData::textureMatrix()
*/
TextureMatrix,
@ -275,9 +711,16 @@ enum class MaterialAttribute: UnsignedInt {
* @ref MaterialAttribute::AmbientTextureCoordinates /
* @ref MaterialAttribute::DiffuseTextureCoordinates /
* @ref MaterialAttribute::SpecularTextureCoordinates /
* @ref MaterialAttribute::NormalTextureCoordinates have a precedence
* @ref MaterialAttribute::MetalnessTextureCoordinates /
* @ref MaterialAttribute::RoughnessTextureCoordinates /
* @ref MaterialAttribute::GlossinessTextureCoordinates /
* @ref MaterialAttribute::NormalTextureCoordinates /
* @ref MaterialAttribute::OcclusionTextureCoordinates /
* @ref MaterialAttribute::EmissiveTextureCoordinates have a precedence
* over this attribute for given texture, if present.
* @see @ref PhongMaterialData::textureCoordinates()
* @see @ref PhongMaterialData::textureCoordinates(),
* @ref PbrMetallicRoughnessMaterialData::textureCoordinates(),
* @ref PbrSpecularGlossinessMaterialData::textureCoordinates()
*/
TextureCoordinates,
};
@ -707,7 +1150,19 @@ enum class MaterialType: UnsignedInt {
/**
* Phong. Use @ref PhongMaterialData for convenience attribute access.
*/
Phong = 1 << 0
Phong = 1 << 0,
/**
* PBR metallic/roughness. Use @ref PbrMetallicRoughnessMaterialData for
* convenience attribute access.
*/
PbrMetallicRoughness = 1 << 1,
/**
* PBR specular/glossiness. Use @ref PbrSpecularGlossinessMaterialData for
* convenience attribute access.
*/
PbrSpecularGlossiness = 1 << 2
};
/** @debugoperatorenum{MaterialType} */

302
src/Magnum/Trade/PbrMetallicRoughnessMaterialData.cpp

@ -0,0 +1,302 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "PbrMetallicRoughnessMaterialData.h"
#include "Magnum/Math/Color.h"
#include "Magnum/Math/Matrix3.h"
namespace Magnum { namespace Trade {
using namespace Math::Literals;
bool PbrMetallicRoughnessMaterialData::hasMetalnessTexture() const {
return hasAttribute(MaterialAttribute::MetalnessTexture) ||
hasAttribute(MaterialAttribute::MetallicRoughnessTexture);
}
bool PbrMetallicRoughnessMaterialData::hasRoughnessTexture() const {
return hasAttribute(MaterialAttribute::RoughnessTexture) ||
hasAttribute(MaterialAttribute::MetallicRoughnessTexture);
}
bool PbrMetallicRoughnessMaterialData::hasMetallicRoughnessTexture() const {
return (hasAttribute(MaterialAttribute::MetallicRoughnessTexture) ||
(hasAttribute(MaterialAttribute::MetalnessTexture) &&
hasAttribute(MaterialAttribute::RoughnessTexture) &&
metalnessTextureSwizzle() == MaterialTextureSwizzle::R &&
roughnessTextureSwizzle() == MaterialTextureSwizzle::G)) &&
metalnessTextureMatrix() == roughnessTextureMatrix() &&
metalnessTextureCoordinates() == roughnessTextureCoordinates();
}
bool PbrMetallicRoughnessMaterialData::hasRoughnessMetallicOcclusionTexture() const {
if(!(hasAttribute(MaterialAttribute::RoughnessTexture) &&
hasAttribute(MaterialAttribute::MetalnessTexture) &&
hasAttribute(MaterialAttribute::OcclusionTexture) &&
roughnessTextureSwizzle() == MaterialTextureSwizzle::R &&
metalnessTextureSwizzle() == MaterialTextureSwizzle::G &&
occlusionTextureSwizzle() == MaterialTextureSwizzle::B))
return false;
const Matrix3 roughnessTextureMatrix = this->roughnessTextureMatrix();
const UnsignedInt roughnessTextureCoordinates = this->roughnessTextureCoordinates();
return metalnessTextureMatrix() == roughnessTextureMatrix &&
occlusionTextureMatrix() == roughnessTextureMatrix &&
metalnessTextureCoordinates() == roughnessTextureCoordinates &&
occlusionTextureCoordinates() == roughnessTextureCoordinates;
}
bool PbrMetallicRoughnessMaterialData::hasOcclusionRoughnessMetallicTexture() const {
if(!(hasAttribute(MaterialAttribute::OcclusionTexture) &&
hasAttribute(MaterialAttribute::RoughnessTexture) &&
hasAttribute(MaterialAttribute::MetalnessTexture) &&
occlusionTextureSwizzle() == MaterialTextureSwizzle::R &&
roughnessTextureSwizzle() == MaterialTextureSwizzle::G &&
metalnessTextureSwizzle() == MaterialTextureSwizzle::B))
return false;
const Matrix3 occlusionTextureMatrix = this->occlusionTextureMatrix();
const UnsignedInt occlusionTextureCoordinates = this->occlusionTextureCoordinates();
return roughnessTextureMatrix() == occlusionTextureMatrix &&
metalnessTextureMatrix() == occlusionTextureMatrix &&
roughnessTextureCoordinates() == occlusionTextureCoordinates &&
metalnessTextureCoordinates() == occlusionTextureCoordinates;
}
bool PbrMetallicRoughnessMaterialData::hasNormalRoughnessMetallicTexture() const {
if(!(hasAttribute(MaterialAttribute::NormalTexture) &&
hasAttribute(MaterialAttribute::RoughnessTexture) &&
hasAttribute(MaterialAttribute::MetalnessTexture) &&
normalTextureSwizzle() == MaterialTextureSwizzle::RG &&
roughnessTextureSwizzle() == MaterialTextureSwizzle::B &&
metalnessTextureSwizzle() == MaterialTextureSwizzle::A))
return false;
const Matrix3 normalTextureMatrix = this->normalTextureMatrix();
const UnsignedInt normalTextureCoordinates = this->normalTextureCoordinates();
return roughnessTextureMatrix() == normalTextureMatrix &&
metalnessTextureMatrix() == normalTextureMatrix &&
roughnessTextureCoordinates() == normalTextureCoordinates &&
metalnessTextureCoordinates() == normalTextureCoordinates;
}
bool PbrMetallicRoughnessMaterialData::hasTextureTransformation() const {
return hasAttribute(MaterialAttribute::TextureMatrix) ||
hasAttribute(MaterialAttribute::BaseColorTextureMatrix) ||
hasAttribute(MaterialAttribute::MetalnessTextureMatrix) ||
hasAttribute(MaterialAttribute::RoughnessTextureMatrix) ||
hasAttribute(MaterialAttribute::NormalTextureMatrix) ||
hasAttribute(MaterialAttribute::OcclusionTextureMatrix) ||
hasAttribute(MaterialAttribute::EmissiveTextureMatrix);;
}
bool PbrMetallicRoughnessMaterialData::hasTextureCoordinates() const {
return hasAttribute(MaterialAttribute::TextureCoordinates) ||
hasAttribute(MaterialAttribute::BaseColorTextureCoordinates) ||
hasAttribute(MaterialAttribute::MetalnessTextureCoordinates) ||
hasAttribute(MaterialAttribute::RoughnessTextureCoordinates) ||
hasAttribute(MaterialAttribute::NormalTextureCoordinates) ||
hasAttribute(MaterialAttribute::OcclusionTextureCoordinates) ||
hasAttribute(MaterialAttribute::EmissiveTextureCoordinates);
}
Color4 PbrMetallicRoughnessMaterialData::baseColor() const {
return attributeOr(MaterialAttribute::BaseColor, 0xffffffff_rgbaf);
}
UnsignedInt PbrMetallicRoughnessMaterialData::baseColorTexture() const {
return attribute<UnsignedInt>(MaterialAttribute::BaseColorTexture);
}
Matrix3 PbrMetallicRoughnessMaterialData::baseColorTextureMatrix() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::BaseColorTexture),
"Trade::PbrMetallicRoughnessMaterialData::baseColorTextureMatrix(): the material doesn't have a base color texture", {});
if(Containers::Optional<Matrix3> value = tryAttribute<Matrix3>(MaterialAttribute::BaseColorTextureMatrix))
return *value;
return attributeOr(MaterialAttribute::TextureMatrix, Matrix3{});
}
UnsignedInt PbrMetallicRoughnessMaterialData::baseColorTextureCoordinates() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::BaseColorTexture),
"Trade::PbrMetallicRoughnessMaterialData::baseColorTextureCoordinates(): the material doesn't have a base color texture", {});
if(Containers::Optional<UnsignedInt> value = tryAttribute<UnsignedInt>(MaterialAttribute::BaseColorTextureCoordinates))
return *value;
return attributeOr(MaterialAttribute::TextureCoordinates, 0u);
}
Float PbrMetallicRoughnessMaterialData::metalness() const {
return attributeOr(MaterialAttribute::Metalness, 1.0f);
}
UnsignedInt PbrMetallicRoughnessMaterialData::metalnessTexture() const {
if(Containers::Optional<UnsignedInt> value = tryAttribute<UnsignedInt>(MaterialAttribute::MetallicRoughnessTexture))
return *value;
return attribute<UnsignedInt>(MaterialAttribute::MetalnessTexture);
}
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;
return attributeOr(MaterialAttribute::MetalnessTextureSwizzle, MaterialTextureSwizzle::R);
}
Matrix3 PbrMetallicRoughnessMaterialData::metalnessTextureMatrix() const {
CORRADE_ASSERT(hasMetalnessTexture(),
"Trade::PbrMetallicRoughnessMaterialData::metalnessTextureMatrix(): the material doesn't have a metalness texture", {});
if(Containers::Optional<Matrix3> value = tryAttribute<Matrix3>(MaterialAttribute::MetalnessTextureMatrix))
return *value;
return attributeOr(MaterialAttribute::TextureMatrix, Matrix3{});
}
UnsignedInt PbrMetallicRoughnessMaterialData::metalnessTextureCoordinates() const {
CORRADE_ASSERT(hasMetalnessTexture(),
"Trade::PbrMetallicRoughnessMaterialData::metalnessTextureCoordinates(): the material doesn't have a metalness texture", {});
if(Containers::Optional<UnsignedInt> value = tryAttribute<UnsignedInt>(MaterialAttribute::MetalnessTextureCoordinates))
return *value;
return attributeOr(MaterialAttribute::TextureCoordinates, 0u);
}
Float PbrMetallicRoughnessMaterialData::roughness() const {
return attributeOr(MaterialAttribute::Roughness, 1.0f);
}
UnsignedInt PbrMetallicRoughnessMaterialData::roughnessTexture() const {
if(Containers::Optional<UnsignedInt> value = tryAttribute<UnsignedInt>(MaterialAttribute::MetallicRoughnessTexture))
return *value;
return attribute<UnsignedInt>(MaterialAttribute::RoughnessTexture);
}
MaterialTextureSwizzle PbrMetallicRoughnessMaterialData::roughnessTextureSwizzle() const {
CORRADE_ASSERT(hasRoughnessTexture(),
"Trade::PbrMetallicRoughnessMaterialData::roughnessTextureSwizzle(): the material doesn't have a roughness texture", {});
if(hasAttribute(MaterialAttribute::MetallicRoughnessTexture))
return MaterialTextureSwizzle::G;
return attributeOr(MaterialAttribute::RoughnessTextureSwizzle, MaterialTextureSwizzle::R);
}
Matrix3 PbrMetallicRoughnessMaterialData::roughnessTextureMatrix() const {
CORRADE_ASSERT(hasRoughnessTexture(),
"Trade::PbrMetallicRoughnessMaterialData::roughnessTextureMatrix(): the material doesn't have a roughness texture", {});
if(Containers::Optional<Matrix3> value = tryAttribute<Matrix3>(MaterialAttribute::RoughnessTextureMatrix))
return *value;
return attributeOr(MaterialAttribute::TextureMatrix, Matrix3{});
}
UnsignedInt PbrMetallicRoughnessMaterialData::roughnessTextureCoordinates() const {
CORRADE_ASSERT(hasRoughnessTexture(),
"Trade::PbrMetallicRoughnessMaterialData::roughnessTextureCoordinates(): the material doesn't have a roughness texture", {});
if(Containers::Optional<UnsignedInt> value = tryAttribute<UnsignedInt>(MaterialAttribute::RoughnessTextureCoordinates))
return *value;
return attributeOr(MaterialAttribute::TextureCoordinates, 0u);
}
UnsignedInt PbrMetallicRoughnessMaterialData::normalTexture() const {
return attribute<UnsignedInt>(MaterialAttribute::NormalTexture);
}
MaterialTextureSwizzle PbrMetallicRoughnessMaterialData::normalTextureSwizzle() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::NormalTexture),
"Trade::PbrMetallicRoughnessMaterialData::normalTextureSwizzle(): the material doesn't have a normal texture", {});
return attributeOr(MaterialAttribute::NormalTextureSwizzle, MaterialTextureSwizzle::RGB);
}
Matrix3 PbrMetallicRoughnessMaterialData::normalTextureMatrix() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::NormalTexture),
"Trade::PbrMetallicRoughnessMaterialData::normalTextureMatrix(): the material doesn't have a normal texture", {});
if(Containers::Optional<Matrix3> value = tryAttribute<Matrix3>(MaterialAttribute::NormalTextureMatrix))
return *value;
return attributeOr(MaterialAttribute::TextureMatrix, Matrix3{});
}
UnsignedInt PbrMetallicRoughnessMaterialData::normalTextureCoordinates() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::NormalTexture),
"Trade::PbrMetallicRoughnessMaterialData::normalTextureCoordinates(): the material doesn't have a normal texture", {});
if(Containers::Optional<UnsignedInt> value = tryAttribute<UnsignedInt>(MaterialAttribute::NormalTextureCoordinates))
return *value;
return attributeOr(MaterialAttribute::TextureCoordinates, 0u);
}
UnsignedInt PbrMetallicRoughnessMaterialData::occlusionTexture() const {
return attribute<UnsignedInt>(MaterialAttribute::OcclusionTexture);
}
MaterialTextureSwizzle PbrMetallicRoughnessMaterialData::occlusionTextureSwizzle() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::OcclusionTexture),
"Trade::PbrMetallicRoughnessMaterialData::occlusionTextureSwizzle(): the material doesn't have an occlusion texture", {});
return attributeOr(MaterialAttribute::OcclusionTextureSwizzle, MaterialTextureSwizzle::R);
}
Matrix3 PbrMetallicRoughnessMaterialData::occlusionTextureMatrix() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::OcclusionTexture),
"Trade::PbrMetallicRoughnessMaterialData::occlusionTextureMatrix(): the material doesn't have an occlusion texture", {});
if(Containers::Optional<Matrix3> value = tryAttribute<Matrix3>(MaterialAttribute::OcclusionTextureMatrix))
return *value;
return attributeOr(MaterialAttribute::TextureMatrix, Matrix3{});
}
UnsignedInt PbrMetallicRoughnessMaterialData::occlusionTextureCoordinates() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::OcclusionTexture),
"Trade::PbrMetallicRoughnessMaterialData::occlusionTextureCoordinates(): the material doesn't have an occlusion texture", {});
if(Containers::Optional<UnsignedInt> value = tryAttribute<UnsignedInt>(MaterialAttribute::OcclusionTextureCoordinates))
return *value;
return attributeOr(MaterialAttribute::TextureCoordinates, 0u);
}
Color3 PbrMetallicRoughnessMaterialData::emissiveColor() const {
return attributeOr(MaterialAttribute::EmissiveColor, 0x000000_srgbf);
}
UnsignedInt PbrMetallicRoughnessMaterialData::emissiveTexture() const {
return attribute<UnsignedInt>(MaterialAttribute::EmissiveTexture);
}
Matrix3 PbrMetallicRoughnessMaterialData::emissiveTextureMatrix() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::EmissiveTexture),
"Trade::PbrMetallicRoughnessMaterialData::emissiveTextureMatrix(): the material doesn't have an emissive texture", {});
if(Containers::Optional<Matrix3> value = tryAttribute<Matrix3>(MaterialAttribute::EmissiveTextureMatrix))
return *value;
return attributeOr(MaterialAttribute::TextureMatrix, Matrix3{});
}
UnsignedInt PbrMetallicRoughnessMaterialData::emissiveTextureCoordinates() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::EmissiveTexture),
"Trade::PbrMetallicRoughnessMaterialData::emissiveTextureCoordinates(): the material doesn't have an emissive texture", {});
if(Containers::Optional<UnsignedInt> value = tryAttribute<UnsignedInt>(MaterialAttribute::EmissiveTextureCoordinates))
return *value;
return attributeOr(MaterialAttribute::TextureCoordinates, 0u);
}
Matrix3 PbrMetallicRoughnessMaterialData::textureMatrix() const {
return attributeOr(MaterialAttribute::TextureMatrix, Matrix3{});
}
UnsignedInt PbrMetallicRoughnessMaterialData::textureCoordinates() const {
return attributeOr(MaterialAttribute::TextureCoordinates, 0u);
}
}}

566
src/Magnum/Trade/PbrMetallicRoughnessMaterialData.h

@ -0,0 +1,566 @@
#ifndef Magnum_Trade_PbrMetallicRoughnessMaterialData_h
#define Magnum_Trade_PbrMetallicRoughnessMaterialData_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
/** @file
* @brief Class @ref Magnum::Trade::PbrMetallicRoughnessMaterialData
* @m_since_latest
*/
#include "Magnum/Trade/MaterialData.h"
namespace Magnum { namespace Trade {
/**
@brief PBR metallic/roughness material data
@m_since_latest
@see @ref AbstractImporter::material(), @ref PbrSpecularGlossinessMaterialData,
@ref PhongMaterialData
*/
class MAGNUM_TRADE_EXPORT PbrMetallicRoughnessMaterialData: public MaterialData {
public:
#ifndef DOXYGEN_GENERATING_OUTPUT
/* Allow constructing subclasses directly. While not used in the
general Importer workflow, it allows users to create instances with
desired convenience APIs easier (and simplifies testing). It's
however hidden from the docs as constructing instances this way
isn't really common and it would add a lot of noise. */
using MaterialData::MaterialData;
#endif
/**
* @brief Whether the material has a metalness texture
*
* Returns @cpp true @ce if any of the
* @ref MaterialAttribute::MetalnessTexture or
* @ref MaterialAttribute::MetallicRoughnessTexture attributes is
* present, @cpp false @ce otherwise.
* @see @ref hasRoughnessTexture(), @ref hasMetallicRoughnessTexture()
*/
bool hasMetalnessTexture() const;
/**
* @brief Whether the material has a roughness texture
*
* Returns @cpp true @ce if any of the
* @ref MaterialAttribute::RoughnessTexture or
* @ref MaterialAttribute::MetallicRoughnessTexture attributes is
* present, @cpp false @ce otherwise.
* @see @ref hasMetalnessTexture(), @ref hasMetallicRoughnessTexture()
*/
bool hasRoughnessTexture() const;
/**
* @brief Whether the material has a combined metallic/roughness 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
* present or have the same value, and
* @ref MaterialAttribute::MetalnessTextureCoordinates and
* @ref MaterialAttribute::RoughnessTextureCoordinates 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
* metalness and roughness texture, and the two are packed together
* with metalness occupying the R channel and roughness the G channel.
* @see @ref hasMetalnessTexture(), @ref hasRoughnessTexture(),
* @ref hasOcclusionRoughnessMetallicTexture(),
* @ref hasRoughnessMetallicOcclusionTexture(),
* @ref hasNormalRoughnessMetallicTexture()
*/
bool hasMetallicRoughnessTexture() const;
/**
* @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
* @ref MaterialAttribute::MetalnessTextureSwizzle is set to
* @ref MaterialTextureSwizzle::B, and additionally
* @ref MaterialAttribute::OcclusionTextureMatrix,
* @ref MaterialAttribute::RoughnessTextureMatrix and
* @ref MaterialAttribute::MetalnessTextureMatrix are all other not
* present or have the same value, and
* @ref MaterialAttribute::OcclusionTextureCoordinates,
* @ref MaterialAttribute::RoughnessTextureCoordinates and
* @ref MaterialAttribute::MetalnessTextureCoordinates are all either
* not present or have the same value; @cpp false @ce otherwise.
*
* In other words, if this function returns @cpp true @ce,
* @ref occlusionTexture(), @ref occlusionTextureMatrix() and
* @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.
* @see @ref hasMetalnessTexture(), @ref hasRoughnessTexture(),
* @ref hasMetallicRoughnessTexture(),
* @ref hasRoughnessMetallicOcclusionTexture(),
* @ref hasNormalRoughnessMetallicTexture()
*/
bool hasOcclusionRoughnessMetallicTexture() const;
/**
* @brief Whether the material has a combined roughness/metallic/occlusion texture
*
* Returns @cpp true @ce if @ref MaterialAttribute::RoughnessTexture,
* @ref MaterialAttribute::MetalnessTexture and
* @ref MaterialAttribute::OcclusionTexture are all present, point to
* the same texture ID, @ref MaterialAttribute::RoughnessTextureSwizzle
* is set to @ref MaterialTextureSwizzle::R (or omitted, in which case
* it's the default), @ref MaterialAttribute::MetalnessTextureSwizzle
* is set to @ref MaterialTextureSwizzle::G and
* @ref MaterialAttribute::OcclusionTextureSwizzle is set to
* @ref MaterialTextureSwizzle::B, and additionally
* @ref MaterialAttribute::RoughnessTextureMatrix,
* @ref MaterialAttribute::MetalnessTextureMatrix and
* @ref MaterialAttribute::OcclusionTextureMatrix are all other not
* present or have the same value, and
* @ref MaterialAttribute::RoughnessTextureCoordinates,
* @ref MaterialAttribute::MetalnessTextureCoordinates and
* @ref MaterialAttribute::OcclusionTextureCoordinates are all either
* not present or have the same value; @cpp false @ce otherwise.
*
* In other words, if this function returns @cpp true @ce,
* @ref roughnessTexture(), @ref roughnessTextureMatrix() and
* @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.
* @see @ref hasMetalnessTexture(), @ref hasRoughnessTexture(),
* @ref hasMetallicRoughnessTexture(),
* @ref hasOcclusionRoughnessMetallicTexture(),
* @ref hasNormalRoughnessMetallicTexture()
*/
bool hasRoughnessMetallicOcclusionTexture() const;
/**
* @brief Whether the material has a combined normal/roughness/metallic texture
*
* Returns @cpp true @ce if @ref MaterialAttribute::NormalTexture,
* @ref MaterialAttribute::RoughnessTexture and
* @ref MaterialAttribute::MetalnessTexture are all present, point to
* the same texture ID, @ref MaterialAttribute::NormalTextureSwizzle
* is set to @ref MaterialTextureSwizzle::RG (with the third channel
* implicit), @ref MaterialAttribute::RoughnessTextureSwizzle
* is set to @ref MaterialTextureSwizzle::B and
* @ref MaterialAttribute::MetalnessTextureSwizzle is set to
* @ref MaterialTextureSwizzle::A, and additionally
* @ref MaterialAttribute::NormalTextureMatrix,
* @ref MaterialAttribute::RoughnessTextureMatrix and
* @ref MaterialAttribute::MetalnessTextureMatrix are all other not
* present or have the same value, and
* @ref MaterialAttribute::NormalTextureCoordinates,
* @ref MaterialAttribute::RoughnessTextureCoordinates and
* @ref MaterialAttribute::MetalnessTextureCoordinates are all either
* not present or have the same value; @cpp false @ce otherwise.
*
* In other words, if this function returns @cpp true @ce,
* @ref normalTexture(), @ref normalTextureMatrix() and
* @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.
* @see @ref hasMetalnessTexture(), @ref hasRoughnessTexture(),
* @ref hasMetallicRoughnessTexture(),
* @ref hasRoughnessMetallicOcclusionTexture(),
* @ref hasOcclusionRoughnessMetallicTexture()
*/
bool hasNormalRoughnessMetallicTexture() const;
/**
* @brief Whether the material has texture transformation
*
* Returns @cpp true @ce if any of the
* @ref MaterialAttribute::BaseColorTextureMatrix,
* @ref MaterialAttribute::MetalnessTextureMatrix,
* @ref MaterialAttribute::RoughnessTextureMatrix,
* @ref MaterialAttribute::NormalTextureMatrix,
* @ref MaterialAttribute::OcclusionTextureMatrix,
* @ref MaterialAttribute::EmissiveTextureMatrix or
* @ref MaterialAttribute::TextureMatrix attributes is present,
* @cpp false @ce otherwise.
*/
bool hasTextureTransformation() const;
/**
* @brief Whether the material uses extra texture coordinate sets
*
* Returns @cpp true @ce if any of the
* @ref MaterialAttribute::BaseColorTextureCoordinates,
* @ref MaterialAttribute::MetalnessTextureCoordinates,
* @ref MaterialAttribute::RoughnessTextureCoordinates,
* @ref MaterialAttribute::NormalTextureCoordinates,
* @ref MaterialAttribute::OcclusionTextureCoordinates,
* @ref MaterialAttribute::EmissiveTextureCoordinates or
* @ref MaterialAttribute::TextureCoordinates attributes is present and
* has a non-zero value, @cpp false @ce otherwise.
*/
bool hasTextureCoordinates() const;
/**
* @brief Base color
*
* Convenience access to the @ref MaterialAttribute::BaseColor
* attribute. If not present, the default is @cpp 0xffffffff_srgbaf @ce.
*
* If the material has @ref MaterialAttribute::BaseColorTexture, the
* color and texture is meant to be multiplied together.
*/
Color4 baseColor() const;
/**
* @brief Base color texture ID
*
* Available only if @ref MaterialAttribute::BaseColorTexture is
* present. Meant to be multiplied with @ref baseColor().
* @see @ref hasAttribute(), @ref AbstractImporter::texture()
*/
UnsignedInt baseColorTexture() const;
/**
* @brief Base color texture coordinate transformation matrix
*
* Convenience access to the @ref MaterialAttribute::BaseColorTextureMatrix
* / @ref MaterialAttribute::TextureMatrix attributes. If neither is
* present, the default is an identity matrix. Available only if the
* material has @ref MaterialAttribute::BaseColorTexture.
* @see @ref hasAttribute()
*/
Matrix3 baseColorTextureMatrix() const;
/**
* @brief Base color texture coordinate set
*
* Convenience access to the @ref MaterialAttribute::BaseColorTextureCoordinates
* / @ref MaterialAttribute::TextureCoordinates attributes. If neither
* is present, the default is @cpp 0 @ce. Available only if the
* material has @ref MaterialAttribute::BaseColorTexture.
* @see @ref hasAttribute()
*/
UnsignedInt baseColorTextureCoordinates() const;
/**
* @brief Metalness factor
*
* Convenience access to the @ref MaterialAttribute::Metalness
* attribute. If not present, the default is @cpp 1.0f @ce.
*
* If the material has a metalness texture, the factor and texture is
* meant to be multiplied together.
* @see @ref hasMetalnessTexture()
*/
Float metalness() const;
/**
* @brief Metalness texture ID
*
* Available only if either @ref MaterialAttribute::MetalnessTexture or
* @ref MaterialAttribute::MetallicRoughnessTexture is present. Meant
* to be multiplied with @ref metalness().
* @see @ref hasMetalnessTexture(), @ref AbstractImporter::texture()
*/
UnsignedInt metalnessTexture() const;
/**
* @brief Metalness texture swizzle
*
* If @ref MaterialAttribute::MetallicRoughnessTexture is present,
* returns always @ref MaterialTextureSwizzle::R. 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.
* @see @ref hasMetalnessTexture()
*/
MaterialTextureSwizzle metalnessTextureSwizzle() const;
/**
* @brief Metalness texture coordinate transformation matrix
*
* Convenience access to the @ref MaterialAttribute::MetalnessTextureMatrix
* / @ref MaterialAttribute::TextureMatrix attributes. If neither is
* present, the default is an identity matrix. Available only if the
* material has a metalness texture.
* @see @ref hasMetalnessTexture()
*/
Matrix3 metalnessTextureMatrix() const;
/**
* @brief Metalness texture coordinate set
*
* Convenience access to the @ref MaterialAttribute::MetalnessTextureCoordinates
* / @ref MaterialAttribute::TextureCoordinates attributes. If neither
* is present, the default is @cpp 0 @ce. Available only if the
* material has a metalness texture.
* @see @ref hasMetalnessTexture()
*/
UnsignedInt metalnessTextureCoordinates() const;
/**
* @brief Roughness factor
*
* Convenience access to the @ref MaterialAttribute::Roughness
* attribute. If not present, the default is @cpp 1.0f @ce.
*
* If the material has a roughness texture, the factor and texture is
* meant to be multiplied together.
* @see @ref hasRoughnessTexture()
*/
Float roughness() const;
/**
* @brief Roughness texture ID
*
* Available only if either @ref MaterialAttribute::RoughnessTexture or
* @ref MaterialAttribute::MetallicRoughnessTexture is present. Meant
* to be multiplied with @ref roughness().
* @see @ref hasRoughnessTexture(), @ref AbstractImporter::texture()
*/
UnsignedInt roughnessTexture() const;
/**
* @brief Roughness texture swizzle
*
* If @ref MaterialAttribute::MetallicRoughnessTexture 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
* if the material has a roughness texture.
* @see @ref hasRoughnessTexture()
*/
MaterialTextureSwizzle roughnessTextureSwizzle() const;
/**
* @brief Roughness texture coordinate transformation matrix
*
* Convenience access to the @ref MaterialAttribute::RoughnessTextureMatrix
* / @ref MaterialAttribute::TextureMatrix attributes. If neither is
* present, the default is an identity matrix. Available only if the
* material has a roughness texture.
* @see @ref hasRoughnessTexture()
*/
Matrix3 roughnessTextureMatrix() const;
/**
* @brief Roughness texture coordinate set
*
* Convenience access to the @ref MaterialAttribute::RoughnessTextureCoordinates
* / @ref MaterialAttribute::TextureCoordinates attributes. If neither
* is present, the default is @cpp 0 @ce. Available only if the
* material has a roughness texture.
* @see @ref hasRoughnessTexture()
*/
UnsignedInt roughnessTextureCoordinates() const;
/**
* @brief Normal texture ID
*
* Available only if @ref MaterialAttribute::NormalTexture is present.
* @see @ref hasAttribute(), @ref AbstractImporter::texture()
*/
UnsignedInt normalTexture() const;
/**
* @brief Normal texture coordinate transformation matrix
*
* Convenience access to the @ref MaterialAttribute::NormalTextureMatrix
* / @ref MaterialAttribute::TextureMatrix attributes. If neither is
* present, the default is an identity matrix. Available only if the
* material has @ref MaterialAttribute::NormalTexture.
* @see @ref hasAttribute(), @ref AbstractImporter::texture()
*/
Matrix3 normalTextureMatrix() const;
/**
* @brief Normal texture swizzle
* @m_since_latest
*
* Convenience access to the
* @ref MaterialAttribute::NormalTextureSwizzle attribute. If not
* present, the default is @ref MaterialTextureSwizzle::RGB. Available
* only if @ref MaterialAttribute::NormalTexture is present.
* @see @ref hasAttribute()
*/
MaterialTextureSwizzle normalTextureSwizzle() const;
/**
* @brief Normal texture coordinate set
*
* Convenience access to the @ref MaterialAttribute::NormalTextureCoordinates
* / @ref MaterialAttribute::TextureCoordinates attributes. If neither is
* present, the default is @cpp 0 @ce. Available only if the material
* has @ref MaterialAttribute::NormalTexture.
* @see @ref hasAttribute(), @ref AbstractImporter::texture()
*/
UnsignedInt normalTextureCoordinates() const;
/**
* @brief Occlusion texture ID
*
* Available only if @ref MaterialAttribute::OcclusionTexture is present.
* @see @ref hasAttribute(), @ref AbstractImporter::texture()
*/
UnsignedInt occlusionTexture() const;
/**
* @brief Occlusion texture swizzle
*
* Convenience access to the
* @ref MaterialAttribute::OcclusionTextureSwizzle attribute. If not
* present, the default is @ref MaterialTextureSwizzle::R. Available
* only if @ref MaterialAttribute::OcclusionTexture is present.
* @see @ref hasAttribute()
*/
MaterialTextureSwizzle occlusionTextureSwizzle() const;
/**
* @brief Occlusion texture coordinate transformation matrix
*
* Convenience access to the @ref MaterialAttribute::OcclusionTextureMatrix
* / @ref MaterialAttribute::TextureMatrix attributes. If neither is
* present, the default is an identity matrix. Available only if the
* material has @ref MaterialAttribute::OcclusionTexture.
* @see @ref hasAttribute()
*/
Matrix3 occlusionTextureMatrix() const;
/**
* @brief Occlusion texture coordinate set
*
* Convenience access to the @ref MaterialAttribute::OcclusionTextureCoordinates
* / @ref MaterialAttribute::TextureCoordinates attributes. If neither
* is present, the default is @cpp 0 @ce. Available only if the
* material has @ref MaterialAttribute::OcclusionTexture.
* @see @ref hasAttribute()
*/
UnsignedInt occlusionTextureCoordinates() const;
/**
* @brief Emissive color
*
* Convenience access to the @ref MaterialAttribute::EmissiveColor
* attribute. If not present, the default is @cpp 0x000000_srgbf @ce
* (i.e, no emission).
*
* If the material has @ref MaterialAttribute::EmissiveTexture, the
* color and texture is meant to be multiplied together.
*/
Color3 emissiveColor() const;
/**
* @brief Emissive texture ID
*
* Available only if @ref MaterialAttribute::EmissiveTexture is present.
* Meant to be multiplied with @ref emissiveColor().
* @see @ref hasAttribute(), @ref AbstractImporter::texture()
*/
UnsignedInt emissiveTexture() const;
/* No EmissiveTextureSwizzle attribute right now (implicitly RGB) */
/**
* @brief Emissive texture coordinate transformation matrix
*
* Convenience access to the @ref MaterialAttribute::EmissiveTextureMatrix
* / @ref MaterialAttribute::TextureMatrix attributes. If neither is
* present, the default is an identity matrix. Available only if the
* material has @ref MaterialAttribute::EmissiveTexture.
* @see @ref hasAttribute()
*/
Matrix3 emissiveTextureMatrix() const;
/**
* @brief Emissive texture coordinate set
*
* Convenience access to the @ref MaterialAttribute::EmissiveTextureCoordinates
* / @ref MaterialAttribute::TextureCoordinates attributes. If neither
* is present, the default is @cpp 0 @ce. Available only if the
* material has @ref MaterialAttribute::EmissiveTexture.
* @see @ref hasAttribute()
*/
UnsignedInt emissiveTextureCoordinates() const;
/**
* @brief Common texture coordinate transformation matrix for all textures
*
* Convenience access to the @ref MaterialAttribute::TextureMatrix
* attribute. If not present, the default is an identity matrix. Note
* that the material may also define per-texture transformation using
* the @ref MaterialAttribute::BaseColorTextureMatrix,
* @ref MaterialAttribute::MetalnessTextureMatrix,
* @ref MaterialAttribute::RoughnessTextureMatrix,
* @ref MaterialAttribute::NormalTextureMatrix,
* @ref MaterialAttribute::OcclusionTextureMatrix and
* @ref MaterialAttribute::EmissiveTextureMatrix attributes, which then
* take precedence over the common one.
* @see @ref hasAttribute(), @ref baseColorTextureMatrix(),
* @ref metalnessTextureMatrix(), @ref roughnessTextureMatrix(),
* @ref normalTextureMatrix(), @ref occlusionTextureMatrix(),
* @ref emissiveTextureMatrix()
*/
Matrix3 textureMatrix() const;
/**
* @brief Common texture coordinate set index for all textures
*
* Convenience access to the @ref MaterialAttribute::TextureCoordinates
* attribute. If not present, the default is @cpp 0 @ce. Note that the
* material may also define per-texture coordinate set using the
* @ref MaterialAttribute::BaseColorTextureCoordinates,
* @ref MaterialAttribute::MetalnessTextureCoordinates,
* @ref MaterialAttribute::RoughnessTextureCoordinates,
* @ref MaterialAttribute::NormalTextureCoordinates,
* @ref MaterialAttribute::OcclusionTextureCoordinates and
* @ref MaterialAttribute::EmissiveTextureCoordinates attributes, which
* then take precedence over the common one.
* @see @ref hasAttribute(), @ref baseColorTextureCoordinates(),
* @ref metalnessTextureCoordinates(),
* @ref roughnessTextureCoordinates(),
* @ref normalTextureCoordinates(),
* @ref occlusionTextureCoordinates(),
* @ref emissiveTextureCoordinates()
*/
UnsignedInt textureCoordinates() const;
};
}}
#endif

251
src/Magnum/Trade/PbrSpecularGlossinessMaterialData.cpp

@ -0,0 +1,251 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "PbrSpecularGlossinessMaterialData.h"
#include "Magnum/Math/Color.h"
#include "Magnum/Math/Matrix3.h"
namespace Magnum { namespace Trade {
using namespace Math::Literals;
bool PbrSpecularGlossinessMaterialData::hasSpecularTexture() const {
return hasAttribute(MaterialAttribute::SpecularTexture) ||
hasAttribute(MaterialAttribute::SpecularGlossinessTexture);
}
bool PbrSpecularGlossinessMaterialData::hasGlossinessTexture() const {
return hasAttribute(MaterialAttribute::GlossinessTexture) ||
hasAttribute(MaterialAttribute::SpecularGlossinessTexture);
}
bool PbrSpecularGlossinessMaterialData::hasSpecularGlossinessTexture() const {
return (hasAttribute(MaterialAttribute::SpecularGlossinessTexture) ||
(hasAttribute(MaterialAttribute::SpecularTexture) &&
hasAttribute(MaterialAttribute::GlossinessTexture) &&
specularTextureSwizzle() == MaterialTextureSwizzle::RGB &&
glossinessTextureSwizzle() == MaterialTextureSwizzle::A)) &&
specularTextureMatrix() == glossinessTextureMatrix() &&
specularTextureCoordinates() == glossinessTextureCoordinates();
}
bool PbrSpecularGlossinessMaterialData::hasTextureTransformation() const {
return hasAttribute(MaterialAttribute::TextureMatrix) ||
hasAttribute(MaterialAttribute::DiffuseTextureMatrix) ||
hasAttribute(MaterialAttribute::SpecularTextureMatrix) ||
hasAttribute(MaterialAttribute::GlossinessTextureMatrix) ||
hasAttribute(MaterialAttribute::NormalTextureMatrix) ||
hasAttribute(MaterialAttribute::OcclusionTextureMatrix) ||
hasAttribute(MaterialAttribute::EmissiveTextureMatrix);
}
bool PbrSpecularGlossinessMaterialData::hasTextureCoordinates() const {
return hasAttribute(MaterialAttribute::TextureCoordinates) ||
hasAttribute(MaterialAttribute::DiffuseTextureCoordinates) ||
hasAttribute(MaterialAttribute::SpecularTextureCoordinates) ||
hasAttribute(MaterialAttribute::GlossinessTextureCoordinates) ||
hasAttribute(MaterialAttribute::NormalTextureCoordinates) ||
hasAttribute(MaterialAttribute::OcclusionTextureCoordinates) ||
hasAttribute(MaterialAttribute::EmissiveTextureCoordinates);
}
Color4 PbrSpecularGlossinessMaterialData::diffuseColor() const {
return attributeOr(MaterialAttribute::DiffuseColor, 0xffffffff_srgbaf);
}
UnsignedInt PbrSpecularGlossinessMaterialData::diffuseTexture() const {
return attribute<UnsignedInt>(MaterialAttribute::DiffuseTexture);
}
Matrix3 PbrSpecularGlossinessMaterialData::diffuseTextureMatrix() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::DiffuseTexture),
"Trade::PbrSpecularGlossinessMaterialData::diffuseTextureMatrix(): the material doesn't have a diffuse texture", {});
if(Containers::Optional<Matrix3> value = tryAttribute<Matrix3>(MaterialAttribute::DiffuseTextureMatrix))
return *value;
return attributeOr(MaterialAttribute::TextureMatrix, Matrix3{});
}
UnsignedInt PbrSpecularGlossinessMaterialData::diffuseTextureCoordinates() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::DiffuseTexture),
"Trade::PbrSpecularGlossinessMaterialData::diffuseTextureCoordinates(): the material doesn't have a diffuse texture", {});
if(Containers::Optional<UnsignedInt> value = tryAttribute<UnsignedInt>(MaterialAttribute::DiffuseTextureCoordinates))
return *value;
return attributeOr(MaterialAttribute::TextureCoordinates, 0u);
}
Color4 PbrSpecularGlossinessMaterialData::specularColor() const {
return attributeOr(MaterialAttribute::SpecularColor, 0xffffff00_srgbaf);
}
UnsignedInt PbrSpecularGlossinessMaterialData::specularTexture() const {
if(Containers::Optional<UnsignedInt> value = tryAttribute<UnsignedInt>(MaterialAttribute::SpecularGlossinessTexture))
return *value;
return attribute<UnsignedInt>(MaterialAttribute::SpecularTexture);
}
MaterialTextureSwizzle PbrSpecularGlossinessMaterialData::specularTextureSwizzle() const {
CORRADE_ASSERT(hasSpecularTexture(),
"Trade::PbrSpecularGlossinessMaterialData::specularTextureSwizzle(): the material doesn't have a specular texture", {});
if(hasAttribute(MaterialAttribute::SpecularGlossinessTexture))
return MaterialTextureSwizzle::RGB;
return attributeOr(MaterialAttribute::SpecularTextureSwizzle, MaterialTextureSwizzle::RGB);
}
Matrix3 PbrSpecularGlossinessMaterialData::specularTextureMatrix() const {
CORRADE_ASSERT(hasSpecularTexture(),
"Trade::PbrSpecularGlossinessMaterialData::specularTextureMatrix(): the material doesn't have a specular texture", {});
if(Containers::Optional<Matrix3> value = tryAttribute<Matrix3>(MaterialAttribute::SpecularTextureMatrix))
return *value;
return attributeOr(MaterialAttribute::TextureMatrix, Matrix3{});
}
UnsignedInt PbrSpecularGlossinessMaterialData::specularTextureCoordinates() const {
CORRADE_ASSERT(hasSpecularTexture(),
"Trade::PbrSpecularGlossinessMaterialData::specularTextureCoordinates(): the material doesn't have a specular texture", {});
if(Containers::Optional<UnsignedInt> value = tryAttribute<UnsignedInt>(MaterialAttribute::SpecularTextureCoordinates))
return *value;
return attributeOr(MaterialAttribute::TextureCoordinates, 0u);
}
Float PbrSpecularGlossinessMaterialData::glossiness() const {
return attributeOr(MaterialAttribute::Glossiness, 1.0f);
}
UnsignedInt PbrSpecularGlossinessMaterialData::glossinessTexture() const {
if(Containers::Optional<UnsignedInt> value = tryAttribute<UnsignedInt>(MaterialAttribute::SpecularGlossinessTexture))
return *value;
return attribute<UnsignedInt>(MaterialAttribute::GlossinessTexture);
}
MaterialTextureSwizzle PbrSpecularGlossinessMaterialData::glossinessTextureSwizzle() const {
CORRADE_ASSERT(hasGlossinessTexture(),
"Trade::PbrSpecularGlossinessMaterialData::glossinessTextureSwizzle(): the material doesn't have a glossiness texture", {});
if(hasAttribute(MaterialAttribute::SpecularGlossinessTexture))
return MaterialTextureSwizzle::A;
return attributeOr(MaterialAttribute::GlossinessTextureSwizzle, MaterialTextureSwizzle::R);
}
Matrix3 PbrSpecularGlossinessMaterialData::glossinessTextureMatrix() const {
CORRADE_ASSERT(hasGlossinessTexture(),
"Trade::PbrSpecularGlossinessMaterialData::glossinessTextureMatrix(): the material doesn't have a glossiness texture", {});
if(Containers::Optional<Matrix3> value = tryAttribute<Matrix3>(MaterialAttribute::GlossinessTextureMatrix))
return *value;
return attributeOr(MaterialAttribute::TextureMatrix, Matrix3{});
}
UnsignedInt PbrSpecularGlossinessMaterialData::glossinessTextureCoordinates() const {
CORRADE_ASSERT(hasGlossinessTexture(),
"Trade::PbrSpecularGlossinessMaterialData::glossinessTextureCoordinates(): the material doesn't have a glossiness texture", {});
if(Containers::Optional<UnsignedInt> value = tryAttribute<UnsignedInt>(MaterialAttribute::GlossinessTextureCoordinates))
return *value;
return attributeOr(MaterialAttribute::TextureCoordinates, 0u);
}
UnsignedInt PbrSpecularGlossinessMaterialData::normalTexture() const {
return attribute<UnsignedInt>(MaterialAttribute::NormalTexture);
}
MaterialTextureSwizzle PbrSpecularGlossinessMaterialData::normalTextureSwizzle() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::NormalTexture),
"Trade::PbrSpecularGlossinessMaterialData::normalTextureSwizzle(): the material doesn't have a normal texture", {});
return attributeOr(MaterialAttribute::NormalTextureSwizzle, MaterialTextureSwizzle::RGB);
}
Matrix3 PbrSpecularGlossinessMaterialData::normalTextureMatrix() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::NormalTexture),
"Trade::PbrSpecularGlossinessMaterialData::normalTextureMatrix(): the material doesn't have a normal texture", {});
if(Containers::Optional<Matrix3> value = tryAttribute<Matrix3>(MaterialAttribute::NormalTextureMatrix))
return *value;
return attributeOr(MaterialAttribute::TextureMatrix, Matrix3{});
}
UnsignedInt PbrSpecularGlossinessMaterialData::normalTextureCoordinates() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::NormalTexture),
"Trade::PbrSpecularGlossinessMaterialData::normalTextureCoordinates(): the material doesn't have a normal texture", {});
if(Containers::Optional<UnsignedInt> value = tryAttribute<UnsignedInt>(MaterialAttribute::NormalTextureCoordinates))
return *value;
return attributeOr(MaterialAttribute::TextureCoordinates, 0u);
}
UnsignedInt PbrSpecularGlossinessMaterialData::occlusionTexture() const {
return attribute<UnsignedInt>(MaterialAttribute::OcclusionTexture);
}
MaterialTextureSwizzle PbrSpecularGlossinessMaterialData::occlusionTextureSwizzle() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::OcclusionTexture),
"Trade::PbrSpecularGlossinessMaterialData::occlusionTextureSwizzle(): the material doesn't have an occlusion texture", {});
return attributeOr(MaterialAttribute::OcclusionTextureSwizzle, MaterialTextureSwizzle::R);
}
Matrix3 PbrSpecularGlossinessMaterialData::occlusionTextureMatrix() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::OcclusionTexture),
"Trade::PbrSpecularGlossinessMaterialData::occlusionTextureMatrix(): the material doesn't have an occlusion texture", {});
if(Containers::Optional<Matrix3> value = tryAttribute<Matrix3>(MaterialAttribute::OcclusionTextureMatrix))
return *value;
return attributeOr(MaterialAttribute::TextureMatrix, Matrix3{});
}
UnsignedInt PbrSpecularGlossinessMaterialData::occlusionTextureCoordinates() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::OcclusionTexture),
"Trade::PbrSpecularGlossinessMaterialData::occlusionTextureCoordinates(): the material doesn't have an occlusion texture", {});
if(Containers::Optional<UnsignedInt> value = tryAttribute<UnsignedInt>(MaterialAttribute::OcclusionTextureCoordinates))
return *value;
return attributeOr(MaterialAttribute::TextureCoordinates, 0u);
}
Color3 PbrSpecularGlossinessMaterialData::emissiveColor() const {
return attributeOr(MaterialAttribute::EmissiveColor, 0x000000_srgbf);
}
UnsignedInt PbrSpecularGlossinessMaterialData::emissiveTexture() const {
return attribute<UnsignedInt>(MaterialAttribute::EmissiveTexture);
}
Matrix3 PbrSpecularGlossinessMaterialData::emissiveTextureMatrix() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::EmissiveTexture),
"Trade::PbrSpecularGlossinessMaterialData::emissiveTextureMatrix(): the material doesn't have an emissive texture", {});
if(Containers::Optional<Matrix3> value = tryAttribute<Matrix3>(MaterialAttribute::EmissiveTextureMatrix))
return *value;
return attributeOr(MaterialAttribute::TextureMatrix, Matrix3{});
}
UnsignedInt PbrSpecularGlossinessMaterialData::emissiveTextureCoordinates() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::EmissiveTexture),
"Trade::PbrSpecularGlossinessMaterialData::emissiveTextureCoordinates(): the material doesn't have an emissive texture", {});
if(Containers::Optional<UnsignedInt> value = tryAttribute<UnsignedInt>(MaterialAttribute::EmissiveTextureCoordinates))
return *value;
return attributeOr(MaterialAttribute::TextureCoordinates, 0u);
}
Matrix3 PbrSpecularGlossinessMaterialData::textureMatrix() const {
return attributeOr(MaterialAttribute::TextureMatrix, Matrix3{});
}
UnsignedInt PbrSpecularGlossinessMaterialData::textureCoordinates() const {
return attributeOr(MaterialAttribute::TextureCoordinates, 0u);
}
}}

460
src/Magnum/Trade/PbrSpecularGlossinessMaterialData.h

@ -0,0 +1,460 @@
#ifndef Magnum_Trade_PbrSpecularGlossinessMaterialData_h
#define Magnum_Trade_PbrSpecularGlossinessMaterialData_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
/** @file
* @brief Class @ref Magnum::Trade::PbrSpecularGlossinessMaterialData
* @m_since_latest
*/
#include "Magnum/Trade/MaterialData.h"
namespace Magnum { namespace Trade {
/**
@brief PBR specular/glossiness material data
@m_since_latest
@see @ref AbstractImporter::material(), @ref PbrMetallicRoughnessMaterialData,
@ref PhongMaterialData
*/
class MAGNUM_TRADE_EXPORT PbrSpecularGlossinessMaterialData: public MaterialData {
public:
#ifndef DOXYGEN_GENERATING_OUTPUT
/* Allow constructing subclasses directly. While not used in the
general Importer workflow, it allows users to create instances with
desired convenience APIs easier (and simplifies testing). It's
however hidden from the docs as constructing instances this way
isn't really common and it would add a lot of noise. */
using MaterialData::MaterialData;
#endif
/**
* @brief Whether the material has a specular texture
*
* Returns @cpp true @ce if any of the
* @ref MaterialAttribute::SpecularTexture or
* @ref MaterialAttribute::SpecularGlossinessTexture attributes is
* present, @cpp false @ce otherwise.
* @see @ref hasGlossinessTexture(),
* @ref hasSpecularGlossinessTexture()
*/
bool hasSpecularTexture() const;
/**
* @brief Whether the material has a glossiness texture
*
* Returns @cpp true @ce if any of the
* @ref MaterialAttribute::GlossinessTexture or
* @ref MaterialAttribute::SpecularGlossinessTexture attributes is
* present, @cpp false @ce otherwise.
* @see @ref hasSpecularTexture(),
* @ref hasSpecularGlossinessTexture()
*/
bool hasGlossinessTexture() const;
/**
* @brief Whether the material has a combined specular/glossiness texture
*
* Returns @cpp true @ce if either the
* @ref MaterialAttribute::SpecularGlossinessTexture attribute is
* present or both @ref MaterialAttribute::SpecularTexture and
* @ref MaterialAttribute::GlossinessTexture are present, point to
* the same texture ID and @ref MaterialAttribute::GlossinessTextureSwizzle
* is set to @ref MaterialTextureSwizzle::A, and ddditionally
* @ref MaterialAttribute::SpecularTextureMatrix and
* @ref MaterialAttribute::GlossinessTextureMatrix are both either not
* present or have the same value, and
* @ref MaterialAttribute::SpecularTextureCoordinates and
* @ref MaterialAttribute::GlossinessTextureCoordinates 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 specularTexture(), @ref specularTextureMatrix() and
* @ref specularTextureCoordinates() return values common for both
* specular and glossiness texture, and the two are packed together
* with specular occupying the RGB channels and glossiness the alpha.
* @see @ref hasSpecularTexture(), @ref hasGlossinessTexture()
*/
bool hasSpecularGlossinessTexture() const;
/**
* @brief Whether the material has texture transformation
*
* Returns @cpp true @ce if any of the
* @ref MaterialAttribute::DiffuseTextureMatrix,
* @ref MaterialAttribute::SpecularTextureMatrix,
* @ref MaterialAttribute::GlossinessTextureMatrix,
* @ref MaterialAttribute::NormalTextureMatrix,
* @ref MaterialAttribute::OcclusionTextureMatrix,
* @ref MaterialAttribute::EmissiveTextureMatrix or
* @ref MaterialAttribute::TextureMatrix attributes is present,
* @cpp false @ce otherwise.
*/
bool hasTextureTransformation() const;
/**
* @brief Whether the material uses extra texture coordinate sets
*
* Returns @cpp true @ce if any of the
* @ref MaterialAttribute::DiffuseTextureCoordinates,
* @ref MaterialAttribute::SpecularTextureCoordinates,
* @ref MaterialAttribute::GlossinessTextureCoordinates,
* @ref MaterialAttribute::NormalTextureCoordinates,
* @ref MaterialAttribute::OcclusionTextureCoordinates,
* @ref MaterialAttribute::EmissiveTextureCoordinates or
* @ref MaterialAttribute::TextureCoordinates attributes is present and
* has a non-zero value, @cpp false @ce otherwise.
*/
bool hasTextureCoordinates() const;
/**
* @brief Base color
*
* Convenience access to the @ref MaterialAttribute::DiffuseColor
* attribute. If not present, the default is @cpp 0xffffffff_srgbaf @ce.
*
* If the material has @ref MaterialAttribute::DiffuseTexture, the
* color and texture is meant to be multiplied together.
*/
Color4 diffuseColor() const;
/**
* @brief Base color texture ID
*
* Available only if @ref MaterialAttribute::DiffuseTexture is
* present. Meant to be multiplied with @ref diffuseColor().
* @see @ref hasAttribute(), @ref AbstractImporter::texture()
*/
UnsignedInt diffuseTexture() const;
/**
* @brief Base color texture coordinate transformation matrix
*
* Convenience access to the @ref MaterialAttribute::DiffuseTextureMatrix
* / @ref MaterialAttribute::TextureMatrix attributes. If neither is
* present, the default is an identity matrix. Available only if the
* material has @ref MaterialAttribute::DiffuseTexture.
* @see @ref hasAttribute()
*/
Matrix3 diffuseTextureMatrix() const;
/**
* @brief Base color texture coordinate set
*
* Convenience access to the @ref MaterialAttribute::DiffuseTextureCoordinates
* / @ref MaterialAttribute::TextureCoordinates attributes. If neither is
* present, the default is @cpp 0 @ce. Available only if the material
* has @ref MaterialAttribute::DiffuseTexture.
* @see @ref hasAttribute()
*/
UnsignedInt diffuseTextureCoordinates() const;
/**
* @brief Specular color
*
* Convenience access to the @ref MaterialAttribute::SpecularColor
* attribute. If not present, the default is @cpp 0xffffff00_srgbaf @ce.
*
* If the material has a specular texture, the color and texture is
* meant to be multiplied together.
* @see @ref hasSpecularTexture()
*/
Color4 specularColor() const;
/**
* @brief Specular texture ID
*
* Available only if either @ref MaterialAttribute::SpecularTexture or
* @ref MaterialAttribute::SpecularGlossinessTexture is present. Meant
* to be multiplied with @ref specularColor().
* @see @ref hasSpecularTexture(), @ref AbstractImporter::texture()
*/
UnsignedInt specularTexture() const;
/**
* @brief Specular texture swizzle
*
* If @ref MaterialAttribute::SpecularGlossinessTexture is present,
* returns always @ref MaterialTextureSwizzle::RGB. Otherwise returns
* the @ref MaterialAttribute::SpecularTextureSwizzle attribute, or
* @ref MaterialTextureSwizzle::RGB if it's not present. Available only
* if the material has a specular texture.
* @see @ref hasSpecularTexture()
*/
MaterialTextureSwizzle specularTextureSwizzle() const;
/**
* @brief Specular texture coordinate transformation matrix
*
* Convenience access to the @ref MaterialAttribute::SpecularTextureMatrix
* / @ref MaterialAttribute::TextureMatrix attributes. If neither is
* present, the default is an identity matrix. Available only if the
* material has a specular texture.
* @see @ref hasSpecularTexture()
*/
Matrix3 specularTextureMatrix() const;
/**
* @brief Specular texture coordinate set
*
* Convenience access to the @ref MaterialAttribute::SpecularTextureCoordinates
* / @ref MaterialAttribute::TextureCoordinates attributes. If neither is
* present, the default is @cpp 0 @ce. Available only if the material
* has a specular texture.
* @see @ref hasSpecularTexture()
*/
UnsignedInt specularTextureCoordinates() const;
/**
* @brief Glossiness factor
*
* Convenience access to the @ref MaterialAttribute::Glossiness
* attribute. If not present, the default is @cpp 1.0f @ce.
*
* If the material has a glossiness texture, the factor and texture is
* meant to be multiplied together.
* @see @ref hasGlossinessTexture()
*/
Float glossiness() const;
/**
* @brief Glossiness texture ID
*
* Available only if either @ref MaterialAttribute::GlossinessTexture or
* @ref MaterialAttribute::SpecularGlossinessTexture is present. Meant
* to be multiplied with @ref glossiness().
* @see @ref hasGlossinessTexture(), @ref AbstractImporter::texture()
*/
UnsignedInt glossinessTexture() const;
/**
* @brief Glossiness texture swizzle
*
* If @ref MaterialAttribute::SpecularGlossinessTexture is present,
* returns always @ref MaterialTextureSwizzle::A. Otherwise returns the
* @ref MaterialAttribute::GlossinessTextureSwizzle attribute, or
* @ref MaterialTextureSwizzle::R if it's not present. Available only
* if the material has a glossiness texture.
* @see @ref hasGlossinessTexture()
*/
MaterialTextureSwizzle glossinessTextureSwizzle() const;
/**
* @brief Glossiness texture coordinate transformation matrix
*
* Convenience access to the @ref MaterialAttribute::GlossinessTextureMatrix
* / @ref MaterialAttribute::TextureMatrix attributes. If neither is
* present, the default is an identity matrix. Available only if the
* material has a glossiness texture.
* @see @ref hasGlossinessTexture()
*/
Matrix3 glossinessTextureMatrix() const;
/**
* @brief Glossiness texture coordinate set
*
* Convenience access to the @ref MaterialAttribute::GlossinessTextureCoordinates
* / @ref MaterialAttribute::TextureCoordinates attributes. If neither is
* present, the default is @cpp 0 @ce. Available only if the material
* has a glossiness texture.
* @see @ref hasGlossinessTexture()
*/
UnsignedInt glossinessTextureCoordinates() const;
/**
* @brief Normal texture ID
*
* Available only if @ref MaterialAttribute::NormalTexture is present.
* @see @ref hasAttribute(), @ref AbstractImporter::texture()
*/
UnsignedInt normalTexture() const;
/**
* @brief Normal texture swizzle
*
* Convenience access to the
* @ref MaterialAttribute::NormalTextureSwizzle attribute. If not
* present, the default is @ref MaterialTextureSwizzle::RGB. Available
* only if @ref MaterialAttribute::NormalTexture is present.
* @see @ref hasAttribute()
*/
MaterialTextureSwizzle normalTextureSwizzle() const;
/**
* @brief Normal texture coordinate transformation matrix
*
* Convenience access to the @ref MaterialAttribute::NormalTextureMatrix
* / @ref MaterialAttribute::TextureMatrix attributes. If neither is
* present, the default is an identity matrix. Available only if the
* material has @ref MaterialAttribute::NormalTexture.
* @see @ref hasAttribute()
*/
Matrix3 normalTextureMatrix() const;
/**
* @brief Normal texture coordinate set
*
* Convenience access to the @ref MaterialAttribute::NormalTextureCoordinates
* / @ref MaterialAttribute::TextureCoordinates attributes. If neither is
* present, the default is @cpp 0 @ce. Available only if the material
* has @ref MaterialAttribute::NormalTexture.
* @see @ref hasAttribute()
*/
UnsignedInt normalTextureCoordinates() const;
/**
* @brief Occlusion texture ID
*
* Available only if @ref MaterialAttribute::OcclusionTexture is present.
* @see @ref hasAttribute(), @ref AbstractImporter::texture()
*/
UnsignedInt occlusionTexture() const;
/**
* @brief Occlusion texture swizzle
*
* Convenience access to the
* @ref MaterialAttribute::OcclusionTextureSwizzle attribute. If not
* present, the default is @ref MaterialTextureSwizzle::R. Available
* only if @ref MaterialAttribute::OcclusionTexture is present.
* @see @ref hasAttribute()
*/
MaterialTextureSwizzle occlusionTextureSwizzle() const;
/**
* @brief Occlusion texture coordinate transformation matrix
*
* Convenience access to the @ref MaterialAttribute::OcclusionTextureMatrix
* / @ref MaterialAttribute::TextureMatrix attributes. If neither is
* present, the default is an identity matrix. Available only if the
* material has @ref MaterialAttribute::OcclusionTexture.
* @see @ref hasAttribute(), @ref AbstractImporter::texture()
*/
Matrix3 occlusionTextureMatrix() const;
/**
* @brief Occlusion texture coordinate set
*
* Convenience access to the @ref MaterialAttribute::OcclusionTextureCoordinates
* / @ref MaterialAttribute::TextureCoordinates attributes. If neither is
* present, the default is @cpp 0 @ce. Available only if the material
* has @ref MaterialAttribute::OcclusionTexture.
* @see @ref hasAttribute(), @ref AbstractImporter::texture()
*/
UnsignedInt occlusionTextureCoordinates() const;
/**
* @brief Emissive color
*
* Convenience access to the @ref MaterialAttribute::EmissiveColor
* attribute. If not present, the default is @cpp 0x000000_srgbf @ce
* (i.e, no emission).
*
* If the material has @ref MaterialAttribute::EmissiveTexture, the
* color and texture is meant to be multiplied together.
*/
Color3 emissiveColor() const;
/**
* @brief Emissive texture ID
*
* Available only if @ref MaterialAttribute::EmissiveTexture is present.
* Meant to be multiplied with @ref emissiveColor().
* @see @ref hasAttribute(), @ref AbstractImporter::texture()
*/
UnsignedInt emissiveTexture() const;
/* No EmissiveTextureSwizzle attribute right now (implicitly RGB) */
/**
* @brief Emissive texture coordinate transformation matrix
*
* Convenience access to the @ref MaterialAttribute::EmissiveTextureMatrix
* / @ref MaterialAttribute::TextureMatrix attributes. If neither is
* present, the default is an identity matrix. Available only if the
* material has @ref MaterialAttribute::EmissiveTexture.
* @see @ref hasAttribute(), @ref AbstractImporter::texture()
*/
Matrix3 emissiveTextureMatrix() const;
/**
* @brief Emissive texture coordinate set
*
* Convenience access to the @ref MaterialAttribute::EmissiveTextureCoordinates
* / @ref MaterialAttribute::TextureCoordinates attributes. If neither
* is present, the default is @cpp 0 @ce. Available only if the
* material has @ref MaterialAttribute::EmissiveTexture.
* @see @ref hasAttribute(), @ref AbstractImporter::texture()
*/
UnsignedInt emissiveTextureCoordinates() const;
/**
* @brief Common texture coordinate transformation matrix for all textures
*
* Convenience access to the @ref MaterialAttribute::TextureMatrix
* attribute. If not present, the default is an identity matrix. Note
* that the material may also define per-texture transformation using
* the @ref MaterialAttribute::DiffuseTextureMatrix,
* @ref MaterialAttribute::SpecularTextureMatrix,
* @ref MaterialAttribute::GlossinessTextureMatrix,
* @ref MaterialAttribute::NormalTextureMatrix,
* @ref MaterialAttribute::OcclusionTextureMatrix and
* @ref MaterialAttribute::EmissiveTextureMatrix attributes, which then
* take precedence over the common one.
* @see @ref hasAttribute(), @ref diffuseTextureMatrix(),
* @ref specularTextureMatrix(), @ref glossinessTextureMatrix(),
* @ref normalTextureMatrix(), @ref occlusionTextureMatrix(),
* @ref emissiveTextureMatrix()
*/
Matrix3 textureMatrix() const;
/**
* @brief Common texture coordinate set index for all textures
*
* Convenience access to the @ref MaterialAttribute::TextureCoordinates
* attribute. If not present, the default is @cpp 0 @ce. Note that the
* material may also define per-texture coordinate set using the
* @ref MaterialAttribute::DiffuseTextureCoordinates,
* @ref MaterialAttribute::SpecularTextureCoordinates,
* @ref MaterialAttribute::GlossinessTextureCoordinates,
* @ref MaterialAttribute::NormalTextureCoordinates,
* @ref MaterialAttribute::OcclusionTextureCoordinates and
* @ref MaterialAttribute::EmissiveTextureCoordinates attributes, which
* then take precedence over the common one.
* @see @ref hasAttribute(), @ref diffuseTextureCoordinates(),
* @ref specularTextureCoordinates(),
* @ref glossinessTextureCoordinates(),
* @ref normalTextureCoordinates(),
* @ref occlusionTextureCoordinates(),
* @ref emissiveTextureCoordinates()
*/
UnsignedInt textureCoordinates() const;
};
}}
#endif

29
src/Magnum/Trade/PhongMaterialData.cpp

@ -115,7 +115,7 @@ PhongMaterialData::Flags PhongMaterialData::flags() const {
flags |= Flag::AmbientTexture;
if(hasAttribute(MaterialAttribute::DiffuseTexture))
flags |= Flag::DiffuseTexture;
if(hasAttribute(MaterialAttribute::SpecularTexture))
if(hasSpecularTexture())
flags |= Flag::SpecularTexture;
if(hasAttribute(MaterialAttribute::NormalTexture))
flags |= Flag::NormalTexture;
@ -129,6 +129,11 @@ PhongMaterialData::Flags PhongMaterialData::flags() const {
CORRADE_IGNORE_DEPRECATED_POP
#endif
bool PhongMaterialData::hasSpecularTexture() const {
return hasAttribute(MaterialAttribute::SpecularTexture) ||
hasAttribute(MaterialAttribute::SpecularGlossinessTexture);
}
bool PhongMaterialData::hasTextureTransformation() const {
return hasAttribute(MaterialAttribute::AmbientTextureMatrix) ||
hasAttribute(MaterialAttribute::DiffuseTextureMatrix) ||
@ -195,15 +200,25 @@ UnsignedInt PhongMaterialData::diffuseTextureCoordinates() const {
}
Color4 PhongMaterialData::specularColor() const {
return attributeOr(MaterialAttribute::SpecularColor, 0xffffffff_rgbaf);
return attributeOr(MaterialAttribute::SpecularColor, 0xffffff00_rgbaf);
}
UnsignedInt PhongMaterialData::specularTexture() const {
if(Containers::Optional<UnsignedInt> value = tryAttribute<UnsignedInt>(MaterialAttribute::SpecularGlossinessTexture))
return *value;
return attribute<UnsignedInt>(MaterialAttribute::SpecularTexture);
}
MaterialTextureSwizzle PhongMaterialData::specularTextureSwizzle() const {
CORRADE_ASSERT(hasSpecularTexture(),
"Trade::PhongMaterialData::specularTextureSwizzle(): the material doesn't have a specular texture", {});
if(hasAttribute(MaterialAttribute::SpecularGlossinessTexture))
return MaterialTextureSwizzle::RGB;
return attributeOr(MaterialAttribute::SpecularTextureSwizzle, MaterialTextureSwizzle::RGB);
}
Matrix3 PhongMaterialData::specularTextureMatrix() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::SpecularTexture),
CORRADE_ASSERT(hasSpecularTexture(),
"Trade::PhongMaterialData::specularTextureMatrix(): the material doesn't have a specular texture", {});
if(Containers::Optional<Matrix3> set = tryAttribute<Matrix3>(MaterialAttribute::SpecularTextureMatrix))
return *set;
@ -211,7 +226,7 @@ Matrix3 PhongMaterialData::specularTextureMatrix() const {
}
UnsignedInt PhongMaterialData::specularTextureCoordinates() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::SpecularTexture),
CORRADE_ASSERT(hasSpecularTexture(),
"Trade::PhongMaterialData::specularTextureCoordinates(): the material doesn't have a specular texture", {});
if(Containers::Optional<UnsignedInt> set = tryAttribute<UnsignedInt>(MaterialAttribute::SpecularTextureCoordinates))
return *set;
@ -222,6 +237,12 @@ UnsignedInt PhongMaterialData::normalTexture() const {
return attribute<UnsignedInt>(MaterialAttribute::NormalTexture);
}
MaterialTextureSwizzle PhongMaterialData::normalTextureSwizzle() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::NormalTexture),
"Trade::PhongMaterialData::normalTextureSwizzle(): the material doesn't have a normal texture", {});
return attributeOr(MaterialAttribute::NormalTextureSwizzle, MaterialTextureSwizzle::RGB);
}
Matrix3 PhongMaterialData::normalTextureMatrix() const {
CORRADE_ASSERT(hasAttribute(MaterialAttribute::NormalTexture),
"Trade::PhongMaterialData::normalTextureMatrix(): the material doesn't have a normal texture", {});

60
src/Magnum/Trade/PhongMaterialData.h

@ -37,7 +37,8 @@ namespace Magnum { namespace Trade {
/**
@brief Phong material data
@see @ref AbstractImporter::material()
@see @ref AbstractImporter::material(), @ref PbrMetallicRoughnessMaterialData,
@ref PbrSpecularGlossinessMaterialData
*/
class MAGNUM_TRADE_EXPORT PhongMaterialData: public MaterialData {
public:
@ -227,6 +228,17 @@ class MAGNUM_TRADE_EXPORT PhongMaterialData: public MaterialData {
CORRADE_IGNORE_DEPRECATED_POP
#endif
/**
* @brief Whether the material has a specular texture
* @m_since_latest
*
* Returns @cpp true @ce if any of the
* @ref MaterialAttribute::SpecularTexture or
* @ref MaterialAttribute::SpecularGlossinessTexture attributes is
* present, @cpp false @ce otherwise.
*/
bool hasSpecularTexture() const;
/**
* @brief Whether the material has texture transformation
* @m_since_latest
@ -390,23 +402,37 @@ class MAGNUM_TRADE_EXPORT PhongMaterialData: public MaterialData {
* @brief Specular color
*
* Convenience access to the @ref MaterialAttribute::SpecularColor
* attribute. If not present, the default is @cpp 0xffffffff_rgbaf @ce.
* attribute. If not present, the default is @cpp 0xffffff00_rgbaf @ce.
*
* If the material has @ref MaterialAttribute::SpecularTexture, the
* color and texture is meant to be multiplied together.
* @see @ref hasAttribute()
* If the material has a specular texture, the color and texture is
* meant to be multiplied together.
* @see @ref hasSpecularTexture()
*/
Color4 specularColor() const;
/**
* @brief Specular texture ID
*
* Available only if @ref MaterialAttribute::SpecularTexture is
* present. Meant to be multiplied with @ref specularColor().
* Available only if either @ref MaterialAttribute::SpecularTexture or
* @ref MaterialAttribute::SpecularGlossinessTexture is present. Meant
* to be multiplied with @ref specularColor().
* @see @ref hasAttribute(), @ref AbstractImporter::texture()
*/
UnsignedInt specularTexture() const;
/**
* @brief Specular texture swizzle
* @m_since_latest
*
* If @ref MaterialAttribute::SpecularGlossinessTexture is present,
* returns always @ref MaterialTextureSwizzle::RGB. Otherwise returns
* the @ref MaterialAttribute::SpecularTextureSwizzle attribute, or
* @ref MaterialTextureSwizzle::RGB if it's not present. Available only
* if the material has a specular texture.
* @see @ref hasSpecularTexture()
*/
MaterialTextureSwizzle specularTextureSwizzle() const;
/**
* @brief Specular texture coordinate transformation matrix
* @m_since_latest
@ -414,8 +440,8 @@ class MAGNUM_TRADE_EXPORT PhongMaterialData: public MaterialData {
* Convenience access to the @ref MaterialAttribute::SpecularTextureMatrix
* / @ref MaterialAttribute::TextureMatrix attributes. If neither is
* present, the default is an identity matrix. Available only if the
* material has @ref MaterialAttribute::SpecularTexture.
* @see @ref hasAttribute()
* material has a specular texture.
* @see @ref hasSpecularTexture()
*/
Matrix3 specularTextureMatrix() const;
@ -426,8 +452,8 @@ class MAGNUM_TRADE_EXPORT PhongMaterialData: public MaterialData {
* Convenience access to the @ref MaterialAttribute::SpecularTextureCoordinates
* / @ref MaterialAttribute::TextureCoordinates attributes. If neither
* is present, the default is @cpp 0 @ce. Available only if the
* material has @ref MaterialAttribute::SpecularTexture.
* @see @ref hasAttribute()
* material has a specular texture.
* @see @ref hasSpecularTexture()
*/
UnsignedInt specularTextureCoordinates() const;
@ -451,6 +477,18 @@ class MAGNUM_TRADE_EXPORT PhongMaterialData: public MaterialData {
*/
UnsignedInt normalTexture() const;
/**
* @brief Normal texture swizzle
* @m_since_latest
*
* Convenience access to the
* @ref MaterialAttribute::NormalTextureSwizzle attribute. If not
* present, the default is @ref MaterialTextureSwizzle::RGB. Available
* only if @ref MaterialAttribute::NormalTexture is present.
* @see @ref hasAttribute()
*/
MaterialTextureSwizzle normalTextureSwizzle() const;
/**
* @brief Normal texture coordinate transformation matrix
* @m_since_latest

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

File diff suppressed because it is too large Load Diff

2
src/Magnum/Trade/Trade.h

@ -90,6 +90,8 @@ class MeshObjectData2D;
class MeshObjectData3D;
class ObjectData2D;
class ObjectData3D;
class PbrMetallicRoughnessMaterialData;
class PbrSpecularGlossinessMaterialData;
class PhongMaterialData;
class TextureData;
class SceneData;

Loading…
Cancel
Save