Define IMaterialExporter, IMaterialImporter

This commit is contained in:
Masataka SUMI 2021-05-26 17:19:17 +09:00
parent 5664c7586a
commit e5d0e927b4
14 changed files with 115 additions and 91 deletions

View File

@ -32,23 +32,21 @@ namespace UniGLTF
#endregion
MaterialFactory m_materialFactory;
public MaterialFactory MaterialFactory => m_materialFactory;
public readonly GltfMaterialImporter GltfMaterialImporter = new GltfMaterialImporter();
TextureFactory m_textureFactory;
public TextureFactory TextureFactory => m_textureFactory;
public IMaterialImporter MaterialImporter { get; protected set; }
public TextureFactory TextureFactory { get; }
public MaterialFactory MaterialFactory { get; }
public ImporterContext(GltfParser parser, IReadOnlyDictionary<SubAssetKey, UnityEngine.Object> externalObjectMap = null)
{
m_parser = parser;
MaterialImporter = new GltfMaterialImporter();
externalObjectMap = externalObjectMap ?? new Dictionary<SubAssetKey, UnityEngine.Object>();
m_textureFactory = new TextureFactory(externalObjectMap
TextureFactory = new TextureFactory(externalObjectMap
.Where(x => x.Value is Texture)
.ToDictionary(x => x.Key, x => (Texture) x.Value));
m_materialFactory = new MaterialFactory(externalObjectMap
MaterialFactory = new MaterialFactory(externalObjectMap
.Where(x => x.Value is Material)
.ToDictionary(x => x.Key, x => (Material) x.Value));
}
@ -105,6 +103,14 @@ namespace UniGLTF
}
}
using (MeasureTime("LoadTextures"))
{
foreach (var (key, param) in GltfTextureEnumerator.EnumerateAllTexturesDistinct(m_parser))
{
}
}
using (MeasureTime("LoadMaterials"))
{
await LoadMaterialsAsync();
@ -178,19 +184,24 @@ namespace UniGLTF
await awaitCaller.NextFrame();
}
private async Task LoadTexturesAsync()
{
}
public async Task LoadMaterialsAsync()
{
if (m_parser.GLTF.materials == null || m_parser.GLTF.materials.Count == 0)
{
// no material. work around.
var param = GltfMaterialImporter.GetMaterialParam(m_parser, 0);
var param = MaterialImporter.GetMaterialParam(m_parser, 0);
var material = await MaterialFactory.LoadAsync(param, TextureFactory.GetTextureAsync);
}
else
{
for (int i = 0; i < m_parser.GLTF.materials.Count; ++i)
{
var param = GltfMaterialImporter.GetMaterialParam(m_parser, i);
var param = MaterialImporter.GetMaterialParam(m_parser, i);
var material = await MaterialFactory.LoadAsync(param, TextureFactory.GetTextureAsync);
}
}
@ -293,8 +304,8 @@ namespace UniGLTF
}
Meshes.Clear();
m_materialFactory.Dispose();
m_textureFactory.Dispose();
MaterialFactory?.Dispose();
TextureFactory?.Dispose();
if (m_ownRoot && Root != null)
{

View File

@ -5,27 +5,29 @@ using VRMShaders;
namespace UniGLTF
{
public delegate bool TryCreateMaterialParamFromGltf(GltfParser parser, int i, out MaterialImportParam param);
public class GltfMaterialImporter
/// <summary>
/// GLTF の MaterialImporter
/// </summary>
public sealed class GltfMaterialImporter : IMaterialImporter
{
/// <summary>
/// gltfMaterialを解釈する関数。
/// 拡張するには、先頭に挿入するべし。
/// </summary>
/// <typeparam name="TryCreateMaterialParamFromGltf"></typeparam>
/// <returns></returns>
public readonly List<TryCreateMaterialParamFromGltf> GltfMaterialParamProcessors = new List<TryCreateMaterialParamFromGltf>();
public GltfMaterialImporter()
public MaterialImportParam GetMaterialParam(GltfParser parser, int i)
{
// unlit を試し
GltfMaterialParamProcessors.Add(GltfUnlitMaterial.TryCreateParam);
// PBR を作成する(失敗しない)
GltfMaterialParamProcessors.Add(GltfPBRMaterial.TryCreateParam);
if (!GltfUnlitMaterial.TryCreateParam(parser, i, out var param))
{
if (!GltfPBRMaterial.TryCreateParam(parser, i, out param))
{
// fallback
#if VRM_DEVELOP
Debug.LogWarning($"material: {i} out of range. fallback");
#endif
return new MaterialImportParam(GetMaterialName(i, null), GltfPBRMaterial.ShaderName);
}
}
return param;
}
public static string MaterialName(int index, glTFMaterial src)
public static string GetMaterialName(int index, glTFMaterial src)
{
if (src != null && !string.IsNullOrEmpty(src.name))
{
@ -33,29 +35,5 @@ namespace UniGLTF
}
return $"material_{index:00}";
}
/// <summary>
/// for unittest
/// </summary>
public static glTF CreateMaterialForTest(glTFMaterial material)
{
return new glTF
{
materials = new System.Collections.Generic.List<glTFMaterial> {
material
},
textures = new List<glTFTexture>{
new glTFTexture{
name = "texture_0"
}
},
images = new List<glTFImage>{
new glTFImage{
name = "image_0",
mimeType = "image/png",
}
},
};
}
}
}

View File

@ -92,7 +92,7 @@ namespace UniGLTF
}
var src = parser.GLTF.materials[i];
param = new MaterialImportParam(GltfMaterialImporter.MaterialName(i, src), ShaderName);
param = new MaterialImportParam(GltfMaterialImporter.GetMaterialName(i, src), ShaderName);
var standardParam = default(TextureImportParam);
if (src.pbrMetallicRoughness != null || src.occlusionTexture != null)

View File

@ -23,7 +23,7 @@ namespace UniGLTF
return false;
}
param = new MaterialImportParam(GltfMaterialImporter.MaterialName(i, src), ShaderName);
param = new MaterialImportParam(GltfMaterialImporter.GetMaterialName(i, src), ShaderName);
// texture
if (src.pbrMetallicRoughness.baseColorTexture != null)

View File

@ -0,0 +1,13 @@
using UnityEngine;
using VRMShaders;
namespace UniGLTF
{
/// <summary>
/// 指定の Unity Material から glTFMaterial を生成する。
/// </summary>
public interface IMaterialExporter
{
glTFMaterial ExportMaterial(Material m, ITextureExporter textureExporter);
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: afbe933c51a9404199ba1efe6d2f8c62
timeCreated: 1622015749

View File

@ -0,0 +1,13 @@
using VRMShaders;
namespace UniGLTF
{
/// <summary>
/// 指定の index の glTFMaterial から Import できる Material の生成情報を生成する。
/// Material の Import は glTFMaterial と 1:1 対応する。
/// </summary>
public interface IMaterialImporter
{
MaterialImportParam GetMaterialParam(GltfParser parser, int i);
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c309fb8ee8534a54b291d408511c9331
timeCreated: 1622015740

View File

@ -13,11 +13,6 @@ namespace UniGLTF
BLEND
}
public interface IMaterialExporter
{
glTFMaterial ExportMaterial(Material m, ITextureExporter textureExporter);
}
public class MaterialExporter : IMaterialExporter
{
public virtual glTFMaterial ExportMaterial(Material m, ITextureExporter textureExporter)

View File

@ -27,8 +27,7 @@ namespace VRM
if (glTF_VRM_extensions.TryDeserialize(GLTF.extensions, out glTF_VRM_extensions vrm))
{
VRM = vrm;
// override material importer
GltfMaterialImporter.GltfMaterialParamProcessors.Insert(0, new VRMMaterialImporter(VRM).TryCreateParam);
MaterialImporter = new VRMMaterialImporter(VRM);
}
else
{

View File

@ -6,7 +6,7 @@ using VRMShaders;
namespace VRM
{
public class VRMMaterialImporter
public sealed class VRMMaterialImporter : IMaterialImporter
{
readonly glTF_VRM_extensions m_vrm;
public VRMMaterialImporter(glTF_VRM_extensions vrm)
@ -103,7 +103,14 @@ namespace VRM
if (!GltfUnlitMaterial.TryCreateParam(parser, i, out param))
{
// pbr
GltfPBRMaterial.TryCreateParam(parser, i, out param);
if (!GltfPBRMaterial.TryCreateParam(parser, i, out param))
{
// fallback
#if VRM_DEVELOP
Debug.LogWarning($"material: {i} out of range. fallback");
#endif
return new MaterialImportParam(GltfMaterialImporter.GetMaterialName(i, null), GltfPBRMaterial.ShaderName);
}
}
}
return param;

View File

@ -24,6 +24,8 @@ namespace UniVRM10
public Vrm10Importer(UniGLTF.GltfParser parser, IReadOnlyDictionary<SubAssetKey, UnityEngine.Object> externalObjectMap = null)
: base(parser, externalObjectMap)
{
MaterialImporter = new Vrm10MaterialImporter();
m_externalMap = externalObjectMap;
if (m_externalMap == null)
{
@ -31,9 +33,6 @@ namespace UniVRM10
}
m_model = ModelReader.Read(parser);
// for `VRMC_materials_mtoon`
this.GltfMaterialImporter.GltfMaterialParamProcessors.Insert(0, Vrm10MaterialImporter.TryCreateParam);
if (!UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.TryGet(parser.GLTF.extensions, out m_vrm))
{
throw new Exception("VRMC_vrm is not found");

View File

@ -4,16 +4,34 @@ using VRMShaders;
namespace UniVRM10
{
public static class Vrm10MaterialImporter
public sealed class Vrm10MaterialImporter : IMaterialImporter
{
public MaterialImportParam GetMaterialParam(GltfParser parser, int i)
{
// mtoon
if (!TryCreateMToonParam(parser, i, out MaterialImportParam param))
{
// unlit
if (!GltfUnlitMaterial.TryCreateParam(parser, i, out param))
{
// pbr
if (!GltfPBRMaterial.TryCreateParam(parser, i, out param))
{
// fallback
#if VRM_DEVELOP
Debug.LogWarning($"material: {i} out of range. fallback");
#endif
return new MaterialImportParam(GltfMaterialImporter.GetMaterialName(i, null), GltfPBRMaterial.ShaderName);
}
}
}
return param;
}
/// <summary>
/// VMRC_materials_mtoon の場合にマテリアル生成情報を作成する
/// </summary>
/// <param name="parser"></param>
/// <param name="i"></param>
/// <param name="param"></param>
/// <returns></returns>
public static bool TryCreateParam(GltfParser parser, int i, out MaterialImportParam param)
public bool TryCreateMToonParam(GltfParser parser, int i, out MaterialImportParam param)
{
var m = parser.GLTF.materials[i];
if (!UniGLTF.Extensions.VRMC_materials_mtoon.GltfDeserializer.TryGet(m.extensions,
@ -48,7 +66,7 @@ namespace UniVRM10
}
param.RenderQueue = Vrm10MToonMaterialParameterImporter.TryGetRenderQueue(m, mtoon);
param.Actions.Add(material =>
{
// Set hidden properties, keywords from float properties.
@ -57,20 +75,5 @@ namespace UniVRM10
return true;
}
public static MaterialImportParam GetMaterialParam(GltfParser parser, int i)
{
// mtoon
if (!TryCreateParam(parser, i, out MaterialImportParam param))
{
// unlit
if (!GltfUnlitMaterial.TryCreateParam(parser, i, out param))
{
// pbr
GltfPBRMaterial.TryCreateParam(parser, i, out param);
}
}
return param;
}
}
}

View File

@ -25,7 +25,7 @@ namespace UniVRM10
var parser = new GltfParser();
parser.Parse(AliciaPath, migratedBytes);
var materialParam = Vrm10MaterialImporter.GetMaterialParam(parser, 0);
var materialParam = new Vrm10MaterialImporter().GetMaterialParam(parser, 0);
Assert.AreEqual("VRM/MToon", materialParam.ShaderName);
Assert.AreEqual("Alicia_body", materialParam.TextureSlots["_MainTex"].UnityObjectName);