Explorar o código

Merge pull request #3552 from Danny-Kint/dev/gltf-KHR_materials

[gltf2] Add support for extensions KHR_materials
Kim Kulling %!s(int64=4) %!d(string=hai) anos
pai
achega
05da2123e1

+ 39 - 0
code/AssetLib/glTF2/glTF2Asset.h

@@ -46,6 +46,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *   KHR_materials_pbrSpecularGlossiness full
  *   KHR_materials_unlit full
  *   KHR_lights_punctual full
+ *   KHR_materials_sheen full
+ *   KHR_materials_clearcoat full
+ *   KHR_materials_transmission full
  */
 #ifndef GLTF2ASSET_H_INC
 #define GLTF2ASSET_H_INC
@@ -677,6 +680,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 defaultSheenFactor = { 0, 0, 0 };
 
 struct TextureInfo {
     Ref<Texture> texture;
@@ -718,6 +722,29 @@ struct PbrSpecularGlossiness {
     void SetDefaults();
 };
 
+struct MaterialSheen {
+    vec3 sheenColorFactor;
+    float sheenRoughnessFactor;
+    TextureInfo sheenColorTexture;
+    TextureInfo sheenRoughnessTexture;
+
+    MaterialSheen() { SetDefaults(); }
+    void SetDefaults();
+};
+
+struct MaterialClearcoat {
+    float clearcoatFactor = 0.f;
+    float clearcoatRoughnessFactor = 0.f;
+    TextureInfo clearcoatTexture;
+    TextureInfo clearcoatRoughnessTexture;
+    NormalTextureInfo clearcoatNormalTexture;
+};
+
+struct MaterialTransmission {
+    TextureInfo transmissionTexture;
+    float transmissionFactor = 0.f;
+};
+
 //! The material appearance of a primitive.
 struct Material : public Object {
     //PBR metallic roughness properties
@@ -735,6 +762,15 @@ struct Material : public Object {
     //extension: KHR_materials_pbrSpecularGlossiness
     Nullable<PbrSpecularGlossiness> pbrSpecularGlossiness;
 
+    //extension: KHR_materials_sheen
+    Nullable<MaterialSheen> materialSheen;
+
+    //extension: KHR_materials_clearcoat
+    Nullable<MaterialClearcoat> materialClearcoat;
+
+    //extension: KHR_materials_transmission
+    Nullable<MaterialTransmission> materialTransmission;
+
     //extension: KHR_materials_unlit
     bool unlit;
 
@@ -1053,6 +1089,9 @@ public:
         bool KHR_materials_unlit;
         bool KHR_lights_punctual;
         bool KHR_texture_transform;
+        bool KHR_materials_sheen;
+        bool KHR_materials_clearcoat;
+        bool KHR_materials_transmission;
     } extensionsUsed;
 
     //! Keeps info about the required extensions

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

@@ -1046,6 +1046,44 @@ inline void Material::Read(Value &material, Asset &r) {
         if (r.extensionsUsed.KHR_texture_transform) {
         }
 
+        if (r.extensionsUsed.KHR_materials_sheen) {
+            if (Value *curMaterialSheen = FindObject(*extensions, "KHR_materials_sheen")) {
+                MaterialSheen sheen;
+
+                ReadMember(*curMaterialSheen, "sheenColorFactor", sheen.sheenColorFactor);
+                ReadTextureProperty(r, *curMaterialSheen, "sheenColorTexture", sheen.sheenColorTexture);
+                ReadMember(*curMaterialSheen, "sheenRoughnessFactor", sheen.sheenRoughnessFactor);
+                ReadTextureProperty(r, *curMaterialSheen, "sheenRoughnessTexture", sheen.sheenRoughnessTexture);
+
+                this->materialSheen = Nullable<MaterialSheen>(sheen);
+            }
+        }
+
+        if (r.extensionsUsed.KHR_materials_clearcoat) {
+            if (Value *curMaterialClearcoat = FindObject(*extensions, "KHR_materials_clearcoat")) {
+                MaterialClearcoat clearcoat;
+
+                ReadMember(*curMaterialClearcoat, "clearcoatFactor", clearcoat.clearcoatFactor);
+                ReadTextureProperty(r, *curMaterialClearcoat, "clearcoatTexture", clearcoat.clearcoatTexture);
+                ReadMember(*curMaterialClearcoat, "clearcoatRoughnessFactor", clearcoat.clearcoatRoughnessFactor);
+                ReadTextureProperty(r, *curMaterialClearcoat, "clearcoatRoughnessTexture", clearcoat.clearcoatRoughnessTexture);
+                ReadTextureProperty(r, *curMaterialClearcoat, "clearcoatNormalTexture", clearcoat.clearcoatNormalTexture);
+
+                this->materialClearcoat = Nullable<MaterialClearcoat>(clearcoat);
+            }
+        }
+
+        if (r.extensionsUsed.KHR_materials_transmission) {
+            if (Value *curMaterialTransmission = FindObject(*extensions, "KHR_materials_transmission")) {
+                MaterialTransmission transmission;
+
+                ReadMember(*curMaterialTransmission, "transmissionFactor", transmission.transmissionFactor);
+                ReadTextureProperty(r, *curMaterialTransmission, "transmissionTexture", transmission.transmissionTexture);
+
+                this->materialTransmission = Nullable<MaterialTransmission>(transmission);
+            }
+        }
+
         unlit = nullptr != FindObject(*extensions, "KHR_materials_unlit");
     }
 }
@@ -1085,6 +1123,12 @@ inline void PbrSpecularGlossiness::SetDefaults() {
     glossinessFactor = 1.0;
 }
 
+inline void MaterialSheen::SetDefaults() {
+    //KHR_materials_sheen properties
+    SetVector(sheenColorFactor, defaultSheenFactor);
+    sheenRoughnessFactor = 0.f;
+}
+
 namespace {
 
 template <int N>
@@ -1737,6 +1781,9 @@ inline void Asset::ReadExtensionsUsed(Document &doc) {
     CHECK_EXT(KHR_materials_unlit);
     CHECK_EXT(KHR_lights_punctual);
     CHECK_EXT(KHR_texture_transform);
+    CHECK_EXT(KHR_materials_sheen);
+    CHECK_EXT(KHR_materials_clearcoat);
+    CHECK_EXT(KHR_materials_transmission);
 
 #undef CHECK_EXT
 }

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

@@ -46,6 +46,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  * glTF Extensions Support:
  *   KHR_materials_pbrSpecularGlossiness: full
  *   KHR_materials_unlit: full
+ *   KHR_materials_sheen: full
+ *   KHR_materials_clearcoat: full
+ *   KHR_materials_transmission: full
  */
 #ifndef GLTF2ASSETWRITER_H_INC
 #define GLTF2ASSETWRITER_H_INC

+ 69 - 0
code/AssetLib/glTF2/glTF2AssetWriter.inl

@@ -417,6 +417,63 @@ namespace glTF2 {
           exts.AddMember("KHR_materials_unlit", unlit, w.mAl);
         }
 
+        if (m.materialSheen.isPresent) {
+            Value materialSheen(rapidjson::Type::kObjectType);
+
+            MaterialSheen &sheen = m.materialSheen.value;
+
+            WriteVec(materialSheen, sheen.sheenColorFactor, "sheenColorFactor", defaultSheenFactor, w.mAl);
+
+            if (sheen.sheenRoughnessFactor != 0.f) {
+                WriteFloat(materialSheen, sheen.sheenRoughnessFactor, "sheenRoughnessFactor", w.mAl);
+            }
+
+            WriteTex(materialSheen, sheen.sheenColorTexture, "sheenColorTexture", w.mAl);
+            WriteTex(materialSheen, sheen.sheenRoughnessTexture, "sheenRoughnessTexture", w.mAl);
+
+            if (!materialSheen.ObjectEmpty()) {
+                exts.AddMember("KHR_materials_sheen", materialSheen, w.mAl);
+            }
+        }
+
+        if (m.materialClearcoat.isPresent) {
+            Value materialClearcoat(rapidjson::Type::kObjectType);
+
+            MaterialClearcoat &clearcoat = m.materialClearcoat.value;
+
+            if (clearcoat.clearcoatFactor != 0.f) {
+                WriteFloat(materialClearcoat, clearcoat.clearcoatFactor, "clearcoatFactor", w.mAl);
+            }
+
+            if (clearcoat.clearcoatRoughnessFactor != 0.f) {
+                WriteFloat(materialClearcoat, clearcoat.clearcoatRoughnessFactor, "clearcoatRoughnessFactor", w.mAl);
+            }
+
+            WriteTex(materialClearcoat, clearcoat.clearcoatTexture, "clearcoatTexture", w.mAl);
+            WriteTex(materialClearcoat, clearcoat.clearcoatRoughnessTexture, "clearcoatRoughnessTexture", w.mAl);
+            WriteTex(materialClearcoat, clearcoat.clearcoatNormalTexture, "clearcoatNormalTexture", w.mAl);
+                        
+            if (!materialClearcoat.ObjectEmpty()) {
+                exts.AddMember("KHR_materials_clearcoat", materialClearcoat, w.mAl);
+            }
+        }
+
+        if (m.materialTransmission.isPresent) {
+            Value materialTransmission(rapidjson::Type::kObjectType);
+
+            MaterialTransmission &transmission = m.materialTransmission.value;
+
+            if (transmission.transmissionFactor != 0.f) {
+                WriteFloat(materialTransmission, transmission.transmissionFactor, "transmissionFactor", w.mAl);
+            }
+
+            WriteTex(materialTransmission, transmission.transmissionTexture, "transmissionTexture", w.mAl);
+                                   
+            if (!materialTransmission.ObjectEmpty()) {
+                exts.AddMember("KHR_materials_transmission", materialTransmission, w.mAl);
+            }
+        }
+
         if (!exts.ObjectEmpty()) {
             obj.AddMember("extensions", exts, w.mAl);
         }
@@ -808,6 +865,18 @@ namespace glTF2 {
             if (this->mAsset.extensionsUsed.KHR_materials_unlit) {
               exts.PushBack(StringRef("KHR_materials_unlit"), mAl);
             }
+
+            if (this->mAsset.extensionsUsed.KHR_materials_sheen) {
+                exts.PushBack(StringRef("KHR_materials_sheen"), mAl);
+            }
+                        
+            if (this->mAsset.extensionsUsed.KHR_materials_clearcoat) {
+                exts.PushBack(StringRef("KHR_materials_clearcoat"), mAl);
+            }
+
+            if (this->mAsset.extensionsUsed.KHR_materials_transmission) {
+                exts.PushBack(StringRef("KHR_materials_transmission"), mAl);
+            }
         }
 
         if (!exts.Empty())

+ 47 - 0
code/AssetLib/glTF2/glTF2Exporter.cpp

@@ -714,6 +714,53 @@ void glTF2Exporter::ExportMaterials()
             mAsset->extensionsUsed.KHR_materials_unlit = true;
             m->unlit = true;
         }
+
+        bool hasMaterialSheen = false;
+        mat->Get(AI_MATKEY_GLTF_MATERIAL_SHEEN, hasMaterialSheen);
+
+        if (hasMaterialSheen) {
+            mAsset->extensionsUsed.KHR_materials_sheen = true;
+
+            MaterialSheen sheen;
+
+            GetMatColor(mat, sheen.sheenColorFactor, AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_FACTOR);
+            mat->Get(AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_FACTOR, sheen.sheenRoughnessFactor);
+            GetMatTex(mat, sheen.sheenColorTexture, AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_TEXTURE);
+            GetMatTex(mat, sheen.sheenRoughnessTexture, AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_TEXTURE);
+
+            m->materialSheen = Nullable<MaterialSheen>(sheen);
+        }
+
+        bool hasMaterialClearcoat = false;
+        mat->Get(AI_MATKEY_GLTF_MATERIAL_CLEARCOAT, hasMaterialClearcoat);
+
+        if (hasMaterialClearcoat) {
+            mAsset->extensionsUsed.KHR_materials_clearcoat= true;
+
+            MaterialClearcoat clearcoat;
+
+            mat->Get(AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_FACTOR, clearcoat.clearcoatFactor);
+            mat->Get(AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_FACTOR, clearcoat.clearcoatRoughnessFactor);
+            GetMatTex(mat, clearcoat.clearcoatTexture, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_TEXTURE);
+            GetMatTex(mat, clearcoat.clearcoatRoughnessTexture, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_TEXTURE);
+            GetMatTex(mat, clearcoat.clearcoatNormalTexture, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_NORMAL_TEXTURE);
+
+            m->materialClearcoat = Nullable<MaterialClearcoat>(clearcoat);
+        }
+
+        bool hasMaterialTransmission = false;
+        mat->Get(AI_MATKEY_GLTF_MATERIAL_TRANSMISSION, hasMaterialTransmission);
+
+        if (hasMaterialTransmission) {
+            mAsset->extensionsUsed.KHR_materials_transmission = true;
+
+            MaterialTransmission transmission;
+
+            mat->Get(AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_FACTOR, transmission.transmissionFactor);
+            GetMatTex(mat, transmission.transmissionTexture, AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_TEXTURE);
+
+            m->materialTransmission = Nullable<MaterialTransmission>(transmission);
+        }
     }
 }
 

+ 32 - 0
code/AssetLib/glTF2/glTF2Importer.cpp

@@ -282,6 +282,38 @@ static aiMaterial *ImportMaterial(std::vector<int> &embeddedTexIdxs, Asset &r, M
             aimat->AddProperty(&mat.unlit, 1, AI_MATKEY_GLTF_UNLIT);
         }
 
+        //KHR_materials_sheen
+        if (mat.materialSheen.isPresent) {
+            MaterialSheen &sheen = mat.materialSheen.value;
+
+            aimat->AddProperty(&mat.materialSheen.isPresent, 1, AI_MATKEY_GLTF_MATERIAL_SHEEN);
+            SetMaterialColorProperty(r, sheen.sheenColorFactor, aimat, AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_FACTOR);
+            aimat->AddProperty(&sheen.sheenRoughnessFactor, 1, AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_FACTOR);
+            SetMaterialTextureProperty(embeddedTexIdxs, r, sheen.sheenColorTexture, aimat, AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_TEXTURE);
+            SetMaterialTextureProperty(embeddedTexIdxs, r, sheen.sheenRoughnessTexture, aimat, AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_TEXTURE);
+        }
+
+        //KHR_materials_clearcoat
+        if (mat.materialClearcoat.isPresent) {
+            MaterialClearcoat &clearcoat = mat.materialClearcoat.value;
+
+            aimat->AddProperty(&mat.materialClearcoat.isPresent, 1, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT);
+            aimat->AddProperty(&clearcoat.clearcoatFactor, 1, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_FACTOR);
+            aimat->AddProperty(&clearcoat.clearcoatRoughnessFactor, 1, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_FACTOR);
+            SetMaterialTextureProperty(embeddedTexIdxs, r, clearcoat.clearcoatTexture, aimat, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_TEXTURE);
+            SetMaterialTextureProperty(embeddedTexIdxs, r, clearcoat.clearcoatRoughnessTexture, aimat, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_TEXTURE);
+            SetMaterialTextureProperty(embeddedTexIdxs, r, clearcoat.clearcoatNormalTexture, aimat, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_NORMAL_TEXTURE);
+        }
+
+        //KHR_materials_transmission
+        if (mat.materialTransmission.isPresent) {
+            MaterialTransmission &transmission = mat.materialTransmission.value;
+
+            aimat->AddProperty(&mat.materialTransmission.isPresent, 1, AI_MATKEY_GLTF_MATERIAL_TRANSMISSION);
+            aimat->AddProperty(&transmission.transmissionFactor, 1, AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_FACTOR);
+            SetMaterialTextureProperty(embeddedTexIdxs, r, transmission.transmissionTexture, aimat, AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_TEXTURE);
+        }
+
         return aimat;
     } catch (...) {
         delete aimat;

+ 14 - 0
include/assimp/pbrmaterial.h

@@ -60,6 +60,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS "$mat.gltf.pbrSpecularGlossiness", 0, 0
 #define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR "$mat.gltf.pbrMetallicRoughness.glossinessFactor", 0, 0
 #define AI_MATKEY_GLTF_UNLIT "$mat.gltf.unlit", 0, 0
+#define AI_MATKEY_GLTF_MATERIAL_SHEEN "$mat.gltf.materialSheen", 0, 0
+#define AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_FACTOR "$mat.gltf.materialSheen.sheenColorFactor", 0, 0
+#define AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_FACTOR "$mat.gltf.materialSheen.sheenRoughnessFactor", 0, 0
+#define AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_TEXTURE aiTextureType_UNKNOWN, 1
+#define AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_TEXTURE aiTextureType_UNKNOWN, 2
+#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT "$mat.gltf.materialClearcoat", 0, 0
+#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_FACTOR "$mat.gltf.materialClearcoat.clearcoatFactor", 0, 0
+#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_FACTOR "$mat.gltf.materialClearcoat.clearcoatRoughnessFactor", 0, 0
+#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_TEXTURE aiTextureType_UNKNOWN, 3
+#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_TEXTURE aiTextureType_UNKNOWN, 4
+#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_NORMAL_TEXTURE aiTextureType_NORMALS, 1
+#define AI_MATKEY_GLTF_MATERIAL_TRANSMISSION "$mat.gltf.materialTransmission", 0, 0
+#define AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_FACTOR "$mat.gltf.materialTransmission.transmissionFactor", 0, 0
+#define AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_TEXTURE aiTextureType_UNKNOWN, 5
 
 #define _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE "$tex.file.texCoord"
 #define _AI_MATKEY_GLTF_MAPPINGNAME_BASE "$tex.mappingname"