From 9157c22eef02f49ff589d5d186355d3202834ba5 Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Wed, 26 May 2021 17:52:53 +0900 Subject: [PATCH 1/4] Define ITextureImporter --- .../UniGLTF/IO/TextureIO/ITextureImporter.cs | 15 +++++++++++++++ .../UniGLTF/IO/TextureIO/ITextureImporter.cs.meta | 3 +++ 2 files changed, 18 insertions(+) create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/ITextureImporter.cs create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/ITextureImporter.cs.meta diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/ITextureImporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/ITextureImporter.cs new file mode 100644 index 000000000..873682cb8 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/ITextureImporter.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using VRMShaders; + +namespace UniGLTF +{ + /// + /// glTF から Import できる Texture の生成情報のリストを生成する。 + /// + /// glTF Texture と Unity Texture の対応関係は N:M である。 + /// + public interface ITextureImporter + { + IReadOnlyDictionary GetTextureParams(GltfParser parser); + } +} diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/ITextureImporter.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/ITextureImporter.cs.meta new file mode 100644 index 000000000..674d3aab5 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/ITextureImporter.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8e671772001d477b82c414ce708b7e7f +timeCreated: 1622018845 \ No newline at end of file From a6d730d15f1171e8bc983907232b51dc807a20a5 Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Wed, 26 May 2021 21:22:34 +0900 Subject: [PATCH 2/4] Refactor Texture enumeration to TextureSetImport --- .../ScriptedImporter/EditorMaterial.cs | 16 ++- .../GlbScriptedImporterEditorGUI.cs | 2 +- .../GltfScriptedImporterEditorGUI.cs | 2 +- .../ScriptedImporter/ScriptedImporterImpl.cs | 4 +- .../ScriptedImporter/TextureExtractor.cs | 6 +- .../Runtime/UniGLTF/IO/ImporterContext.cs | 36 +++-- .../IO/MaterialIO/GltfPbrMaterialImporter.cs | 44 +----- .../IO/TextureIO/GltfPbrTextureImporter.cs | 91 +++++++++++++ .../TextureIO/GltfPbrTextureImporter.cs.meta | 3 + .../IO/TextureIO/GltfTextureEnumerator.cs | 97 ------------- .../IO/TextureIO/GltfTextureSetImporter.cs | 63 +++++++++ ...cs.meta => GltfTextureSetImporter.cs.meta} | 0 .../UniGLTF/IO/TextureIO/ITextureImporter.cs | 15 -- .../IO/TextureIO/ITextureSetImporter.cs | 15 ++ ...er.cs.meta => ITextureSetImporter.cs.meta} | 0 Assets/UniGLTF/Tests/UniGLTF/GltfLoadTests.cs | 5 +- .../Tests/UniGLTF/TextureEnumerateTests.cs | 12 +- Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs | 10 +- .../Editor/Format/VRMEditorImporterContext.cs | 3 +- Assets/VRM/Editor/Format/VRMImporterMenu.cs | 2 +- .../Editor/Format/vrmAssetPostprocessor.cs | 2 +- Assets/VRM/Runtime/IO/MToonTextureParam.cs | 27 ---- .../VRM/Runtime/IO/MToonTextureParam.cs.meta | 11 -- Assets/VRM/Runtime/IO/VRMImporterContext.cs | 1 + .../Runtime/IO/VRMMToonMaterialImporter.cs | 79 +++++++++++ .../IO/VRMMToonMaterialImporter.cs.meta | 3 + .../VRM/Runtime/IO/VRMMToonTextureImporter.cs | 64 +++++++++ .../IO/VRMMToonTextureImporter.cs.meta | 3 + Assets/VRM/Runtime/IO/VRMMaterialImporter.cs | 128 +----------------- .../VRM/Runtime/IO/VRMTextureSetImporter.cs | 77 +++++++++++ .../Runtime/IO/VRMTextureSetImporter.cs.meta | 3 + Assets/VRM/Tests/MToonTest.cs | 4 +- Assets/VRM/Tests/VRMTextureEnumerateTests.cs | 2 +- .../VrmScriptedImporterEditorGUI.cs | 2 +- .../VrmScriptedImporterImpl.cs | 2 +- ...orter.cs => Vrm10MToonMaterialImporter.cs} | 67 +++++++-- ...eta => Vrm10MToonMaterialImporter.cs.meta} | 0 .../IO/Material/Vrm10MaterialImporter.cs | 32 +++++ .../Vrm10MaterialImporter.cs.meta | 0 .../Vrm10MToonTextureImporter.cs} | 8 +- .../Vrm10MToonTextureImporter.cs.meta} | 0 ...umerator.cs => Vrm10TextureSetImporter.cs} | 90 ++++++------ ...s.meta => Vrm10TextureSetImporter.cs.meta} | 0 Assets/VRM10/Runtime/IO/Vrm10Importer.cs | 2 +- .../VRM10/Runtime/IO/Vrm10MaterialImporter.cs | 79 ----------- .../GLTF/IO/Runtime/TextureImportParam.cs | 5 - 46 files changed, 611 insertions(+), 506 deletions(-) create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfPbrTextureImporter.cs create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfPbrTextureImporter.cs.meta delete mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfTextureEnumerator.cs create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfTextureSetImporter.cs rename Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/{GltfTextureEnumerator.cs.meta => GltfTextureSetImporter.cs.meta} (100%) delete mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/ITextureImporter.cs create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/ITextureSetImporter.cs rename Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/{ITextureImporter.cs.meta => ITextureSetImporter.cs.meta} (100%) delete mode 100644 Assets/VRM/Runtime/IO/MToonTextureParam.cs delete mode 100644 Assets/VRM/Runtime/IO/MToonTextureParam.cs.meta create mode 100644 Assets/VRM/Runtime/IO/VRMMToonMaterialImporter.cs create mode 100644 Assets/VRM/Runtime/IO/VRMMToonMaterialImporter.cs.meta create mode 100644 Assets/VRM/Runtime/IO/VRMMToonTextureImporter.cs create mode 100644 Assets/VRM/Runtime/IO/VRMMToonTextureImporter.cs.meta create mode 100644 Assets/VRM/Runtime/IO/VRMTextureSetImporter.cs create mode 100644 Assets/VRM/Runtime/IO/VRMTextureSetImporter.cs.meta rename Assets/VRM10/Runtime/IO/Material/{Vrm10MToonMaterialParameterImporter.cs => Vrm10MToonMaterialImporter.cs} (83%) rename Assets/VRM10/Runtime/IO/Material/{Vrm10MToonMaterialParameterImporter.cs.meta => Vrm10MToonMaterialImporter.cs.meta} (100%) create mode 100644 Assets/VRM10/Runtime/IO/Material/Vrm10MaterialImporter.cs rename Assets/VRM10/Runtime/IO/{ => Material}/Vrm10MaterialImporter.cs.meta (100%) rename Assets/VRM10/Runtime/IO/{Material/Vrm10MToonMaterialTextureImporter.cs => Texture/Vrm10MToonTextureImporter.cs} (96%) rename Assets/VRM10/Runtime/IO/{Material/Vrm10MToonMaterialTextureImporter.cs.meta => Texture/Vrm10MToonTextureImporter.cs.meta} (100%) rename Assets/VRM10/Runtime/IO/Texture/{Vrm10TextureEnumerator.cs => Vrm10TextureSetImporter.cs} (60%) rename Assets/VRM10/Runtime/IO/Texture/{Vrm10TextureEnumerator.cs.meta => Vrm10TextureSetImporter.cs.meta} (100%) delete mode 100644 Assets/VRM10/Runtime/IO/Vrm10MaterialImporter.cs diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/EditorMaterial.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/EditorMaterial.cs index cf8c8673b..e9a1aafa8 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/EditorMaterial.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/EditorMaterial.cs @@ -33,14 +33,14 @@ namespace UniGLTF static bool s_foldMaterials = true; static bool s_foldTextures = true; - public static void OnGUI(ScriptedImporter importer, GltfParser parser, EnumerateAllTexturesDistinctFunc enumTextures, Func textureDir, Func materialDir) + public static void OnGUI(ScriptedImporter importer, GltfParser parser, ITextureSetImporter textureSetImporter, Func textureDir, Func materialDir) { var hasExternal = importer.GetExternalObjectMap().Any(x => x.Value is Material || x.Value is Texture2D); using (new TmpGuiEnable(!hasExternal)) { if (GUILayout.Button("Extract Materials And Textures ...")) { - ExtractMaterialsAndTextures(importer, parser, enumTextures, textureDir, materialDir); + ExtractMaterialsAndTextures(importer, parser, textureSetImporter, textureDir, materialDir); } } @@ -56,7 +56,7 @@ namespace UniGLTF s_foldTextures = EditorGUILayout.Foldout(s_foldTextures, "Remapped Textures"); if (s_foldTextures) { - importer.DrawRemapGUI(enumTextures(parser).Select(x => x.Key)); + importer.DrawRemapGUI(textureSetImporter.GetTextureParamsDistinct().Select(x => x.SubAssetKey)); } if (GUILayout.Button("Clear")) @@ -74,7 +74,7 @@ namespace UniGLTF AssetDatabase.ImportAsset(self.assetPath, ImportAssetOptions.ForceUpdate); } - static void ExtractMaterialsAndTextures(ScriptedImporter self, GltfParser parser, EnumerateAllTexturesDistinctFunc enumTextures, Func textureDir, Func materialDir) + static void ExtractMaterialsAndTextures(ScriptedImporter self, GltfParser parser, ITextureSetImporter textureSetImporter, Func textureDir, Func materialDir) { if (string.IsNullOrEmpty(self.assetPath)) { @@ -94,12 +94,14 @@ namespace UniGLTF var assetPath = UnityPath.FromFullpath(parser.TargetPath); var dirName = textureDir(assetPath.Value); // $"{assetPath.FileNameWithoutExtension}.Textures"; - TextureExtractor.ExtractTextures(parser, assetPath.Parent.Child(dirName), - enumTextures, + TextureExtractor.ExtractTextures( + parser, + assetPath.Parent.Child(dirName), + textureSetImporter, self.GetSubAssets(self.assetPath).ToDictionary(kv => kv.Item1, kv => kv.Item2), addRemap, onCompleted - ); + ); } public static void ExtractMaterials(this ScriptedImporter importer, Func materialDir) diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GlbScriptedImporterEditorGUI.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GlbScriptedImporterEditorGUI.cs index 65e4d14d2..dc77ff6a1 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GlbScriptedImporterEditorGUI.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GlbScriptedImporterEditorGUI.cs @@ -49,7 +49,7 @@ namespace UniGLTF break; case Tabs.Materials: - EditorMaterial.OnGUI(m_importer, m_parser, GltfTextureEnumerator.EnumerateAllTexturesDistinct, + EditorMaterial.OnGUI(m_importer, m_parser, new GltfTextureSetImporter(m_parser), assetPath => $"{Path.GetFileNameWithoutExtension(assetPath)}.Textures", assetPath => $"{Path.GetFileNameWithoutExtension(assetPath)}.Materials"); break; diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporterEditorGUI.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporterEditorGUI.cs index f184f1cb6..5c9e03a58 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporterEditorGUI.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporterEditorGUI.cs @@ -49,7 +49,7 @@ namespace UniGLTF break; case Tabs.Materials: - EditorMaterial.OnGUI(m_importer, m_parser, GltfTextureEnumerator.EnumerateAllTexturesDistinct, + EditorMaterial.OnGUI(m_importer, m_parser, new GltfTextureSetImporter(m_parser), assetPath => $"{Path.GetFileNameWithoutExtension(assetPath)}.Textures", assetPath => $"{Path.GetFileNameWithoutExtension(assetPath)}.Materials"); break; diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ScriptedImporterImpl.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ScriptedImporterImpl.cs index 77950e431..c9c8360b0 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ScriptedImporterImpl.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ScriptedImporterImpl.cs @@ -43,8 +43,8 @@ namespace UniGLTF using (var loader = new ImporterContext(parser, extractedObjects)) { - // settings TextureImporters - foreach (var (key, textureInfo) in GltfTextureEnumerator.EnumerateAllTexturesDistinct(parser)) + // Configure TextureImporter to Extracted Textures. + foreach (var textureInfo in loader.TextureSetImporter.GetTextureParamsDistinct()) { TextureImporterConfigurator.Configure(textureInfo, loader.TextureFactory.ExternalTextures); } diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/TextureExtractor.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/TextureExtractor.cs index 0ea1925ec..0bbe04cb9 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/TextureExtractor.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/TextureExtractor.cs @@ -75,14 +75,14 @@ namespace UniGLTF /// /// public static void ExtractTextures(GltfParser parser, UnityPath textureDirectory, - EnumerateAllTexturesDistinctFunc textureEnumerator, IReadOnlyDictionary subAssets, + ITextureSetImporter textureSetImporter, IReadOnlyDictionary subAssets, Action addRemap, Action> onCompleted = null) { var extractor = new TextureExtractor(parser, textureDirectory, subAssets); - foreach (var (key, x) in textureEnumerator(parser)) + foreach (var param in textureSetImporter.GetTextureParamsDistinct()) { - extractor.Extract(key, x); + extractor.Extract(param.SubAssetKey, param); } EditorApplication.delayCall += () => diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs index 60f2c6c90..a0b293a0a 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs @@ -32,14 +32,15 @@ namespace UniGLTF #endregion + public ITextureSetImporter TextureSetImporter { get; protected set; } public IMaterialImporter MaterialImporter { get; protected set; } public TextureFactory TextureFactory { get; } public MaterialFactory MaterialFactory { get; } public ImporterContext(GltfParser parser, IReadOnlyDictionary externalObjectMap = null) { - m_parser = parser; - + Parser = parser; + TextureSetImporter = new GltfTextureSetImporter(Parser); MaterialImporter = new GltfMaterialImporter(); externalObjectMap = externalObjectMap ?? new Dictionary(); @@ -52,11 +53,10 @@ namespace UniGLTF } #region Source - GltfParser m_parser; - public GltfParser Parser => m_parser; - public String Json => m_parser.Json; - public glTF GLTF => m_parser.GLTF; - public IStorage Storage => m_parser.Storage; + public GltfParser Parser { get; } + public String Json => Parser.Json; + public glTF GLTF => Parser.GLTF; + public IStorage Storage => Parser.Storage; #endregion // configuration @@ -103,6 +103,11 @@ namespace UniGLTF } } + using (MeasureTime("LoadTextures")) + { + await LoadTexturesAsync(); + } + using (MeasureTime("LoadMaterials")) { await LoadMaterialsAsync(); @@ -176,19 +181,28 @@ namespace UniGLTF await awaitCaller.NextFrame(); } + public async Task LoadTexturesAsync() + { + var textures = TextureSetImporter.GetTextureParamsDistinct(); + foreach (var param in textures) + { + var tex = await TextureFactory.GetTextureAsync(param); + } + } + public async Task LoadMaterialsAsync() { - if (m_parser.GLTF.materials == null || m_parser.GLTF.materials.Count == 0) + if (Parser.GLTF.materials == null || Parser.GLTF.materials.Count == 0) { // no material. work around. - var param = MaterialImporter.GetMaterialParam(m_parser, 0); + var param = MaterialImporter.GetMaterialParam(Parser, 0); var material = await MaterialFactory.LoadAsync(param, TextureFactory.GetTextureAsync); } else { - for (int i = 0; i < m_parser.GLTF.materials.Count; ++i) + for (int i = 0; i < Parser.GLTF.materials.Count; ++i) { - var param = MaterialImporter.GetMaterialParam(m_parser, i); + var param = MaterialImporter.GetMaterialParam(Parser, i); var material = await MaterialFactory.LoadAsync(param, TextureFactory.GetTextureAsync); } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfPbrMaterialImporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfPbrMaterialImporter.cs index 99e98813a..438bade49 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfPbrMaterialImporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfPbrMaterialImporter.cs @@ -47,42 +47,6 @@ namespace UniGLTF Transparent } - public static (SubAssetKey, TextureImportParam Param) BaseColorTexture(GltfParser parser, glTFMaterial src) - { - var (offset, scale) = GltfTextureImporter.GetTextureOffsetAndScale(src.pbrMetallicRoughness.baseColorTexture); - return GltfTextureImporter.CreateSRGB(parser, src.pbrMetallicRoughness.baseColorTexture.index, offset, scale); - } - - public static (SubAssetKey, TextureImportParam) StandardTexture(GltfParser parser, glTFMaterial src) - { - var metallicFactor = 1.0f; - var roughnessFactor = 1.0f; - if (src.pbrMetallicRoughness != null) - { - metallicFactor = src.pbrMetallicRoughness.metallicFactor; - roughnessFactor = src.pbrMetallicRoughness.roughnessFactor; - } - var (offset, scale) = GltfTextureImporter.GetTextureOffsetAndScale(src.pbrMetallicRoughness.metallicRoughnessTexture); - return GltfTextureImporter.CreateStandard(parser, - src.pbrMetallicRoughness?.metallicRoughnessTexture?.index, - src.occlusionTexture?.index, - offset, scale, - metallicFactor, - roughnessFactor); - } - - public static (SubAssetKey, TextureImportParam Param) NormalTexture(GltfParser parser, glTFMaterial src) - { - var (offset, scale) = GltfTextureImporter.GetTextureOffsetAndScale(src.normalTexture); - return GltfTextureImporter.CreateNormal(parser, src.normalTexture.index, offset, scale); - } - - public static (SubAssetKey, TextureImportParam Param) EmissiveTexture(GltfParser parser, glTFMaterial src) - { - var (offset, scale) = GltfTextureImporter.GetTextureOffsetAndScale(src.emissiveTexture); - return GltfTextureImporter.CreateSRGB(parser, src.emissiveTexture.index, offset, scale); - } - public static bool TryCreateParam(GltfParser parser, int i, out MaterialImportParam param) { if (i < 0 || i >= parser.GLTF.materials.Count) @@ -100,7 +64,7 @@ namespace UniGLTF if (src.pbrMetallicRoughness.metallicRoughnessTexture != null || src.occlusionTexture != null) { SubAssetKey key; - (key, standardParam) = StandardTexture(parser, src); + (key, standardParam) = GltfPbrTextureImporter.StandardTexture(parser, src); } if (src.pbrMetallicRoughness.baseColorFactor != null && src.pbrMetallicRoughness.baseColorFactor.Length == 4) @@ -112,7 +76,7 @@ namespace UniGLTF if (src.pbrMetallicRoughness.baseColorTexture != null && src.pbrMetallicRoughness.baseColorTexture.index != -1) { - var (key, textureParam) = BaseColorTexture(parser, src); + var (key, textureParam) = GltfPbrTextureImporter.BaseColorTexture(parser, src); param.TextureSlots.Add("_MainTex", textureParam); } @@ -134,7 +98,7 @@ namespace UniGLTF if (src.normalTexture != null && src.normalTexture.index != -1) { param.Actions.Add(material => material.EnableKeyword("_NORMALMAP")); - var (key, textureParam) = NormalTexture(parser, src); + var (key, textureParam) = GltfPbrTextureImporter.NormalTexture(parser, src); param.TextureSlots.Add("_BumpMap", textureParam); param.FloatValues.Add("_BumpScale", src.normalTexture.scale); } @@ -163,7 +127,7 @@ namespace UniGLTF if (src.emissiveTexture != null && src.emissiveTexture.index != -1) { - var (key, textureParam) = EmissiveTexture(parser, src); + var (key, textureParam) = GltfPbrTextureImporter.EmissiveTexture(parser, src); param.TextureSlots.Add("_EmissionMap", textureParam); } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfPbrTextureImporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfPbrTextureImporter.cs new file mode 100644 index 000000000..355d34cc9 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfPbrTextureImporter.cs @@ -0,0 +1,91 @@ +using System.Collections.Generic; +using VRMShaders; + +namespace UniGLTF +{ + public sealed class GltfPbrTextureImporter + { + public static IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateTexturesReferencedByMaterial(GltfParser parser, int i) + { + var m = parser.GLTF.materials[i]; + + int? metallicRoughnessTexture = default; + if (m.pbrMetallicRoughness != null) + { + // base color + if (m.pbrMetallicRoughness?.baseColorTexture != null) + { + yield return BaseColorTexture(parser, m); + } + + // metallic roughness + if (m.pbrMetallicRoughness?.metallicRoughnessTexture != null && m.pbrMetallicRoughness.metallicRoughnessTexture.index != -1) + { + metallicRoughnessTexture = m.pbrMetallicRoughness?.metallicRoughnessTexture?.index; + } + } + + // emission + if (m.emissiveTexture != null) + { + yield return EmissiveTexture(parser, m); + } + + // normal + if (m.normalTexture != null) + { + yield return NormalTexture(parser, m); + } + + // occlusion + int? occlusionTexture = default; + if (m.occlusionTexture != null && m.occlusionTexture.index != -1) + { + occlusionTexture = m.occlusionTexture.index; + } + + // metallicSmooth and occlusion + if (metallicRoughnessTexture.HasValue || occlusionTexture.HasValue) + { + yield return StandardTexture(parser, m); + } + } + + public static (SubAssetKey, TextureImportParam Param) BaseColorTexture(GltfParser parser, glTFMaterial src) + { + var (offset, scale) = GltfTextureImporter.GetTextureOffsetAndScale(src.pbrMetallicRoughness.baseColorTexture); + return GltfTextureImporter.CreateSRGB(parser, src.pbrMetallicRoughness.baseColorTexture.index, offset, scale); + } + + public static (SubAssetKey, TextureImportParam) StandardTexture(GltfParser parser, glTFMaterial src) + { + var metallicFactor = 1.0f; + var roughnessFactor = 1.0f; + if (src.pbrMetallicRoughness != null) + { + metallicFactor = src.pbrMetallicRoughness.metallicFactor; + roughnessFactor = src.pbrMetallicRoughness.roughnessFactor; + } + var (offset, scale) = GltfTextureImporter.GetTextureOffsetAndScale(src.pbrMetallicRoughness.metallicRoughnessTexture); + return GltfTextureImporter.CreateStandard(parser, + src.pbrMetallicRoughness?.metallicRoughnessTexture?.index, + src.occlusionTexture?.index, + offset, scale, + metallicFactor, + roughnessFactor); + } + + public static (SubAssetKey, TextureImportParam Param) NormalTexture(GltfParser parser, glTFMaterial src) + { + var (offset, scale) = GltfTextureImporter.GetTextureOffsetAndScale(src.normalTexture); + return GltfTextureImporter.CreateNormal(parser, src.normalTexture.index, offset, scale); + } + + public static (SubAssetKey, TextureImportParam Param) EmissiveTexture(GltfParser parser, glTFMaterial src) + { + var (offset, scale) = GltfTextureImporter.GetTextureOffsetAndScale(src.emissiveTexture); + return GltfTextureImporter.CreateSRGB(parser, src.emissiveTexture.index, offset, scale); + } + + } +} diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfPbrTextureImporter.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfPbrTextureImporter.cs.meta new file mode 100644 index 000000000..6fecbedc0 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfPbrTextureImporter.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9a1c5210d71f47ab80a1549b77c9a8a3 +timeCreated: 1622027042 \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfTextureEnumerator.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfTextureEnumerator.cs deleted file mode 100644 index 5f2baecc9..000000000 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfTextureEnumerator.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System; -using System.Collections.Generic; -using VRMShaders; - - -namespace UniGLTF -{ - public delegate IEnumerable<(SubAssetKey Key, TextureImportParam Param)> EnumerateAllTexturesDistinctFunc(GltfParser parser); - - /// - /// Texture 生成に関して - /// Runtimeは LoadImage するだけだが、Editor時には Asset 化するにあたって続きの処理がある。 - /// - /// * (gltf/glb/vrm-1): AssetImporterContext.AddObjectToAsset(SubAsset) - /// * (gltf/glb/vrm-1): ScriptedImporter.GetExternalObjectMap(Extracted) - /// * (vrm-0): (Extracted) ScriptedImporter では無いので ScriptedImporter.AddRemap, GetExternalObjectMap が無い - /// - /// AddRemap, GetExternalObjectMap は Dictionary[SourceAssetIdentifier, UnityEngine.Object] に対する API で - /// SourceAssetIdentifier 型がリソースを識別するキーとなる。 - /// - /// gltfTexture から SourceAssetIdentifier を作り出すことで、GetExternalObjectMap との対応関係を作る。 - /// - /// [例外] - /// glTF で外部ファイルを uri 参照する場合 - /// * sRGB 外部ファイルをそのまま使うので SubAsset にしない - /// * normal 外部ライルをそのまま使うので SubAsset にしない(normalとしてロードするためにAssetImporterの設定は必用) - /// * metallicRoughnessOcclusion 変換結果を SubAsset 化する - /// - public static class GltfTextureEnumerator - { - public static IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateTexturesReferencedByMaterials(GltfParser parser, int i) - { - var m = parser.GLTF.materials[i]; - - int? metallicRoughnessTexture = default; - if (m.pbrMetallicRoughness != null) - { - // base color - if (m.pbrMetallicRoughness?.baseColorTexture != null) - { - yield return GltfPbrMaterialImporter.BaseColorTexture(parser, m); - } - - // metallic roughness - if (m.pbrMetallicRoughness?.metallicRoughnessTexture != null && m.pbrMetallicRoughness.metallicRoughnessTexture.index != -1) - { - metallicRoughnessTexture = m.pbrMetallicRoughness?.metallicRoughnessTexture?.index; - } - } - - // emission - if (m.emissiveTexture != null) - { - yield return GltfPbrMaterialImporter.EmissiveTexture(parser, m); - } - - // normal - if (m.normalTexture != null) - { - yield return GltfPbrMaterialImporter.NormalTexture(parser, m); - } - - // occlusion - int? occlusionTexture = default; - if (m.occlusionTexture != null && m.occlusionTexture.index != -1) - { - occlusionTexture = m.occlusionTexture.index; - } - - // metallicSmooth and occlusion - if (metallicRoughnessTexture.HasValue || occlusionTexture.HasValue) - { - yield return GltfPbrMaterialImporter.StandardTexture(parser, m); - } - } - - /// - /// glTF 全体で使うテクスチャーをユニークになるように列挙する - /// - /// - /// - public static IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateAllTexturesDistinct(GltfParser parser) - { - var usedTextures = new HashSet(); - for (int i = 0; i < parser.GLTF.materials.Count; ++i) - { - foreach ((SubAssetKey key, TextureImportParam) kv in EnumerateTexturesReferencedByMaterials(parser, i)) - { - if (usedTextures.Add(kv.key)) - { - yield return kv; - } - } - } - } - } -} diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfTextureSetImporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfTextureSetImporter.cs new file mode 100644 index 000000000..0d2942c44 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfTextureSetImporter.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using VRMShaders; + + +namespace UniGLTF +{ + /// + /// Texture 生成に関して + /// Runtimeは LoadImage するだけだが、Editor時には Asset 化するにあたって続きの処理がある。 + /// + /// * (gltf/glb/vrm-1): AssetImporterContext.AddObjectToAsset(SubAsset) + /// * (gltf/glb/vrm-1): ScriptedImporter.GetExternalObjectMap(Extracted) + /// * (vrm-0): (Extracted) ScriptedImporter では無いので ScriptedImporter.AddRemap, GetExternalObjectMap が無い + /// + /// AddRemap, GetExternalObjectMap は Dictionary[SourceAssetIdentifier, UnityEngine.Object] に対する API で + /// SourceAssetIdentifier 型がリソースを識別するキーとなる。 + /// + /// gltfTexture から SourceAssetIdentifier を作り出すことで、GetExternalObjectMap との対応関係を作る。 + /// + /// [例外] + /// glTF で外部ファイルを uri 参照する場合 + /// * sRGB 外部ファイルをそのまま使うので SubAsset にしない + /// * normal 外部ライルをそのまま使うので SubAsset にしない(normalとしてロードするためにAssetImporterの設定は必用) + /// * metallicRoughnessOcclusion 変換結果を SubAsset 化する + /// + public sealed class GltfTextureSetImporter : ITextureSetImporter + { + private readonly GltfParser m_parser; + + public GltfTextureSetImporter(GltfParser parser) + { + m_parser = parser; + } + + public IEnumerable GetTextureParamsDistinct() + { + var usedTextures = new HashSet(); + foreach (var (key, param) in EnumerateAllTextures(m_parser)) + { + if (usedTextures.Add(key)) + { + yield return param; + } + } + } + + /// + /// glTF 全体で使うテクスチャーを列挙。 + /// + private static IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateAllTextures(GltfParser parser) + { + for (int i = 0; i < parser.GLTF.materials.Count; ++i) + { + foreach (var kv in GltfPbrTextureImporter.EnumerateTexturesReferencedByMaterial(parser, i)) + { + yield return kv; + } + } + } + } +} diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfTextureEnumerator.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfTextureSetImporter.cs.meta similarity index 100% rename from Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfTextureEnumerator.cs.meta rename to Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfTextureSetImporter.cs.meta diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/ITextureImporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/ITextureImporter.cs deleted file mode 100644 index 873682cb8..000000000 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/ITextureImporter.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Collections.Generic; -using VRMShaders; - -namespace UniGLTF -{ - /// - /// glTF から Import できる Texture の生成情報のリストを生成する。 - /// - /// glTF Texture と Unity Texture の対応関係は N:M である。 - /// - public interface ITextureImporter - { - IReadOnlyDictionary GetTextureParams(GltfParser parser); - } -} diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/ITextureSetImporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/ITextureSetImporter.cs new file mode 100644 index 000000000..1236eaf68 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/ITextureSetImporter.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using VRMShaders; + +namespace UniGLTF +{ + /// + /// glTF から Import できる、すべての Texture の生成情報を生成する。 + /// + /// glTF Texture と Unity Texture の対応関係は N:M である。 + /// + public interface ITextureSetImporter + { + IEnumerable GetTextureParamsDistinct(); + } +} diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/ITextureImporter.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/ITextureSetImporter.cs.meta similarity index 100% rename from Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/ITextureImporter.cs.meta rename to Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/ITextureSetImporter.cs.meta diff --git a/Assets/UniGLTF/Tests/UniGLTF/GltfLoadTests.cs b/Assets/UniGLTF/Tests/UniGLTF/GltfLoadTests.cs index af3bd6b63..ee30d42e2 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/GltfLoadTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/GltfLoadTests.cs @@ -136,8 +136,11 @@ namespace UniGLTF } // should unique - var gltfTextures = GltfTextureEnumerator.EnumerateAllTexturesDistinct(parser).ToArray(); + var gltfTextures = new GltfTextureSetImporter(parser).GetTextureParamsDistinct() + .Select(x => x.SubAssetKey) + .ToArray(); var distinct = gltfTextures.Distinct().ToArray(); + Assert.True(gltfTextures.Length == distinct.Length); Assert.True(gltfTextures.SequenceEqual(distinct)); } diff --git a/Assets/UniGLTF/Tests/UniGLTF/TextureEnumerateTests.cs b/Assets/UniGLTF/Tests/UniGLTF/TextureEnumerateTests.cs index 938a78118..0fe344ccd 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/TextureEnumerateTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/TextureEnumerateTests.cs @@ -59,8 +59,8 @@ namespace UniGLTF }, }, }; - } - + } + static glTF TwoTextureOneUri() { return new glTF @@ -207,7 +207,7 @@ namespace UniGLTF { GLTF = TwoTexture(), }; - var items = GltfTextureEnumerator.EnumerateAllTexturesDistinct(parser).ToArray(); + var items = new GltfTextureSetImporter(parser).GetTextureParamsDistinct().ToArray(); Assert.AreEqual(2, items.Length); } @@ -216,7 +216,7 @@ namespace UniGLTF { GLTF = TwoTextureOneUri(), }; - var items = GltfTextureEnumerator.EnumerateAllTexturesDistinct(parser).ToArray(); + var items = new GltfTextureSetImporter(parser).GetTextureParamsDistinct().ToArray(); Assert.AreEqual(1, items.Length); } @@ -225,7 +225,7 @@ namespace UniGLTF { GLTF = TwoTextureOneImage(), }; - var items = GltfTextureEnumerator.EnumerateAllTexturesDistinct(parser).ToArray(); + var items = new GltfTextureSetImporter(parser).GetTextureParamsDistinct().ToArray(); Assert.AreEqual(1, items.Length); } @@ -234,7 +234,7 @@ namespace UniGLTF { GLTF = CombineMetallicSmoothOcclusion(), }; - var items = GltfTextureEnumerator.EnumerateAllTexturesDistinct(parser).ToArray(); + var items = new GltfTextureSetImporter(parser).GetTextureParamsDistinct().ToArray(); Assert.AreEqual(1, items.Length); } } diff --git a/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs b/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs index 41589cad0..6f1ff0054 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs @@ -91,14 +91,14 @@ namespace UniGLTF parser.ParsePath(path.FullName); // load - var loader = new ImporterContext(parser); - loader.Load(); + var context = new ImporterContext(parser); + context.Load(); // extractor - var extractor = new TextureExtractor(parser, UnityPath.FromUnityPath(""), loader.TextureFactory.ConvertedTextures); - var m = GltfTextureEnumerator.EnumerateTexturesReferencedByMaterials(parser, 0).FirstOrDefault(x => x.Item1.Name == "texture_1.standard"); + var extractor = new TextureExtractor(parser, UnityPath.FromUnityPath(""), context.TextureFactory.ConvertedTextures); + var m = context.TextureSetImporter.GetTextureParamsDistinct().FirstOrDefault(x => x.SubAssetKey.Name == "texture_1.standard"); - Assert.Catch(() => extractor.Extract(m.Item1, m.Item2)); + Assert.Catch(() => extractor.Extract(m.SubAssetKey, m)); } } } diff --git a/Assets/VRM/Editor/Format/VRMEditorImporterContext.cs b/Assets/VRM/Editor/Format/VRMEditorImporterContext.cs index 6cbd005ac..eb36e54d2 100644 --- a/Assets/VRM/Editor/Format/VRMEditorImporterContext.cs +++ b/Assets/VRM/Editor/Format/VRMEditorImporterContext.cs @@ -14,6 +14,7 @@ namespace VRM UnityPath m_prefabPath; List m_paths = new List(); + public ITextureSetImporter TextureSetImporter => m_context.TextureSetImporter; public VRMEditorImporterContext(VRMImporterContext context, UnityPath prefabPath) { @@ -104,7 +105,7 @@ namespace VRM var subAssets = m_context.TextureFactory.ConvertedTextures; var vrmTextures = new VRMMaterialImporter(m_context.VRM); var dirName = $"{m_prefabPath.FileNameWithoutExtension}.Textures"; - TextureExtractor.ExtractTextures(m_context.Parser, m_prefabPath.Parent.Child(dirName), vrmTextures.EnumerateAllTexturesDistinct, subAssets, (_x, _y) => { }, onTextureReloaded); + TextureExtractor.ExtractTextures(m_context.Parser, m_prefabPath.Parent.Child(dirName), m_context.TextureSetImporter, subAssets, (_x, _y) => { }, onTextureReloaded); } bool SaveAsAsset(UnityEngine.Object o) diff --git a/Assets/VRM/Editor/Format/VRMImporterMenu.cs b/Assets/VRM/Editor/Format/VRMImporterMenu.cs index 4ff0a99c6..faca0f0a1 100644 --- a/Assets/VRM/Editor/Format/VRMImporterMenu.cs +++ b/Assets/VRM/Editor/Format/VRMImporterMenu.cs @@ -84,7 +84,7 @@ namespace VRM using (var context = new VRMImporterContext(parser, map)) { var editor = new VRMEditorImporterContext(context, prefabPath); - foreach (var (key, textureInfo) in new VRMMaterialImporter(context.VRM).EnumerateAllTexturesDistinct(parser)) + foreach (var textureInfo in editor.TextureSetImporter.GetTextureParamsDistinct()) { VRMShaders.TextureImporterConfigurator.Configure(textureInfo, context.TextureFactory.ExternalTextures); } diff --git a/Assets/VRM/Editor/Format/vrmAssetPostprocessor.cs b/Assets/VRM/Editor/Format/vrmAssetPostprocessor.cs index 82ec9f494..c5a3f56b9 100644 --- a/Assets/VRM/Editor/Format/vrmAssetPostprocessor.cs +++ b/Assets/VRM/Editor/Format/vrmAssetPostprocessor.cs @@ -59,7 +59,7 @@ namespace VRM using (var context = new VRMImporterContext(parser, map)) { var editor = new VRMEditorImporterContext(context, prefabPath); - foreach (var (key, textureInfo) in new VRMMaterialImporter(context.VRM).EnumerateAllTexturesDistinct(parser)) + foreach (var textureInfo in context.TextureSetImporter.GetTextureParamsDistinct()) { VRMShaders.TextureImporterConfigurator.Configure(textureInfo, context.TextureFactory.ExternalTextures); } diff --git a/Assets/VRM/Runtime/IO/MToonTextureParam.cs b/Assets/VRM/Runtime/IO/MToonTextureParam.cs deleted file mode 100644 index a22822de9..000000000 --- a/Assets/VRM/Runtime/IO/MToonTextureParam.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using UniGLTF; -using UnityEngine; -using VRMShaders; - - -namespace VRM -{ - public static class MToonTextureParam - { - public static (SubAssetKey, TextureImportParam) Create(GltfParser parser, int index, Vector2 offset, Vector2 scale, string prop, float metallicFactor, float roughnessFactor) - { - switch (prop) - { - case TextureImportParam.NORMAL_PROP: - return GltfTextureImporter.CreateNormal(parser, index, offset, scale); - - default: - return GltfTextureImporter.CreateSRGB(parser, index, offset, scale); - - case TextureImportParam.OCCLUSION_PROP: - case TextureImportParam.METALLIC_GLOSS_PROP: - throw new NotImplementedException(); - } - } - } -} diff --git a/Assets/VRM/Runtime/IO/MToonTextureParam.cs.meta b/Assets/VRM/Runtime/IO/MToonTextureParam.cs.meta deleted file mode 100644 index 382c9f4ec..000000000 --- a/Assets/VRM/Runtime/IO/MToonTextureParam.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a7af3a3bafe41a64db660a18b1c25097 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/VRM/Runtime/IO/VRMImporterContext.cs b/Assets/VRM/Runtime/IO/VRMImporterContext.cs index aaef4f6d6..11d5b5361 100644 --- a/Assets/VRM/Runtime/IO/VRMImporterContext.cs +++ b/Assets/VRM/Runtime/IO/VRMImporterContext.cs @@ -27,6 +27,7 @@ namespace VRM if (glTF_VRM_extensions.TryDeserialize(GLTF.extensions, out glTF_VRM_extensions vrm)) { VRM = vrm; + TextureSetImporter = new VRMTextureSetImporter(Parser, VRM); MaterialImporter = new VRMMaterialImporter(VRM); } else diff --git a/Assets/VRM/Runtime/IO/VRMMToonMaterialImporter.cs b/Assets/VRM/Runtime/IO/VRMMToonMaterialImporter.cs new file mode 100644 index 000000000..fe0d066b4 --- /dev/null +++ b/Assets/VRM/Runtime/IO/VRMMToonMaterialImporter.cs @@ -0,0 +1,79 @@ +using UniGLTF; +using UnityEngine; +using VRMShaders; + +namespace VRM +{ + public static class VRMMToonMaterialImporter + { + public static bool TryCreateParam(GltfParser parser, glTF_VRM_extensions vrm, int materialIdx, out MaterialImportParam param) + { + var vrmMaterial = vrm.materialProperties[materialIdx]; + if (vrmMaterial.shader == VRM.glTF_VRM_Material.VRM_USE_GLTFSHADER) + { + // fallback to gltf + param = default; + return false; + } + + // + // restore VRM material + // + // use material.name, because material name may renamed in GltfParser. + var name = parser.GLTF.materials[materialIdx].name; + param = new MaterialImportParam(name, vrmMaterial.shader); + + param.RenderQueue = vrmMaterial.renderQueue; + + foreach (var kv in vrmMaterial.floatProperties) + { + param.FloatValues.Add(kv.Key, kv.Value); + } + + foreach (var kv in vrmMaterial.vectorProperties) + { + // vector4 exclude TextureOffsetScale + if (!vrmMaterial.textureProperties.ContainsKey(kv.Key)) + { + var v = new Vector4(kv.Value[0], kv.Value[1], kv.Value[2], kv.Value[3]); + param.Vectors.Add(kv.Key, v); + } + } + + foreach (var kv in vrmMaterial.textureProperties) + { + if (VRMMToonTextureImporter.TryGetTextureFromMaterialProperty(parser, vrm, materialIdx, kv.Key, out var texture)) + { + param.TextureSlots.Add(kv.Key, texture.Item2); + } + } + + foreach (var kv in vrmMaterial.keywordMap) + { + if (kv.Value) + { + param.Actions.Add(material => material.EnableKeyword(kv.Key)); + } + else + { + param.Actions.Add(material => material.DisableKeyword(kv.Key)); + } + } + + foreach (var kv in vrmMaterial.tagMap) + { + param.Actions.Add(material => material.SetOverrideTag(kv.Key, kv.Value)); + } + + if (vrmMaterial.shader == MToon.Utils.ShaderName) + { + // TODO: Material拡張にMToonの項目が追加されたら旧バージョンのshaderPropから変換をかける + // インポート時にUniVRMに含まれるMToonのバージョンに上書きする + param.FloatValues[MToon.Utils.PropVersion] = MToon.Utils.VersionNumber; + } + + return true; + } + + } +} diff --git a/Assets/VRM/Runtime/IO/VRMMToonMaterialImporter.cs.meta b/Assets/VRM/Runtime/IO/VRMMToonMaterialImporter.cs.meta new file mode 100644 index 000000000..62eb10d7f --- /dev/null +++ b/Assets/VRM/Runtime/IO/VRMMToonMaterialImporter.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9278370bf609490fa83b1f7ccdf118c7 +timeCreated: 1622028284 \ No newline at end of file diff --git a/Assets/VRM/Runtime/IO/VRMMToonTextureImporter.cs b/Assets/VRM/Runtime/IO/VRMMToonTextureImporter.cs new file mode 100644 index 000000000..940753b8b --- /dev/null +++ b/Assets/VRM/Runtime/IO/VRMMToonTextureImporter.cs @@ -0,0 +1,64 @@ +using System.Collections.Generic; +using UniGLTF; +using UnityEngine; +using VRMShaders; + +namespace VRM +{ + public static class VRMMToonTextureImporter + { + public static IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateTexturesReferencedByMaterial(GltfParser parser, glTF_VRM_extensions vrm, int materialIdx) + { + var vrmMaterial = vrm.materialProperties[materialIdx]; + foreach (var kv in vrmMaterial.textureProperties) + { + if (TryGetTextureFromMaterialProperty(parser, vrm, materialIdx, kv.Key, out var texture)) + { + yield return texture; + } + } + } + + public static bool TryGetTextureFromMaterialProperty(GltfParser parser, glTF_VRM_extensions vrm, int materialIdx, string textureKey, out (SubAssetKey, TextureImportParam) texture) + { + var vrmMaterial = vrm.materialProperties[materialIdx]; + if (vrmMaterial.shader == MToon.Utils.ShaderName && vrmMaterial.textureProperties.TryGetValue(textureKey, out var textureIdx)) + { + var (offset, scale) = (new Vector2(0, 0), new Vector2(1, 1)); + if (TryGetTextureOffsetAndScale(vrm, materialIdx, textureKey, out var os)) + { + offset = os.offset; + scale = os.scale; + } + + switch (textureKey) + { + case MToon.Utils.PropBumpMap: + texture = GltfTextureImporter.CreateNormal(parser, textureIdx, offset, scale); + break; + default: + texture = GltfTextureImporter.CreateSRGB(parser, textureIdx, offset, scale); + break; + } + return true; + } + + texture = default; + return false; + } + + public static bool TryGetTextureOffsetAndScale(glTF_VRM_extensions vrm, int materialIdx, string unityTextureKey, out (Vector2 offset, Vector2 scale) os) + { + var vrmMaterial = vrm.materialProperties[materialIdx]; + + if (vrmMaterial.vectorProperties.TryGetValue(unityTextureKey, out var vector)) + { + os = (new Vector2(vector[0], vector[1]), new Vector2(vector[2], vector[3])); + return true; + } + + os = (new Vector2(0, 0), new Vector2(1, 1)); + return false; + } + } +} diff --git a/Assets/VRM/Runtime/IO/VRMMToonTextureImporter.cs.meta b/Assets/VRM/Runtime/IO/VRMMToonTextureImporter.cs.meta new file mode 100644 index 000000000..aca2fe8d3 --- /dev/null +++ b/Assets/VRM/Runtime/IO/VRMMToonTextureImporter.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6c6ca158f51f41fab48b800cc6c406eb +timeCreated: 1622028479 \ No newline at end of file diff --git a/Assets/VRM/Runtime/IO/VRMMaterialImporter.cs b/Assets/VRM/Runtime/IO/VRMMaterialImporter.cs index 2032d1c8b..d81118683 100644 --- a/Assets/VRM/Runtime/IO/VRMMaterialImporter.cs +++ b/Assets/VRM/Runtime/IO/VRMMaterialImporter.cs @@ -14,90 +14,10 @@ namespace VRM m_vrm = vrm; } - public bool TryCreateParam(GltfParser parser, int i, out MaterialImportParam param) - { - var vrmMaterial = m_vrm.materialProperties[i]; - if (vrmMaterial.shader == VRM.glTF_VRM_Material.VRM_USE_GLTFSHADER) - { - // fallback to gltf - param = default; - return false; - } - - // - // restore VRM material - // - // use material.name, because material name may renamed in GltfParser. - var name = parser.GLTF.materials[i].name; - param = new MaterialImportParam(name, vrmMaterial.shader); - - param.RenderQueue = vrmMaterial.renderQueue; - - foreach (var kv in vrmMaterial.floatProperties) - { - param.FloatValues.Add(kv.Key, kv.Value); - } - - var offsetScaleMap = new Dictionary(); - foreach (var kv in vrmMaterial.vectorProperties) - { - if (vrmMaterial.textureProperties.ContainsKey(kv.Key)) - { - // texture offset & scale - offsetScaleMap.Add(kv.Key, kv.Value); - } - else - { - // vector4 - var v = new Vector4(kv.Value[0], kv.Value[1], kv.Value[2], kv.Value[3]); - param.Vectors.Add(kv.Key, v); - } - } - - foreach (var kv in vrmMaterial.textureProperties) - { - var (offset, scale) = (Vector2.zero, Vector2.one); - if (offsetScaleMap.TryGetValue(kv.Key, out float[] value)) - { - offset = new Vector2(value[0], value[1]); - scale = new Vector2(value[2], value[3]); - } - - var (key, textureParam) = MToonTextureParam.Create(parser, kv.Value, offset, scale, kv.Key, 1, 1); - param.TextureSlots.Add(kv.Key, textureParam); - } - - foreach (var kv in vrmMaterial.keywordMap) - { - if (kv.Value) - { - param.Actions.Add(material => material.EnableKeyword(kv.Key)); - } - else - { - param.Actions.Add(material => material.DisableKeyword(kv.Key)); - } - } - - foreach (var kv in vrmMaterial.tagMap) - { - param.Actions.Add(material => material.SetOverrideTag(kv.Key, kv.Value)); - } - - if (vrmMaterial.shader == MToon.Utils.ShaderName) - { - // TODO: Material拡張にMToonの項目が追加されたら旧バージョンのshaderPropから変換をかける - // インポート時にUniVRMに含まれるMToonのバージョンに上書きする - param.FloatValues[MToon.Utils.PropVersion] = MToon.Utils.VersionNumber; - } - - return true; - } - public MaterialImportParam GetMaterialParam(GltfParser parser, int i) { // mtoon - if (!TryCreateParam(parser, i, out MaterialImportParam param)) + if (!VRMMToonMaterialImporter.TryCreateParam(parser, m_vrm, i, out MaterialImportParam param)) { // unlit if (!GltfUnlitMaterialImporter.TryCreateParam(parser, i, out param)) @@ -115,51 +35,5 @@ namespace VRM } return param; } - - public IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateAllTexturesDistinct(GltfParser parser) - { - var used = new HashSet(); - - for (int i = 0; i < parser.GLTF.materials.Count; ++i) - { - var vrmMaterial = m_vrm.materialProperties[i]; - if (vrmMaterial.shader == MToon.Utils.ShaderName) - { - // MToon - if (!TryCreateParam(parser, i, out MaterialImportParam param)) - { - throw new Exception(); - } - foreach (var (key, value) in param.EnumerateSubAssetKeyValue()) - { - if (used.Add(key)) - { - yield return (key, value); - } - } - } - else - { - // PBR or Unlit - foreach (var (key, value) in GltfTextureEnumerator.EnumerateTexturesReferencedByMaterials(parser, i)) - { - if (used.Add(key)) - { - yield return (key, value); - } - } - } - } - - // thumbnail - if (m_vrm.meta != null && m_vrm.meta.texture != -1) - { - var (key, value) = GltfTextureImporter.CreateSRGB(parser, m_vrm.meta.texture, Vector2.zero, Vector2.one); - if (used.Add(key)) - { - yield return (key, value); - } - } - } } } diff --git a/Assets/VRM/Runtime/IO/VRMTextureSetImporter.cs b/Assets/VRM/Runtime/IO/VRMTextureSetImporter.cs new file mode 100644 index 000000000..cb2d85e29 --- /dev/null +++ b/Assets/VRM/Runtime/IO/VRMTextureSetImporter.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using UniGLTF; +using UnityEngine; +using VRMShaders; + +namespace VRM +{ + public sealed class VRMTextureSetImporter : ITextureSetImporter + { + private readonly GltfParser m_parser; + private readonly glTF_VRM_extensions m_vrm; + + public VRMTextureSetImporter(GltfParser parser, glTF_VRM_extensions vrm) + { + m_parser = parser; + m_vrm = vrm; + } + + public IEnumerable GetTextureParamsDistinct() + { + var usedTextures = new HashSet(); + foreach (var (_, param) in EnumerateAllTextures(m_parser, m_vrm)) + { + if (usedTextures.Add(param.SubAssetKey)) + { + yield return param; + } + } + } + + private static IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateAllTextures(GltfParser parser, glTF_VRM_extensions vrm) + { + // Materials + for (var materialIdx = 0; materialIdx < parser.GLTF.materials.Count; ++materialIdx) + { + var material = parser.GLTF.materials[materialIdx]; + var vrmMaterial = vrm.materialProperties[materialIdx]; + + if (vrmMaterial.shader == MToon.Utils.ShaderName) + { + // MToon + foreach (var kv in VRMMToonTextureImporter.EnumerateTexturesReferencedByMaterial(parser, vrm, materialIdx)) + { + yield return kv; + } + } + else + { + // Unlit or PBR + foreach (var kv in GltfPbrTextureImporter.EnumerateTexturesReferencedByMaterial(parser, materialIdx)) + { + yield return kv; + } + } + } + + // Thumbnail + if (TryGetThumbnailTexture(parser, vrm, out var thumbnail)) + { + yield return thumbnail; + } + } + + private static bool TryGetThumbnailTexture(GltfParser parser, glTF_VRM_extensions vrm, out (SubAssetKey, TextureImportParam) texture) + { + if (vrm.meta.texture > -1) + { + texture = GltfTextureImporter.CreateSRGB(parser, vrm.meta.texture, Vector2.zero, Vector2.one); + return true; + } + + texture = default; + return false; + } + } +} diff --git a/Assets/VRM/Runtime/IO/VRMTextureSetImporter.cs.meta b/Assets/VRM/Runtime/IO/VRMTextureSetImporter.cs.meta new file mode 100644 index 000000000..5745712a8 --- /dev/null +++ b/Assets/VRM/Runtime/IO/VRMTextureSetImporter.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f9d2e1522c584b49bbe9c2875eae3370 +timeCreated: 1622024170 \ No newline at end of file diff --git a/Assets/VRM/Tests/MToonTest.cs b/Assets/VRM/Tests/MToonTest.cs index e9b43dda0..612c4c5a4 100644 --- a/Assets/VRM/Tests/MToonTest.cs +++ b/Assets/VRM/Tests/MToonTest.cs @@ -51,10 +51,8 @@ namespace VRM var importer = new VRMImporterContext(parser, null); - var materialImporter = new VRMMaterialImporter(importer.VRM); - Assert.AreEqual(73, parser.GLTF.materials.Count); - Assert.True(materialImporter.TryCreateParam(parser, 0, out MaterialImportParam param)); + Assert.True(VRMMToonMaterialImporter.TryCreateParam(parser, importer.VRM, 0, out MaterialImportParam param)); } static string AliciaPath diff --git a/Assets/VRM/Tests/VRMTextureEnumerateTests.cs b/Assets/VRM/Tests/VRMTextureEnumerateTests.cs index 18d544b66..9c812060f 100644 --- a/Assets/VRM/Tests/VRMTextureEnumerateTests.cs +++ b/Assets/VRM/Tests/VRMTextureEnumerateTests.cs @@ -72,7 +72,7 @@ namespace VRM }, } }; - var items = new VRMMaterialImporter(vrm).EnumerateAllTexturesDistinct(parser).ToArray(); + var items = new VRMTextureSetImporter(parser, vrm).GetTextureParamsDistinct().ToArray(); Assert.AreEqual(1, items.Length); } } diff --git a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs index 1d8f69369..14cf8ca24 100644 --- a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs +++ b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs @@ -69,7 +69,7 @@ namespace UniVRM10 case Tabs.Materials: if (m_parser != null) { - EditorMaterial.OnGUI(m_importer, m_parser, Vrm10TextureEnumerator.EnumerateAllTexturesDistinct, + EditorMaterial.OnGUI(m_importer, m_parser, new Vrm10TextureSetImporter(m_parser), assetPath => $"{Path.GetFileNameWithoutExtension(assetPath)}.vrm1.Textures", assetPath => $"{Path.GetFileNameWithoutExtension(assetPath)}.vrm1.Materials"); } diff --git a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs index fb43fc264..8222b36e1 100644 --- a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs +++ b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs @@ -101,7 +101,7 @@ namespace UniVRM10 using (var loader = new Vrm10Importer(parser, extractedObjects)) { // settings TextureImporters - foreach (var (key, textureInfo) in Vrm10TextureEnumerator.EnumerateAllTexturesDistinct(parser)) + foreach (var textureInfo in loader.TextureSetImporter.GetTextureParamsDistinct()) { VRMShaders.TextureImporterConfigurator.Configure(textureInfo, loader.TextureFactory.ExternalTextures); } diff --git a/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialParameterImporter.cs b/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialImporter.cs similarity index 83% rename from Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialParameterImporter.cs rename to Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialImporter.cs index dcaaf9f80..7857cb613 100644 --- a/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialParameterImporter.cs +++ b/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialImporter.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using UniGLTF; using UniGLTF.Extensions.VRMC_materials_mtoon; using UnityEngine; +using VRMShaders; using ColorSpace = UniGLTF.ColorSpace; using OutlineWidthMode = UniGLTF.Extensions.VRMC_materials_mtoon.OutlineWidthMode; @@ -11,12 +12,60 @@ namespace UniVRM10 /// /// Convert MToon parameters from glTF specification to Unity implementation. /// - public static class Vrm10MToonMaterialParameterImporter + public static class Vrm10MToonMaterialImporter { + /// + /// VMRC_materials_mtoon の場合にマテリアル生成情報を作成する + /// + public static bool TryCreateParam(GltfParser parser, int i, out MaterialImportParam param) + { + var m = parser.GLTF.materials[i]; + if (!UniGLTF.Extensions.VRMC_materials_mtoon.GltfDeserializer.TryGet(m.extensions, + out UniGLTF.Extensions.VRMC_materials_mtoon.VRMC_materials_mtoon mtoon)) + { + // Fallback to glTF, when MToon extension does not exist. + param = default; + return false; + } + + // use material.name, because material name may renamed in GltfParser. + param = new MaterialImportParam(m.name, MToon.Utils.ShaderName); + + foreach (var (key, (subAssetKey, value)) in Vrm10MToonTextureImporter.TryGetAllTextures(parser, m, mtoon)) + { + param.TextureSlots.Add(key, value); + } + + foreach (var (key, value) in TryGetAllColors(m, mtoon)) + { + param.Colors.Add(key, value); + } + + foreach (var (key, value) in TryGetAllFloats(m, mtoon)) + { + param.FloatValues.Add(key, value); + } + + foreach (var (key, value) in TryGetAllFloatArrays(m, mtoon)) + { + param.Vectors.Add(key, value); + } + + param.RenderQueue = TryGetRenderQueue(m, mtoon); + + param.Actions.Add(material => + { + // Set hidden properties, keywords from float properties. + MToon.Utils.ValidateProperties(material, isBlendModeChangedByUser: false); + }); + + return true; + } + public static IEnumerable<(string key, Color value)> TryGetAllColors(glTFMaterial material, VRMC_materials_mtoon mToon) { const ColorSpace gltfColorSpace = ColorSpace.Linear; - + var baseColor = material?.pbrMetallicRoughness?.baseColorFactor?.ToColor4(gltfColorSpace, ColorSpace.sRGB); if (baseColor.HasValue) { @@ -63,23 +112,23 @@ namespace UniVRM10 var outlineMode = GetMToonOutlineWidthMode(material, mToon); { yield return (MToon.Utils.PropOutlineWidthMode, (float) outlineMode); - + // In case of VRM 1.0 MToon, outline color mode is always MixedLighting. yield return (MToon.Utils.PropOutlineColorMode, (float) MToon.OutlineColorMode.MixedLighting); } - + var cutoff = material?.alphaCutoff; if (cutoff.HasValue) { yield return (MToon.Utils.PropCutoff, cutoff.Value); } - + var normalScale = material?.normalTexture?.scale; if (normalScale.HasValue) { yield return ("_BumpScale", normalScale.Value); } - + var shadingShift = mToon?.ShadingShiftFactor; if (shadingShift.HasValue) { @@ -144,14 +193,14 @@ namespace UniVRM10 { yield return (MToon.Utils.PropUvAnimScrollX, uvAnimSpeedScrollX.Value); } - + // UV coords conversion. // glTF (top-left origin) to Unity (bottom-left origin) var uvAnimSpeedScrollY = mToon?.UvAnimationScrollYSpeedFactor; if (uvAnimSpeedScrollY.HasValue) { const float invertY = -1f; - + yield return (MToon.Utils.PropUvAnimScrollY, uvAnimSpeedScrollY.Value * invertY); } @@ -241,4 +290,4 @@ namespace UniVRM10 } } } -} \ No newline at end of file +} diff --git a/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialParameterImporter.cs.meta b/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialImporter.cs.meta similarity index 100% rename from Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialParameterImporter.cs.meta rename to Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialImporter.cs.meta diff --git a/Assets/VRM10/Runtime/IO/Material/Vrm10MaterialImporter.cs b/Assets/VRM10/Runtime/IO/Material/Vrm10MaterialImporter.cs new file mode 100644 index 000000000..484fd3d55 --- /dev/null +++ b/Assets/VRM10/Runtime/IO/Material/Vrm10MaterialImporter.cs @@ -0,0 +1,32 @@ +using UniGLTF; +using UnityEngine; +using VRMShaders; + +namespace UniVRM10 +{ + public sealed class Vrm10MaterialImporter : IMaterialImporter + { + public MaterialImportParam GetMaterialParam(GltfParser parser, int i) + { + // mtoon + if (!Vrm10MToonMaterialImporter.TryCreateParam(parser, i, out MaterialImportParam param)) + { + // unlit + if (!GltfUnlitMaterialImporter.TryCreateParam(parser, i, out param)) + { + // pbr + if (!GltfPbrMaterialImporter.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), GltfPbrMaterialImporter.ShaderName); + } + } + } + return param; + } + + } +} diff --git a/Assets/VRM10/Runtime/IO/Vrm10MaterialImporter.cs.meta b/Assets/VRM10/Runtime/IO/Material/Vrm10MaterialImporter.cs.meta similarity index 100% rename from Assets/VRM10/Runtime/IO/Vrm10MaterialImporter.cs.meta rename to Assets/VRM10/Runtime/IO/Material/Vrm10MaterialImporter.cs.meta diff --git a/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialTextureImporter.cs b/Assets/VRM10/Runtime/IO/Texture/Vrm10MToonTextureImporter.cs similarity index 96% rename from Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialTextureImporter.cs rename to Assets/VRM10/Runtime/IO/Texture/Vrm10MToonTextureImporter.cs index 127f9a7e7..81f44f04f 100644 --- a/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialTextureImporter.cs +++ b/Assets/VRM10/Runtime/IO/Texture/Vrm10MToonTextureImporter.cs @@ -7,7 +7,7 @@ using VRMShaders; namespace UniVRM10 { - public static class Vrm10MToonMaterialTextureImporter + public static class Vrm10MToonTextureImporter { public static IEnumerable<(string key, (SubAssetKey, TextureImportParam))> TryGetAllTextures(GltfParser parser, glTFMaterial material, VRMC_materials_mtoon mToon) { @@ -62,7 +62,7 @@ namespace UniVRM10 { try { - pair = GltfPbrMaterialImporter.BaseColorTexture(parser, src); + pair = GltfPbrTextureImporter.BaseColorTexture(parser, src); return true; } catch (NullReferenceException) @@ -81,7 +81,7 @@ namespace UniVRM10 { try { - pair = GltfPbrMaterialImporter.EmissiveTexture(parser, src); + pair = GltfPbrTextureImporter.EmissiveTexture(parser, src); return true; } catch (NullReferenceException) @@ -101,7 +101,7 @@ namespace UniVRM10 { try { - pair = GltfPbrMaterialImporter.NormalTexture(parser, src); + pair = GltfPbrTextureImporter.NormalTexture(parser, src); return true; } catch (NullReferenceException) diff --git a/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialTextureImporter.cs.meta b/Assets/VRM10/Runtime/IO/Texture/Vrm10MToonTextureImporter.cs.meta similarity index 100% rename from Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialTextureImporter.cs.meta rename to Assets/VRM10/Runtime/IO/Texture/Vrm10MToonTextureImporter.cs.meta diff --git a/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureEnumerator.cs b/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureSetImporter.cs similarity index 60% rename from Assets/VRM10/Runtime/IO/Texture/Vrm10TextureEnumerator.cs rename to Assets/VRM10/Runtime/IO/Texture/Vrm10TextureSetImporter.cs index 2c05cb8e1..eaf610220 100644 --- a/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureEnumerator.cs +++ b/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureSetImporter.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Threading.Tasks; using UniGLTF; using UnityEngine; @@ -6,39 +7,62 @@ using VRMShaders; namespace UniVRM10 { - public static class Vrm10TextureEnumerator + public sealed class Vrm10TextureSetImporter : ITextureSetImporter { + private readonly GltfParser m_parser; + + public Vrm10TextureSetImporter(GltfParser parser) + { + m_parser = parser; + } + + public IEnumerable GetTextureParamsDistinct() + { + var usedTextures = new HashSet(); + foreach (var (_, param) in EnumerateAllTexturesDistinct(m_parser)) + { + if (usedTextures.Add(param.SubAssetKey)) + { + yield return param; + } + } + } + /// - /// glTF 全体で使うテクスチャーをユニークになるように列挙する + /// glTF 全体で使うテクスチャーを列挙する /// - public static IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateAllTexturesDistinct(GltfParser parser) + private static IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateAllTexturesDistinct(GltfParser parser) { if (!UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.TryGet(parser.GLTF.extensions, out UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm)) { throw new System.Exception("not vrm"); } - var usedTextures = new HashSet(); + // Textures referenced by Materials. + for (var materialIdx = 0; materialIdx < parser.GLTF.materials.Count; ++materialIdx) + { + var m = parser.GLTF.materials[materialIdx]; + if (UniGLTF.Extensions.VRMC_materials_mtoon.GltfDeserializer.TryGet(m.extensions, out var mToon)) + { + foreach (var (_, tex) in Vrm10MToonTextureImporter.TryGetAllTextures(parser, m, mToon)) + { + yield return tex; + } + } + else + { + // Fallback to glTF PBR & glTF Unlit + foreach (var tex in GltfPbrTextureImporter.EnumerateTexturesReferencedByMaterial(parser, materialIdx)) + { + yield return tex; + } + } + } // Thumbnail Texture referenced by VRM Meta. if (TryGetMetaThumbnailTextureImportParam(parser, vrm, out (SubAssetKey key, TextureImportParam) thumbnail)) { - if (usedTextures.Add(thumbnail.key)) - { - yield return thumbnail; - } - } - - // Textures referenced by Materials. - for (int i = 0; i < parser.GLTF.materials.Count; ++i) - { - foreach ((SubAssetKey key, TextureImportParam) kv in EnumerateTexturesReferencedByMaterials(parser, i)) - { - if (usedTextures.Add(kv.key)) - { - yield return kv; - } - } + yield return thumbnail; } } @@ -69,29 +93,5 @@ namespace UniVRM10 value = (param.SubAssetKey, param); return true; } - - /// - /// Material によって参照されている Texture を Enumerate する. - /// まず VRM Material だと仮定して処理し, 失敗すれば glTF Material だとして処理する. - /// - private static IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateTexturesReferencedByMaterials(GltfParser parser, int i) - { - var m = parser.GLTF.materials[i]; - if (UniGLTF.Extensions.VRMC_materials_mtoon.GltfDeserializer.TryGet(m.extensions, out var mToon)) - { - foreach (var (key, tex) in Vrm10MToonMaterialTextureImporter.TryGetAllTextures(parser, m, mToon)) - { - yield return tex; - } - } - else - { - // Fallback to glTF PBR & glTF Unlit - foreach (var kv in GltfTextureEnumerator.EnumerateTexturesReferencedByMaterials(parser, i)) - { - yield return kv; - } - } - } } } diff --git a/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureEnumerator.cs.meta b/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureSetImporter.cs.meta similarity index 100% rename from Assets/VRM10/Runtime/IO/Texture/Vrm10TextureEnumerator.cs.meta rename to Assets/VRM10/Runtime/IO/Texture/Vrm10TextureSetImporter.cs.meta diff --git a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs index 8094490c3..86fe8387d 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs @@ -280,7 +280,7 @@ namespace UniVRM10 { m_meta.Authors.AddRange(src.Authors); } - if (Vrm10TextureEnumerator.TryGetMetaThumbnailTextureImportParam(Parser, vrm, out (SubAssetKey, VRMShaders.TextureImportParam Param) kv)) + if (Vrm10TextureSetImporter.TryGetMetaThumbnailTextureImportParam(Parser, vrm, out (SubAssetKey, VRMShaders.TextureImportParam Param) kv)) { var texture = await TextureFactory.GetTextureAsync(kv.Param); if (texture is Texture2D tex2D) diff --git a/Assets/VRM10/Runtime/IO/Vrm10MaterialImporter.cs b/Assets/VRM10/Runtime/IO/Vrm10MaterialImporter.cs deleted file mode 100644 index 384fa7902..000000000 --- a/Assets/VRM10/Runtime/IO/Vrm10MaterialImporter.cs +++ /dev/null @@ -1,79 +0,0 @@ -using UniGLTF; -using UnityEngine; -using VRMShaders; - -namespace UniVRM10 -{ - public sealed class Vrm10MaterialImporter : IMaterialImporter - { - public MaterialImportParam GetMaterialParam(GltfParser parser, int i) - { - // mtoon - if (!TryCreateMToonParam(parser, i, out MaterialImportParam param)) - { - // unlit - if (!GltfUnlitMaterialImporter.TryCreateParam(parser, i, out param)) - { - // pbr - if (!GltfPbrMaterialImporter.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), GltfPbrMaterialImporter.ShaderName); - } - } - } - return param; - } - - /// - /// VMRC_materials_mtoon の場合にマテリアル生成情報を作成する - /// - 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, - out UniGLTF.Extensions.VRMC_materials_mtoon.VRMC_materials_mtoon mtoon)) - { - // Fallback to glTF, when MToon extension does not exist. - param = default; - return false; - } - - // use material.name, because material name may renamed in GltfParser. - param = new MaterialImportParam(m.name, MToon.Utils.ShaderName); - - foreach (var (key, (subAssetKey, value)) in Vrm10MToonMaterialTextureImporter.TryGetAllTextures(parser, m, mtoon)) - { - param.TextureSlots.Add(key, value); - } - - foreach (var (key, value) in Vrm10MToonMaterialParameterImporter.TryGetAllColors(m, mtoon)) - { - param.Colors.Add(key, value); - } - - foreach (var (key, value) in Vrm10MToonMaterialParameterImporter.TryGetAllFloats(m, mtoon)) - { - param.FloatValues.Add(key, value); - } - - foreach (var (key, value) in Vrm10MToonMaterialParameterImporter.TryGetAllFloatArrays(m, mtoon)) - { - param.Vectors.Add(key, value); - } - - param.RenderQueue = Vrm10MToonMaterialParameterImporter.TryGetRenderQueue(m, mtoon); - - param.Actions.Add(material => - { - // Set hidden properties, keywords from float properties. - MToon.Utils.ValidateProperties(material, isBlendModeChangedByUser: false); - }); - - return true; - } - } -} diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/TextureImportParam.cs b/Assets/VRMShaders/GLTF/IO/Runtime/TextureImportParam.cs index 16338709c..0f99d4e0c 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/TextureImportParam.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/TextureImportParam.cs @@ -20,11 +20,6 @@ namespace VRMShaders /// public readonly struct TextureImportParam { - public const string NORMAL_PROP = "_BumpMap"; - - public const string METALLIC_GLOSS_PROP = "_MetallicGlossMap"; - public const string OCCLUSION_PROP = "_OcclusionMap"; - public readonly string UnityObjectName; public readonly string Ext; public readonly string Uri; From 7aecbc794957be2f786ef824cf040143be16ca87 Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Wed, 26 May 2021 21:32:13 +0900 Subject: [PATCH 3/4] Use Vrm10TextureSetImporter in Vrm10Importer --- Assets/VRM10/Runtime/IO/Vrm10Importer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs index 86fe8387d..7476f3d97 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs @@ -24,6 +24,7 @@ namespace UniVRM10 public Vrm10Importer(UniGLTF.GltfParser parser, IReadOnlyDictionary externalObjectMap = null) : base(parser, externalObjectMap) { + TextureSetImporter = new Vrm10TextureSetImporter(parser); MaterialImporter = new Vrm10MaterialImporter(); m_externalMap = externalObjectMap; From 6ebd030f3a54cc0ba3a091b5c9606637291fda3c Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Wed, 26 May 2021 21:50:23 +0900 Subject: [PATCH 4/4] Ignore enumerating if vrm is 0 --- .../Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs index 14cf8ca24..b106ac3ab 100644 --- a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs +++ b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs @@ -67,7 +67,7 @@ namespace UniVRM10 break; case Tabs.Materials: - if (m_parser != null) + if (m_parser != null && m_vrm != null) { EditorMaterial.OnGUI(m_importer, m_parser, new Vrm10TextureSetImporter(m_parser), assetPath => $"{Path.GetFileNameWithoutExtension(assetPath)}.vrm1.Textures", @@ -76,7 +76,7 @@ namespace UniVRM10 break; case Tabs.Vrm: - if (m_parser != null) + if (m_parser != null && m_vrm != null) { EditorVrm.OnGUI(m_importer, m_parser, m_vrm); }