diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfMaterialImporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfMaterialImporter.cs
index 5c001e499..deb3e1e04 100644
--- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfMaterialImporter.cs
+++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfMaterialImporter.cs
@@ -77,7 +77,7 @@ namespace UniGLTF
scale = new Vector2(textureTransform.scale[0], textureTransform.scale[1]);
}
- // Coordinate Conversion: GL (top-left origin) to DX (bottom-left origin)
+ // UV Coordinate Conversion: glTF(top-left origin) to Unity(bottom-left origin)
// Formula: https://github.com/vrm-c/UniVRM/issues/930
offset.y = 1.0f - offset.y - scale.y;
}
diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfPBRMaterial.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfPBRMaterial.cs
index b38096100..ed9e1fd87 100644
--- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfPBRMaterial.cs
+++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfPBRMaterial.cs
@@ -78,6 +78,12 @@ namespace UniGLTF
var (offset, scale) = GltfMaterialImporter.GetTextureOffsetAndScale(src.normalTexture);
return GltfTextureImporter.CreateNormal(parser, src.normalTexture.index, offset, scale);
}
+
+ public static (SubAssetKey, TextureImportParam Param) EmissiveTexture(GltfParser parser, glTFMaterial src)
+ {
+ var (offset, scale) = GltfMaterialImporter.GetTextureOffsetAndScale(src.emissiveTexture);
+ return GltfTextureImporter.CreateSRGB(parser, src.emissiveTexture.index, offset, scale);
+ }
public static bool TryCreateParam(GltfParser parser, int i, out MaterialImportParam param)
{
@@ -159,8 +165,7 @@ namespace UniGLTF
if (src.emissiveTexture != null && src.emissiveTexture.index != -1)
{
- var (offset, scale) = GltfMaterialImporter.GetTextureOffsetAndScale(src.emissiveTexture);
- var (key, textureParam) = GltfTextureImporter.CreateSRGB(parser, src.emissiveTexture.index, offset, scale);
+ var (key, textureParam) = EmissiveTexture(parser, src);
param.TextureSlots.Add("_EmissionMap", textureParam);
}
}
diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfTextureEnumerator.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfTextureEnumerator.cs
index 258b13b35..c72081b79 100644
--- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfTextureEnumerator.cs
+++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfTextureEnumerator.cs
@@ -51,8 +51,7 @@ namespace UniGLTF
// emission
if (m.emissiveTexture != null)
{
- var (offset, scale) = GltfMaterialImporter.GetTextureOffsetAndScale(m.emissiveTexture);
- yield return GltfTextureImporter.CreateSRGB(parser, m.emissiveTexture.index, offset, scale);
+ yield return GltfPBRMaterial.EmissiveTexture(parser, m);
}
// normal
diff --git a/Assets/VRM/Runtime/IO/VRMMaterialImporter.cs b/Assets/VRM/Runtime/IO/VRMMaterialImporter.cs
index 491793f19..d6b69d1de 100644
--- a/Assets/VRM/Runtime/IO/VRMMaterialImporter.cs
+++ b/Assets/VRM/Runtime/IO/VRMMaterialImporter.cs
@@ -31,7 +31,7 @@ namespace VRM
var name = parser.GLTF.materials[i].name;
param = new MaterialImportParam(name, vrmMaterial.shader);
- param.Actions.Add(material => material.renderQueue = vrmMaterial.renderQueue);
+ param.RenderQueue = vrmMaterial.renderQueue;
foreach (var kv in vrmMaterial.floatProperties)
{
diff --git a/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialParameterImporter.cs b/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialParameterImporter.cs
new file mode 100644
index 000000000..c3880069a
--- /dev/null
+++ b/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialParameterImporter.cs
@@ -0,0 +1,237 @@
+using System;
+using System.Collections.Generic;
+using UniGLTF;
+using UniGLTF.Extensions.VRMC_materials_mtoon;
+using UnityEngine;
+using ColorSpace = UniGLTF.ColorSpace;
+using OutlineWidthMode = UniGLTF.Extensions.VRMC_materials_mtoon.OutlineWidthMode;
+
+namespace UniVRM10
+{
+ ///
+ /// Convert MToon parameters from glTF specification to Unity implementation.
+ ///
+ public static class Vrm10MToonMaterialParameterImporter
+ {
+ public static IEnumerable<(string key, Color value)> TryGetAllColors(glTFMaterial material, VRMC_materials_mtoon mToon)
+ {
+ const ColorSpace gltfColorSpace = ColorSpace.Linear;
+
+ var baseColor = material?.pbrMetallicRoughness?.baseColorFactor?.ToColor4(gltfColorSpace, ColorSpace.sRGB);
+ if (baseColor.HasValue)
+ {
+ yield return (MToon.Utils.PropColor, baseColor.Value);
+ }
+
+ var emissionColor = material?.emissiveFactor?.ToColor3(gltfColorSpace, ColorSpace.Linear);
+ if (emissionColor.HasValue)
+ {
+ yield return (MToon.Utils.PropEmissionColor, emissionColor.Value);
+ }
+
+ var shadeColor = mToon?.ShadeColorFactor?.ToColor3(gltfColorSpace, ColorSpace.sRGB);
+ if (shadeColor.HasValue)
+ {
+ yield return (MToon.Utils.PropShadeColor, shadeColor.Value);
+ }
+
+ var rimColor = mToon?.ParametricRimColorFactor?.ToColor3(gltfColorSpace, ColorSpace.Linear);
+ if (rimColor.HasValue)
+ {
+ yield return (MToon.Utils.PropRimColor, rimColor.Value);
+ }
+
+ var outlineColor = mToon?.OutlineColorFactor?.ToColor3(gltfColorSpace, ColorSpace.sRGB);
+ if (outlineColor.HasValue)
+ {
+ yield return (MToon.Utils.PropOutlineColor, outlineColor.Value);
+ }
+ }
+
+ public static IEnumerable<(string key, float value)> TryGetAllFloats(glTFMaterial material, VRMC_materials_mtoon mToon)
+ {
+ var renderMode = GetMToonRenderMode(material, mToon);
+ {
+ yield return (MToon.Utils.PropBlendMode, (float) renderMode);
+ }
+
+ var cullMode = GetMToonCullMode(material, mToon);
+ {
+ yield return (MToon.Utils.PropCullMode, (float) cullMode);
+ }
+
+ var outlineMode = GetMToonOutlineWidthMode(material, mToon);
+ {
+ yield return (MToon.Utils.PropOutlineWidthMode, (float) outlineMode);
+
+ // In case of VRM 1.0 MToon, outline color mode is always MixedLighting.
+ yield return (MToon.Utils.PropOutlineColorMode, (float) MToon.OutlineColorMode.MixedLighting);
+ }
+
+ var cutoff = material?.alphaCutoff;
+ if (cutoff.HasValue)
+ {
+ yield return (MToon.Utils.PropCutoff, cutoff.Value);
+ }
+
+ var normalScale = material?.normalTexture?.scale;
+ if (normalScale.HasValue)
+ {
+ yield return ("_BumpScale", normalScale.Value);
+ }
+
+ var shadingShift = mToon?.ShadingShiftFactor;
+ if (shadingShift.HasValue)
+ {
+ yield return (MToon.Utils.PropShadeShift, shadingShift.Value);
+ }
+
+ var shadingToony = mToon?.ShadingToonyFactor;
+ if (shadingToony.HasValue)
+ {
+ yield return (MToon.Utils.PropShadeToony, shadingToony.Value);
+ }
+
+ var giIntensity = mToon?.GiIntensityFactor;
+ if (giIntensity.HasValue)
+ {
+ yield return (MToon.Utils.PropIndirectLightIntensity, giIntensity.Value);
+ }
+
+ var rimLightMix = mToon?.RimLightingMixFactor;
+ if (rimLightMix.HasValue)
+ {
+ yield return (MToon.Utils.PropRimLightingMix, rimLightMix.Value);
+ }
+
+ var rimFresnelPower = mToon?.ParametricRimFresnelPowerFactor;
+ if (rimFresnelPower.HasValue)
+ {
+ yield return (MToon.Utils.PropRimFresnelPower, rimFresnelPower.Value);
+ }
+
+ var rimLift = mToon?.ParametricRimLiftFactor;
+ if (rimLift.HasValue)
+ {
+ yield return (MToon.Utils.PropRimLift, rimLift.Value);
+ }
+
+ // Unit conversion.
+ // Because Unity implemented MToon uses centimeter unit in width parameter.
+ var outlineWidth = mToon?.OutlineWidthFactor;
+ if (outlineWidth.HasValue)
+ {
+ const float meterToCentimeter = 100f;
+
+ yield return (MToon.Utils.PropOutlineWidth, outlineWidth.Value * meterToCentimeter);
+ }
+
+ var outlineLightMix = mToon?.OutlineLightingMixFactor;
+ if (outlineLightMix.HasValue)
+ {
+ yield return (MToon.Utils.PropOutlineLightingMix, outlineLightMix.Value);
+ }
+
+ var uvAnimSpeedScrollX = mToon?.UvAnimationScrollXSpeedFactor;
+ if (uvAnimSpeedScrollX.HasValue)
+ {
+ yield return (MToon.Utils.PropUvAnimScrollX, uvAnimSpeedScrollX.Value);
+ }
+
+ // UV coords conversion.
+ // glTF (top-left origin) to Unity (bottom-left origin)
+ var uvAnimSpeedScrollY = mToon?.UvAnimationScrollYSpeedFactor;
+ if (uvAnimSpeedScrollY.HasValue)
+ {
+ const float invertY = -1f;
+
+ yield return (MToon.Utils.PropUvAnimScrollY, uvAnimSpeedScrollY.Value * invertY);
+ }
+
+ var uvAnimSpeedRotation = mToon?.UvAnimationRotationSpeedFactor;
+ if (uvAnimSpeedRotation.HasValue)
+ {
+ yield return (MToon.Utils.PropUvAnimRotation, uvAnimSpeedRotation.Value);
+ }
+ }
+
+ public static IEnumerable<(string key, Vector4 value)> TryGetAllFloatArrays(glTFMaterial material, VRMC_materials_mtoon mToon)
+ {
+ yield break;
+ }
+
+ public static int? TryGetRenderQueue(glTFMaterial material, VRMC_materials_mtoon mToon)
+ {
+ var renderQueueOffset = mToon?.RenderQueueOffsetNumber;
+ if (renderQueueOffset.HasValue)
+ {
+ var renderMode = GetMToonRenderMode(material, mToon);
+ return MToon.Utils.GetRenderQueueRequirement(renderMode).DefaultValue +
+ renderQueueOffset.Value;
+ }
+ return default;
+ }
+
+
+ private static MToon.RenderMode GetMToonRenderMode(glTFMaterial material, VRMC_materials_mtoon mToon)
+ {
+ switch (material?.alphaMode)
+ {
+ case "OPAQUE":
+ return MToon.RenderMode.Opaque;
+ case "MASK":
+ return MToon.RenderMode.Cutout;
+ case "BLEND":
+ var mToonZWrite = mToon?.TransparentWithZWrite;
+ if (mToonZWrite.HasValue)
+ {
+ if (mToonZWrite.Value)
+ {
+ return MToon.RenderMode.TransparentWithZWrite;
+ }
+ else
+ {
+ return MToon.RenderMode.Transparent;
+ }
+ }
+ else
+ {
+ // Invalid
+ return MToon.RenderMode.Transparent;
+ }
+ default:
+ // Invalid
+ return MToon.RenderMode.Opaque;
+ }
+ }
+
+ private static MToon.CullMode GetMToonCullMode(glTFMaterial material, VRMC_materials_mtoon mToon)
+ {
+ var doubleSided = material?.doubleSided;
+ if (doubleSided.HasValue && doubleSided.Value)
+ {
+ return MToon.CullMode.Off;
+ }
+ else
+ {
+ return MToon.CullMode.Back;
+ }
+ }
+
+ private static MToon.OutlineWidthMode GetMToonOutlineWidthMode(glTFMaterial material, VRMC_materials_mtoon mToon)
+ {
+ switch (mToon.OutlineWidthMode)
+ {
+ case OutlineWidthMode.none:
+ return MToon.OutlineWidthMode.None;
+ case OutlineWidthMode.worldCoordinates:
+ return MToon.OutlineWidthMode.WorldCoordinates;
+ case OutlineWidthMode.screenCoordinates:
+ return MToon.OutlineWidthMode.ScreenCoordinates;
+ default:
+ // Invalid
+ return MToon.OutlineWidthMode.None;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialParameterImporter.cs.meta b/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialParameterImporter.cs.meta
new file mode 100644
index 000000000..af9937828
--- /dev/null
+++ b/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialParameterImporter.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 01c1ac60c9a047b59ea52aaddb7a0d63
+timeCreated: 1620630516
\ No newline at end of file
diff --git a/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialImporter.cs b/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialTextureImporter.cs
similarity index 57%
rename from Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialImporter.cs
rename to Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialTextureImporter.cs
index 9aba6f56b..e707f5459 100644
--- a/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialImporter.cs
+++ b/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialTextureImporter.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using UniGLTF;
using UniGLTF.Extensions.VRMC_materials_mtoon;
using UnityEngine;
@@ -6,9 +7,58 @@ using VRMShaders;
namespace UniVRM10
{
- public static class Vrm10MToonMaterialImporter
+ public static class Vrm10MToonMaterialTextureImporter
{
- public static bool TryGetBaseColorTexture(GltfParser parser, glTFMaterial src, out (SubAssetKey, TextureImportParam) pair)
+ public static IEnumerable<(string key, (SubAssetKey, TextureImportParam))> TryGetAllTextures(GltfParser parser, glTFMaterial material, VRMC_materials_mtoon mToon)
+ {
+ if (TryGetBaseColorTexture(parser, material, out var litTex))
+ {
+ yield return (MToon.Utils.PropMainTex, litTex);
+ }
+
+ if (TryGetEmissiveTexture(parser, material, out var emissiveTex))
+ {
+ yield return (MToon.Utils.PropEmissionMap, emissiveTex);
+ }
+
+ if (TryGetNormalTexture(parser, material, out var normalTex))
+ {
+ yield return ("_BumpMap", normalTex);
+ }
+
+ if (TryGetShadeMultiplyTexture(parser, mToon, out var shadeTex))
+ {
+ yield return (MToon.Utils.PropShadeTexture, shadeTex);
+ }
+
+ if (TryGetShadingShiftTexture(parser, mToon, out var shadeShiftTex))
+ {
+ Debug.LogWarning("Need VRM 1.0 MToon implementation.");
+ yield return ("_NEED_IMPLEMENTATION_MTOON_1_0", shadeShiftTex);
+ }
+
+ if (TryGetMatcapTexture(parser, mToon, out var matcapTex))
+ {
+ yield return (MToon.Utils.PropSphereAdd, matcapTex);
+ }
+
+ if (TryGetRimMultiplyTexture(parser, mToon, out var rimTex))
+ {
+ yield return (MToon.Utils.PropRimTexture, rimTex);
+ }
+
+ if (TryGetOutlineWidthMultiplyTexture(parser, mToon, out var outlineTex))
+ {
+ yield return (MToon.Utils.PropOutlineWidthTexture, outlineTex);
+ }
+
+ if (TryGetUvAnimationMaskTexture(parser, mToon, out var uvAnimMaskTex))
+ {
+ yield return (MToon.Utils.PropUvAnimMaskTexture, uvAnimMaskTex);
+ }
+ }
+
+ private static bool TryGetBaseColorTexture(GltfParser parser, glTFMaterial src, out (SubAssetKey, TextureImportParam) pair)
{
try
{
@@ -26,8 +76,28 @@ namespace UniVRM10
return false;
}
}
-
- public static bool TryGetNormalTexture(GltfParser parser, glTFMaterial src, out (SubAssetKey, TextureImportParam) pair)
+
+ private static bool TryGetEmissiveTexture(GltfParser parser, glTFMaterial src, out (SubAssetKey, TextureImportParam) pair)
+ {
+ try
+ {
+ pair = GltfPBRMaterial.EmissiveTexture(parser, src);
+ return true;
+ }
+ catch (NullReferenceException)
+ {
+ pair = default;
+ return false;
+ }
+ catch (ArgumentOutOfRangeException)
+ {
+ pair = default;
+ return false;
+ }
+
+ }
+
+ private static bool TryGetNormalTexture(GltfParser parser, glTFMaterial src, out (SubAssetKey, TextureImportParam) pair)
{
try
{
@@ -46,32 +116,32 @@ namespace UniVRM10
}
}
- public static bool TryGetShadeMultiplyTexture(GltfParser parser, VRMC_materials_mtoon mToon, out (SubAssetKey, TextureImportParam) pair)
+ private static bool TryGetShadeMultiplyTexture(GltfParser parser, VRMC_materials_mtoon mToon, out (SubAssetKey, TextureImportParam) pair)
{
return TryGetSRGBTexture(parser, new Vrm10TextureInfo(mToon.ShadeMultiplyTexture), out pair);
}
- public static bool TryGetShadingShiftTexture(GltfParser parser, VRMC_materials_mtoon mToon, out (SubAssetKey, TextureImportParam) pair)
+ private static bool TryGetShadingShiftTexture(GltfParser parser, VRMC_materials_mtoon mToon, out (SubAssetKey, TextureImportParam) pair)
{
return TryGetLinearTexture(parser, new Vrm10TextureInfo(mToon.ShadingShiftTexture), out pair);
}
-
- public static bool TryGetMatcapTexture(GltfParser parser, VRMC_materials_mtoon mToon, out (SubAssetKey, TextureImportParam) pair)
+
+ private static bool TryGetMatcapTexture(GltfParser parser, VRMC_materials_mtoon mToon, out (SubAssetKey, TextureImportParam) pair)
{
return TryGetSRGBTexture(parser, new Vrm10TextureInfo(mToon.ShadingShiftTexture), out pair);
}
-
- public static bool TryGetRimMultiplyTexture(GltfParser parser, VRMC_materials_mtoon mToon, out (SubAssetKey, TextureImportParam) pair)
+
+ private static bool TryGetRimMultiplyTexture(GltfParser parser, VRMC_materials_mtoon mToon, out (SubAssetKey, TextureImportParam) pair)
{
return TryGetSRGBTexture(parser, new Vrm10TextureInfo(mToon.RimMultiplyTexture), out pair);
}
- public static bool TryGetOutlineWidthMultiplyTexture(GltfParser parser, VRMC_materials_mtoon mToon, out (SubAssetKey, TextureImportParam) pair)
+ private static bool TryGetOutlineWidthMultiplyTexture(GltfParser parser, VRMC_materials_mtoon mToon, out (SubAssetKey, TextureImportParam) pair)
{
return TryGetLinearTexture(parser, new Vrm10TextureInfo(mToon.OutlineWidthMultiplyTexture), out pair);
}
- public static bool TryGetUvAnimationMaskTexture(GltfParser parser, VRMC_materials_mtoon mToon, out (SubAssetKey, TextureImportParam) pair)
+ private static bool TryGetUvAnimationMaskTexture(GltfParser parser, VRMC_materials_mtoon mToon, out (SubAssetKey, TextureImportParam) pair)
{
return TryGetLinearTexture(parser, new Vrm10TextureInfo(mToon.UvAnimationMaskTexture), out pair);
}
diff --git a/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialImporter.cs.meta b/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialTextureImporter.cs.meta
similarity index 100%
rename from Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialImporter.cs.meta
rename to Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialTextureImporter.cs.meta
diff --git a/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureEnumerator.cs b/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureEnumerator.cs
index f2ba0ae2a..59404d092 100644
--- a/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureEnumerator.cs
+++ b/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureEnumerator.cs
@@ -80,23 +80,10 @@ namespace UniVRM10
var m = parser.GLTF.materials[i];
if (UniGLTF.Extensions.VRMC_materials_mtoon.GltfDeserializer.TryGet(m.extensions, out var mToon))
{
- // Enumerate VRM MToon Textures
- if (Vrm10MToonMaterialImporter.TryGetBaseColorTexture(parser, m, out var litTex))
- yield return litTex;
- if (Vrm10MToonMaterialImporter.TryGetNormalTexture(parser, m, out var normalTex))
- yield return normalTex;
- if (Vrm10MToonMaterialImporter.TryGetShadeMultiplyTexture(parser, mToon, out var shadeTex))
- yield return shadeTex;
- if (Vrm10MToonMaterialImporter.TryGetShadingShiftTexture(parser, mToon, out var shadeShiftTex))
- yield return shadeShiftTex;
- if (Vrm10MToonMaterialImporter.TryGetMatcapTexture(parser, mToon, out var matcapTex))
- yield return matcapTex;
- if (Vrm10MToonMaterialImporter.TryGetRimMultiplyTexture(parser, mToon, out var rimTex))
- yield return rimTex;
- if (Vrm10MToonMaterialImporter.TryGetOutlineWidthMultiplyTexture(parser, mToon, out var outlineTex))
- yield return outlineTex;
- if (Vrm10MToonMaterialImporter.TryGetUvAnimationMaskTexture(parser, mToon, out var uvAnimMaskTex))
- yield return uvAnimMaskTex;
+ foreach (var (key, tex) in Vrm10MToonMaterialTextureImporter.TryGetAllTextures(parser, m, mToon))
+ {
+ yield return tex;
+ }
}
else
{
diff --git a/Assets/VRM10/Runtime/IO/Vrm10MaterialImporter.cs b/Assets/VRM10/Runtime/IO/Vrm10MaterialImporter.cs
index 605a81aa8..16eede2f8 100644
--- a/Assets/VRM10/Runtime/IO/Vrm10MaterialImporter.cs
+++ b/Assets/VRM10/Runtime/IO/Vrm10MaterialImporter.cs
@@ -19,7 +19,7 @@ namespace UniVRM10
if (!UniGLTF.Extensions.VRMC_materials_mtoon.GltfDeserializer.TryGet(m.extensions,
out UniGLTF.Extensions.VRMC_materials_mtoon.VRMC_materials_mtoon mtoon))
{
- // fallback to gltf
+ // Fallback to glTF, when MToon extension does not exist.
param = default;
return false;
}
@@ -27,138 +27,34 @@ namespace UniVRM10
// use material.name, because material name may renamed in GltfParser.
param = new MaterialImportParam(m.name, MToon.Utils.ShaderName);
+ foreach (var (key, (subAssetKey, value)) in Vrm10MToonMaterialTextureImporter.TryGetAllTextures(parser, m, mtoon))
+ {
+ param.TextureSlots.Add(key, value);
+ }
+
+ foreach (var (key, value) in Vrm10MToonMaterialParameterImporter.TryGetAllColors(m, mtoon))
+ {
+ param.Colors.Add(key, value);
+ }
+
+ foreach (var (key, value) in Vrm10MToonMaterialParameterImporter.TryGetAllFloats(m, mtoon))
+ {
+ param.FloatValues.Add(key, value);
+ }
+
+ foreach (var (key, value) in Vrm10MToonMaterialParameterImporter.TryGetAllFloatArrays(m, mtoon))
+ {
+ param.Vectors.Add(key, value);
+ }
+
+ param.RenderQueue = Vrm10MToonMaterialParameterImporter.TryGetRenderQueue(m, mtoon);
+
param.Actions.Add(material =>
{
- // Texture 以外をここで設定。Texture は TextureSlots へ
- {
- // material.SetFloat(PropVersion, mtoon.Version);
- }
- {
- // var rendering = mtoon.Rendering;
- // SetRenderMode(material, rendering.RenderMode, rendering.RenderQueueOffsetNumber,
- // useDefaultRenderQueue: false);
- // SetCullMode(material, rendering.CullMode);
- }
- {
- // var color = mtoon.Color;
- material.SetColor(MToon.Utils.PropColor, m.pbrMetallicRoughness.baseColorFactor
- .ToColor4(UniGLTF.ColorSpace.Linear, UniGLTF.ColorSpace.sRGB)
- );
- if (mtoon.ShadeColorFactor != null)
- {
- material.SetColor(MToon.Utils.PropShadeColor, mtoon.ShadeColorFactor
- .ToColor3(UniGLTF.ColorSpace.Linear, UniGLTF.ColorSpace.sRGB)
- );
- }
- material.SetFloat(MToon.Utils.PropCutoff, m.alphaCutoff);
- }
- {
- {
- if (mtoon.ShadingShiftFactor.HasValue) material.SetFloat(MToon.Utils.PropShadeShift, mtoon.ShadingShiftFactor.Value);
- if (mtoon.ShadingToonyFactor.HasValue) material.SetFloat(MToon.Utils.PropShadeToony, mtoon.ShadingToonyFactor.Value);
- // material.SetFloat(PropReceiveShadowRate, mtoon.prop.ShadowReceiveMultiplierValue);
- // material.SetFloat(PropShadingGradeRate, mtoon.mix prop.LitAndShadeMixingMultiplierValue);
- }
- {
- if (mtoon.GiIntensityFactor.HasValue) material.SetFloat(MToon.Utils.PropIndirectLightIntensity, mtoon.GiIntensityFactor.Value);
- }
- }
- {
- material.SetColor(MToon.Utils.PropEmissionColor,
- m.emissiveFactor.ToColor3(UniGLTF.ColorSpace.Linear, UniGLTF.ColorSpace.Linear)
- );
- }
- {
- if (mtoon.ParametricRimColorFactor != null)
- {
- material.SetColor(MToon.Utils.PropRimColor, mtoon.ParametricRimColorFactor
- .ToColor3(UniGLTF.ColorSpace.Linear, UniGLTF.ColorSpace.sRGB)
- );
- }
- if (mtoon.RimLightingMixFactor.HasValue) material.SetFloat(MToon.Utils.PropRimLightingMix, mtoon.RimLightingMixFactor.Value);
- if (mtoon.ParametricRimFresnelPowerFactor.HasValue) material.SetFloat(MToon.Utils.PropRimFresnelPower, mtoon.ParametricRimFresnelPowerFactor.Value);
- if (mtoon.ParametricRimLiftFactor.HasValue) material.SetFloat(MToon.Utils.PropRimLift, mtoon.ParametricRimLiftFactor.Value);
- }
- {
- if (mtoon.OutlineWidthFactor.HasValue) material.SetFloat(MToon.Utils.PropOutlineWidth, mtoon.OutlineWidthFactor.Value);
- if (mtoon.OutlineColorFactor != null)
- {
- material.SetColor(MToon.Utils.PropOutlineColor, mtoon.OutlineColorFactor
- .ToColor3(UniGLTF.ColorSpace.Linear, UniGLTF.ColorSpace.sRGB)
- );
- }
- if (mtoon.OutlineLightingMixFactor.HasValue) material.SetFloat(MToon.Utils.PropOutlineLightingMix, mtoon.OutlineLightingMixFactor.Value);
-
- // private
- // MToon.Utils.SetOutlineMode(material, outline.OutlineWidthMode, outline.OutlineColorMode);
- }
- {
- // material.SetTextureScale(PropMainTex, mtoon.MainTextureLeftBottomOriginScale);
- // material.SetTextureOffset(PropMainTex, mtoon.MainTextureLeftBottomOriginOffset);
- if (mtoon.UvAnimationScrollXSpeedFactor.HasValue) material.SetFloat(MToon.Utils.PropUvAnimScrollX, mtoon.UvAnimationScrollXSpeedFactor.Value);
- if (mtoon.UvAnimationScrollYSpeedFactor.HasValue) material.SetFloat(MToon.Utils.PropUvAnimScrollY, mtoon.UvAnimationScrollYSpeedFactor.Value);
- if (mtoon.UvAnimationRotationSpeedFactor.HasValue) material.SetFloat(MToon.Utils.PropUvAnimRotation, mtoon.UvAnimationRotationSpeedFactor.Value);
- }
-
+ // Set hidden properties, keywords from float properties.
MToon.Utils.ValidateProperties(material, isBlendModeChangedByUser: false);
});
- // SetTexture(material, PropMainTex, color.LitMultiplyTexture);
- // SetNormalMapping(material, prop.NormalTexture, prop.NormalScaleValue);
- // SetTexture(material, PropEmissionMap, emission.EmissionMultiplyTexture);
-
- if (m.pbrMetallicRoughness != null)
- {
- // base color
- if (m.pbrMetallicRoughness?.baseColorTexture != null)
- {
- param.TextureSlots.Add("_MainTex", GltfPBRMaterial.BaseColorTexture(parser, m).Param);
- }
- }
-
- if (m.normalTexture != null && m.normalTexture.index != -1)
- {
- // normal map
- param.Actions.Add(material => material.EnableKeyword("_NORMALMAP"));
- var textureParam = GltfPBRMaterial.NormalTexture(parser, m).Param;
- param.TextureSlots.Add("_BumpMap", textureParam);
- param.FloatValues.Add("_BumpScale", m.normalTexture.scale);
- }
-
- if (m.emissiveTexture != null && m.emissiveTexture.index != -1)
- {
- var (offset, scale) = GltfMaterialImporter.GetTextureOffsetAndScale(m.emissiveTexture);
- var textureParam = GltfTextureImporter.CreateSRGB(parser, m.emissiveTexture.index, offset, scale).Param;
- param.TextureSlots.Add("_EmissionMap", textureParam);
- }
-
- // TODO:
- if (mtoon.ShadeMultiplyTexture != null)
- {
- var textureParam = GltfTextureImporter.CreateSRGB(parser, mtoon.ShadeMultiplyTexture.Index.Value, Vector2.zero, Vector2.one).Param;
- param.TextureSlots.Add("_ShadeTexture", textureParam);
- }
- if (mtoon.OutlineWidthMultiplyTexture != null)
- {
- var textureParam = GltfTextureImporter.CreateSRGB(parser, mtoon.OutlineWidthMultiplyTexture.Index.Value, Vector2.zero, Vector2.one).Param;
- param.TextureSlots.Add("_OutlineWidthTexture", textureParam);
- }
- if (mtoon.MatcapTexture != null)
- {
- var textureParam = GltfTextureImporter.CreateSRGB(parser, mtoon.MatcapTexture.Index.Value, Vector2.zero, Vector2.one).Param;
- param.TextureSlots.Add("_SphereAdd", textureParam);
- }
- if (mtoon.RimMultiplyTexture != null)
- {
- var textureParam = GltfTextureImporter.CreateSRGB(parser, mtoon.RimMultiplyTexture.Index.Value, Vector2.zero, Vector2.one).Param;
- param.TextureSlots.Add("_RimTexture", textureParam); ;
- }
- if (mtoon.UvAnimationMaskTexture != null)
- {
- var textureParam = GltfTextureImporter.CreateSRGB(parser, mtoon.UvAnimationMaskTexture.Index.Value, Vector2.zero, Vector2.one).Param;
- param.TextureSlots.Add("_UvAnimMaskTexture", textureParam);
- }
-
return true;
}
diff --git a/Assets/VRM10/Runtime/Migration/MigrationMToon.cs b/Assets/VRM10/Runtime/Migration/MigrationMToon.cs
index 1a07cf141..4e3551bfb 100644
--- a/Assets/VRM10/Runtime/Migration/MigrationMToon.cs
+++ b/Assets/VRM10/Runtime/Migration/MigrationMToon.cs
@@ -6,6 +6,7 @@ using UniGLTF.Extensions.VRMC_materials_mtoon;
using UniJSON;
using UnityEngine;
using ColorSpace = UniGLTF.ColorSpace;
+using RenderMode = MToon.RenderMode;
namespace UniVRM10
{
@@ -43,7 +44,7 @@ namespace UniVRM10
/// Texture2D は作成せずに、直接 index を操作する。
///
///
- struct MToonValue
+ sealed class MToonValue
{
public MToon.MToonDefinition Definition;
@@ -250,6 +251,10 @@ namespace UniVRM10
}
}
+ definition.Rendering.RenderQueueOffsetNumber =
+ vrmMaterial["renderQueue"].GetInt32() -
+ MToon.Utils.GetRenderQueueRequirement(definition.Rendering.RenderMode).DefaultValue;
+
return new MToonValue
{
Definition = definition,
@@ -274,6 +279,10 @@ namespace UniVRM10
public static void Migrate(glTF gltf, JsonNode json)
{
+ const float centimeterToMeter = 0.01f;
+
+ // Create MToonDefinition(0.x) from JSON(0.x)
+ var sourceMaterials = new (MToonValue, glTFMaterial)[gltf.materials.Count];
for (int i = 0; i < gltf.materials.Count; ++i)
{
var vrmMaterial = json["extensions"]["VRM"]["materialProperties"][i];
@@ -281,10 +290,9 @@ namespace UniVRM10
{
continue;
}
-
// VRM-0 MToon の情報
var mtoon = MToonValue.Create(vrmMaterial);
-
+
// KHR_materials_unlit として fallback した情報が入っている
var gltfMaterial = gltf.materials[i];
if (!glTF_KHR_materials_unlit.IsEnable(gltfMaterial))
@@ -292,7 +300,47 @@ namespace UniVRM10
// 古いモデルは無い場合がある
// throw new Exception($"[{i}]{gltfMaterial.name} has no extensions");
}
+ sourceMaterials[i] = (mtoon, gltfMaterial);
+ }
+ // Collect RenderQueues Pass
+ // 元の描画順序をできるだけ保つようにして RenderQueue を変換する
+ var transparentRenderQueues = new SortedSet();
+ var transparentZWriteRenderQueues = new SortedSet();
+ foreach (var (mtoon, gltfMaterial) in sourceMaterials)
+ {
+ switch (mtoon.Definition.Rendering.RenderMode)
+ {
+ case RenderMode.Opaque:
+ break;
+ case RenderMode.Cutout:
+ break;
+ case RenderMode.Transparent:
+ transparentRenderQueues.Add(mtoon.Definition.Rendering.RenderQueueOffsetNumber);
+ break;
+ case RenderMode.TransparentWithZWrite:
+ transparentZWriteRenderQueues.Add(mtoon.Definition.Rendering.RenderQueueOffsetNumber);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+ var defaultTransparentQueue = 0;
+ var transparentRenderQueueMap = new Dictionary();
+ foreach (var srcQueue in transparentRenderQueues.Reverse())
+ {
+ transparentRenderQueueMap.Add(srcQueue, defaultTransparentQueue--);
+ }
+ var defaultTransparentZWriteQueue = 0;
+ var transparentZWriteRenderQueueMap = new Dictionary();
+ foreach (var srcQueue in transparentZWriteRenderQueues)
+ {
+ transparentZWriteRenderQueueMap.Add(srcQueue, defaultTransparentZWriteQueue++);
+ }
+
+ // Main Pass
+ foreach (var (mtoon, gltfMaterial) in sourceMaterials)
+ {
var extensions = new glTFExtensionExport();
gltfMaterial.extensions = extensions;
extensions.Add(
@@ -331,9 +379,16 @@ namespace UniVRM10
// Outline
dst.OutlineColorFactor = mtoon.Definition.Outline.OutlineColor.ToFloat3(ColorSpace.sRGB, ColorSpace.Linear);
- dst.OutlineLightingMixFactor = mtoon.Definition.Outline.OutlineLightingMixValue;
+ if (mtoon.Definition.Outline.OutlineColorMode == MToon.OutlineColorMode.MixedLighting)
+ {
+ dst.OutlineLightingMixFactor = mtoon.Definition.Outline.OutlineLightingMixValue;
+ }
+ else
+ {
+ dst.OutlineLightingMixFactor = 0.0f;
+ }
dst.OutlineWidthMode = (UniGLTF.Extensions.VRMC_materials_mtoon.OutlineWidthMode)mtoon.Definition.Outline.OutlineWidthMode;
- dst.OutlineWidthFactor = mtoon.Definition.Outline.OutlineWidthValue;
+ dst.OutlineWidthFactor = mtoon.Definition.Outline.OutlineWidthValue * centimeterToMeter;
if (mtoon.TextureIndexMap.OutlineWidthTexture.HasValue)
{
dst.OutlineWidthMultiplyTexture = new TextureInfo { Index = mtoon.TextureIndexMap.OutlineWidthTexture.Value };
@@ -400,7 +455,25 @@ namespace UniVRM10
throw new NotImplementedException();
}
(gltfMaterial.alphaMode, dst.TransparentWithZWrite) = GetRenderMode(mtoon.Definition.Rendering.RenderMode);
- dst.RenderQueueOffsetNumber = mtoon.Definition.Rendering.RenderQueueOffsetNumber;
+ var renderQueueOffset = mtoon.Definition.Rendering.RenderQueueOffsetNumber;
+ switch (mtoon.Definition.Rendering.RenderMode)
+ {
+ case RenderMode.Opaque:
+ renderQueueOffset = 0;
+ break;
+ case RenderMode.Cutout:
+ renderQueueOffset = 0;
+ break;
+ case RenderMode.Transparent:
+ renderQueueOffset = Mathf.Clamp(transparentRenderQueueMap[renderQueueOffset], -9, 0);
+ break;
+ case RenderMode.TransparentWithZWrite:
+ renderQueueOffset = Mathf.Clamp(transparentZWriteRenderQueueMap[renderQueueOffset], 0, +9);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ dst.RenderQueueOffsetNumber = renderQueueOffset;
// rim
dst.ParametricRimColorFactor = mtoon.Definition.Rim.RimColor.ToFloat3(ColorSpace.sRGB, ColorSpace.Linear);
diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/MaterialFactory.cs b/Assets/VRMShaders/GLTF/IO/Runtime/MaterialFactory.cs
index 8ef4afe1b..d566f780a 100644
--- a/Assets/VRMShaders/GLTF/IO/Runtime/MaterialFactory.cs
+++ b/Assets/VRMShaders/GLTF/IO/Runtime/MaterialFactory.cs
@@ -144,6 +144,11 @@ namespace VRMShaders
material.SetFloat(kv.Key, kv.Value);
}
+ if (param.RenderQueue.HasValue)
+ {
+ material.renderQueue = param.RenderQueue.Value;
+ }
+
foreach(var action in param.Actions)
{
action(material);
diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/MaterialImportParam.cs b/Assets/VRMShaders/GLTF/IO/Runtime/MaterialImportParam.cs
index b0676f804..e6d895ccc 100644
--- a/Assets/VRMShaders/GLTF/IO/Runtime/MaterialImportParam.cs
+++ b/Assets/VRMShaders/GLTF/IO/Runtime/MaterialImportParam.cs
@@ -13,6 +13,7 @@ namespace VRMShaders
public readonly Dictionary FloatValues = new Dictionary();
public readonly Dictionary Colors = new Dictionary();
public readonly Dictionary Vectors = new Dictionary();
+ public int? RenderQueue;
public readonly List> Actions = new List>();
public MaterialImportParam(string name, string shaderName)
diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/TextureFactory.cs b/Assets/VRMShaders/GLTF/IO/Runtime/TextureFactory.cs
index 45f7c26fb..cfc8384fa 100644
--- a/Assets/VRMShaders/GLTF/IO/Runtime/TextureFactory.cs
+++ b/Assets/VRMShaders/GLTF/IO/Runtime/TextureFactory.cs
@@ -240,11 +240,18 @@ namespace VRMShaders
return info.Texture;
}
- default:
+ case TextureImportTypes.sRGB:
{
var baseTexture = await GetOrCreateBaseTexture(param.UnityObjectName, param, param.Index0, RenderTextureReadWrite.sRGB, true);
return baseTexture.Texture;
}
+ case TextureImportTypes.Linear:
+ {
+ var baseTexture = await GetOrCreateBaseTexture(param.UnityObjectName, param, param.Index0, RenderTextureReadWrite.Linear, true);
+ return baseTexture.Texture;
+ }
+ default:
+ throw new ArgumentOutOfRangeException();
}
throw new NotImplementedException();