mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-04-24 15:08:02 -05:00
Implements VRM10 MToon Exporter
This commit is contained in:
parent
44145bc6ca
commit
d33b928eeb
231
Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialExporter.cs
Normal file
231
Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialExporter.cs
Normal 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
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 83b9443cb6d94771a7e0090baefa80ee
|
||||
timeCreated: 1620981552
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user