From e5d0e927b400a3cc0e8609725fb773fa41f1da2e Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Wed, 26 May 2021 17:19:17 +0900 Subject: [PATCH] Define IMaterialExporter, IMaterialImporter --- .../Runtime/UniGLTF/IO/ImporterContext.cs | 37 ++++++++---- .../IO/MaterialIO/GltfMaterialImporter.cs | 60 ++++++------------- .../UniGLTF/IO/MaterialIO/GltfPBRMaterial.cs | 2 +- .../IO/MaterialIO/GltfUnlitMaterial.cs | 2 +- .../IO/MaterialIO/IMaterialExporter.cs | 13 ++++ .../IO/MaterialIO/IMaterialExporter.cs.meta | 3 + .../IO/MaterialIO/IMaterialImporter.cs | 13 ++++ .../IO/MaterialIO/IMaterialImporter.cs.meta | 3 + .../UniGLTF/IO/MaterialIO/MaterialExporter.cs | 5 -- Assets/VRM/Runtime/IO/VRMImporterContext.cs | 3 +- Assets/VRM/Runtime/IO/VRMMaterialImporter.cs | 11 +++- Assets/VRM10/Runtime/IO/Vrm10Importer.cs | 5 +- .../VRM10/Runtime/IO/Vrm10MaterialImporter.cs | 47 ++++++++------- Assets/VRM10/Tests/MaterialImportTests.cs | 2 +- 14 files changed, 115 insertions(+), 91 deletions(-) create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/IMaterialExporter.cs create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/IMaterialExporter.cs.meta create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/IMaterialImporter.cs create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/IMaterialImporter.cs.meta diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs index 39a7b4cd5..22051d931 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs @@ -32,23 +32,21 @@ namespace UniGLTF #endregion - MaterialFactory m_materialFactory; - public MaterialFactory MaterialFactory => m_materialFactory; - - public readonly GltfMaterialImporter GltfMaterialImporter = new GltfMaterialImporter(); - - TextureFactory m_textureFactory; - public TextureFactory TextureFactory => m_textureFactory; + public IMaterialImporter MaterialImporter { get; protected set; } + public TextureFactory TextureFactory { get; } + public MaterialFactory MaterialFactory { get; } public ImporterContext(GltfParser parser, IReadOnlyDictionary externalObjectMap = null) { m_parser = parser; + MaterialImporter = new GltfMaterialImporter(); + externalObjectMap = externalObjectMap ?? new Dictionary(); - m_textureFactory = new TextureFactory(externalObjectMap + TextureFactory = new TextureFactory(externalObjectMap .Where(x => x.Value is Texture) .ToDictionary(x => x.Key, x => (Texture) x.Value)); - m_materialFactory = new MaterialFactory(externalObjectMap + MaterialFactory = new MaterialFactory(externalObjectMap .Where(x => x.Value is Material) .ToDictionary(x => x.Key, x => (Material) x.Value)); } @@ -105,6 +103,14 @@ namespace UniGLTF } } + using (MeasureTime("LoadTextures")) + { + foreach (var (key, param) in GltfTextureEnumerator.EnumerateAllTexturesDistinct(m_parser)) + { + + } + } + using (MeasureTime("LoadMaterials")) { await LoadMaterialsAsync(); @@ -178,19 +184,24 @@ namespace UniGLTF await awaitCaller.NextFrame(); } + private async Task LoadTexturesAsync() + { + + } + public async Task LoadMaterialsAsync() { if (m_parser.GLTF.materials == null || m_parser.GLTF.materials.Count == 0) { // no material. work around. - var param = GltfMaterialImporter.GetMaterialParam(m_parser, 0); + var param = MaterialImporter.GetMaterialParam(m_parser, 0); var material = await MaterialFactory.LoadAsync(param, TextureFactory.GetTextureAsync); } else { for (int i = 0; i < m_parser.GLTF.materials.Count; ++i) { - var param = GltfMaterialImporter.GetMaterialParam(m_parser, i); + var param = MaterialImporter.GetMaterialParam(m_parser, i); var material = await MaterialFactory.LoadAsync(param, TextureFactory.GetTextureAsync); } } @@ -293,8 +304,8 @@ namespace UniGLTF } Meshes.Clear(); - m_materialFactory.Dispose(); - m_textureFactory.Dispose(); + MaterialFactory?.Dispose(); + TextureFactory?.Dispose(); if (m_ownRoot && Root != null) { diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfMaterialImporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfMaterialImporter.cs index 18a15adfa..7b284db05 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfMaterialImporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfMaterialImporter.cs @@ -5,27 +5,29 @@ using VRMShaders; namespace UniGLTF { - public delegate bool TryCreateMaterialParamFromGltf(GltfParser parser, int i, out MaterialImportParam param); - - public class GltfMaterialImporter + /// + /// GLTF の MaterialImporter + /// + public sealed class GltfMaterialImporter : IMaterialImporter { - /// - /// gltfMaterialを解釈する関数。 - /// 拡張するには、先頭に挿入するべし。 - /// - /// - /// - public readonly List GltfMaterialParamProcessors = new List(); - - public GltfMaterialImporter() + public MaterialImportParam GetMaterialParam(GltfParser parser, int i) { - // unlit を試し - GltfMaterialParamProcessors.Add(GltfUnlitMaterial.TryCreateParam); - // PBR を作成する(失敗しない) - GltfMaterialParamProcessors.Add(GltfPBRMaterial.TryCreateParam); + if (!GltfUnlitMaterial.TryCreateParam(parser, i, out var param)) + { + if (!GltfPBRMaterial.TryCreateParam(parser, i, out param)) + { + // fallback +#if VRM_DEVELOP + Debug.LogWarning($"material: {i} out of range. fallback"); +#endif + return new MaterialImportParam(GetMaterialName(i, null), GltfPBRMaterial.ShaderName); + } + } + + return param; } - public static string MaterialName(int index, glTFMaterial src) + public static string GetMaterialName(int index, glTFMaterial src) { if (src != null && !string.IsNullOrEmpty(src.name)) { @@ -33,29 +35,5 @@ namespace UniGLTF } return $"material_{index:00}"; } - - /// - /// for unittest - /// - public static glTF CreateMaterialForTest(glTFMaterial material) - { - return new glTF - { - materials = new System.Collections.Generic.List { - material - }, - textures = new List{ - new glTFTexture{ - name = "texture_0" - } - }, - images = new List{ - new glTFImage{ - name = "image_0", - mimeType = "image/png", - } - }, - }; - } } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfPBRMaterial.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfPBRMaterial.cs index 0844eda09..a9ff09904 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfPBRMaterial.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfPBRMaterial.cs @@ -92,7 +92,7 @@ namespace UniGLTF } var src = parser.GLTF.materials[i]; - param = new MaterialImportParam(GltfMaterialImporter.MaterialName(i, src), ShaderName); + param = new MaterialImportParam(GltfMaterialImporter.GetMaterialName(i, src), ShaderName); var standardParam = default(TextureImportParam); if (src.pbrMetallicRoughness != null || src.occlusionTexture != null) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfUnlitMaterial.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfUnlitMaterial.cs index 05c335d19..ea833944d 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfUnlitMaterial.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfUnlitMaterial.cs @@ -23,7 +23,7 @@ namespace UniGLTF return false; } - param = new MaterialImportParam(GltfMaterialImporter.MaterialName(i, src), ShaderName); + param = new MaterialImportParam(GltfMaterialImporter.GetMaterialName(i, src), ShaderName); // texture if (src.pbrMetallicRoughness.baseColorTexture != null) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/IMaterialExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/IMaterialExporter.cs new file mode 100644 index 000000000..be4270182 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/IMaterialExporter.cs @@ -0,0 +1,13 @@ +using UnityEngine; +using VRMShaders; + +namespace UniGLTF +{ + /// + /// 指定の Unity Material から glTFMaterial を生成する。 + /// + public interface IMaterialExporter + { + glTFMaterial ExportMaterial(Material m, ITextureExporter textureExporter); + } +} diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/IMaterialExporter.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/IMaterialExporter.cs.meta new file mode 100644 index 000000000..c8cff3c4c --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/IMaterialExporter.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: afbe933c51a9404199ba1efe6d2f8c62 +timeCreated: 1622015749 \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/IMaterialImporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/IMaterialImporter.cs new file mode 100644 index 000000000..9919e17c0 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/IMaterialImporter.cs @@ -0,0 +1,13 @@ +using VRMShaders; + +namespace UniGLTF +{ + /// + /// 指定の index の glTFMaterial から Import できる Material の生成情報を生成する。 + /// Material の Import は glTFMaterial と 1:1 対応する。 + /// + public interface IMaterialImporter + { + MaterialImportParam GetMaterialParam(GltfParser parser, int i); + } +} diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/IMaterialImporter.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/IMaterialImporter.cs.meta new file mode 100644 index 000000000..386a8bc44 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/IMaterialImporter.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c309fb8ee8534a54b291d408511c9331 +timeCreated: 1622015740 \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/MaterialExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/MaterialExporter.cs index fcb75526f..b8c6b3216 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/MaterialExporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/MaterialExporter.cs @@ -13,11 +13,6 @@ namespace UniGLTF BLEND } - public interface IMaterialExporter - { - glTFMaterial ExportMaterial(Material m, ITextureExporter textureExporter); - } - public class MaterialExporter : IMaterialExporter { public virtual glTFMaterial ExportMaterial(Material m, ITextureExporter textureExporter) diff --git a/Assets/VRM/Runtime/IO/VRMImporterContext.cs b/Assets/VRM/Runtime/IO/VRMImporterContext.cs index ad0951171..aaef4f6d6 100644 --- a/Assets/VRM/Runtime/IO/VRMImporterContext.cs +++ b/Assets/VRM/Runtime/IO/VRMImporterContext.cs @@ -27,8 +27,7 @@ namespace VRM if (glTF_VRM_extensions.TryDeserialize(GLTF.extensions, out glTF_VRM_extensions vrm)) { VRM = vrm; - // override material importer - GltfMaterialImporter.GltfMaterialParamProcessors.Insert(0, new VRMMaterialImporter(VRM).TryCreateParam); + MaterialImporter = new VRMMaterialImporter(VRM); } else { diff --git a/Assets/VRM/Runtime/IO/VRMMaterialImporter.cs b/Assets/VRM/Runtime/IO/VRMMaterialImporter.cs index d6b69d1de..ed25512e3 100644 --- a/Assets/VRM/Runtime/IO/VRMMaterialImporter.cs +++ b/Assets/VRM/Runtime/IO/VRMMaterialImporter.cs @@ -6,7 +6,7 @@ using VRMShaders; namespace VRM { - public class VRMMaterialImporter + public sealed class VRMMaterialImporter : IMaterialImporter { readonly glTF_VRM_extensions m_vrm; public VRMMaterialImporter(glTF_VRM_extensions vrm) @@ -103,7 +103,14 @@ namespace VRM if (!GltfUnlitMaterial.TryCreateParam(parser, i, out param)) { // pbr - GltfPBRMaterial.TryCreateParam(parser, i, out param); + if (!GltfPBRMaterial.TryCreateParam(parser, i, out param)) + { + // fallback +#if VRM_DEVELOP + Debug.LogWarning($"material: {i} out of range. fallback"); +#endif + return new MaterialImportParam(GltfMaterialImporter.GetMaterialName(i, null), GltfPBRMaterial.ShaderName); + } } } return param; diff --git a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs index 51329db12..8094490c3 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs @@ -24,6 +24,8 @@ namespace UniVRM10 public Vrm10Importer(UniGLTF.GltfParser parser, IReadOnlyDictionary externalObjectMap = null) : base(parser, externalObjectMap) { + MaterialImporter = new Vrm10MaterialImporter(); + m_externalMap = externalObjectMap; if (m_externalMap == null) { @@ -31,9 +33,6 @@ namespace UniVRM10 } m_model = ModelReader.Read(parser); - // for `VRMC_materials_mtoon` - this.GltfMaterialImporter.GltfMaterialParamProcessors.Insert(0, Vrm10MaterialImporter.TryCreateParam); - if (!UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.TryGet(parser.GLTF.extensions, out m_vrm)) { throw new Exception("VRMC_vrm is not found"); diff --git a/Assets/VRM10/Runtime/IO/Vrm10MaterialImporter.cs b/Assets/VRM10/Runtime/IO/Vrm10MaterialImporter.cs index 16eede2f8..b9196f20b 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10MaterialImporter.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10MaterialImporter.cs @@ -4,16 +4,34 @@ using VRMShaders; namespace UniVRM10 { - public static class Vrm10MaterialImporter + public sealed class Vrm10MaterialImporter : IMaterialImporter { + public MaterialImportParam GetMaterialParam(GltfParser parser, int i) + { + // mtoon + if (!TryCreateMToonParam(parser, i, out MaterialImportParam param)) + { + // unlit + if (!GltfUnlitMaterial.TryCreateParam(parser, i, out param)) + { + // pbr + if (!GltfPBRMaterial.TryCreateParam(parser, i, out param)) + { + // fallback +#if VRM_DEVELOP + Debug.LogWarning($"material: {i} out of range. fallback"); +#endif + return new MaterialImportParam(GltfMaterialImporter.GetMaterialName(i, null), GltfPBRMaterial.ShaderName); + } + } + } + return param; + } + /// /// VMRC_materials_mtoon の場合にマテリアル生成情報を作成する /// - /// - /// - /// - /// - public static bool TryCreateParam(GltfParser parser, int i, out MaterialImportParam param) + public bool TryCreateMToonParam(GltfParser parser, int i, out MaterialImportParam param) { var m = parser.GLTF.materials[i]; if (!UniGLTF.Extensions.VRMC_materials_mtoon.GltfDeserializer.TryGet(m.extensions, @@ -48,7 +66,7 @@ namespace UniVRM10 } param.RenderQueue = Vrm10MToonMaterialParameterImporter.TryGetRenderQueue(m, mtoon); - + param.Actions.Add(material => { // Set hidden properties, keywords from float properties. @@ -57,20 +75,5 @@ namespace UniVRM10 return true; } - - public static MaterialImportParam GetMaterialParam(GltfParser parser, int i) - { - // mtoon - if (!TryCreateParam(parser, i, out MaterialImportParam param)) - { - // unlit - if (!GltfUnlitMaterial.TryCreateParam(parser, i, out param)) - { - // pbr - GltfPBRMaterial.TryCreateParam(parser, i, out param); - } - } - return param; - } } } diff --git a/Assets/VRM10/Tests/MaterialImportTests.cs b/Assets/VRM10/Tests/MaterialImportTests.cs index 4568eeb7a..6eeca4155 100644 --- a/Assets/VRM10/Tests/MaterialImportTests.cs +++ b/Assets/VRM10/Tests/MaterialImportTests.cs @@ -25,7 +25,7 @@ namespace UniVRM10 var parser = new GltfParser(); parser.Parse(AliciaPath, migratedBytes); - var materialParam = Vrm10MaterialImporter.GetMaterialParam(parser, 0); + var materialParam = new Vrm10MaterialImporter().GetMaterialParam(parser, 0); Assert.AreEqual("VRM/MToon", materialParam.ShaderName); Assert.AreEqual("Alicia_body", materialParam.TextureSlots["_MainTex"].UnityObjectName);