您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

100 行
4.5 KiB

using System;
using System.Linq;
using UniGLTF;
using UniJSON;
using UnityEngine;
using ColorSpace = VRMShaders.ColorSpace;
namespace UniVRM10
{
internal static class MigrationPbrMaterial
{
private const string UsingGltfMaterialKeywordInVrmExtension = "VRM_USE_GLTFSHADER";
private const string ExporterVersionKey = "exporterVersion";
/// <summary>
/// vanilla の gltf material を対象とする.
/// KHR_materials_unlit 拡張や VRM.materialProperties で MToon を対象とするマテリアルは処理してはいけない。
/// </summary>
public static void Migrate(glTF gltf, JsonNode vrm0XExtension)
{
var needMigrationRoughnessTextureValueSquared = false;
var needMigrationEmissiveFactorGamma = false;
if (vrm0XExtension.TryGet(ExporterVersionKey, out var vrm0XVersionStringNode))
{
var vrm0XVersionString = vrm0XVersionStringNode.GetString();
if (Vrm0XVersion.ParseVersion(vrm0XVersionString, out var vrm0XVersion))
{
needMigrationRoughnessTextureValueSquared = Vrm0XVersion.IsNewer(
new Vrm0XVersion.Version
{
Major = 0,
Minor = 69,
Patch = 0,
Pre = "",
},
vrm0XVersion
);
needMigrationEmissiveFactorGamma = Vrm0XVersion.IsNewer(
new Vrm0XVersion.Version
{
Major = 0,
Minor = 107,
Patch = 0,
Pre = "",
},
vrm0XVersion
);
}
}
for (var idx = 0; idx < gltf.materials.Count; ++idx)
{
MigrateMaterial(gltf, vrm0XExtension, idx, needMigrationRoughnessTextureValueSquared, needMigrationEmissiveFactorGamma);
}
}
private static void MigrateMaterial(glTF gltf, JsonNode vrm0XExtension, int idx, bool needMigrationRoughnessTextureValueSquared, bool needMigrationEmissiveFactorGamma)
{
var src = gltf.materials[idx];
var vrm0XMaterial = vrm0XExtension["materialProperties"][idx];
// NOTE: ignore MToon
if (MigrationMaterialUtil.GetShaderName(vrm0XMaterial) != UsingGltfMaterialKeywordInVrmExtension) return;
// NOTE: ignore Unlit
if (glTF_KHR_materials_unlit.IsEnable(src)) return;
if (needMigrationRoughnessTextureValueSquared)
{
// NOTE: 非常に実装がめんどくさい、かつ刺さるシチュエーションがかなり少ないので放置.
}
if (needMigrationEmissiveFactorGamma && src.emissiveFactor != null && src.emissiveFactor.Length == 3)
{
var emissiveFactor = new Color(src.emissiveFactor[0], src.emissiveFactor[1], src.emissiveFactor[2]);
if (UniGLTF.glTF_KHR_materials_emissive_strength.TryGet(src.extensions, out var emissiveStrength))
{
emissiveFactor *= emissiveStrength.emissiveStrength;
}
else if (UniGLTF.Extensions.VRMC_materials_hdr_emissiveMultiplier.GltfDeserializer.TryGet(src.extensions, out var ex))
{
if (ex.EmissiveMultiplier != null)
{
emissiveFactor *= ex.EmissiveMultiplier.Value;
}
}
// NOTE: 新しい emissive_strength 拡張を書き込むため、拡張をまっさらにする
var extensionsExport = new glTFExtensionExport();
src.extensions = extensionsExport;
var linearEmissiveFactor = emissiveFactor.linear;
if (linearEmissiveFactor.maxColorComponent > 1)
{
var maxColorComponent = linearEmissiveFactor.maxColorComponent;
linearEmissiveFactor /= maxColorComponent;
UniGLTF.glTF_KHR_materials_emissive_strength.Serialize(ref src.extensions, maxColorComponent);
}
src.emissiveFactor = linearEmissiveFactor.ToFloat3(ColorSpace.Linear, ColorSpace.Linear);
}
}
}
}