Merge pull request #955 from Santarh/exportMtoon10

Implements exporting VRM 1.0 MToon
This commit is contained in:
ousttrue 2021-05-19 16:03:13 +09:00 committed by GitHub
commit 67558710d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 255 additions and 92 deletions

View File

@ -190,7 +190,7 @@ namespace UniGLTF
{
var offset = m.GetTextureOffset(propertyName);
var scale = m.GetTextureScale(propertyName);
offset.y = (offset.y + scale.y - 1) * -1.0f;
offset.y = 1.0f - offset.y - scale.y;
glTF_KHR_texture_transform.Serialize(textureInfo, (offset.x, offset.y), (scale.x, scale.y));
}

View File

@ -0,0 +1,231 @@
using System;
using MToon;
using UniGLTF;
using UniGLTF.Extensions.VRMC_materials_mtoon;
using UnityEngine;
using VRMShaders;
using ColorSpace = UniGLTF.ColorSpace;
using OutlineWidthMode = MToon.OutlineWidthMode;
using RenderMode = MToon.RenderMode;
namespace UniVRM10
{
public static class Vrm10MToonMaterialExporter
{
public static bool TryExportMaterialAsMToon(Material src, TextureExporter textureExporter, out glTFMaterial dst)
{
try
{
if (src.shader.name != MToon.Utils.ShaderName)
{
dst = null;
return false;
}
// convert MToon intermediate value from UnityEngine.Material
var def = MToon.Utils.GetMToonParametersFromMaterial(src);
// gltfMaterial
dst = new glTFMaterial
{
name = src.name,
// Rendering
doubleSided = def.Rendering.CullMode == CullMode.Off,
alphaMode = ExportAlphaMode(def.Rendering.RenderMode),
alphaCutoff = Mathf.Max(def.Color.CutoutThresholdValue, 0),
// Lighting
pbrMetallicRoughness = new glTFPbrMetallicRoughness
{
baseColorFactor = def.Color.LitColor.ToFloat4(ColorSpace.sRGB, ColorSpace.Linear),
baseColorTexture = new glTFMaterialBaseColorTextureInfo
{
index = textureExporter.ExportSRGB(def.Color.LitMultiplyTexture),
},
},
normalTexture = new glTFMaterialNormalTextureInfo
{
index = textureExporter.ExportNormal(def.Lighting.Normal.NormalTexture),
scale = def.Lighting.Normal.NormalScaleValue,
},
// Emission
emissiveFactor = def.Emission.EmissionColor.ToFloat3(ColorSpace.Linear, ColorSpace.Linear),
emissiveTexture = new glTFMaterialEmissiveTextureInfo
{
index = textureExporter.ExportSRGB(def.Emission.EmissionMultiplyTexture),
},
};
const float centimeterToMeter = 0.01f;
const float invertY = -1f;
// VRMC_materials_mtoon
var mtoon = new UniGLTF.Extensions.VRMC_materials_mtoon.VRMC_materials_mtoon
{
Version = "",
// Rendering
TransparentWithZWrite = def.Rendering.RenderMode == RenderMode.TransparentWithZWrite,
RenderQueueOffsetNumber = ExportRenderQueueOffset(def.Rendering.RenderMode, def.Rendering.RenderQueueOffsetNumber),
// Lighting
ShadeColorFactor = def.Color.ShadeColor.ToFloat3(ColorSpace.sRGB, ColorSpace.Linear),
ShadeMultiplyTexture = new TextureInfo
{
Index = textureExporter.ExportSRGB(def.Color.ShadeMultiplyTexture),
},
ShadingToonyFactor = def.Lighting.LitAndShadeMixing.ShadingToonyValue,
ShadingShiftFactor = def.Lighting.LitAndShadeMixing.ShadingShiftValue,
ShadingShiftTexture = null,
// Global Illumination
GiIntensityFactor = def.Lighting.LightingInfluence.GiIntensityValue,
// Rim Lighting
MatcapTexture = new TextureInfo
{
Index = textureExporter.ExportSRGB(def.MatCap.AdditiveTexture),
},
ParametricRimColorFactor = def.Rim.RimColor.ToFloat3(ColorSpace.Linear, ColorSpace.Linear),
ParametricRimFresnelPowerFactor = def.Rim.RimFresnelPowerValue,
ParametricRimLiftFactor = def.Rim.RimLiftValue,
RimMultiplyTexture = new TextureInfo
{
Index = textureExporter.ExportSRGB(def.Rim.RimMultiplyTexture),
},
RimLightingMixFactor = def.Rim.RimLightingMixValue,
// Outline
OutlineWidthMode = ExportOutlineWidthMode(def.Outline.OutlineWidthMode),
OutlineWidthFactor = def.Outline.OutlineWidthValue * centimeterToMeter,
OutlineWidthMultiplyTexture = new TextureInfo
{
Index = textureExporter.ExportLinear(def.Outline.OutlineWidthMultiplyTexture),
},
OutlineColorFactor = def.Outline.OutlineColor.ToFloat3(ColorSpace.sRGB, ColorSpace.Linear),
OutlineLightingMixFactor = ExportOutlineLightingMixFactor(def.Outline.OutlineColorMode, def.Outline.OutlineLightingMixValue),
// UV Anim
UvAnimationMaskTexture = new TextureInfo
{
Index = textureExporter.ExportLinear(def.TextureOption.UvAnimationMaskTexture),
},
UvAnimationScrollXSpeedFactor = def.TextureOption.UvAnimationScrollXSpeedValue,
UvAnimationScrollYSpeedFactor = def.TextureOption.UvAnimationScrollYSpeedValue * invertY,
UvAnimationRotationSpeedFactor = def.TextureOption.UvAnimationRotationSpeedValue,
};
// Texture Transforms
var scale = def.TextureOption.MainTextureLeftBottomOriginScale;
var offset = def.TextureOption.MainTextureLeftBottomOriginOffset;
ExportTextureTransform(dst.pbrMetallicRoughness.baseColorTexture, scale, offset);
ExportTextureTransform(dst.emissiveTexture, scale, offset);
ExportTextureTransform(dst.normalTexture, scale, offset);
ExportTextureTransform(mtoon.ShadeMultiplyTexture, scale, offset);
ExportTextureTransform(mtoon.MatcapTexture, scale, offset);
ExportTextureTransform(mtoon.RimMultiplyTexture, scale, offset);
ExportTextureTransform(mtoon.OutlineWidthMultiplyTexture, scale, offset);
ExportTextureTransform(mtoon.UvAnimationMaskTexture, scale, offset);
UniGLTF.Extensions.VRMC_materials_mtoon.GltfSerializer.SerializeTo(ref dst.extensions, mtoon);
return true;
}
catch (Exception e)
{
dst = null;
return false;
}
}
private static string ExportAlphaMode(MToon.RenderMode renderMode)
{
switch (renderMode)
{
case RenderMode.Opaque:
return "OPAQUE";
case RenderMode.Cutout:
return "MASK";
case RenderMode.Transparent:
return "BLEND";
case RenderMode.TransparentWithZWrite:
return "BLEND";
default:
throw new ArgumentOutOfRangeException(nameof(renderMode), renderMode, null);
}
}
private static int ExportRenderQueueOffset(MToon.RenderMode renderMode, int offset)
{
switch (renderMode)
{
case RenderMode.Opaque:
return 0;
case RenderMode.Cutout:
return 0;
case RenderMode.Transparent:
return Mathf.Clamp(offset, -9, 0);
case RenderMode.TransparentWithZWrite:
return Mathf.Clamp(offset, 0, +9);
default:
throw new ArgumentOutOfRangeException(nameof(renderMode), renderMode, null);
}
}
private static UniGLTF.Extensions.VRMC_materials_mtoon.OutlineWidthMode ExportOutlineWidthMode(
MToon.OutlineWidthMode mode)
{
switch (mode)
{
case OutlineWidthMode.None:
return UniGLTF.Extensions.VRMC_materials_mtoon.OutlineWidthMode.none;
case OutlineWidthMode.WorldCoordinates:
return UniGLTF.Extensions.VRMC_materials_mtoon.OutlineWidthMode.worldCoordinates;
case OutlineWidthMode.ScreenCoordinates:
return UniGLTF.Extensions.VRMC_materials_mtoon.OutlineWidthMode.screenCoordinates;
default:
throw new ArgumentOutOfRangeException(nameof(mode), mode, null);
}
}
private static float ExportOutlineLightingMixFactor(OutlineColorMode mode, float mixValue)
{
switch (mode)
{
case OutlineColorMode.FixedColor:
return 0;
case OutlineColorMode.MixedLighting:
return mixValue;
default:
throw new ArgumentOutOfRangeException(nameof(mode), mode, null);
}
}
private static void ExportTextureTransform(glTFTextureInfo textureInfo, Vector2 unityScale, Vector2 unityOffset)
{
var scale = unityScale;
var offset = new Vector2(unityOffset.x, 1.0f - unityOffset.y - unityScale.y);
glTF_KHR_texture_transform.Serialize(textureInfo, (offset.x, offset.y), (scale.x, scale.y));
}
private static void ExportTextureTransform(TextureInfo textureInfo, Vector2 unityScale, Vector2 unityOffset)
{
// Generate extension to empty holder.
var gltfTextureInfo = new EmptyGltfTextureInfo();
ExportTextureTransform(gltfTextureInfo, unityScale, unityOffset);
// Copy extension from empty holder.
textureInfo.Extensions = gltfTextureInfo.extensions;
}
private sealed class EmptyGltfTextureInfo : glTFTextureInfo
{
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 83b9443cb6d94771a7e0090baefa80ee
timeCreated: 1620981552

View File

@ -86,6 +86,13 @@ namespace UniVRM10
yield return (MToon.Utils.PropShadeShift, shadingShift.Value);
}
var shadingShiftTextureScale = mToon?.ShadingShiftTexture?.Scale;
if (shadingShiftTextureScale.HasValue)
{
Debug.LogWarning("Need VRM 1.0 MToon implementation.");
yield return ("_NEED_IMPLEMENTATION_MTOON_1_0_shadingShiftTextureScale", shadingShiftTextureScale.Value);
}
var shadingToony = mToon?.ShadingToonyFactor;
if (shadingToony.HasValue)
{

View File

@ -34,7 +34,7 @@ namespace UniVRM10
if (TryGetShadingShiftTexture(parser, mToon, out var shadeShiftTex))
{
Debug.LogWarning("Need VRM 1.0 MToon implementation.");
yield return ("_NEED_IMPLEMENTATION_MTOON_1_0", shadeShiftTex);
yield return ("_NEED_IMPLEMENTATION_MTOON_1_0_shadingShiftTexture", shadeShiftTex);
}
if (TryGetMatcapTexture(parser, mToon, out var matcapTex))

View File

@ -1,7 +1,6 @@
using UniGLTF;
using UnityEngine;
using VRMShaders;
using ColorSpace = UniGLTF.ColorSpace;
namespace UniVRM10
{
@ -9,91 +8,14 @@ namespace UniVRM10
{
public override glTFMaterial ExportMaterial(Material m, TextureExporter textureExporter)
{
if (m.shader.name != MToon.Utils.ShaderName)
if (Vrm10MToonMaterialExporter.TryExportMaterialAsMToon(m, textureExporter, out var dst))
{
return dst;
}
else
{
return base.ExportMaterial(m, textureExporter);
}
// convert MToon intermediate value from UnityEngine.Material
var def = MToon.Utils.GetMToonParametersFromMaterial(m);
// gltfMaterial
var material = new glTFMaterial
{
name = m.name,
pbrMetallicRoughness = new glTFPbrMetallicRoughness
{
baseColorFactor = def.Color.LitColor.ToFloat4(ColorSpace.sRGB, ColorSpace.Linear),
baseColorTexture = new glTFMaterialBaseColorTextureInfo
{
index = textureExporter.ExportSRGB(def.Color.LitMultiplyTexture),
},
},
emissiveFactor = def.Emission.EmissionColor.ToFloat3(ColorSpace.Linear, ColorSpace.Linear),
};
// VRMC_materials_mtoon
var mtoon = new UniGLTF.Extensions.VRMC_materials_mtoon.VRMC_materials_mtoon
{
Version = "",
TransparentWithZWrite = false,
RenderQueueOffsetNumber = 0,
ShadeColorFactor = new float[] { 0, 0, 0 },
ShadeMultiplyTexture = new UniGLTF.Extensions.VRMC_materials_mtoon.TextureInfo
{
Index = textureExporter.ExportSRGB(def.Color.ShadeMultiplyTexture),
},
// Lighting
ShadingShiftFactor = 0,
ShadingToonyFactor = 0,
GiIntensityFactor = 0,
// MatCap
// AdditiveTexture;
// Rim
ParametricRimColorFactor = new float[] { 0, 0, 0 },
// public int? RimMultiplyTexture;
RimLightingMixFactor = 0,
ParametricRimFresnelPowerFactor = 0,
ParametricRimLiftFactor = 0,
// Outline
OutlineWidthMode = UniGLTF.Extensions.VRMC_materials_mtoon.OutlineWidthMode.none,
OutlineWidthFactor = 0,
// public int? OutlineWidthMultiplyTexture;
OutlineColorFactor = new float[] { 0, 0, 0 },
OutlineLightingMixFactor = 0,
// public int? UvAnimationMaskTexture;
UvAnimationScrollXSpeedFactor = 0,
UvAnimationScrollYSpeedFactor = 0,
UvAnimationRotationSpeedFactor = 0,
};
UniGLTF.Extensions.VRMC_materials_mtoon.GltfSerializer.SerializeTo(ref material.extensions, mtoon);
return material;
}
}
}

View File

@ -40,9 +40,9 @@ namespace UniVRM10
/// <summary>
/// vrm-0 の json から vrm-0 の MToon.Definition を生成する。
///
///
/// Texture2D は作成せずに、直接 index を操作する。
///
///
/// </summary>
sealed class MToonValue
{
@ -115,7 +115,7 @@ namespace UniVRM10
break;
default:
#if VRM_DEVELOP
#if VRM_DEVELOP
Debug.LogWarning($"vectorProperties: {kv.Key}: {kv.Value}");
#endif
break;
@ -219,7 +219,7 @@ namespace UniVRM10
break;
default:
#if VRM_DEVELOP
#if VRM_DEVELOP
Debug.LogWarning($"floatProperties: {kv.Key} is unknown");
#endif
break;
@ -244,7 +244,7 @@ namespace UniVRM10
case "_OutlineWidthTexture": map.OutlineWidthTexture = index; break;
case "_UvAnimMaskTexture": map.UvAnimMaskTexture = index; break;
default:
#if VRM_DEVELOP
#if VRM_DEVELOP
Debug.LogWarning($"textureProperties: {kv.Key} is unknown");
#endif
break;
@ -297,7 +297,7 @@ namespace UniVRM10
var gltfMaterial = gltf.materials[i];
if (!glTF_KHR_materials_unlit.IsEnable(gltfMaterial))
{
// 古いモデルは無い場合がある
// 古いモデルは無い場合がある
// throw new Exception($"[{i}]{gltfMaterial.name} has no extensions");
}
sourceMaterials[i] = (mtoon, gltfMaterial);
@ -500,7 +500,7 @@ namespace UniVRM10
}
dst.UvAnimationRotationSpeedFactor = mtoon.Definition.TextureOption.UvAnimationRotationSpeedValue;
dst.UvAnimationScrollXSpeedFactor = mtoon.Definition.TextureOption.UvAnimationScrollXSpeedValue;
dst.UvAnimationScrollYSpeedFactor = mtoon.Definition.TextureOption.UvAnimationScrollYSpeedValue;
dst.UvAnimationScrollYSpeedFactor = mtoon.Definition.TextureOption.UvAnimationScrollYSpeedValue * -1f;
UniGLTF.Extensions.VRMC_materials_mtoon.GltfSerializer.SerializeTo(ref gltfMaterial.extensions, dst);
}