ソースを参照

Merge branch 'master' into FixSkinnedWeightsAfterVertexRemappingOptimization

Kim Kulling 2 年 前
コミット
17c1a9125f

+ 1 - 1
code/AssetLib/X/XFileImporter.cpp

@@ -578,7 +578,7 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, std::vector<XFile::Materi
                 aiString name;
                 pScene->mMaterials[b]->Get( AI_MATKEY_NAME, name);
                 if( strcmp( name.C_Str(), oldMat.mName.data()) == 0 ) {
-                    oldMat.sceneIndex = a;
+                    oldMat.sceneIndex = b;
                     break;
                 }
             }

+ 24 - 7
code/AssetLib/glTF2/glTF2Asset.h

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

+ 20 - 0
code/AssetLib/glTF2/glTF2Asset.inl

@@ -1263,6 +1263,19 @@ inline void Material::Read(Value &material, Asset &r) {
                 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
 
@@ -1361,6 +1374,12 @@ inline void PbrSpecularGlossiness::SetDefaults() {
     glossinessFactor = 1.0f;
 }
 
+inline void MaterialSpecular::SetDefaults() {
+    //KHR_materials_specular properties
+    SetVector(specularColorFactor, defaultSpecularColorFactor);
+    specularFactor = 0.f;
+}
+
 inline void MaterialSheen::SetDefaults() {
     //KHR_materials_sheen properties
     SetVector(sheenColorFactor, defaultSheenFactor);
@@ -2047,6 +2066,7 @@ inline void Asset::ReadExtensionsUsed(Document &doc) {
     }
 
     CHECK_EXT(KHR_materials_pbrSpecularGlossiness);
+    CHECK_EXT(KHR_materials_specular);
     CHECK_EXT(KHR_materials_unlit);
     CHECK_EXT(KHR_lights_punctual);
     CHECK_EXT(KHR_texture_transform);

+ 1 - 0
code/AssetLib/glTF2/glTF2AssetWriter.h

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

+ 26 - 2
code/AssetLib/glTF2/glTF2AssetWriter.inl

@@ -418,6 +418,26 @@ namespace glTF2 {
           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) {
             Value materialSheen(rapidjson::Type::kObjectType);
 
@@ -550,7 +570,7 @@ namespace glTF2 {
 
     inline void Write(Value& obj, Mesh& m, AssetWriter& w)
     {
-		/****************** Primitives *******************/
+        /****************** Primitives *******************/
         Value primitives;
         primitives.SetArray();
         primitives.Reserve(unsigned(m.primitives.size()), w.mAl);
@@ -929,6 +949,10 @@ namespace glTF2 {
               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) {
                 exts.PushBack(StringRef("KHR_materials_sheen"), mAl);
             }
@@ -980,7 +1004,7 @@ namespace glTF2 {
         if (d.mObjs.empty()) return;
 
         Value* container = &mDoc;
-		const char* context = "Document";
+        const char* context = "Document";
 
         if (d.mExtId) {
             Value* exts = FindObject(mDoc, "extensions");

+ 28 - 5
code/AssetLib/glTF2/glTF2Exporter.cpp

@@ -640,11 +640,10 @@ aiReturn glTF2Exporter::GetMatColor(const aiMaterial &mat, vec3 &prop, const cha
     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 result = false;
     // 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) {
         result = true;
     } else {
@@ -674,6 +673,25 @@ bool glTF2Exporter::GetMatSpecGloss(const aiMaterial &mat, glTF2::PbrSpecularGlo
     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) {
     // Return true if got any valid Sheen properties or textures
     if (GetMatColor(mat, sheen.sheenColorFactor, AI_MATKEY_SHEEN_COLOR_FACTOR) != aiReturn_SUCCESS) {
@@ -818,9 +836,9 @@ void glTF2Exporter::ExportMaterials() {
             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
-            // NOTE: This extension is being considered for deprecation (Dec 2020)
             PbrSpecularGlossiness pbrSG;
             if (GetMatSpecGloss(mat, pbrSG)) {
                 mAsset->extensionsUsed.KHR_materials_pbrSpecularGlossiness = true;
@@ -837,7 +855,12 @@ void glTF2Exporter::ExportMaterials() {
         } else {
             // These extensions are not compatible with KHR_materials_unlit or KHR_materials_pbrSpecularGlossiness
             if (!m->pbrSpecularGlossiness.isPresent) {
-                // Sheen
+                MaterialSpecular specular;
+                if (GetMatSpecular(mat, specular)) {
+                    mAsset->extensionsUsed.KHR_materials_specular = true;
+                    m->materialSpecular = Nullable<MaterialSpecular>(specular);
+                }
+
                 MaterialSheen sheen;
                 if (GetMatSheen(mat, sheen)) {
                     mAsset->extensionsUsed.KHR_materials_sheen = true;

+ 2 - 0
code/AssetLib/glTF2/glTF2Exporter.h

@@ -76,6 +76,7 @@ struct OcclusionTextureInfo;
 struct Node;
 struct Texture;
 struct PbrSpecularGlossiness;
+struct MaterialSpecular;
 struct MaterialSheen;
 struct MaterialClearcoat;
 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::vec3 &prop, const char *propName, int type, int idx) const;
     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 GetMatClearcoat(const aiMaterial &mat, glTF2::MaterialClearcoat &clearcoat);
     bool GetMatTransmission(const aiMaterial &mat, glTF2::MaterialTransmission &transmission);

+ 12 - 1
code/AssetLib/glTF2/glTF2Importer.cpp

@@ -278,8 +278,19 @@ static aiMaterial *ImportMaterial(std::vector<int> &embeddedTexIdxs, Asset &r, M
         aimat->AddProperty(&alphaMode, AI_MATKEY_GLTF_ALPHAMODE);
         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
-        if (mat.pbrSpecularGlossiness.isPresent) {
+        else if (mat.pbrSpecularGlossiness.isPresent) {
             PbrSpecularGlossiness &pbrSG = mat.pbrSpecularGlossiness.value;
 
             SetMaterialColorProperty(r, pbrSG.diffuseFactor, aimat, AI_MATKEY_COLOR_DIFFUSE);

+ 1 - 2
code/CMakeLists.txt

@@ -1200,7 +1200,6 @@ IF (ASSIMP_WARNINGS_AS_ERRORS)
 
     IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) # clang-cl
       TARGET_COMPILE_OPTIONS(assimp PRIVATE -Wall -Werror
-        -Wno-unused-function
         -Wno-microsoft-enum-value
         -Wno-switch-enum
         -Wno-covered-switch-default
@@ -1390,7 +1389,7 @@ ENDIF()
 
 # Add RT-extension library for glTF importer with Open3DGC-compression.
 IF (RT_FOUND AND ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC)
-  TARGET_LINK_LIBRARIES(assimp ${RT_LIBRARY})
+  TARGET_LINK_LIBRARIES(assimp rt)
 ENDIF ()
 
 

+ 1 - 1
code/Common/Exporter.cpp

@@ -225,7 +225,7 @@ static void setupExporterArray(std::vector<Exporter::ExportFormatEntry> &exporte
 #endif
 
 #ifndef ASSIMP_BUILD_NO_PBRT_EXPORTER
-	exporters.emplace_back("pbrt", "pbrt-v4 scene description file", "pbrt", &ExportScenePbrt, aiProcess_Triangulate | aiProcess_SortByPType);
+	exporters.emplace_back("pbrt", "pbrt-v4 scene description file", "pbrt", &ExportScenePbrt, aiProcess_ConvertToLeftHanded | aiProcess_Triangulate | aiProcess_SortByPType);
 #endif
 
 #ifndef ASSIMP_BUILD_NO_ASSJSON_EXPORTER

+ 8 - 0
code/Common/StbCommon.h

@@ -48,6 +48,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #pragma GCC diagnostic ignored "-Wunused-function"
 #endif
 
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-function"
+#endif
+
 #ifndef STB_USE_HUNTER
 /*  Use prefixed names for the symbols from stb_image as it is a very commonly embedded library.
     Including vanilla stb_image symbols causes duplicate symbol problems if assimp is linked
@@ -114,3 +119,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #pragma GCC diagnostic pop
 #endif
 
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif

+ 21 - 6
code/Pbrt/PbrtExporter.cpp

@@ -111,7 +111,22 @@ PbrtExporter::PbrtExporter(
         mScene(pScene),
         mIOSystem(pIOSystem),
         mPath(path),
-        mFile(file) {
+        mFile(file),
+        mRootTransform(
+            // rotates the (already left-handed) CRS -90 degrees around the x axis in order to
+            // make +Z 'up' and +Y 'towards viewer', as in default in pbrt
+            1.f,  0.f,  0.f, 0.f, //
+            0.f,  0.f, -1.f, 0.f, //
+            0.f,  1.f,  0.f, 0.f, //
+            0.f,  0.f,  0.f, 1.f  //
+        ) {
+
+    mRootTransform = aiMatrix4x4(
+        -1.f,  0,  0.f, 0.f, //
+        0.0f,  -1.f,  0.f, 0.f, //
+        0.f,  0.f,  1.f, 0.f, //
+        0.f,  0.f,  0.f, 1.f  //
+    ) * mRootTransform;
     // Export embedded textures.
     if (mScene->mNumTextures > 0)
         if (!mIOSystem->CreateDirectory("textures"))
@@ -260,7 +275,7 @@ aiMatrix4x4 PbrtExporter::GetNodeTransform(const aiString &name) const {
             node = node->mParent;
         }
     }
-    return m;
+    return mRootTransform * m;
 }
 
 std::string PbrtExporter::TransformAsString(const aiMatrix4x4 &m) {
@@ -309,7 +324,7 @@ void PbrtExporter::WriteCamera(int i) {
 
     // Get camera fov
     float hfov = AI_RAD_TO_DEG(camera->mHorizontalFOV);
-    float fov = (aspect >= 1.0) ? hfov : (hfov * aspect);
+    float fov = (aspect >= 1.0) ? hfov : (hfov / aspect);
     if (fov < 5) {
         std::cerr << fov << ": suspiciously low field of view specified by camera. Setting to 45 degrees.\n";
         fov = 45;
@@ -327,7 +342,7 @@ void PbrtExporter::WriteCamera(int i) {
 
     if (!cameraActive)
         mOutput << "# ";
-    mOutput << "Scale -1 1 1\n";  // right handed -> left handed
+    mOutput << "Scale 1 1 1\n";
     if (!cameraActive)
         mOutput << "# ";
     mOutput << "LookAt "
@@ -383,8 +398,8 @@ void PbrtExporter::WriteWorldDefinition() {
     }
 
     mOutput << "# Geometry\n\n";
-    aiMatrix4x4 worldFromObject;
-    WriteGeometricObjects(mScene->mRootNode, worldFromObject, meshUses);
+
+    WriteGeometricObjects(mScene->mRootNode, mRootTransform, meshUses);
 }
 
 void PbrtExporter::WriteTextures() {

+ 3 - 0
code/Pbrt/PbrtExporter.h

@@ -100,6 +100,9 @@ private:
     //  A private set to keep track of which textures have been declared
     std::set<std::string> mTextureSet;
 
+    // Transform to apply to the root node and all root objects such as cameras, lights, etc.
+    aiMatrix4x4 mRootTransform;
+
     aiMatrix4x4 GetNodeTransform(const aiString& name) const;
     static std::string TransformAsString(const aiMatrix4x4& m);
 

+ 11 - 0
include/assimp/config.h.in

@@ -1065,6 +1065,17 @@ enum aiComponent
  */
 #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.
  * 

+ 7 - 1
test/unit/utglTF2ImportExport.cpp

@@ -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",
             aiProcess_ValidateDataStructure);
     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"));
+    
+    // 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
     EXPECT_TRUE(importerMatTest(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/BoxTextured_out.glb", true));