diff --git a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MaterialValidator.cs b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MaterialValidator.cs
new file mode 100644
index 000000000..cd285f2b6
--- /dev/null
+++ b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MaterialValidator.cs
@@ -0,0 +1,58 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace UniGLTF
+{
+ public interface IMaterialValidator
+ {
+ ///
+ /// shaderName から glTF マテリアルタイプ を得る
+ ///
+ /// shaderName が エクスポートできるものでないときは null を返す(gltfデフォルトの pbr として処理される)
+ ///
+ ///
+ ///
+ string GetGltfMaterialTypeFromUnityShaderName(string shaderName);
+
+ ///
+ /// テクスチャーを使うプロパティを列挙する
+ ///
+ ///
+ ///
+ ///
+ IEnumerable<(string propertyName, Texture texture)> EnumerateTextureProperties(Material m);
+ }
+
+ public class DefaultMaterialValidator : IMaterialValidator
+ {
+ public virtual string GetGltfMaterialTypeFromUnityShaderName(string shaderName)
+ {
+ if (shaderName == "Standard")
+ {
+ return "pbr";
+ }
+ if (MaterialExporter.IsUnlit(shaderName))
+ {
+ return "unlit";
+ }
+ return null;
+ }
+
+ public virtual IEnumerable<(string propertyName, Texture texture)> EnumerateTextureProperties(Material m)
+ {
+ // main color
+ yield return (MaterialExporter.COLOR_TEXTURE_PROP, m.GetTexture(MaterialExporter.COLOR_TEXTURE_PROP));
+
+ if (GetGltfMaterialTypeFromUnityShaderName(m.shader.name) == "unlit")
+ {
+ yield break;
+ }
+
+ // PBR
+ yield return (MaterialExporter.METALLIC_TEX_PROP, m.GetTexture(MaterialExporter.METALLIC_TEX_PROP));
+ yield return (MaterialExporter.NORMAL_TEX_PROP, m.GetTexture(MaterialExporter.NORMAL_TEX_PROP));
+ yield return (MaterialExporter.EMISSION_TEX_PROP, m.GetTexture(MaterialExporter.EMISSION_TEX_PROP));
+ yield return (MaterialExporter.OCCLUSION_TEX_PROP, m.GetTexture(MaterialExporter.OCCLUSION_TEX_PROP));
+ }
+ }
+}
diff --git a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MaterialValidator.cs.meta b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MaterialValidator.cs.meta
new file mode 100644
index 000000000..d46f5c32a
--- /dev/null
+++ b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MaterialValidator.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6ba5723a5618eac438268641047d9549
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs
index d3d94dc76..976a39ff4 100644
--- a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs
+++ b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs
@@ -1,8 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
using UniGLTF.M17N;
+using UnityEditor;
using UnityEngine;
namespace UniGLTF
@@ -27,37 +27,24 @@ namespace UniGLTF
return null;
}
- public List Meshes = new List();
+ public MeshExportList Meshes = new MeshExportList();
public int ExpectedExportByteSize => Meshes.Where(x => x.IsRendererActive).Sum(x => x.ExportByteSize);
public void SetRoot(GameObject ExportRoot, GltfExportSettings settings, IBlendShapeExportFilter blendShapeFilter)
{
- if(ExportRoot==null)
+ if (ExportRoot == null)
{
return;
}
- MeshExportInfo.GetInfo(ExportRoot.transform.Traverse().Skip(1), Meshes, settings);
- foreach(var info in Meshes)
+ Meshes.GetInfo(ExportRoot.transform.Traverse().Skip(1), settings);
+ foreach (var info in Meshes)
{
info.CalcMeshSize(ExportRoot, info.Renderers[0].Item1, settings, blendShapeFilter);
}
}
- public Func GltfMaterialFromUnityShaderName = DefaultGltfMaterialType;
-
- public static string DefaultGltfMaterialType(string shaderName)
- {
- if (shaderName == "Standard")
- {
- return "pbr";
- }
- if (MaterialExporter.IsUnlit(shaderName))
- {
- return "unlit";
- }
- return null;
- }
+ public IMaterialValidator MaterialValidator = new DefaultMaterialValidator();
public enum Messages
{
@@ -93,20 +80,47 @@ namespace UniGLTF
}
}
- foreach (var m in Meshes.SelectMany(x => x.Materials).Distinct())
+ foreach (var m in Meshes.GetUniqueMaterials())
{
- if (m == null)
- {
- continue;
- }
- var gltfMaterial = GltfMaterialFromUnityShaderName(m.shader.name);
+ var gltfMaterial = MaterialValidator.GetGltfMaterialTypeFromUnityShaderName(m.shader.name);
if (string.IsNullOrEmpty(gltfMaterial))
{
yield return Validation.Warning($"{m}: unknown shader: {m.shader.name} => export as gltf default");
}
- }
- yield break;
+ var used = new HashSet();
+ foreach (var (propName, texture) in MaterialValidator.EnumerateTextureProperties(m))
+ {
+ if (texture == null)
+ {
+ continue;
+ }
+ var assetPath = AssetDatabase.GetAssetPath(texture);
+ if (!string.IsNullOrEmpty(assetPath))
+ {
+ if (AssetImporter.GetAtPath(assetPath) is TextureImporter textureImporter)
+ {
+ switch (textureImporter.textureType)
+ {
+ case TextureImporterType.Default:
+ case TextureImporterType.NormalMap:
+ break;
+
+ default:
+ // EditorTextureSerializer throw Exception
+ // エクスポート未実装
+ if (used.Add(texture))
+ {
+ yield return Validation.Error($"{texture}: unknown texture type: {textureImporter.textureType}", ValidationContext.Create(texture));
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ yield break;
+ }
}
}
}
diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/MaterialExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/MaterialExporter.cs
index 8711d43e4..14a14cec3 100644
--- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/MaterialExporter.cs
+++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/MaterialExporter.cs
@@ -30,6 +30,12 @@ namespace UniGLTF
return material;
}
+ public const string COLOR_TEXTURE_PROP = "_MainTex";
+ public const string METALLIC_TEX_PROP = "_MetallicGlossMap";
+ public const string NORMAL_TEX_PROP = "_BumpMap";
+ public const string EMISSION_TEX_PROP = "_EmissionMap";
+ public const string OCCLUSION_TEX_PROP = "_OcclusionMap";
+
static void Export_Color(Material m, ITextureExporter textureManager, glTFMaterial material)
{
if (m.HasProperty("_Color"))
@@ -37,12 +43,12 @@ namespace UniGLTF
material.pbrMetallicRoughness.baseColorFactor = m.GetColor("_Color").ToFloat4(ColorSpace.sRGB, ColorSpace.Linear);
}
- if (m.HasProperty("_MainTex"))
+ if (m.HasProperty(COLOR_TEXTURE_PROP))
{
// Don't export alpha channel if material was OPAQUE
var unnecessaryAlpha = string.Equals(material.alphaMode, "OPAQUE", StringComparison.Ordinal);
- var index = textureManager.RegisterExportingAsSRgb(m.GetTexture("_MainTex"), !unnecessaryAlpha);
+ var index = textureManager.RegisterExportingAsSRgb(m.GetTexture(COLOR_TEXTURE_PROP), !unnecessaryAlpha);
if (index != -1)
{
material.pbrMetallicRoughness.baseColorTexture = new glTFMaterialBaseColorTextureInfo()
@@ -67,20 +73,20 @@ namespace UniGLTF
float smoothness = 1.0f;
var textuerNames = m.GetTexturePropertyNames();
- if (textuerNames.Contains("_MetallicGlossMap"))
+ if (textuerNames.Contains(METALLIC_TEX_PROP))
{
if (m.HasProperty("_GlossMapScale"))
{
smoothness = m.GetFloat("_GlossMapScale");
}
- metallicSmoothTexture = m.GetTexture("_MetallicGlossMap");
+ metallicSmoothTexture = m.GetTexture(METALLIC_TEX_PROP);
}
Texture occlusionTexture = default;
var occlusionStrength = 1.0f;
- if (textuerNames.Contains("_OcclusionMap"))
+ if (textuerNames.Contains(OCCLUSION_TEX_PROP))
{
- occlusionTexture = m.GetTexture("_OcclusionMap");
+ occlusionTexture = m.GetTexture(OCCLUSION_TEX_PROP);
if (occlusionTexture != null && m.HasProperty("_OcclusionStrength"))
{
occlusionStrength = m.GetFloat("_OcclusionStrength");
@@ -128,9 +134,9 @@ namespace UniGLTF
static void Export_Normal(Material m, ITextureExporter textureExporter, glTFMaterial material)
{
- if (m.HasProperty("_BumpMap"))
+ if (m.HasProperty(NORMAL_TEX_PROP))
{
- var index = textureExporter.RegisterExportingAsNormal(m.GetTexture("_BumpMap"));
+ var index = textureExporter.RegisterExportingAsNormal(m.GetTexture(NORMAL_TEX_PROP));
if (index != -1)
{
material.normalTexture = new glTFMaterialNormalTextureInfo()
@@ -174,9 +180,9 @@ namespace UniGLTF
material.emissiveFactor = color.ToFloat3(ColorSpace.Linear, ColorSpace.Linear);
}
- if (m.HasProperty("_EmissionMap"))
+ if (m.HasProperty(EMISSION_TEX_PROP))
{
- var index = textureExporter.RegisterExportingAsSRgb(m.GetTexture("_EmissionMap"), needsAlpha: false);
+ var index = textureExporter.RegisterExportingAsSRgb(m.GetTexture(EMISSION_TEX_PROP), needsAlpha: false);
if (index != -1)
{
material.emissiveTexture = new glTFMaterialEmissiveTextureInfo()
@@ -191,7 +197,7 @@ namespace UniGLTF
static void Export_MainTextureTransform(Material m, glTFTextureInfo textureInfo)
{
- Export_TextureTransform(m, textureInfo, "_MainTex");
+ Export_TextureTransform(m, textureInfo, COLOR_TEXTURE_PROP);
}
static void Export_TextureTransform(Material m, glTFTextureInfo textureInfo, string propertyName)
diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs
index 1e768fa08..0a52c8c29 100644
--- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs
+++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -50,7 +51,7 @@ namespace UniGLTF
}
}
- public static bool TryGetSameMeshIndex(List meshWithRenderers, Mesh mesh, Material[] materials, out int meshIndex)
+ public static bool TryGetSameMeshIndex(IReadOnlyList meshWithRenderers, Mesh mesh, Material[] materials, out int meshIndex)
{
for (var i = 0; i < meshWithRenderers.Count; i++)
{
@@ -183,7 +184,7 @@ namespace UniGLTF
public string Summary;
#endregion
- MeshExportInfo(Renderer renderer, GltfExportSettings settings)
+ public MeshExportInfo(Renderer renderer, GltfExportSettings settings)
{
if (renderer == null)
{
@@ -220,7 +221,7 @@ namespace UniGLTF
PushRenderer(renderer);
}
- void PushRenderer(Renderer renderer)
+ public void PushRenderer(Renderer renderer)
{
if (renderer is SkinnedMeshRenderer smr)
{
@@ -261,53 +262,12 @@ namespace UniGLTF
}
}
- public static MeshExportInfo Create(GameObject go)
- {
- var list = new List();
- GetInfo(go.transform.Traverse(), list, new GltfExportSettings());
- return list[0];
- }
-
- ///
- /// ヒエラルキーからエクスポートする Mesh の情報を収集する
- ///
- ///
- ///
- ///
- /// blendShape の export を filtering する
- public static void GetInfo(IEnumerable nodes, List list, GltfExportSettings settings)
- {
- list.Clear();
- foreach (var node in nodes)
- {
- var renderer = node.GetComponent();
- if (renderer == null)
- {
- continue;
- }
-
- var found = list.FirstOrDefault(x => x.IsSameMeshAndMaterials(renderer));
- if (found != null)
- {
- found.PushRenderer(renderer);
- continue;
- }
-
- var info = new MeshExportInfo(renderer, settings);
- if (info.Mesh != null)
- {
- list.Add(info);
- }
- }
- }
-
static bool TryGetMeshInfo()
{
return true;
}
-
public void CalcMeshSize(
GameObject root,
Renderer renderer,
@@ -409,4 +369,68 @@ namespace UniGLTF
Summary = sb.ToString();
}
}
+
+ public class MeshExportList : IReadOnlyList
+ {
+ List m_list = new List();
+
+ public int Count => m_list.Count;
+
+ public MeshExportInfo this[int index] => m_list[index];
+
+ public IEnumerator GetEnumerator()
+ {
+ return m_list.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ public IEnumerable GetUniqueMaterials()
+ {
+ return m_list.SelectMany(x => x.Materials).Where(x => x != null).Distinct();
+ }
+
+ ///
+ /// ヒエラルキーからエクスポートする Mesh の情報を収集する
+ ///
+ ///
+ ///
+ ///
+ /// blendShape の export を filtering する
+ public void GetInfo(IEnumerable nodes, GltfExportSettings settings)
+ {
+ m_list.Clear();
+ foreach (var node in nodes)
+ {
+ var renderer = node.GetComponent();
+ if (renderer == null)
+ {
+ continue;
+ }
+
+ var found = m_list.FirstOrDefault(x => x.IsSameMeshAndMaterials(renderer));
+ if (found != null)
+ {
+ found.PushRenderer(renderer);
+ continue;
+ }
+
+ var info = new MeshExportInfo(renderer, settings);
+ if (info.Mesh != null)
+ {
+ m_list.Add(info);
+ }
+ }
+ }
+
+ public static MeshExportInfo Create(GameObject go)
+ {
+ var list = new MeshExportList();
+ list.GetInfo(go.transform.Traverse(), new GltfExportSettings());
+ return list.m_list[0];
+ }
+ }
}
diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs
index 203fa6a97..0a9f650be 100644
--- a/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs
+++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs
@@ -142,7 +142,7 @@ namespace UniGLTF
}
#region Export
- static glTFNode ExportNode(Transform x, List nodes, List meshWithRenderers, List skins)
+ static glTFNode ExportNode(Transform x, List nodes, IReadOnlyList meshWithRenderers, List skins)
{
var node = new glTFNode
{
@@ -231,11 +231,11 @@ namespace UniGLTF
.Skip(1) // exclude root object for the symmetry with the importer
.ToList();
- var uniqueUnityMeshes = new List();
- MeshExportInfo.GetInfo(Nodes, uniqueUnityMeshes, meshExportSettings);
+ var uniqueUnityMeshes = new MeshExportList();
+ uniqueUnityMeshes.GetInfo(Nodes, meshExportSettings);
#region Materials and Textures
- Materials = uniqueUnityMeshes.SelectMany(x => x.Materials).Where(x => x != null).Distinct().ToList();
+ Materials = uniqueUnityMeshes.GetUniqueMaterials().ToList();
m_textureExporter = new TextureExporter(textureSerializer);
diff --git a/Assets/UniGLTF/Runtime/UniGLTF/Validation/Validation.cs b/Assets/UniGLTF/Runtime/UniGLTF/Validation/Validation.cs
index b6fa5ad92..be438bf3a 100644
--- a/Assets/UniGLTF/Runtime/UniGLTF/Validation/Validation.cs
+++ b/Assets/UniGLTF/Runtime/UniGLTF/Validation/Validation.cs
@@ -32,14 +32,14 @@ namespace UniGLTF
/// Messageの発生個所にジャンプするための情報
///
public Type Type;
- public UnityEngine.Component Context;
+ public UnityEngine.Object Context;
///
/// DrawGUIから呼び出す。追加のGUIボタンなどを実装する
///
public Action Extended;
- public static ValidationContext Create(T c) where T : UnityEngine.Component
+ public static ValidationContext Create(T c) where T : UnityEngine.Object
{
return new ValidationContext
{
diff --git a/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs b/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs
index dcfb007f3..d7f7a63b7 100644
--- a/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs
+++ b/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs
@@ -134,7 +134,7 @@ namespace UniGLTF
};
var axisInverter = Axes.X.Create();
- var unityMesh = MeshExportInfo.Create(go);
+ var unityMesh = MeshExportList.Create(go);
var (gltfMesh, blendShapeIndexMap) = meshExportSettings.DivideVertexBuffer
? MeshExporter_DividedVertexBuffer.Export(glTF, bufferIndex, unityMesh, Materials, axisInverter, meshExportSettings)
: MeshExporter_SharedVertexBuffer.Export(glTF, bufferIndex, unityMesh, Materials,axisInverter, meshExportSettings)
@@ -182,7 +182,7 @@ namespace UniGLTF
};
var axisInverter = Axes.X.Create();
- var unityMesh = MeshExportInfo.Create(go);
+ var unityMesh = MeshExportList.Create(go);
var (gltfMesh, blendShapeIndexMap) = meshExportSettings.DivideVertexBuffer
? MeshExporter_DividedVertexBuffer.Export(glTF, bufferIndex, unityMesh, Materials, axisInverter, meshExportSettings)
: MeshExporter_SharedVertexBuffer.Export(glTF, bufferIndex, unityMesh, Materials,axisInverter, meshExportSettings)
diff --git a/Assets/VRM/Editor/Format/VRMExporterWizard.cs b/Assets/VRM/Editor/Format/VRMExporterWizard.cs
index 2861af0c6..db6b5a9d6 100644
--- a/Assets/VRM/Editor/Format/VRMExporterWizard.cs
+++ b/Assets/VRM/Editor/Format/VRMExporterWizard.cs
@@ -124,14 +124,40 @@ namespace VRM
m_meshes = null;
}
- static string GltfMaterialFromUnityShaderName(string shaderName)
+ ///
+ /// VRM0
+ ///
+ class VRMMaterialValidator : DefaultMaterialValidator
{
- var name = VRMMaterialExporter.VrmMaterialName(shaderName);
- if (!string.IsNullOrEmpty(name))
+ public override string GetGltfMaterialTypeFromUnityShaderName(string shaderName)
{
- return name;
+ var name = VRMMaterialExporter.VrmMaterialName(shaderName);
+ if (!string.IsNullOrEmpty(name))
+ {
+ return name;
+ }
+ return base.GetGltfMaterialTypeFromUnityShaderName(shaderName);
+ }
+
+ public override IEnumerable<(string propertyName, Texture texture)> EnumerateTextureProperties(Material m)
+ {
+ if (m.shader.name != "VRM/MToon")
+ {
+ foreach (var x in base.EnumerateTextureProperties(m))
+ {
+ yield return x;
+ }
+ }
+
+ var prop = UniGLTF.ShaderPropExporter.PreShaderPropExporter.GetPropsForSupportedShader(m.shader.name);
+ foreach (var kv in prop.Properties)
+ {
+ if (kv.ShaderPropertyType == UniGLTF.ShaderPropExporter.ShaderPropertyType.TexEnv)
+ {
+ yield return (kv.Key, m.GetTexture(kv.Key));
+ }
+ }
}
- return MeshExportValidator.DefaultGltfMaterialType(shaderName);
}
protected override IEnumerable ValidatorFactory()
@@ -145,7 +171,7 @@ namespace VRM
}
// Mesh/Renderer のチェック
- m_meshes.GltfMaterialFromUnityShaderName = GltfMaterialFromUnityShaderName;
+ m_meshes.MaterialValidator = new VRMMaterialValidator();
yield return m_meshes.Validate;
// Humanoid のチェック
diff --git a/Assets/VRM/Editor/VRM.Editor.asmdef b/Assets/VRM/Editor/VRM.Editor.asmdef
index ebcd2e1c1..38a926c9d 100644
--- a/Assets/VRM/Editor/VRM.Editor.asmdef
+++ b/Assets/VRM/Editor/VRM.Editor.asmdef
@@ -6,7 +6,8 @@
"VRMShaders.GLTF.IO.Runtime",
"VRMShaders.GLTF.IO.Editor",
"UniGLTF",
- "UniGLTF.Editor"
+ "UniGLTF.Editor",
+ "VRMShaders.VRM.IO.Runtime"
],
"optionalUnityReferences": [],
"includePlatforms": [