您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
144 行
5.8 KiB
144 行
5.8 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using UniGLTF;
|
|
using UniGLTF.Extensions.VRMC_materials_mtoon;
|
|
using UniJSON;
|
|
using UnityEngine;
|
|
|
|
namespace UniVRM10
|
|
{
|
|
/// <summary>
|
|
/// Migration Target: VRM file with "VRM/UnlitTransparentZWrite" material exported with UniVRM v0.43 or lower.
|
|
///
|
|
/// 過去の UniVRM の "VRM/UnlitTransparentZWrite" シェーダをマイグレーションする.
|
|
/// 他の Unlit シェーダと違い、VRMC_materials_mtoon を用いてマイグレーションする.
|
|
/// </summary>
|
|
internal static class MigrationUnlitTransparentZWriteMaterial
|
|
{
|
|
private const int MaxRenderQueueOffset = 9; // NOTE: vrm-1.0 spec
|
|
|
|
private const string Unity0XShaderName = "VRM/UnlitTransparentZWrite";
|
|
private const int Unity0XDefaultRenderQueue = 2501;
|
|
|
|
public static bool Migrate(glTF gltf, IReadOnlyList<JsonNode> vrm0XMaterials)
|
|
{
|
|
var anyMigrated = false;
|
|
var mapper = GetRenderQueueMapper(vrm0XMaterials);
|
|
|
|
for (var materialIdx = 0; materialIdx < gltf.materials.Count; ++materialIdx)
|
|
{
|
|
try
|
|
{
|
|
var newMaterial = Migrate(vrm0XMaterials[materialIdx], gltf.materials[materialIdx].name, mapper);
|
|
if (newMaterial != null)
|
|
{
|
|
// NOTE: UnlitTransparentZWrite の場合は、名前を引き継いで、glTFMaterial を上書きする.
|
|
gltf.materials[materialIdx] = newMaterial;
|
|
anyMigrated = true;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogException(ex);
|
|
}
|
|
}
|
|
|
|
return anyMigrated;
|
|
}
|
|
|
|
private static Dictionary<int, int> GetRenderQueueMapper(IReadOnlyList<JsonNode> vrm0XMaterials)
|
|
{
|
|
try
|
|
{
|
|
var renderQueueSet = new SortedSet<int>();
|
|
foreach (var vrm0XMaterial in vrm0XMaterials)
|
|
{
|
|
var renderQueue = MigrationMaterialUtil.GetRenderQueue(vrm0XMaterial);
|
|
if (renderQueue.HasValue && renderQueue.Value != -1)
|
|
{
|
|
renderQueueSet.Add(renderQueue.Value);
|
|
}
|
|
else
|
|
{
|
|
renderQueueSet.Add(Unity0XDefaultRenderQueue);
|
|
}
|
|
}
|
|
|
|
var mapper = new Dictionary<int, int>();
|
|
var currentQueueOffset = 0;
|
|
foreach (var queue in renderQueueSet)
|
|
{
|
|
mapper.Add(queue, currentQueueOffset);
|
|
currentQueueOffset = Mathf.Min(currentQueueOffset + 1, MaxRenderQueueOffset);
|
|
}
|
|
|
|
return mapper;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogException(ex);
|
|
return new Dictionary<int, int>();
|
|
}
|
|
}
|
|
|
|
private static glTFMaterial Migrate(JsonNode vrm0XMaterial, string materialName, Dictionary<int, int> renderQueueMapper)
|
|
{
|
|
try
|
|
{
|
|
if (MigrationMaterialUtil.GetShaderName(vrm0XMaterial) != Unity0XShaderName)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var baseColorFactor = MigrationMaterialUtil.GetBaseColorFactor(vrm0XMaterial);
|
|
var baseColorTexture = MigrationMaterialUtil.GetBaseColorTexture(vrm0XMaterial);
|
|
var emissiveTexture = new glTFMaterialEmissiveTextureInfo
|
|
{
|
|
index = baseColorTexture.index,
|
|
extensions = baseColorTexture.extensions,
|
|
};
|
|
var renderQueue = MigrationMaterialUtil.GetRenderQueue(vrm0XMaterial) ?? Unity0XDefaultRenderQueue;
|
|
var renderQueueOffset = renderQueueMapper.ContainsKey(renderQueue) ? renderQueueMapper[renderQueue] : 0;
|
|
|
|
var mtoonMaterial = new glTFMaterial
|
|
{
|
|
name = materialName,
|
|
extensions = new glTFExtensionExport().Add(
|
|
glTF_KHR_materials_unlit.ExtensionName,
|
|
new ArraySegment<byte>(glTF_KHR_materials_unlit.Raw)
|
|
),
|
|
pbrMetallicRoughness = new glTFPbrMetallicRoughness
|
|
{
|
|
baseColorFactor = new[] { 0f, 0f, 0f, baseColorFactor[3] }, // black + _Color.a
|
|
baseColorTexture = baseColorTexture, // _MainTex
|
|
metallicFactor = 0f,
|
|
roughnessFactor = 1f,
|
|
},
|
|
alphaMode = "BLEND",
|
|
alphaCutoff = 0.5f,
|
|
doubleSided = false,
|
|
emissiveFactor = new[] { baseColorFactor[0], baseColorFactor[1], baseColorFactor[2] }, // _Color.rgb
|
|
emissiveTexture = emissiveTexture,
|
|
};
|
|
|
|
var mtoon10 = new VRMC_materials_mtoon
|
|
{
|
|
SpecVersion = Vrm10Exporter.MTOON_SPEC_VERSION,
|
|
TransparentWithZWrite = true, // transparent with zWrite
|
|
RenderQueueOffsetNumber = renderQueueOffset,
|
|
ShadeColorFactor = new[] { 0f, 0f, 0f }, // black
|
|
OutlineWidthMode = OutlineWidthMode.none // disable outline
|
|
};
|
|
UniGLTF.Extensions.VRMC_materials_mtoon.GltfSerializer.SerializeTo(ref mtoonMaterial.extensions,
|
|
mtoon10);
|
|
|
|
return mtoonMaterial;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
Debug.LogWarning($"Migration failed in VRM/UnlitTransparentZWrite material: {materialName}");
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
}
|