Merge pull request #938 from Santarh/vrm10MToon1

VRM1.0 で MToon の Import ができる
This commit is contained in:
ousttrue
2021-05-11 12:26:08 +09:00
committed by GitHub
14 changed files with 453 additions and 170 deletions

View File

@@ -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;
}

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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
{
/// <summary>
/// Convert MToon parameters from glTF specification to Unity implementation.
/// </summary>
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;
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 01c1ac60c9a047b59ea52aaddb7a0d63
timeCreated: 1620630516

View File

@@ -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);
}

View File

@@ -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
{

View File

@@ -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;
}

View File

@@ -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 を操作する。
///
/// </summary>
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<int>();
var transparentZWriteRenderQueues = new SortedSet<int>();
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<int, int>();
foreach (var srcQueue in transparentRenderQueues.Reverse())
{
transparentRenderQueueMap.Add(srcQueue, defaultTransparentQueue--);
}
var defaultTransparentZWriteQueue = 0;
var transparentZWriteRenderQueueMap = new Dictionary<int, int>();
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);

View File

@@ -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);

View File

@@ -13,6 +13,7 @@ namespace VRMShaders
public readonly Dictionary<string, float> FloatValues = new Dictionary<string, float>();
public readonly Dictionary<string, Color> Colors = new Dictionary<string, Color>();
public readonly Dictionary<string, Vector4> Vectors = new Dictionary<string, Vector4>();
public int? RenderQueue;
public readonly List<Action<Material>> Actions = new List<Action<Material>>();
public MaterialImportParam(string name, string shaderName)

View File

@@ -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();