From e2b2495e1c767b3dddd1dff4ae6379aa647a7c36 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Wed, 10 Feb 2021 20:14:13 +0900 Subject: [PATCH] =?UTF-8?q?*=20MaterialImporter=20=E3=82=92=20MaterialItem?= =?UTF-8?q?=20=E3=81=AB=E5=88=86=E8=A7=A3=20*=20MaterialImporter=20?= =?UTF-8?q?=E3=82=92=20interface=20=E3=81=8B=E3=82=89=20delegate=20?= =?UTF-8?q?=E3=81=AB=E6=A0=BC=E4=B8=8B=E3=81=92=20*=20UniUnlit=20=E3=81=AE?= =?UTF-8?q?=E5=B0=8E=E5=85=A5=E3=81=AB=E3=82=88=E3=82=8A=E4=B8=8D=E8=A6=81?= =?UTF-8?q?=E3=81=AB=E3=81=AA=E3=81=A3=E3=81=9F=20ShaderStore=20=E3=82=92?= =?UTF-8?q?=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runtime/UniGLTF/IO/ImporterContext.cs | 17 +- .../Runtime/UniGLTF/IO/MeshImporter.cs | 8 +- .../UniGLTF/Runtime/UniGLTF/IO/ShaderStore.cs | 123 ------- .../Runtime/UniGLTF/IO/ShaderStore.cs.meta | 12 - .../MaterialFacotry/MaterialFactory.cs | 58 +-- .../MaterialFacotry/MaterialImporter.cs | 310 ---------------- .../UniGLTF/MaterialFacotry/MaterialItem.cs | 346 ++++++++++++++++++ ...lImporter.cs.meta => MaterialItem.cs.meta} | 2 +- Assets/UniGLTF/Tests/UniGLTF/MaterialTests.cs | 87 +++-- Assets/VRM/Runtime/IO/VRMImporterContext.cs | 8 +- Assets/VRM/Runtime/IO/VRMMaterialImporter.cs | 49 ++- 11 files changed, 468 insertions(+), 552 deletions(-) delete mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/ShaderStore.cs delete mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/ShaderStore.cs.meta delete mode 100644 Assets/UniGLTF/Runtime/UniGLTF/MaterialFacotry/MaterialImporter.cs create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/MaterialFacotry/MaterialItem.cs rename Assets/UniGLTF/Runtime/UniGLTF/MaterialFacotry/{MaterialImporter.cs.meta => MaterialItem.cs.meta} (83%) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs index ea2c77037..12622452e 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs @@ -106,12 +106,7 @@ namespace UniGLTF #endregion MaterialFactory m_materialFactory = new MaterialFactory(); - public MaterialFactory MaterialFacotry => m_materialFactory; - - public ImporterContext(IShaderStore shaderStore) - { - m_materialFactory.ShaderStore = shaderStore; - } + public MaterialFactory MaterialFactory => m_materialFactory; public ImporterContext(MaterialImporter materialImporter) { @@ -573,13 +568,13 @@ namespace UniGLTF MeshWithMaterials meshWithMaterials; if (EnableLoadBalancing) { - var buildMesh = MeshImporter.BuildMeshCoroutine(this, x); + var buildMesh = MeshImporter.BuildMeshCoroutine(MaterialFactory, x); yield return buildMesh; meshWithMaterials = buildMesh.Current as MeshWithMaterials; } else { - meshWithMaterials = MeshImporter.BuildMesh(this, x); + meshWithMaterials = MeshImporter.BuildMesh(MaterialFactory, x); } var mesh = meshWithMaterials.Mesh; @@ -605,7 +600,7 @@ namespace UniGLTF for (int i = 0; i < GLTF.meshes.Count; ++i) { var meshContext = meshImporter.ReadMesh(this, i); - var meshWithMaterials = MeshImporter.BuildMesh(this, meshContext); + var meshWithMaterials = MeshImporter.BuildMesh(MaterialFactory, meshContext); var mesh = meshWithMaterials.Mesh; if (string.IsNullOrEmpty(mesh.name)) { @@ -702,7 +697,7 @@ namespace UniGLTF protected virtual IEnumerable ObjectsForSubAsset() { HashSet textures = new HashSet(); - foreach (var x in MaterialFacotry.GetTextures().SelectMany(y => y.GetTexturesForSaveAssets())) + foreach (var x in MaterialFactory.GetTextures().SelectMany(y => y.GetTexturesForSaveAssets())) { if (!textures.Contains(x)) { @@ -710,7 +705,7 @@ namespace UniGLTF } } foreach (var x in textures) { yield return x; } - foreach (var x in MaterialFacotry.GetMaterials()) { yield return x; } + foreach (var x in MaterialFactory.GetMaterials()) { yield return x.GetOrCreate(MaterialFactory.GetTexture); } foreach (var x in Meshes) { yield return x.Mesh; } foreach (var x in AnimationClips) { yield return x; } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshImporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshImporter.cs index f715fe957..305a47bdc 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshImporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshImporter.cs @@ -625,7 +625,7 @@ namespace UniGLTF } } - public static MeshWithMaterials BuildMesh(ImporterContext ctx, MeshImporter.MeshContext meshContext) + public static MeshWithMaterials BuildMesh(MaterialFactory ctx, MeshImporter.MeshContext meshContext) { var (mesh, recalculateTangents) = _BuildMesh(meshContext); @@ -637,7 +637,7 @@ namespace UniGLTF var result = new MeshWithMaterials { Mesh = mesh, - Materials = meshContext.MaterialIndices.Select(x => ctx.MaterialFacotry.GetMaterial(x)).ToArray() + Materials = meshContext.MaterialIndices.Select(x => ctx.GetMaterial(x).GetOrCreate(ctx.GetTexture)).ToArray() }; if (meshContext.BlendShapes.Count > 0) @@ -651,7 +651,7 @@ namespace UniGLTF return result; } - public static IEnumerator BuildMeshCoroutine(ImporterContext ctx, MeshImporter.MeshContext meshContext) + public static IEnumerator BuildMeshCoroutine(MaterialFactory ctx, MeshImporter.MeshContext meshContext) { var (mesh, recalculateTangents) = _BuildMesh(meshContext); @@ -665,7 +665,7 @@ namespace UniGLTF var result = new MeshWithMaterials { Mesh = mesh, - Materials = meshContext.MaterialIndices.Select(x => ctx.MaterialFacotry.GetMaterial(x)).ToArray() + Materials = meshContext.MaterialIndices.Select(x => ctx.GetMaterial(x).GetOrCreate(ctx.GetTexture)).ToArray() }; yield return null; diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/ShaderStore.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/ShaderStore.cs deleted file mode 100644 index 933676fa8..000000000 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/ShaderStore.cs +++ /dev/null @@ -1,123 +0,0 @@ -using UnityEngine; - - -namespace UniGLTF -{ - public interface IShaderStore - { - Shader GetShader(glTFMaterial material); - } - - public class ShaderStore : IShaderStore - { - readonly string m_defaultShaderName = "Standard"; - Shader m_default; - Shader Default - { - get - { - if (m_default == null) - { - m_default = Shader.Find(m_defaultShaderName); - } - return m_default; - } - } - - Shader m_vcolor; - Shader VColor - { - get - { - if (m_vcolor == null) m_vcolor = Shader.Find("UniGLTF/StandardVColor"); - return m_vcolor; - } - } - - Shader m_uniUnlit; - Shader UniUnlit - { - get - { - if (m_uniUnlit == null) m_uniUnlit = Shader.Find("UniGLTF/UniUnlit"); - return m_uniUnlit; - } - } - - Shader m_unlitTexture; - Shader UnlitTexture - { - get - { - if (m_unlitTexture == null) m_unlitTexture = Shader.Find("Unlit/Texture"); - return m_unlitTexture; - } - } - - Shader m_unlitColor; - Shader UnlitColor - { - get - { - if (m_unlitColor == null) m_unlitColor = Shader.Find("Unlit/Color"); - return m_unlitColor; - } - } - - Shader m_unlitTransparent; - Shader UnlitTransparent - { - get - { - if (m_unlitTransparent == null) m_unlitTransparent = Shader.Find("Unlit/Transparent"); - return m_unlitTransparent; - } - } - - Shader m_unlitCutout; - Shader UnlitCutout - { - get - { - if (m_unlitCutout == null) m_unlitCutout = Shader.Find("Unlit/Transparent Cutout"); - return m_unlitCutout; - } - } - - //ImporterContext m_context; - public ShaderStore(MaterialFactory _) - { - //m_context = context; - } - - public static bool IsWhite(float[] color) - { - if (color == null) return false; - if(color.Length!=4)return false; - if(color[0]!=1 - || color[1]!=1 - || color[2]!=1 - || color[3] != 1) - { - return false; - } - return true; - } - - public Shader GetShader(glTFMaterial material) - { - if (material == null) - { - return Default; - } - - if(glTF_KHR_materials_unlit.IsEnable(material)) - { - return UniUnlit; - } - - // standard - return Default; - } - } -} diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/ShaderStore.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/ShaderStore.cs.meta deleted file mode 100644 index def6e6602..000000000 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/ShaderStore.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 75aae8e866422d24180458afaacb2c1d -timeCreated: 1529327427 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/UniGLTF/MaterialFacotry/MaterialFactory.cs b/Assets/UniGLTF/Runtime/UniGLTF/MaterialFacotry/MaterialFactory.cs index f7f6c164f..22cd4788a 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/MaterialFacotry/MaterialFactory.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/MaterialFacotry/MaterialFactory.cs @@ -6,25 +6,13 @@ using UnityEngine; namespace UniGLTF { + public delegate TextureItem GetTextureItemFunc(int i); + public delegate Shader GetShaderFunc(); + public delegate MaterialItemBase MaterialImporter(int i, glTFMaterial x, bool hasVertexColor); + + public class MaterialFactory { - public IShaderStore m_shaderStore; - public IShaderStore ShaderStore - { - set - { - m_shaderStore = value; - } - get - { - if (m_shaderStore == null) - { - m_shaderStore = new ShaderStore(this); - } - return m_shaderStore; - } - } - MaterialImporter m_materialImporter; public MaterialImporter MaterialImporter { @@ -36,7 +24,7 @@ namespace UniGLTF { if (m_materialImporter == null) { - m_materialImporter = new MaterialImporter(ShaderStore); + m_materialImporter = CreateMaterial; } return m_materialImporter; } @@ -60,22 +48,22 @@ namespace UniGLTF m_textures.Add(item); } - List m_materials = new List(); - public void AddMaterial(Material material) + List m_materials = new List(); + public void AddMaterial(MaterialItemBase material) { - var originalName = material.name; + var originalName = material.Name; int j = 2; - while (m_materials.Any(x => x.name == material.name)) + while (m_materials.Any(x => x.Name == material.Name)) { - material.name = string.Format("{0}({1})", originalName, j++); + material.Name = string.Format("{0}({1})", originalName, j++); } m_materials.Add(material); } - public IList GetMaterials() + public IList GetMaterials() { return m_materials; } - public Material GetMaterial(int index) + public MaterialItemBase GetMaterial(int index) { if (index < 0) return null; if (index >= m_materials.Count) return null; @@ -173,17 +161,33 @@ namespace UniGLTF { if (gltf.materials == null || !gltf.materials.Any()) { - AddMaterial(MaterialImporter.CreateMaterial(0, null, false, GetTexture)); + AddMaterial(MaterialImporter(0, null, false)); } else { for (int i = 0; i < gltf.materials.Count; ++i) { - AddMaterial(MaterialImporter.CreateMaterial(i, gltf.materials[i], gltf.MaterialHasVertexColor(i), GetTexture)); + AddMaterial(MaterialImporter(i, gltf.materials[i], gltf.MaterialHasVertexColor(i))); } } } yield return null; } + + public static MaterialItemBase CreateMaterial(int i, glTFMaterial x, bool hasVertexColor) + { + if (x == null) + { + UnityEngine.Debug.LogWarning("glTFMaterial is empty"); + return new PBRMaterialItem(i, x); + } + + if (glTF_KHR_materials_unlit.IsEnable(x)) + { + return new UnlitMaterialItem(i, x, hasVertexColor); + } + + return new PBRMaterialItem(i, x); + } } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/MaterialFacotry/MaterialImporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/MaterialFacotry/MaterialImporter.cs deleted file mode 100644 index b124c8d39..000000000 --- a/Assets/UniGLTF/Runtime/UniGLTF/MaterialFacotry/MaterialImporter.cs +++ /dev/null @@ -1,310 +0,0 @@ -using UnityEngine; -using System; -using UnityEngine.Rendering; -#if UNITY_EDITOR -using UnityEditor; -#endif - - -namespace UniGLTF -{ - public class MaterialImporter - { - IShaderStore m_shaderStore; - - public MaterialImporter(IShaderStore shaderStore) - { - m_shaderStore = shaderStore; - } - - public delegate TextureItem GetTextureFunc(int index); - - private enum BlendMode - { - Opaque, - Cutout, - Fade, - Transparent - } - - /// StandardShader variables - /// - /// _Color - /// _MainTex - /// _Cutoff - /// _Glossiness - /// _Metallic - /// _MetallicGlossMap - /// _BumpScale - /// _BumpMap - /// _Parallax - /// _ParallaxMap - /// _OcclusionStrength - /// _OcclusionMap - /// _EmissionColor - /// _EmissionMap - /// _DetailMask - /// _DetailAlbedoMap - /// _DetailNormalMapScale - /// _DetailNormalMap - /// _UVSec - /// _EmissionScaleUI - /// _EmissionColorUI - /// _Mode - /// _SrcBlend - /// _DstBlend - /// _ZWrite - public virtual Material CreateMaterial(int i, glTFMaterial x, bool hasVertexColor, GetTextureFunc getTexture) - { - var shader = m_shaderStore.GetShader(x); - //Debug.LogFormat("[{0}]{1}", i, shader.name); - var material = new Material(shader); -#if UNITY_EDITOR - // textureImporter.SaveAndReimport(); may destroy this material - material.hideFlags = HideFlags.DontUnloadUnusedAsset; -#endif - - material.name = (x == null || string.IsNullOrEmpty(x.name)) - ? string.Format("material_{0:00}", i) - : x.name - ; - - if (x == null) - { - Debug.LogWarning("glTFMaterial is empty"); - return material; - } - - // unlit material - if (glTF_KHR_materials_unlit.IsEnable(x)) - { - // texture - if (x.pbrMetallicRoughness.baseColorTexture != null) - { - var texture = getTexture(x.pbrMetallicRoughness.baseColorTexture.index); - if (texture != null) - { - material.mainTexture = texture.Texture; - } - - // Texture Offset and Scale - SetTextureOffsetAndScale(material, x.pbrMetallicRoughness.baseColorTexture, "_MainTex"); - } - - // color - if (x.pbrMetallicRoughness.baseColorFactor != null && x.pbrMetallicRoughness.baseColorFactor.Length == 4) - { - var color = x.pbrMetallicRoughness.baseColorFactor; - material.color = (new Color(color[0], color[1], color[2], color[3])).gamma; - } - - //renderMode - if (x.alphaMode == "OPAQUE") - { - UniUnlit.Utils.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Opaque); - } - else if (x.alphaMode == "BLEND") - { - UniUnlit.Utils.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Transparent); - } - else if (x.alphaMode == "MASK") - { - UniUnlit.Utils.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Cutout); - material.SetFloat("_Cutoff", x.alphaCutoff); - } - else - { - // default OPAQUE - UniUnlit.Utils.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Opaque); - } - - // culling - if (x.doubleSided) - { - UniUnlit.Utils.SetCullMode(material, UniUnlit.UniUnlitCullMode.Off); - } - else - { - UniUnlit.Utils.SetCullMode(material, UniUnlit.UniUnlitCullMode.Back); - } - - // VColor - if (hasVertexColor) - { - UniUnlit.Utils.SetVColBlendMode(material, UniUnlit.UniUnlitVertexColorBlendOp.Multiply); - } - - UniUnlit.Utils.ValidateProperties(material, true); - - return material; - } - - // PBR material - if (x.pbrMetallicRoughness != null) - { - if (x.pbrMetallicRoughness.baseColorFactor != null && x.pbrMetallicRoughness.baseColorFactor.Length == 4) - { - var color = x.pbrMetallicRoughness.baseColorFactor; - material.color = (new Color(color[0], color[1], color[2], color[3])).gamma; - } - - if (x.pbrMetallicRoughness.baseColorTexture != null && x.pbrMetallicRoughness.baseColorTexture.index != -1) - { - var texture = getTexture(x.pbrMetallicRoughness.baseColorTexture.index); - if (texture != null) - { - material.mainTexture = texture.Texture; - } - - // Texture Offset and Scale - SetTextureOffsetAndScale(material, x.pbrMetallicRoughness.baseColorTexture, "_MainTex"); - } - - if (x.pbrMetallicRoughness.metallicRoughnessTexture != null && x.pbrMetallicRoughness.metallicRoughnessTexture.index != -1) - { - material.EnableKeyword("_METALLICGLOSSMAP"); - var texture = getTexture(x.pbrMetallicRoughness.metallicRoughnessTexture.index); - if (texture != null) - { - var prop = "_MetallicGlossMap"; - // Bake roughnessFactor values into a texture. - material.SetTexture(prop, texture.ConvertTexture(prop, x.pbrMetallicRoughness.roughnessFactor)); - } - - material.SetFloat("_Metallic", 1.0f); - // Set 1.0f as hard-coded. See: https://github.com/dwango/UniVRM/issues/212. - material.SetFloat("_GlossMapScale", 1.0f); - - // Texture Offset and Scale - SetTextureOffsetAndScale(material, x.pbrMetallicRoughness.metallicRoughnessTexture, "_MetallicGlossMap"); - } - else - { - material.SetFloat("_Metallic", x.pbrMetallicRoughness.metallicFactor); - material.SetFloat("_Glossiness", 1.0f - x.pbrMetallicRoughness.roughnessFactor); - } - } - - if (x.normalTexture != null && x.normalTexture.index != -1) - { - material.EnableKeyword("_NORMALMAP"); - var texture = getTexture(x.normalTexture.index); - if (texture != null) - { - var prop = "_BumpMap"; - material.SetTexture(prop, texture.ConvertTexture(prop)); - material.SetFloat("_BumpScale", x.normalTexture.scale); - } - - // Texture Offset and Scale - SetTextureOffsetAndScale(material, x.normalTexture, "_BumpMap"); - } - - if (x.occlusionTexture != null && x.occlusionTexture.index != -1) - { - var texture = getTexture(x.occlusionTexture.index); - if (texture != null) - { - var prop = "_OcclusionMap"; - material.SetTexture(prop, texture.ConvertTexture(prop)); - material.SetFloat("_OcclusionStrength", x.occlusionTexture.strength); - } - - // Texture Offset and Scale - SetTextureOffsetAndScale(material, x.occlusionTexture, "_OcclusionMap"); - } - - if (x.emissiveFactor != null - || (x.emissiveTexture != null && x.emissiveTexture.index != -1)) - { - material.EnableKeyword("_EMISSION"); - material.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack; - - if (x.emissiveFactor != null && x.emissiveFactor.Length == 3) - { - material.SetColor("_EmissionColor", new Color(x.emissiveFactor[0], x.emissiveFactor[1], x.emissiveFactor[2])); - } - - if (x.emissiveTexture != null && x.emissiveTexture.index != -1) - { - var texture = getTexture(x.emissiveTexture.index); - if (texture != null) - { - material.SetTexture("_EmissionMap", texture.Texture); - } - - // Texture Offset and Scale - SetTextureOffsetAndScale(material, x.emissiveTexture, "_EmissionMap"); - } - } - - BlendMode blendMode = BlendMode.Opaque; - // https://forum.unity.com/threads/standard-material-shader-ignoring-setfloat-property-_mode.344557/#post-2229980 - switch (x.alphaMode) - { - case "BLEND": - blendMode = BlendMode.Fade; - material.SetOverrideTag("RenderType", "Transparent"); - material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); - material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); - material.SetInt("_ZWrite", 0); - material.DisableKeyword("_ALPHATEST_ON"); - material.EnableKeyword("_ALPHABLEND_ON"); - material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); - material.renderQueue = 3000; - break; - - case "MASK": - blendMode = BlendMode.Cutout; - material.SetOverrideTag("RenderType", "TransparentCutout"); - material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); - material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); - material.SetInt("_ZWrite", 1); - material.SetFloat("_Cutoff", x.alphaCutoff); - material.EnableKeyword("_ALPHATEST_ON"); - material.DisableKeyword("_ALPHABLEND_ON"); - material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); - material.renderQueue = 2450; - - break; - - default: // OPAQUE - blendMode = BlendMode.Opaque; - material.SetOverrideTag("RenderType", ""); - material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); - material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); - material.SetInt("_ZWrite", 1); - material.DisableKeyword("_ALPHATEST_ON"); - material.DisableKeyword("_ALPHABLEND_ON"); - material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); - material.renderQueue = -1; - break; - } - - material.SetFloat("_Mode", (float)blendMode); - return material; - } - - private static void SetTextureOffsetAndScale(Material material, glTFTextureInfo textureInfo, string propertyName) - { - if (glTF_KHR_texture_transform.TryGet(textureInfo, out glTF_KHR_texture_transform textureTransform)) - { - Vector2 offset = new Vector2(0, 0); - Vector2 scale = new Vector2(1, 1); - if (textureTransform.offset != null && textureTransform.offset.Length == 2) - { - offset = new Vector2(textureTransform.offset[0], textureTransform.offset[1]); - } - if (textureTransform.scale != null && textureTransform.scale.Length == 2) - { - scale = new Vector2(textureTransform.scale[0], textureTransform.scale[1]); - } - - offset.y = (offset.y + scale.y - 1.0f) * -1.0f; - - material.SetTextureOffset(propertyName, offset); - material.SetTextureScale(propertyName, scale); - } - } - } -} diff --git a/Assets/UniGLTF/Runtime/UniGLTF/MaterialFacotry/MaterialItem.cs b/Assets/UniGLTF/Runtime/UniGLTF/MaterialFacotry/MaterialItem.cs new file mode 100644 index 000000000..65ffdedbb --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/MaterialFacotry/MaterialItem.cs @@ -0,0 +1,346 @@ +using System; +using UnityEngine; +using UnityEngine.Rendering; + +namespace UniGLTF +{ + public abstract class MaterialItemBase + { + protected int m_index; + protected glTFMaterial m_src; + + public string Name { get; set; } + + public MaterialItemBase(int i, glTFMaterial src) + { + m_index = i; + m_src = src; + Name = src != null ? m_src.name : ""; + } + + public abstract Material GetOrCreate(GetTextureItemFunc getTexture); + + protected static void SetTextureOffsetAndScale(Material material, glTFTextureInfo textureInfo, string propertyName) + { + if (glTF_KHR_texture_transform.TryGet(textureInfo, out glTF_KHR_texture_transform textureTransform)) + { + Vector2 offset = new Vector2(0, 0); + Vector2 scale = new Vector2(1, 1); + if (textureTransform.offset != null && textureTransform.offset.Length == 2) + { + offset = new Vector2(textureTransform.offset[0], textureTransform.offset[1]); + } + if (textureTransform.scale != null && textureTransform.scale.Length == 2) + { + scale = new Vector2(textureTransform.scale[0], textureTransform.scale[1]); + } + + offset.y = (offset.y + scale.y - 1.0f) * -1.0f; + + material.SetTextureOffset(propertyName, offset); + material.SetTextureScale(propertyName, scale); + } + } + } + + public class UnlitMaterialItem : MaterialItemBase + { + public const string UniUnlitShaderName = "UniGLTF/UniUnlit"; + + bool m_hasVertexColor; + + public UnlitMaterialItem(int i, glTFMaterial src, bool hasVertexColor) : base(i, src) + { + m_hasVertexColor = hasVertexColor; + } + + public override Material GetOrCreate(GetTextureItemFunc getTexture) + { + if (getTexture == null) + { + getTexture = _ => null; + } + + var material = new Material(Shader.Find(UniUnlitShaderName)); +#if UNITY_EDITOR + // textureImporter.SaveAndReimport(); may destroy this material + material.hideFlags = HideFlags.DontUnloadUnusedAsset; +#endif + material.name = (m_src == null || string.IsNullOrEmpty(m_src.name)) + ? string.Format("material_{0:00}", m_index) + : m_src.name + ; + + // texture + if (m_src.pbrMetallicRoughness.baseColorTexture != null) + { + var texture = getTexture(m_src.pbrMetallicRoughness.baseColorTexture.index); + if (texture != null) + { + material.mainTexture = texture.Texture; + } + + // Texture Offset and Scale + SetTextureOffsetAndScale(material, m_src.pbrMetallicRoughness.baseColorTexture, "_MainTex"); + } + + // color + if (m_src.pbrMetallicRoughness.baseColorFactor != null && m_src.pbrMetallicRoughness.baseColorFactor.Length == 4) + { + var color = m_src.pbrMetallicRoughness.baseColorFactor; + material.color = (new Color(color[0], color[1], color[2], color[3])).gamma; + } + + //renderMode + if (m_src.alphaMode == "OPAQUE") + { + UniUnlit.Utils.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Opaque); + } + else if (m_src.alphaMode == "BLEND") + { + UniUnlit.Utils.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Transparent); + } + else if (m_src.alphaMode == "MASK") + { + UniUnlit.Utils.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Cutout); + material.SetFloat("_Cutoff", m_src.alphaCutoff); + } + else + { + // default OPAQUE + UniUnlit.Utils.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Opaque); + } + + // culling + if (m_src.doubleSided) + { + UniUnlit.Utils.SetCullMode(material, UniUnlit.UniUnlitCullMode.Off); + } + else + { + UniUnlit.Utils.SetCullMode(material, UniUnlit.UniUnlitCullMode.Back); + } + + // VColor + if (m_hasVertexColor) + { + UniUnlit.Utils.SetVColBlendMode(material, UniUnlit.UniUnlitVertexColorBlendOp.Multiply); + } + + UniUnlit.Utils.ValidateProperties(material, true); + + return material; + } + } + + /// StandardShader variables + /// + /// _Color + /// _MainTex + /// _Cutoff + /// _Glossiness + /// _Metallic + /// _MetallicGlossMap + /// _BumpScale + /// _BumpMap + /// _Parallax + /// _ParallaxMap + /// _OcclusionStrength + /// _OcclusionMap + /// _EmissionColor + /// _EmissionMap + /// _DetailMask + /// _DetailAlbedoMap + /// _DetailNormalMapScale + /// _DetailNormalMap + /// _UVSec + /// _EmissionScaleUI + /// _EmissionColorUI + /// _Mode + /// _SrcBlend + /// _DstBlend + /// _ZWrite + public class PBRMaterialItem : MaterialItemBase + { + public const string PBRShaderName = "Standard"; + + private enum BlendMode + { + Opaque, + Cutout, + Fade, + Transparent + } + + public PBRMaterialItem(int i, glTFMaterial src) : base(i, src) + { + } + + public override Material GetOrCreate(GetTextureItemFunc getTexture) + { + if (getTexture == null) + { + getTexture = _ => null; + } + + var material = new Material(Shader.Find(PBRShaderName)); +#if UNITY_EDITOR + // textureImporter.SaveAndReimport(); may destroy this material + material.hideFlags = HideFlags.DontUnloadUnusedAsset; +#endif + material.name = (base.m_src == null || string.IsNullOrEmpty(base.m_src.name)) + ? string.Format("material_{0:00}", m_index) + : base.m_src.name + ; + + // PBR material + if (m_src != null) + { + if (m_src.pbrMetallicRoughness != null) + { + if (m_src.pbrMetallicRoughness.baseColorFactor != null && m_src.pbrMetallicRoughness.baseColorFactor.Length == 4) + { + var color = m_src.pbrMetallicRoughness.baseColorFactor; + material.color = (new Color(color[0], color[1], color[2], color[3])).gamma; + } + + if (m_src.pbrMetallicRoughness.baseColorTexture != null && m_src.pbrMetallicRoughness.baseColorTexture.index != -1) + { + var texture = getTexture(m_src.pbrMetallicRoughness.baseColorTexture.index); + if (texture != null) + { + material.mainTexture = texture.Texture; + } + + // Texture Offset and Scale + SetTextureOffsetAndScale(material, m_src.pbrMetallicRoughness.baseColorTexture, "_MainTex"); + } + + if (m_src.pbrMetallicRoughness.metallicRoughnessTexture != null && m_src.pbrMetallicRoughness.metallicRoughnessTexture.index != -1) + { + material.EnableKeyword("_METALLICGLOSSMAP"); + var texture = getTexture(m_src.pbrMetallicRoughness.metallicRoughnessTexture.index); + if (texture != null) + { + var prop = "_MetallicGlossMap"; + // Bake roughnessFactor values into a texture. + material.SetTexture(prop, texture.ConvertTexture(prop, m_src.pbrMetallicRoughness.roughnessFactor)); + } + + material.SetFloat("_Metallic", 1.0f); + // Set 1.0f as hard-coded. See: https://github.com/dwango/UniVRM/issues/212. + material.SetFloat("_GlossMapScale", 1.0f); + + // Texture Offset and Scale + SetTextureOffsetAndScale(material, m_src.pbrMetallicRoughness.metallicRoughnessTexture, "_MetallicGlossMap"); + } + else + { + material.SetFloat("_Metallic", m_src.pbrMetallicRoughness.metallicFactor); + material.SetFloat("_Glossiness", 1.0f - m_src.pbrMetallicRoughness.roughnessFactor); + } + } + + if (m_src.normalTexture != null && m_src.normalTexture.index != -1) + { + material.EnableKeyword("_NORMALMAP"); + var texture = getTexture(m_src.normalTexture.index); + if (texture != null) + { + var prop = "_BumpMap"; + material.SetTexture(prop, texture.ConvertTexture(prop)); + material.SetFloat("_BumpScale", m_src.normalTexture.scale); + } + + // Texture Offset and Scale + SetTextureOffsetAndScale(material, m_src.normalTexture, "_BumpMap"); + } + + if (m_src.occlusionTexture != null && m_src.occlusionTexture.index != -1) + { + var texture = getTexture(m_src.occlusionTexture.index); + if (texture != null) + { + var prop = "_OcclusionMap"; + material.SetTexture(prop, texture.ConvertTexture(prop)); + material.SetFloat("_OcclusionStrength", m_src.occlusionTexture.strength); + } + + // Texture Offset and Scale + SetTextureOffsetAndScale(material, m_src.occlusionTexture, "_OcclusionMap"); + } + + if (m_src.emissiveFactor != null + || (m_src.emissiveTexture != null && m_src.emissiveTexture.index != -1)) + { + material.EnableKeyword("_EMISSION"); + material.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack; + + if (m_src.emissiveFactor != null && m_src.emissiveFactor.Length == 3) + { + material.SetColor("_EmissionColor", new Color(m_src.emissiveFactor[0], m_src.emissiveFactor[1], m_src.emissiveFactor[2])); + } + + if (m_src.emissiveTexture != null && m_src.emissiveTexture.index != -1) + { + var texture = getTexture(m_src.emissiveTexture.index); + if (texture != null) + { + material.SetTexture("_EmissionMap", texture.Texture); + } + + // Texture Offset and Scale + SetTextureOffsetAndScale(material, m_src.emissiveTexture, "_EmissionMap"); + } + } + + BlendMode blendMode = BlendMode.Opaque; + // https://forum.unity.com/threads/standard-material-shader-ignoring-setfloat-property-_mode.344557/#post-2229980 + switch (m_src.alphaMode) + { + case "BLEND": + blendMode = BlendMode.Fade; + material.SetOverrideTag("RenderType", "Transparent"); + material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); + material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); + material.SetInt("_ZWrite", 0); + material.DisableKeyword("_ALPHATEST_ON"); + material.EnableKeyword("_ALPHABLEND_ON"); + material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); + material.renderQueue = 3000; + break; + + case "MASK": + blendMode = BlendMode.Cutout; + material.SetOverrideTag("RenderType", "TransparentCutout"); + material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); + material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); + material.SetInt("_ZWrite", 1); + material.SetFloat("_Cutoff", m_src.alphaCutoff); + material.EnableKeyword("_ALPHATEST_ON"); + material.DisableKeyword("_ALPHABLEND_ON"); + material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); + material.renderQueue = 2450; + + break; + + default: // OPAQUE + blendMode = BlendMode.Opaque; + material.SetOverrideTag("RenderType", ""); + material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); + material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); + material.SetInt("_ZWrite", 1); + material.DisableKeyword("_ALPHATEST_ON"); + material.DisableKeyword("_ALPHABLEND_ON"); + material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); + material.renderQueue = -1; + break; + } + + material.SetFloat("_Mode", (float)blendMode); + } + + return material; + } + } +} diff --git a/Assets/UniGLTF/Runtime/UniGLTF/MaterialFacotry/MaterialImporter.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/MaterialFacotry/MaterialItem.cs.meta similarity index 83% rename from Assets/UniGLTF/Runtime/UniGLTF/MaterialFacotry/MaterialImporter.cs.meta rename to Assets/UniGLTF/Runtime/UniGLTF/MaterialFacotry/MaterialItem.cs.meta index b5647b3ba..d6713eb21 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/MaterialFacotry/MaterialImporter.cs.meta +++ b/Assets/UniGLTF/Runtime/UniGLTF/MaterialFacotry/MaterialItem.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: c7dc5ea1cfb854745a2f5c9f6701218f +guid: f49a88d3a0e6eb24e91af983452f59f6 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/UniGLTF/Tests/UniGLTF/MaterialTests.cs b/Assets/UniGLTF/Tests/UniGLTF/MaterialTests.cs index 2ba1e589e..42c7d34bf 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/MaterialTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/MaterialTests.cs @@ -32,9 +32,7 @@ namespace UniGLTF var gltfMaterial = materialExporter.ExportMaterial(srcMaterial, textureManager); gltfMaterial.pbrMetallicRoughness.baseColorTexture.extensions = gltfMaterial.pbrMetallicRoughness.baseColorTexture.extensions.Deserialize(); - var shaderStore = new ShaderStore(null); - var materialImporter = new MaterialImporter(shaderStore); - var dstMaterial = materialImporter.CreateMaterial(0, gltfMaterial, false, x => null); + var dstMaterial = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null); Assert.AreEqual(dstMaterial.mainTextureOffset.x, offset.x, 0.3f); Assert.AreEqual(dstMaterial.mainTextureOffset.y, offset.y, 0.2f); @@ -70,7 +68,7 @@ namespace UniGLTF Assert.AreEqual(glTF_KHR_materials_unlit.ExtensionNameUtf8, list[0].Key.GetUtf8String()); Assert.AreEqual(0, list[0].Value.GetObjectCount()); - var material = new glTFMaterial + var gltfMaterial = new glTFMaterial { alphaMode = "OPAQUE", pbrMetallicRoughness = new glTFPbrMetallicRoughness @@ -80,22 +78,19 @@ namespace UniGLTF extensions = extension, }; - Assert.IsTrue(glTF_KHR_materials_unlit.IsEnable(material)); + Assert.IsTrue(glTF_KHR_materials_unlit.IsEnable(gltfMaterial)); - var shaderStore = new ShaderStore(null); - var shader = shaderStore.GetShader(material); - Assert.AreEqual("UniGLTF/UniUnlit", shader.name); + var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null); + Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name); } } [Test] public void UnlitShaderImportTest() { - var shaderStore = new ShaderStore(null); - { // OPAQUE/Color - var shader = shaderStore.GetShader(new glTFMaterial + var gltfMaterial = new glTFMaterial { alphaMode = "OPAQUE", pbrMetallicRoughness = new glTFPbrMetallicRoughness @@ -103,13 +98,14 @@ namespace UniGLTF baseColorFactor = new float[] { 1, 0, 0, 1 }, }, extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(), - }); - Assert.AreEqual("UniGLTF/UniUnlit", shader.name); + }; + var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null); + Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name); } { // OPAQUE/Texture - var shader = shaderStore.GetShader(new glTFMaterial + var gltfMaterial = new glTFMaterial { alphaMode = "OPAQUE", pbrMetallicRoughness = new glTFPbrMetallicRoughness @@ -117,13 +113,14 @@ namespace UniGLTF baseColorTexture = new glTFMaterialBaseColorTextureInfo(), }, extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(), - }); - Assert.AreEqual("UniGLTF/UniUnlit", shader.name); + }; + var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null); + Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name); } { // OPAQUE/Color/Texture - var shader = shaderStore.GetShader(new glTFMaterial + var gltfMaterial = new glTFMaterial { alphaMode = "OPAQUE", pbrMetallicRoughness = new glTFPbrMetallicRoughness @@ -132,13 +129,14 @@ namespace UniGLTF baseColorTexture = new glTFMaterialBaseColorTextureInfo(), }, extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(), - }); - Assert.AreEqual("UniGLTF/UniUnlit", shader.name); + }; + var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null); + Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name); } { // BLEND/Color - var shader = shaderStore.GetShader(new glTFMaterial + var gltfMaterial = new glTFMaterial { alphaMode = "BLEND", pbrMetallicRoughness = new glTFPbrMetallicRoughness @@ -146,13 +144,14 @@ namespace UniGLTF baseColorFactor = new float[] { 1, 0, 0, 1 }, }, extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(), - }); - Assert.AreEqual("UniGLTF/UniUnlit", shader.name); + }; + var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null); + Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name); } { // BLEND/Texture - var shader = shaderStore.GetShader(new glTFMaterial + var gltfMaterial = new glTFMaterial { alphaMode = "BLEND", pbrMetallicRoughness = new glTFPbrMetallicRoughness @@ -160,13 +159,14 @@ namespace UniGLTF baseColorTexture = new glTFMaterialBaseColorTextureInfo(), }, extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(), - }); - Assert.AreEqual("UniGLTF/UniUnlit", shader.name); + }; + var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null); + Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name); } { // BLEND/Color/Texture - var shader = shaderStore.GetShader(new glTFMaterial + var gltfMaterial = new glTFMaterial { alphaMode = "BLEND", pbrMetallicRoughness = new glTFPbrMetallicRoughness @@ -175,13 +175,14 @@ namespace UniGLTF baseColorTexture = new glTFMaterialBaseColorTextureInfo(), }, extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(), - }); - Assert.AreEqual("UniGLTF/UniUnlit", shader.name); + }; + var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null); + Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name); } { // MASK/Texture - var shader = shaderStore.GetShader(new glTFMaterial + var gltfMaterial = new glTFMaterial { alphaMode = "MASK", pbrMetallicRoughness = new glTFPbrMetallicRoughness @@ -189,13 +190,14 @@ namespace UniGLTF baseColorTexture = new glTFMaterialBaseColorTextureInfo(), }, extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(), - }); - Assert.AreEqual("UniGLTF/UniUnlit", shader.name); + }; + var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null); + Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name); } { // MASK/Color/Texture - var shader = shaderStore.GetShader(new glTFMaterial + var gltfMaterial = new glTFMaterial { alphaMode = "MASK", pbrMetallicRoughness = new glTFPbrMetallicRoughness @@ -204,30 +206,27 @@ namespace UniGLTF baseColorTexture = new glTFMaterialBaseColorTextureInfo(), }, extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(), - }); - Assert.AreEqual("UniGLTF/UniUnlit", shader.name); + }; + var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null); + Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name); } { // default - var shader = shaderStore.GetShader(new glTFMaterial + var gltfMaterial = new glTFMaterial { extensions = glTF_KHR_materials_unlit.Serialize().Deserialize(), - }); - Assert.AreEqual("UniGLTF/UniUnlit", shader.name); + }; + var material = MaterialFactory.CreateMaterial(0, gltfMaterial, false).GetOrCreate(null); + Assert.AreEqual("UniGLTF/UniUnlit", material.shader.name); } } [Test] public void MaterialImportTest() { - var shaderStore = new ShaderStore(null); - var materialImporter = new MaterialImporter(shaderStore); - - { - var material = materialImporter.CreateMaterial(0, new glTFMaterial { }, false, null); - Assert.AreEqual("Standard", material.shader.name); - } + var material = MaterialFactory.CreateMaterial(0, new glTFMaterial { }, false).GetOrCreate(null); + Assert.AreEqual("Standard", material.shader.name); } [Test] diff --git a/Assets/VRM/Runtime/IO/VRMImporterContext.cs b/Assets/VRM/Runtime/IO/VRMImporterContext.cs index f3468e68e..50d6ff0d2 100644 --- a/Assets/VRM/Runtime/IO/VRMImporterContext.cs +++ b/Assets/VRM/Runtime/IO/VRMImporterContext.cs @@ -42,7 +42,7 @@ namespace VRM { VRM = vrm; // override material importer - MaterialFacotry.MaterialImporter = new VRMMaterialImporter(new ShaderStore(MaterialFacotry), VRM.materialProperties); + MaterialFactory.MaterialImporter = new VRMMaterialImporter(VRM.materialProperties).CreateMaterial; } else { @@ -193,7 +193,7 @@ namespace VRM } } - var material = MaterialFacotry.GetMaterials().FirstOrDefault(y => y.name == x.materialName); + var material = MaterialFactory.GetMaterials().FirstOrDefault(y => y.Name == x.materialName).GetOrCreate(MaterialFactory.GetTexture); var propertyName = x.propertyName; if (x.propertyName.FastEndsWith("_ST_S") || x.propertyName.FastEndsWith("_ST_T")) @@ -305,7 +305,7 @@ namespace VRM meta.Reference = gltfMeta.reference; meta.Title = gltfMeta.title; - var thumbnail = MaterialFacotry.GetTexture(gltfMeta.texture); + var thumbnail = MaterialFactory.GetTexture(gltfMeta.texture); if (thumbnail != null) { // ロード済み @@ -316,7 +316,7 @@ namespace VRM // 作成する(先行ロード用) if (gltfMeta.texture >= 0 && gltfMeta.texture < GLTF.textures.Count) { - var t = new TextureItem(gltfMeta.texture, MaterialFacotry.CreateTextureLoader(gltfMeta.texture)); + var t = new TextureItem(gltfMeta.texture, MaterialFactory.CreateTextureLoader(gltfMeta.texture)); t.Process(GLTF, Storage); meta.Thumbnail = t.Texture; } diff --git a/Assets/VRM/Runtime/IO/VRMMaterialImporter.cs b/Assets/VRM/Runtime/IO/VRMMaterialImporter.cs index 47610ef61..c758deb49 100644 --- a/Assets/VRM/Runtime/IO/VRMMaterialImporter.cs +++ b/Assets/VRM/Runtime/IO/VRMMaterialImporter.cs @@ -6,14 +6,8 @@ using System; namespace VRM { - public class VRMMaterialImporter : MaterialImporter + public class MToonMaterialItem : MaterialItemBase { - List m_materials; - public VRMMaterialImporter(IShaderStore shaderStore, List materials) : base(shaderStore) - { - m_materials = materials; - } - static string[] VRM_SHADER_NAMES = { "Standard", @@ -26,15 +20,18 @@ namespace VRM "VRM/UnlitTransparentZWrite", }; - public override Material CreateMaterial(int i, glTFMaterial src, bool hasVertexColor, GetTextureFunc getTexture) - { - if (i == 0 && m_materials.Count == 0) - { - // dummy - return new Material(Shader.Find("Standard")); - } + glTF_VRM_Material m_vrmMaterial; + bool m_hasVertexColor; - var item = m_materials[i]; + public MToonMaterialItem(int i, glTFMaterial src, bool hasVertexColor, glTF_VRM_Material vrmMaterial) : base(i, src) + { + m_hasVertexColor = hasVertexColor; + m_vrmMaterial = vrmMaterial; + } + + public override Material GetOrCreate(GetTextureItemFunc getTexture) + { + var item = m_vrmMaterial; var shaderName = item.shader; var shader = Shader.Find(shaderName); if (shader == null) @@ -50,7 +47,7 @@ namespace VRM { Debug.LogWarningFormat("unknown shader {0}.", shaderName); } - return base.CreateMaterial(i, src, hasVertexColor, getTexture); + return MaterialFactory.CreateMaterial(m_index, m_src, m_hasVertexColor).GetOrCreate(getTexture); } // @@ -121,4 +118,24 @@ namespace VRM return material; } } + + public class VRMMaterialImporter + { + List m_materials; + public VRMMaterialImporter(List materials) + { + m_materials = materials; + } + + public MaterialItemBase CreateMaterial(int i, glTFMaterial src, bool hasVertexColor) + { + if (i == 0 && m_materials.Count == 0) + { + // dummy + return new PBRMaterialItem(i, src); + } + + return new MToonMaterialItem(i, src, hasVertexColor, m_materials[i]); + } + } }