Merge pull request #4786 from Beilinson/refactor/KHR_material_specular

Removed KHR_materials_pbrSpecularGlossiness, added KHR_materials_specular
pull/5087/head^2
Kim Kulling 2023-05-23 12:44:47 +02:00 committed by GitHub
commit 9f593d70b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 131 additions and 16 deletions

View File

@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* glTF Extensions Support: * glTF Extensions Support:
* KHR_materials_pbrSpecularGlossiness full * KHR_materials_pbrSpecularGlossiness full
* KHR_materials_specular full
* KHR_materials_unlit full * KHR_materials_unlit full
* KHR_lights_punctual full * KHR_lights_punctual full
* KHR_materials_sheen full * KHR_materials_sheen full
@ -710,6 +711,7 @@ const vec4 defaultBaseColor = { 1, 1, 1, 1 };
const vec3 defaultEmissiveFactor = { 0, 0, 0 }; const vec3 defaultEmissiveFactor = { 0, 0, 0 };
const vec4 defaultDiffuseFactor = { 1, 1, 1, 1 }; const vec4 defaultDiffuseFactor = { 1, 1, 1, 1 };
const vec3 defaultSpecularFactor = { 1, 1, 1 }; const vec3 defaultSpecularFactor = { 1, 1, 1 };
const vec3 defaultSpecularColorFactor = { 0, 0, 0 };
const vec3 defaultSheenFactor = { 0, 0, 0 }; const vec3 defaultSheenFactor = { 0, 0, 0 };
const vec3 defaultAttenuationColor = { 1, 1, 1 }; const vec3 defaultAttenuationColor = { 1, 1, 1 };
@ -753,6 +755,16 @@ struct PbrSpecularGlossiness {
void SetDefaults(); void SetDefaults();
}; };
struct MaterialSpecular {
float specularFactor;
vec3 specularColorFactor;
TextureInfo specularTexture;
TextureInfo specularColorTexture;
MaterialSpecular() { SetDefaults(); }
void SetDefaults();
};
struct MaterialSheen { struct MaterialSheen {
vec3 sheenColorFactor; vec3 sheenColorFactor;
float sheenRoughnessFactor; float sheenRoughnessFactor;
@ -817,6 +829,9 @@ struct Material : public Object {
//extension: KHR_materials_pbrSpecularGlossiness //extension: KHR_materials_pbrSpecularGlossiness
Nullable<PbrSpecularGlossiness> pbrSpecularGlossiness; Nullable<PbrSpecularGlossiness> pbrSpecularGlossiness;
//extension: KHR_materials_specular
Nullable<MaterialSpecular> materialSpecular;
//extension: KHR_materials_sheen //extension: KHR_materials_sheen
Nullable<MaterialSheen> materialSheen; Nullable<MaterialSheen> materialSheen;
@ -1099,6 +1114,7 @@ public:
//! Keeps info about the enabled extensions //! Keeps info about the enabled extensions
struct Extensions { struct Extensions {
bool KHR_materials_pbrSpecularGlossiness; bool KHR_materials_pbrSpecularGlossiness;
bool KHR_materials_specular;
bool KHR_materials_unlit; bool KHR_materials_unlit;
bool KHR_lights_punctual; bool KHR_lights_punctual;
bool KHR_texture_transform; bool KHR_texture_transform;
@ -1113,13 +1129,14 @@ public:
bool KHR_texture_basisu; bool KHR_texture_basisu;
Extensions() : Extensions() :
KHR_materials_pbrSpecularGlossiness(false), KHR_materials_pbrSpecularGlossiness(false),
KHR_materials_unlit(false), KHR_materials_specular(false),
KHR_lights_punctual(false), KHR_materials_unlit(false),
KHR_texture_transform(false), KHR_lights_punctual(false),
KHR_materials_sheen(false), KHR_texture_transform(false),
KHR_materials_clearcoat(false), KHR_materials_sheen(false),
KHR_materials_transmission(false), KHR_materials_clearcoat(false),
KHR_materials_transmission(false),
KHR_materials_volume(false), KHR_materials_volume(false),
KHR_materials_ior(false), KHR_materials_ior(false),
KHR_materials_emissive_strength(false), KHR_materials_emissive_strength(false),

View File

@ -1263,6 +1263,19 @@ inline void Material::Read(Value &material, Asset &r) {
this->pbrSpecularGlossiness = Nullable<PbrSpecularGlossiness>(pbrSG); this->pbrSpecularGlossiness = Nullable<PbrSpecularGlossiness>(pbrSG);
} }
} }
if (r.extensionsUsed.KHR_materials_specular) {
if (Value *curMatSpecular = FindObject(*extensions, "KHR_materials_specular")) {
MaterialSpecular specular;
ReadMember(*curMatSpecular, "specularFactor", specular.specularFactor);
ReadTextureProperty(r, *curMatSpecular, "specularTexture", specular.specularTexture);
ReadMember(*curMatSpecular, "specularColorFactor", specular.specularColorFactor);
ReadTextureProperty(r, *curMatSpecular, "specularColorTexture", specular.specularColorTexture);
this->materialSpecular = Nullable<MaterialSpecular>(specular);
}
}
// Extension KHR_texture_transform is handled in ReadTextureProperty // Extension KHR_texture_transform is handled in ReadTextureProperty
@ -1361,6 +1374,12 @@ inline void PbrSpecularGlossiness::SetDefaults() {
glossinessFactor = 1.0f; glossinessFactor = 1.0f;
} }
inline void MaterialSpecular::SetDefaults() {
//KHR_materials_specular properties
SetVector(specularColorFactor, defaultSpecularColorFactor);
specularFactor = 0.f;
}
inline void MaterialSheen::SetDefaults() { inline void MaterialSheen::SetDefaults() {
//KHR_materials_sheen properties //KHR_materials_sheen properties
SetVector(sheenColorFactor, defaultSheenFactor); SetVector(sheenColorFactor, defaultSheenFactor);
@ -2047,6 +2066,7 @@ inline void Asset::ReadExtensionsUsed(Document &doc) {
} }
CHECK_EXT(KHR_materials_pbrSpecularGlossiness); CHECK_EXT(KHR_materials_pbrSpecularGlossiness);
CHECK_EXT(KHR_materials_specular);
CHECK_EXT(KHR_materials_unlit); CHECK_EXT(KHR_materials_unlit);
CHECK_EXT(KHR_lights_punctual); CHECK_EXT(KHR_lights_punctual);
CHECK_EXT(KHR_texture_transform); CHECK_EXT(KHR_texture_transform);

View File

@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* glTF Extensions Support: * glTF Extensions Support:
* KHR_materials_pbrSpecularGlossiness: full * KHR_materials_pbrSpecularGlossiness: full
* KHR_materials_specular: full
* KHR_materials_unlit: full * KHR_materials_unlit: full
* KHR_materials_sheen: full * KHR_materials_sheen: full
* KHR_materials_clearcoat: full * KHR_materials_clearcoat: full

View File

@ -418,6 +418,26 @@ namespace glTF2 {
exts.AddMember("KHR_materials_unlit", unlit, w.mAl); exts.AddMember("KHR_materials_unlit", unlit, w.mAl);
} }
if (m.materialSpecular.isPresent) {
Value materialSpecular(rapidjson::Type::kObjectType);
materialSpecular.SetObject();
MaterialSpecular &specular = m.materialSpecular.value;
if (specular.specularFactor != 0.0f) {
WriteFloat(materialSpecular, specular.specularFactor, "specularFactor", w.mAl);
WriteTex(materialSpecular, specular.specularTexture, "specularTexture", w.mAl);
}
if (specular.specularColorFactor[0] != defaultSpecularColorFactor[0] && specular.specularColorFactor[1] != defaultSpecularColorFactor[1] && specular.specularColorFactor[2] != defaultSpecularColorFactor[2]) {
WriteVec(materialSpecular, specular.specularColorFactor, "specularColorFactor", w.mAl);
WriteTex(materialSpecular, specular.specularColorTexture, "specularColorTexture", w.mAl);
}
if (!materialSpecular.ObjectEmpty()) {
exts.AddMember("KHR_materials_specular", materialSpecular, w.mAl);
}
}
if (m.materialSheen.isPresent) { if (m.materialSheen.isPresent) {
Value materialSheen(rapidjson::Type::kObjectType); Value materialSheen(rapidjson::Type::kObjectType);
@ -550,7 +570,7 @@ namespace glTF2 {
inline void Write(Value& obj, Mesh& m, AssetWriter& w) inline void Write(Value& obj, Mesh& m, AssetWriter& w)
{ {
/****************** Primitives *******************/ /****************** Primitives *******************/
Value primitives; Value primitives;
primitives.SetArray(); primitives.SetArray();
primitives.Reserve(unsigned(m.primitives.size()), w.mAl); primitives.Reserve(unsigned(m.primitives.size()), w.mAl);
@ -929,6 +949,10 @@ namespace glTF2 {
exts.PushBack(StringRef("KHR_materials_unlit"), mAl); exts.PushBack(StringRef("KHR_materials_unlit"), mAl);
} }
if (this->mAsset.extensionsUsed.KHR_materials_specular) {
exts.PushBack(StringRef("KHR_materials_specular"), mAl);
}
if (this->mAsset.extensionsUsed.KHR_materials_sheen) { if (this->mAsset.extensionsUsed.KHR_materials_sheen) {
exts.PushBack(StringRef("KHR_materials_sheen"), mAl); exts.PushBack(StringRef("KHR_materials_sheen"), mAl);
} }
@ -980,7 +1004,7 @@ namespace glTF2 {
if (d.mObjs.empty()) return; if (d.mObjs.empty()) return;
Value* container = &mDoc; Value* container = &mDoc;
const char* context = "Document"; const char* context = "Document";
if (d.mExtId) { if (d.mExtId) {
Value* exts = FindObject(mDoc, "extensions"); Value* exts = FindObject(mDoc, "extensions");

View File

@ -640,11 +640,10 @@ aiReturn glTF2Exporter::GetMatColor(const aiMaterial &mat, vec3 &prop, const cha
return result; return result;
} }
// This extension has been deprecated, only export with the specific flag enabled, defaults to false. Uses KHR_material_specular default.
bool glTF2Exporter::GetMatSpecGloss(const aiMaterial &mat, glTF2::PbrSpecularGlossiness &pbrSG) { bool glTF2Exporter::GetMatSpecGloss(const aiMaterial &mat, glTF2::PbrSpecularGlossiness &pbrSG) {
bool result = false; bool result = false;
// If has Glossiness, a Specular Color or Specular Texture, use the KHR_materials_pbrSpecularGlossiness extension // If has Glossiness, a Specular Color or Specular Texture, use the KHR_materials_pbrSpecularGlossiness extension
// NOTE: This extension is being considered for deprecation (Dec 2020), may be replaced by KHR_material_specular
if (mat.Get(AI_MATKEY_GLOSSINESS_FACTOR, pbrSG.glossinessFactor) == AI_SUCCESS) { if (mat.Get(AI_MATKEY_GLOSSINESS_FACTOR, pbrSG.glossinessFactor) == AI_SUCCESS) {
result = true; result = true;
} else { } else {
@ -674,6 +673,25 @@ bool glTF2Exporter::GetMatSpecGloss(const aiMaterial &mat, glTF2::PbrSpecularGlo
return result; return result;
} }
bool glTF2Exporter::GetMatSpecular(const aiMaterial &mat, glTF2::MaterialSpecular &specular) {
// Specular requires either/or, default factors of zero disables specular, so do not export
if (GetMatColor(mat, specular.specularColorFactor, AI_MATKEY_COLOR_SPECULAR) != AI_SUCCESS || mat.Get(AI_MATKEY_SPECULAR_FACTOR, specular.specularFactor) != AI_SUCCESS) {
return false;
}
// The spec states that the default is 1.0 and [1.0, 1.0, 1.0]. We if both are 0, which should disable specular. Otherwise, if one is 0, set to 1.0
const bool colorFactorIsZero = specular.specularColorFactor[0] == defaultSpecularColorFactor[0] && specular.specularColorFactor[1] == defaultSpecularColorFactor[1] && specular.specularColorFactor[2] == defaultSpecularColorFactor[2];
if (specular.specularFactor == 0.0f && colorFactorIsZero) {
return false;
} else if (specular.specularFactor == 0.0f) {
specular.specularFactor = 1.0f;
} else if (colorFactorIsZero) {
specular.specularColorFactor[0] = specular.specularColorFactor[1] = specular.specularColorFactor[2] = 1.0f;
}
GetMatTex(mat, specular.specularColorTexture, aiTextureType_SPECULAR);
GetMatTex(mat, specular.specularTexture, aiTextureType_SPECULAR);
return true;
}
bool glTF2Exporter::GetMatSheen(const aiMaterial &mat, glTF2::MaterialSheen &sheen) { bool glTF2Exporter::GetMatSheen(const aiMaterial &mat, glTF2::MaterialSheen &sheen) {
// Return true if got any valid Sheen properties or textures // Return true if got any valid Sheen properties or textures
if (GetMatColor(mat, sheen.sheenColorFactor, AI_MATKEY_SHEEN_COLOR_FACTOR) != aiReturn_SUCCESS) { if (GetMatColor(mat, sheen.sheenColorFactor, AI_MATKEY_SHEEN_COLOR_FACTOR) != aiReturn_SUCCESS) {
@ -818,9 +836,9 @@ void glTF2Exporter::ExportMaterials() {
m->alphaMode = alphaMode.C_Str(); m->alphaMode = alphaMode.C_Str();
} }
{ // This extension has been deprecated, only export with the specific flag enabled, defaults to false. Uses KHR_material_specular default.
if (mProperties->GetPropertyBool(AI_CONFIG_USE_GLTF_PBR_SPECULAR_GLOSSINESS)) {
// KHR_materials_pbrSpecularGlossiness extension // KHR_materials_pbrSpecularGlossiness extension
// NOTE: This extension is being considered for deprecation (Dec 2020)
PbrSpecularGlossiness pbrSG; PbrSpecularGlossiness pbrSG;
if (GetMatSpecGloss(mat, pbrSG)) { if (GetMatSpecGloss(mat, pbrSG)) {
mAsset->extensionsUsed.KHR_materials_pbrSpecularGlossiness = true; mAsset->extensionsUsed.KHR_materials_pbrSpecularGlossiness = true;
@ -837,7 +855,12 @@ void glTF2Exporter::ExportMaterials() {
} else { } else {
// These extensions are not compatible with KHR_materials_unlit or KHR_materials_pbrSpecularGlossiness // These extensions are not compatible with KHR_materials_unlit or KHR_materials_pbrSpecularGlossiness
if (!m->pbrSpecularGlossiness.isPresent) { if (!m->pbrSpecularGlossiness.isPresent) {
// Sheen MaterialSpecular specular;
if (GetMatSpecular(mat, specular)) {
mAsset->extensionsUsed.KHR_materials_specular = true;
m->materialSpecular = Nullable<MaterialSpecular>(specular);
}
MaterialSheen sheen; MaterialSheen sheen;
if (GetMatSheen(mat, sheen)) { if (GetMatSheen(mat, sheen)) {
mAsset->extensionsUsed.KHR_materials_sheen = true; mAsset->extensionsUsed.KHR_materials_sheen = true;

View File

@ -76,6 +76,7 @@ struct OcclusionTextureInfo;
struct Node; struct Node;
struct Texture; struct Texture;
struct PbrSpecularGlossiness; struct PbrSpecularGlossiness;
struct MaterialSpecular;
struct MaterialSheen; struct MaterialSheen;
struct MaterialClearcoat; struct MaterialClearcoat;
struct MaterialTransmission; struct MaterialTransmission;
@ -117,6 +118,7 @@ protected:
aiReturn GetMatColor(const aiMaterial &mat, glTF2::vec4 &prop, const char *propName, int type, int idx) const; aiReturn GetMatColor(const aiMaterial &mat, glTF2::vec4 &prop, const char *propName, int type, int idx) const;
aiReturn GetMatColor(const aiMaterial &mat, glTF2::vec3 &prop, const char *propName, int type, int idx) const; aiReturn GetMatColor(const aiMaterial &mat, glTF2::vec3 &prop, const char *propName, int type, int idx) const;
bool GetMatSpecGloss(const aiMaterial &mat, glTF2::PbrSpecularGlossiness &pbrSG); bool GetMatSpecGloss(const aiMaterial &mat, glTF2::PbrSpecularGlossiness &pbrSG);
bool GetMatSpecular(const aiMaterial &mat, glTF2::MaterialSpecular &specular);
bool GetMatSheen(const aiMaterial &mat, glTF2::MaterialSheen &sheen); bool GetMatSheen(const aiMaterial &mat, glTF2::MaterialSheen &sheen);
bool GetMatClearcoat(const aiMaterial &mat, glTF2::MaterialClearcoat &clearcoat); bool GetMatClearcoat(const aiMaterial &mat, glTF2::MaterialClearcoat &clearcoat);
bool GetMatTransmission(const aiMaterial &mat, glTF2::MaterialTransmission &transmission); bool GetMatTransmission(const aiMaterial &mat, glTF2::MaterialTransmission &transmission);

View File

@ -278,8 +278,19 @@ static aiMaterial *ImportMaterial(std::vector<int> &embeddedTexIdxs, Asset &r, M
aimat->AddProperty(&alphaMode, AI_MATKEY_GLTF_ALPHAMODE); aimat->AddProperty(&alphaMode, AI_MATKEY_GLTF_ALPHAMODE);
aimat->AddProperty(&mat.alphaCutoff, 1, AI_MATKEY_GLTF_ALPHACUTOFF); aimat->AddProperty(&mat.alphaCutoff, 1, AI_MATKEY_GLTF_ALPHACUTOFF);
// KHR_materials_specular
if (mat.materialSpecular.isPresent) {
MaterialSpecular &specular = mat.materialSpecular.value;
// Default values of zero disables Specular
if (std::memcmp(specular.specularColorFactor, defaultSpecularColorFactor, sizeof(glTFCommon::vec3)) != 0 || specular.specularFactor != 0.0f) {
SetMaterialColorProperty(r, specular.specularColorFactor, aimat, AI_MATKEY_COLOR_SPECULAR);
aimat->AddProperty(&specular.specularFactor, 1, AI_MATKEY_SPECULAR_FACTOR);
SetMaterialTextureProperty(embeddedTexIdxs, r, specular.specularTexture, aimat, aiTextureType_SPECULAR);
SetMaterialTextureProperty(embeddedTexIdxs, r, specular.specularColorTexture, aimat, aiTextureType_SPECULAR);
}
}
// pbrSpecularGlossiness // pbrSpecularGlossiness
if (mat.pbrSpecularGlossiness.isPresent) { else if (mat.pbrSpecularGlossiness.isPresent) {
PbrSpecularGlossiness &pbrSG = mat.pbrSpecularGlossiness.value; PbrSpecularGlossiness &pbrSG = mat.pbrSpecularGlossiness.value;
SetMaterialColorProperty(r, pbrSG.diffuseFactor, aimat, AI_MATKEY_COLOR_DIFFUSE); SetMaterialColorProperty(r, pbrSG.diffuseFactor, aimat, AI_MATKEY_COLOR_DIFFUSE);

View File

@ -1065,6 +1065,17 @@ enum aiComponent
*/ */
#define AI_CONFIG_EXPORT_POINT_CLOUDS "EXPORT_POINT_CLOUDS" #define AI_CONFIG_EXPORT_POINT_CLOUDS "EXPORT_POINT_CLOUDS"
/** @brief Specifies whether to use the deprecated KHR_materials_pbrSpecularGlossiness extension
*
* When this flag is undefined any material with specularity will use the new KHR_materials_specular
* extension. Enabling this flag will revert to the deprecated extension. Note that exporting
* KHR_materials_pbrSpecularGlossiness with extensions other than KHR_materials_unlit is unsupported,
* including the basic pbrMetallicRoughness spec.
*
* Property type: Bool. Default value: false.
*/
#define AI_CONFIG_USE_GLTF_PBR_SPECULAR_GLOSSINESS "USE_GLTF_PBR_SPECULAR_GLOSSINESS"
/** /**
* @brief Specifies the blob name, assimp uses for exporting. * @brief Specifies the blob name, assimp uses for exporting.
* *

View File

@ -219,8 +219,14 @@ TEST_F(utglTF2ImportExport, importglTF2AndExport_KHR_materials_pbrSpecularGlossi
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/BoxTextured.gltf", const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/BoxTextured.gltf",
aiProcess_ValidateDataStructure); aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene); EXPECT_NE(nullptr, scene);
// Export
// Export with specular glossiness disabled
EXPECT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "glb2", ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/BoxTextured_out.glb")); EXPECT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "glb2", ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/BoxTextured_out.glb"));
// Export with specular glossiness enabled
ExportProperties props;
props.SetPropertyBool(AI_CONFIG_USE_GLTF_PBR_SPECULAR_GLOSSINESS, true);
EXPECT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "glb2", ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/BoxTextured_out.glb", 0, &props));
// And re-import // And re-import
EXPECT_TRUE(importerMatTest(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/BoxTextured_out.glb", true)); EXPECT_TRUE(importerMatTest(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/BoxTextured_out.glb", true));