mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-08-28 05:44:48 -05:00
Merge pull request #938 from Santarh/vrm10MToon1
VRM1.0 で MToon の Import ができる
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01c1ac60c9a047b59ea52aaddb7a0d63
|
||||
timeCreated: 1620630516
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user