Vrm10MaterialExporter

This commit is contained in:
ousttrue
2021-04-07 20:33:12 +09:00
parent 90d6f49c24
commit a207729d09
8 changed files with 459 additions and 45 deletions

View File

@@ -41,8 +41,16 @@ namespace MeshUtility
if (value != null && AssetDatabase.IsMainAsset(value))
{
assetPath = AssetDatabase.GetAssetPath(value);
isPrefab = true;
value = PrefabUtility.LoadPrefabContents(assetPath);
try
{
var prefab = PrefabUtility.LoadPrefabContents(assetPath);
value = prefab;
isPrefab = true;
}
catch (ArgumentException ex)
{
// Debug.LogWarning(ex);
}
}
if (m_root.GameObject == value)
{

View File

@@ -15,21 +15,21 @@ namespace UniGLTF
public interface IMaterialExporter
{
glTFMaterial ExportMaterial(Material m, TextureExporter textureManager);
glTFMaterial ExportMaterial(Material m, TextureExporter textureExporter);
}
public class MaterialExporter : IMaterialExporter
{
public virtual glTFMaterial ExportMaterial(Material m, TextureExporter textureManager)
public virtual glTFMaterial ExportMaterial(Material m, TextureExporter textureExporter)
{
var material = CreateMaterial(m);
// common params
material.name = m.name;
Export_Color(m, textureManager, material);
Export_Emission(m, textureManager, material);
Export_Normal(m, textureManager, material);
Export_OcclusionMetallicRoughness(m, textureManager, material);
Export_Color(m, textureExporter, material);
Export_Emission(m, textureExporter, material);
Export_Normal(m, textureExporter, material);
Export_OcclusionMetallicRoughness(m, textureExporter, material);
return material;
}

View File

@@ -85,7 +85,7 @@ namespace UniVRM10
#endif
var message = TryParseOrMigrate(scriptedImporter.assetPath, migrateToVrm1, out GltfParser parser);
if (string.IsNullOrEmpty(message))
if (!string.IsNullOrEmpty(message))
{
// fail to parse vrm1
return;

View File

@@ -4,6 +4,7 @@ using System.IO;
using System.Linq;
using System.Reflection;
using MeshUtility;
using UniGLTF;
using UnityEditor;
using UnityEngine;
using VrmLib;
@@ -322,14 +323,168 @@ namespace UniVRM10
exporter.Export(model, option);
// material
// var textureExporter = new TextureExporter(AssetTextureUtil.IsTextureEditorAsset);
// var materialExporter = new Vrm10MaterialExporter();
// foreach (var m in materials)
// {
// }
var textureExporter = new TextureExporter(AssetTextureUtil.IsTextureEditorAsset);
var materialExporter = new Vrm10MaterialExporter();
foreach (Material m in model.Materials)
{
var glTFMaterial = materialExporter.ExportMaterial(m, textureExporter);
exporter.Storage.Gltf.materials.Add(glTFMaterial);
}
//
// export VRM extensions
//
{
var vrm = new UniGLTF.Extensions.VRMC_vrm.VRMC_vrm
{
Humanoid = new UniGLTF.Extensions.VRMC_vrm.Humanoid
{
HumanBones = new UniGLTF.Extensions.VRMC_vrm.HumanBones
{
},
},
Meta = new UniGLTF.Extensions.VRMC_vrm.Meta
{
AllowExcessivelySexualUsage = false,
AllowExcessivelyViolentUsage = false,
AllowPoliticalOrReligiousUsage = false,
AllowRedistribution = false,
},
};
// humanoid
for (int i = 0; i < model.Nodes.Count; ++i)
{
var bone = model.Nodes[i];
switch (bone.HumanoidBone)
{
case HumanoidBones.hips: vrm.Humanoid.HumanBones.Hips = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.spine: vrm.Humanoid.HumanBones.Spine = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.chest: vrm.Humanoid.HumanBones.Chest = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.upperChest: vrm.Humanoid.HumanBones.UpperChest = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.neck: vrm.Humanoid.HumanBones.Neck = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.head: vrm.Humanoid.HumanBones.Head = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftEye: vrm.Humanoid.HumanBones.LeftEye = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightEye: vrm.Humanoid.HumanBones.RightEye = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.jaw: vrm.Humanoid.HumanBones.Jaw = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftUpperLeg: vrm.Humanoid.HumanBones.LeftUpperLeg = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftLowerLeg: vrm.Humanoid.HumanBones.LeftLowerLeg = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftFoot: vrm.Humanoid.HumanBones.LeftFoot = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftToes: vrm.Humanoid.HumanBones.LeftToes = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightUpperLeg: vrm.Humanoid.HumanBones.RightUpperLeg = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightLowerLeg: vrm.Humanoid.HumanBones.RightLowerLeg = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightFoot: vrm.Humanoid.HumanBones.RightFoot = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightToes: vrm.Humanoid.HumanBones.RightToes = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftShoulder: vrm.Humanoid.HumanBones.LeftShoulder = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftUpperArm: vrm.Humanoid.HumanBones.LeftUpperArm = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftLowerArm: vrm.Humanoid.HumanBones.LeftLowerArm = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftHand: vrm.Humanoid.HumanBones.LeftHand = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightShoulder: vrm.Humanoid.HumanBones.RightShoulder = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightUpperArm: vrm.Humanoid.HumanBones.RightUpperArm = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightLowerArm: vrm.Humanoid.HumanBones.RightLowerArm = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightHand: vrm.Humanoid.HumanBones.RightHand = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftThumbProximal: vrm.Humanoid.HumanBones.LeftThumbProximal = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftThumbIntermediate: vrm.Humanoid.HumanBones.LeftThumbIntermediate = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftThumbDistal: vrm.Humanoid.HumanBones.LeftThumbDistal = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftIndexProximal: vrm.Humanoid.HumanBones.LeftIndexProximal = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftIndexIntermediate: vrm.Humanoid.HumanBones.LeftIndexIntermediate = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftIndexDistal: vrm.Humanoid.HumanBones.LeftIndexDistal = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftMiddleProximal: vrm.Humanoid.HumanBones.LeftMiddleProximal = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftMiddleIntermediate: vrm.Humanoid.HumanBones.LeftMiddleIntermediate = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftMiddleDistal: vrm.Humanoid.HumanBones.LeftMiddleDistal = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftRingProximal: vrm.Humanoid.HumanBones.LeftRingProximal = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftRingIntermediate: vrm.Humanoid.HumanBones.LeftRingIntermediate = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftRingDistal: vrm.Humanoid.HumanBones.LeftRingDistal = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftLittleProximal: vrm.Humanoid.HumanBones.LeftLittleProximal = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftLittleIntermediate: vrm.Humanoid.HumanBones.LeftLittleIntermediate = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.leftLittleDistal: vrm.Humanoid.HumanBones.LeftLittleDistal = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightThumbProximal: vrm.Humanoid.HumanBones.RightThumbProximal = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightThumbIntermediate: vrm.Humanoid.HumanBones.RightThumbIntermediate = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightThumbDistal: vrm.Humanoid.HumanBones.RightThumbDistal = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightIndexProximal: vrm.Humanoid.HumanBones.RightIndexProximal = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightIndexIntermediate: vrm.Humanoid.HumanBones.RightIndexIntermediate = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightIndexDistal: vrm.Humanoid.HumanBones.RightIndexDistal = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightMiddleProximal: vrm.Humanoid.HumanBones.RightMiddleProximal = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightMiddleIntermediate: vrm.Humanoid.HumanBones.RightMiddleIntermediate = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightMiddleDistal: vrm.Humanoid.HumanBones.RightMiddleDistal = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightRingProximal: vrm.Humanoid.HumanBones.RightRingProximal = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightRingIntermediate: vrm.Humanoid.HumanBones.RightRingIntermediate = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightRingDistal: vrm.Humanoid.HumanBones.RightRingDistal = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightLittleProximal: vrm.Humanoid.HumanBones.RightLittleProximal = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightLittleIntermediate: vrm.Humanoid.HumanBones.RightLittleIntermediate = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
case HumanoidBones.rightLittleDistal: vrm.Humanoid.HumanBones.RightLittleDistal = new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = i }; break;
}
}
// meta
// expression
// lookAt
// firstPerson
UniGLTF.Extensions.VRMC_vrm.GltfSerializer.SerializeTo(ref exporter.Storage.Gltf.extensions, vrm);
}
{
// springBone
}
{
// constraint
}
var exportedBytes = exporter.Storage.ToBytes();
@@ -353,7 +508,7 @@ namespace UniVRM10
static string ToAssetPath(string path)
{
var assetPath = UnityPath.FromFullpath(path);
var assetPath = UniGLTF.UnityPath.FromFullpath(path);
return assetPath.Value;
}
}

View File

@@ -18,17 +18,10 @@ namespace UniVRM10
UniGLTF.Extensions.VRMC_vrm.VRMC_vrm m_vrm;
List<(string, UnityEngine.Object)> m_external = new List<(string, UnityEngine.Object)>();
public RuntimeUnityBuilder(UniGLTF.GltfParser parser, IEnumerable<(string, UnityEngine.Object)> externalObjectMap = null) : base(parser, externalObjectMap)
{
m_model = VrmLoader.CreateVrmModel(parser);
if (externalObjectMap != null)
{
m_external.AddRange(externalObjectMap);
}
// for `VRMC_materials_mtoon`
this.GltfMaterialImporter.GltfMaterialParamProcessors.Insert(0, Vrm10MToonMaterialImporter.TryCreateParam);
@@ -236,17 +229,7 @@ namespace UniVRM10
async Task LoadVrmAsync(IAwaitCaller awaitCaller, VRM10Controller controller, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm)
{
// meta
controller.Meta = m_external.Select(x => x.Item2 as VRM10MetaObject).FirstOrDefault(x => x != null);
// external meta != null のとき m_meta は null になる
if (controller.Meta != null)
{
// texture の 取得
if (Vrm10MToonMaterialImporter.TryGetMetaThumbnailTextureImportParam(Parser, vrm, out VRMShaders.TextureImportParam param))
{
var texture = await TextureFactory.GetTextureAsync(param);
}
}
else if (vrm.Meta != null)
if (vrm.Meta != null)
{
var src = vrm.Meta;
m_meta = ScriptableObject.CreateInstance<VRM10MetaObject>();
@@ -286,8 +269,7 @@ namespace UniVRM10
}
// expression
controller.Expression.ExpressionAvatar = m_external.Select(x => x.Item2 as VRM10ExpressionAvatar).FirstOrDefault(x => x != null);
if (controller.Expression.ExpressionAvatar == null && vrm.Expressions != null)
if (vrm.Expressions != null)
{
controller.Expression.ExpressionAvatar = ScriptableObject.CreateInstance<VRM10ExpressionAvatar>();
@@ -299,7 +281,7 @@ namespace UniVRM10
var clip = ScriptableObject.CreateInstance<UniVRM10.VRM10Expression>();
clip.Preset = expression.Preset;
clip.ExpressionName = expression.Name;
clip.name = expression.ExtractKey();
clip.name = expression.ExtractName();
clip.IsBinary = expression.IsBinary.GetValueOrDefault();
clip.OverrideBlink = expression.OverrideBlink;
clip.OverrideLookAt = expression.OverrideLookAt;
@@ -573,15 +555,12 @@ namespace UniVRM10
m_humanoid = null;
}
if (m_meta != null)
if (take(m_meta))
{
if (take(m_meta))
{
m_meta = null;
}
m_meta = null;
}
if (m_exressionAvatar != null)
if (m_exressionAvatar != null && m_exressionAvatar.Clips != null)
{
foreach (var x in m_exressionAvatar.Clips)
{

View File

@@ -214,7 +214,7 @@ namespace UniVRM10
/// <returns></returns>
public static bool TryGetMetaThumbnailTextureImportParam(GltfParser parser, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm, out TextureImportParam value)
{
if (!vrm.Meta.ThumbnailImage.HasValue)
if (vrm?.Meta == null || !vrm.Meta.ThumbnailImage.HasValue)
{
value = default;
return false;

View File

@@ -0,0 +1,272 @@
using System;
// using System.Collections.Generic;
using System.Linq;
using UniGLTF;
using UniGLTF.ShaderPropExporter;
using UnityEngine;
using VRMShaders;
namespace UniVRM10
{
public class Vrm10MaterialExporter : MaterialExporter
{
protected override glTFMaterial CreateMaterial(Material m)
{
switch (m.shader.name)
{
case "VRM/UnlitTexture":
return Export_VRMUnlitTexture(m);
case "VRM/UnlitTransparent":
return Export_VRMUnlitTransparent(m);
case "VRM/UnlitCutout":
return Export_VRMUnlitCutout(m);
case "VRM/UnlitTransparentZWrite":
return Export_VRMUnlitTransparentZWrite(m);
case "VRM/MToon":
return Export_VRMMToon(m);
default:
return base.CreateMaterial(m);
}
}
static glTFMaterial Export_VRMUnlitTexture(Material m)
{
var material = glTF_KHR_materials_unlit.CreateDefault();
material.alphaMode = "OPAQUE";
return material;
}
static glTFMaterial Export_VRMUnlitTransparent(Material m)
{
var material = glTF_KHR_materials_unlit.CreateDefault();
material.alphaMode = "BLEND";
return material;
}
static glTFMaterial Export_VRMUnlitCutout(Material m)
{
var material = glTF_KHR_materials_unlit.CreateDefault();
material.alphaMode = "MASK";
return material;
}
static glTFMaterial Export_VRMUnlitTransparentZWrite(Material m)
{
var material = glTF_KHR_materials_unlit.CreateDefault();
material.alphaMode = "BLEND";
return material;
}
static glTFMaterial Export_VRMMToon(Material m)
{
var material = glTF_KHR_materials_unlit.CreateDefault();
switch (m.GetTag("RenderType", true))
{
case "Transparent":
material.alphaMode = "BLEND";
break;
case "TransparentCutout":
material.alphaMode = "MASK";
material.alphaCutoff = m.GetFloat("_Cutoff");
break;
default:
material.alphaMode = "OPAQUE";
break;
}
switch ((int)m.GetFloat("_CullMode"))
{
case 0:
material.doubleSided = true;
break;
case 1:
Debug.LogWarning("ignore cull front");
break;
case 2:
// cull back
break;
default:
throw new NotImplementedException();
}
return material;
}
#region CreateFromMaterial
static readonly string[] TAGS = new string[]{
"RenderType",
// "Queue",
};
public override glTFMaterial ExportMaterial(Material m, TextureExporter textureExporter)
{
if (m.shader.name != MToon.Utils.ShaderName)
{
return base.ExportMaterial(m, textureExporter);
}
var material = new glTFMaterial
{
name = m.name,
emissiveFactor = new float[] { 0, 0, 0 },
};
// default values
var mtoon = new UniGLTF.Extensions.VRMC_materials_mtoon.VRMC_materials_mtoon
{
Version = "",
TransparentWithZWrite = false,
RenderQueueOffsetNumber = 0,
ShadeFactor = new float[] { 0, 0, 0 },
// ShadeMultiplyTexture;
// Lighting
ShadingShiftFactor = 0,
ShadingToonyFactor = 0,
LightColorAttenuationFactor = 0,
GiIntensityFactor = 0,
// MatCap
// AdditiveTexture;
// Rim
RimFactor = new float[] { 0, 0, 0 },
// public int? RimMultiplyTexture;
RimLightingMixFactor = 0,
RimFresnelPowerFactor = 0,
RimLiftFactor = 0,
// Outline
OutlineWidthMode = UniGLTF.Extensions.VRMC_materials_mtoon.OutlineWidthMode.none,
OutlineWidthFactor = 0,
// public int? OutlineWidthMultiplyTexture;
OutlineScaledMaxDistanceFactor = 0,
OutlineColorMode = UniGLTF.Extensions.VRMC_materials_mtoon.OutlineColorMode.fixedColor,
OutlineFactor = new float[] { 0, 0, 0 },
OutlineLightingMixFactor = 0,
// public int? UvAnimationMaskTexture;
UvAnimationScrollXSpeedFactor = 0,
UvAnimationScrollYSpeedFactor = 0,
UvAnimationRotationSpeedFactor = 0,
};
// var prop = PreShaderPropExporter.GetPropsForSupportedShader(m.shader.name);
// if (prop == null)
// {
// Debug.LogWarningFormat("Fail to export shader: {0}", m.shader.name);
// }
// else
// {
// foreach (var keyword in m.shaderKeywords)
// {
// material.keywordMap.Add(keyword, m.IsKeywordEnabled(keyword));
// }
// // get properties
// //material.SetProp(prop);
// foreach (var kv in prop.Properties)
// {
// switch (kv.ShaderPropertyType)
// {
// case ShaderPropertyType.Color:
// {
// var value = m.GetColor(kv.Key).ToArray();
// material.vectorProperties.Add(kv.Key, value);
// }
// break;
// case ShaderPropertyType.Range:
// case ShaderPropertyType.Float:
// {
// var value = m.GetFloat(kv.Key);
// material.floatProperties.Add(kv.Key, value);
// }
// break;
// case ShaderPropertyType.TexEnv:
// {
// var texture = m.GetTexture(kv.Key);
// if (texture != null)
// {
// var value = kv.Key == "_BumpMap"
// ? textureExporter.ExportNormal(texture)
// : textureExporter.ExportSRGB(texture)
// ;
// if (value == -1)
// {
// Debug.LogFormat("not found {0}", texture.name);
// }
// else
// {
// material.textureProperties.Add(kv.Key, value);
// }
// }
// // offset & scaling
// var offset = m.GetTextureOffset(kv.Key);
// var scaling = m.GetTextureScale(kv.Key);
// material.vectorProperties.Add(kv.Key,
// new float[] { offset.x, offset.y, scaling.x, scaling.y });
// }
// break;
// case ShaderPropertyType.Vector:
// {
// var value = m.GetVector(kv.Key).ToArray();
// material.vectorProperties.Add(kv.Key, value);
// }
// break;
// default:
// throw new NotImplementedException();
// }
// }
// }
// foreach (var tag in TAGS)
// {
// var value = m.GetTag(tag, false);
// if (!String.IsNullOrEmpty(value))
// {
// material.tagMap.Add(tag, value);
// }
// }
UniGLTF.Extensions.VRMC_materials_mtoon.GltfSerializer.SerializeTo(ref material.extensions, mtoon);
return material;
}
#endregion
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 984cd6e6d31fcc348a71adee5a752400
guid: f6eeec83f2a72884dae19571cf1d749b
MonoImporter:
externalObjects: {}
serializedVersion: 2