Refactor Texture enumeration to TextureSetImport

This commit is contained in:
Masataka SUMI 2021-05-26 21:22:34 +09:00
parent 58e7faee32
commit a6d730d15f
46 changed files with 611 additions and 506 deletions

View File

@ -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<string, string> textureDir, Func<string, string> materialDir)
public static void OnGUI(ScriptedImporter importer, GltfParser parser, ITextureSetImporter textureSetImporter, Func<string, string> textureDir, Func<string, string> 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<UnityEngine.Texture>(enumTextures(parser).Select(x => x.Key));
importer.DrawRemapGUI<UnityEngine.Texture>(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<string, string> textureDir, Func<string, string> materialDir)
static void ExtractMaterialsAndTextures(ScriptedImporter self, GltfParser parser, ITextureSetImporter textureSetImporter, Func<string, string> textureDir, Func<string, string> 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<Texture>(self.assetPath).ToDictionary(kv => kv.Item1, kv => kv.Item2),
addRemap,
onCompleted
);
);
}
public static void ExtractMaterials(this ScriptedImporter importer, Func<string, string> materialDir)

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -75,14 +75,14 @@ namespace UniGLTF
/// <param name="dirName"></param>
/// <param name="onCompleted"></param>
public static void ExtractTextures(GltfParser parser, UnityPath textureDirectory,
EnumerateAllTexturesDistinctFunc textureEnumerator, IReadOnlyDictionary<SubAssetKey, Texture> subAssets,
ITextureSetImporter textureSetImporter, IReadOnlyDictionary<SubAssetKey, Texture> subAssets,
Action<SubAssetKey, Texture2D> addRemap,
Action<IEnumerable<UnityPath>> 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 += () =>

View File

@ -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<SubAssetKey, UnityEngine.Object> externalObjectMap = null)
{
m_parser = parser;
Parser = parser;
TextureSetImporter = new GltfTextureSetImporter(Parser);
MaterialImporter = new GltfMaterialImporter();
externalObjectMap = externalObjectMap ?? new Dictionary<SubAssetKey, UnityEngine.Object>();
@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9a1c5210d71f47ab80a1549b77c9a8a3
timeCreated: 1622027042

View File

@ -1,97 +0,0 @@
using System;
using System.Collections.Generic;
using VRMShaders;
namespace UniGLTF
{
public delegate IEnumerable<(SubAssetKey Key, TextureImportParam Param)> EnumerateAllTexturesDistinctFunc(GltfParser parser);
/// <summary>
/// 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 化する
/// </summary>
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);
}
}
/// <summary>
/// glTF 全体で使うテクスチャーをユニークになるように列挙する
/// </summary>
/// <param name="parser"></param>
/// <returns></returns>
public static IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateAllTexturesDistinct(GltfParser parser)
{
var usedTextures = new HashSet<SubAssetKey>();
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;
}
}
}
}
}
}

View File

@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.Linq;
using VRMShaders;
namespace UniGLTF
{
/// <summary>
/// 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 化する
/// </summary>
public sealed class GltfTextureSetImporter : ITextureSetImporter
{
private readonly GltfParser m_parser;
public GltfTextureSetImporter(GltfParser parser)
{
m_parser = parser;
}
public IEnumerable<TextureImportParam> GetTextureParamsDistinct()
{
var usedTextures = new HashSet<SubAssetKey>();
foreach (var (key, param) in EnumerateAllTextures(m_parser))
{
if (usedTextures.Add(key))
{
yield return param;
}
}
}
/// <summary>
/// glTF 全体で使うテクスチャーを列挙。
/// </summary>
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;
}
}
}
}
}

View File

@ -1,15 +0,0 @@
using System.Collections.Generic;
using VRMShaders;
namespace UniGLTF
{
/// <summary>
/// glTF から Import できる Texture の生成情報のリストを生成する。
///
/// glTF Texture と Unity Texture の対応関係は N:M である。
/// </summary>
public interface ITextureImporter
{
IReadOnlyDictionary<SubAssetKey, TextureImportParam> GetTextureParams(GltfParser parser);
}
}

View File

@ -0,0 +1,15 @@
using System.Collections.Generic;
using VRMShaders;
namespace UniGLTF
{
/// <summary>
/// glTF から Import できる、すべての Texture の生成情報を生成する。
///
/// glTF Texture と Unity Texture の対応関係は N:M である。
/// </summary>
public interface ITextureSetImporter
{
IEnumerable<TextureImportParam> GetTextureParamsDistinct();
}
}

View File

@ -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));
}

View File

@ -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);
}
}

View File

@ -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<NotImplementedException>(() => extractor.Extract(m.Item1, m.Item2));
Assert.Catch<NotImplementedException>(() => extractor.Extract(m.SubAssetKey, m));
}
}
}

View File

@ -14,6 +14,7 @@ namespace VRM
UnityPath m_prefabPath;
List<UnityPath> m_paths = new List<UnityPath>();
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)

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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();
}
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: a7af3a3bafe41a64db660a18b1c25097
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9278370bf609490fa83b1f7ccdf118c7
timeCreated: 1622028284

View File

@ -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;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6c6ca158f51f41fab48b800cc6c406eb
timeCreated: 1622028479

View File

@ -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<string, float[]>();
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<SubAssetKey>();
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);
}
}
}
}
}

View File

@ -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<TextureImportParam> GetTextureParamsDistinct()
{
var usedTextures = new HashSet<SubAssetKey>();
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;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f9d2e1522c584b49bbe9c2875eae3370
timeCreated: 1622024170

View File

@ -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

View File

@ -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);
}
}

View File

@ -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");
}

View File

@ -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);
}

View File

@ -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
/// <summary>
/// Convert MToon parameters from glTF specification to Unity implementation.
/// </summary>
public static class Vrm10MToonMaterialParameterImporter
public static class Vrm10MToonMaterialImporter
{
/// <summary>
/// VMRC_materials_mtoon の場合にマテリアル生成情報を作成する
/// </summary>
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
}
}
}
}
}

View File

@ -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;
}
}
}

View File

@ -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)

View File

@ -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<TextureImportParam> GetTextureParamsDistinct()
{
var usedTextures = new HashSet<SubAssetKey>();
foreach (var (_, param) in EnumerateAllTexturesDistinct(m_parser))
{
if (usedTextures.Add(param.SubAssetKey))
{
yield return param;
}
}
}
/// <summary>
/// glTF 全体で使うテクスチャーをユニークになるように列挙する
/// glTF 全体で使うテクスチャーを列挙する
/// </summary>
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<SubAssetKey>();
// 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;
}
/// <summary>
/// Material によって参照されている Texture を Enumerate する.
/// まず VRM Material だと仮定して処理し, 失敗すれば glTF Material だとして処理する.
/// </summary>
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;
}
}
}
}
}

View File

@ -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)

View File

@ -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;
}
/// <summary>
/// VMRC_materials_mtoon の場合にマテリアル生成情報を作成する
/// </summary>
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;
}
}
}

View File

@ -20,11 +20,6 @@ namespace VRMShaders
/// </summary>
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;