UniVRM/Assets/VRM10/MToon10/Runtime/MToonMaterialMigrator.cs

129 lines
6.9 KiB
C#

using System;
using UnityEngine;
using VRM10.MToon10.MToon0X;
using MToon0XUtils = VRM10.MToon10.MToon0X.MToon0XUtils;
using Object = UnityEngine.Object;
namespace VRM10.MToon10
{
public sealed class MToonMaterialMigrator
{
public MToonMaterialMigrator()
{
}
public bool TryMigrate(Material material, bool validateShaderName = true)
{
var tempMat = new Material(Shader.Find("VRM10/MToon10"));
try
{
if (validateShaderName && material.shader.name != MToon0XUtils.ShaderName)
{
throw new ArgumentException($"The shader of the material is not {MToon0XUtils.ShaderName}");
}
var src = MToon0XUtils.GetMToonParametersFromMaterial(material);
var dst = new MToon10Context(tempMat);
dst.AlphaMode = src.Rendering.RenderMode switch
{
MToon0XRenderMode.Opaque => MToon10AlphaMode.Opaque,
MToon0XRenderMode.Cutout => MToon10AlphaMode.Cutout,
MToon0XRenderMode.Transparent => MToon10AlphaMode.Transparent,
MToon0XRenderMode.TransparentWithZWrite => MToon10AlphaMode.Transparent,
_ => throw new ArgumentOutOfRangeException()
};
dst.TransparentWithZWriteMode = src.Rendering.RenderMode switch
{
MToon0XRenderMode.Opaque => MToon10TransparentWithZWriteMode.Off,
MToon0XRenderMode.Cutout => MToon10TransparentWithZWriteMode.Off,
MToon0XRenderMode.Transparent => MToon10TransparentWithZWriteMode.Off,
MToon0XRenderMode.TransparentWithZWrite => MToon10TransparentWithZWriteMode.On,
_ => throw new ArgumentOutOfRangeException()
};
dst.AlphaCutoff = src.Color.CutoutThresholdValue;
dst.RenderQueueOffsetNumber = src.Rendering.RenderQueueOffsetNumber; // NOTE: Breaking Change
dst.DoubleSidedMode = src.Rendering.CullMode switch
{
MToon0XCullMode.Back => MToon10DoubleSidedMode.Off,
MToon0XCullMode.Off => MToon10DoubleSidedMode.On,
MToon0XCullMode.Front => MToon10DoubleSidedMode.On, // NOTE: Breaking Change
_ => throw new ArgumentOutOfRangeException()
};
dst.BaseColorFactorSrgb = src.Color.LitColor; // NOTE: gamma -> gamma
dst.BaseColorTexture = src.Color.LitMultiplyTexture;
dst.ShadeColorFactorSrgb = src.Color.ShadeColor; // NOTE: gamma -> gamma
dst.ShadeColorTexture = src.Color.ShadeMultiplyTexture;
dst.NormalTexture = src.Lighting.Normal.NormalTexture;
dst.NormalTextureScale = src.Lighting.Normal.NormalScaleValue;
dst.ShadingShiftFactor = MToon10Migrator.MigrateToShadingShift(src.Lighting.LitAndShadeMixing.ShadingToonyValue, src.Lighting.LitAndShadeMixing.ShadingShiftValue);
dst.ShadingShiftTexture = src.Lighting.LitAndShadeMixing.LitAndShadeMixingMultiplierMultiplyTexture;
dst.ShadingShiftTexture = null;
dst.ShadingShiftTextureScale = 1f;
dst.ShadingToonyFactor = MToon10Migrator.MigrateToShadingToony(src.Lighting.LitAndShadeMixing.ShadingToonyValue, src.Lighting.LitAndShadeMixing.ShadingShiftValue);
dst.GiEqualizationFactor = MToon10Migrator.MigrateToGiEqualization(src.Lighting.LightingInfluence.GiIntensityValue);
dst.EmissiveFactorLinear = src.Emission.EmissionColor; // NOTE: linear -> linear
dst.EmissiveTexture = src.Emission.EmissionMultiplyTexture;
dst.MatcapColorFactorSrgb = src.MatCap.AdditiveTexture != null ? new Color(1, 1, 1) : new Color(0, 0, 0); // NOTE: gamma -> gamma
dst.MatcapTexture = src.MatCap.AdditiveTexture;
dst.ParametricRimColorFactorSrgb = src.Rim.RimColor; // NOTE: gamma -> gamma
dst.ParametricRimFresnelPowerFactor = src.Rim.RimFresnelPowerValue;
dst.ParametricRimLiftFactor = src.Rim.RimLiftValue;
dst.RimMultiplyTexture = src.Rim.RimMultiplyTexture;
dst.RimLightingMixFactor = 1.0f; // NOTE: Breaking Change
dst.OutlineWidthMode = src.Outline.OutlineWidthMode switch
{
MToon0XOutlineWidthMode.None => MToon10OutlineMode.None,
MToon0XOutlineWidthMode.WorldCoordinates => MToon10OutlineMode.World,
MToon0XOutlineWidthMode.ScreenCoordinates => MToon10OutlineMode.Screen,
_ => throw new ArgumentOutOfRangeException()
};
const float centimeterToMeter = 0.01f;
const float oneHundredth = 0.01f;
dst.OutlineWidthFactor = src.Outline.OutlineWidthMode switch
{
MToon0XOutlineWidthMode.None => 0f,
MToon0XOutlineWidthMode.WorldCoordinates => src.Outline.OutlineWidthValue * centimeterToMeter,
MToon0XOutlineWidthMode.ScreenCoordinates => src.Outline.OutlineWidthValue * oneHundredth * 0.5f,
_ => throw new ArgumentOutOfRangeException()
};
dst.OutlineWidthMultiplyTexture = src.Outline.OutlineWidthMultiplyTexture;
dst.OutlineColorFactorSrgb = src.Outline.OutlineColor; // NOTE: gamma -> gamma
dst.OutlineLightingMixFactor = src.Outline.OutlineColorMode switch
{
MToon0XOutlineColorMode.FixedColor => 0f,
MToon0XOutlineColorMode.MixedLighting => src.Outline.OutlineLightingMixValue,
_ => throw new ArgumentOutOfRangeException()
};
dst.UvAnimationMaskTexture = src.TextureOption.UvAnimationMaskTexture;
dst.UvAnimationScrollXSpeedFactor = src.TextureOption.UvAnimationScrollXSpeedValue;
dst.UvAnimationScrollYSpeedFactor = src.TextureOption.UvAnimationScrollYSpeedValue;
dst.UvAnimationRotationSpeedFactor = src.TextureOption.UvAnimationRotationSpeedValue;
dst.TextureScale = src.TextureOption.MainTextureLeftBottomOriginScale;
dst.TextureOffset = src.TextureOption.MainTextureLeftBottomOriginOffset;
dst.Validate();
material.shader = tempMat.shader;
material.CopyPropertiesFromMaterial(tempMat);
return true;
}
catch (Exception)
{
return false;
}
finally
{
if (Application.isPlaying)
{
Object.Destroy(tempMat);
}
else
{
Object.DestroyImmediate(tempMat);
}
}
}
}
}