From fbd885c67c94734b491ecdb1821d68b246fa220c Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Wed, 23 Jun 2021 23:04:16 +0900 Subject: [PATCH] Export texture's alpha if only necessary. --- .../UniGLTF/IO/MaterialIO/MaterialExporter.cs | 4 +- .../Runtime/UniGLTF/IO/gltfExporter.cs | 5 +- Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs | 6 +- Assets/VRM/Runtime/IO/VRMExporter.cs | 2 +- Assets/VRM/Runtime/IO/VRMMaterialExporter.cs | 2 +- .../IO/Material/Vrm10MToonMaterialExporter.cs | 16 +- Assets/VRM10/Runtime/IO/Vrm10Exporter.cs | 7 +- .../GLTF/IO/Runtime/ITextureExporter.cs | 9 +- .../GLTF/IO/Runtime/TextureConverter.cs | 5 +- .../GLTF/IO/Runtime/TextureExportKey.cs | 39 +++ .../GLTF/IO/Runtime/TextureExportKey.cs.meta | 3 + .../GLTF/IO/Runtime/TextureExportTypes.cs | 14 ++ .../IO/Runtime/TextureExportTypes.cs.meta | 3 + .../GLTF/IO/Runtime/TextureExporter.cs | 235 +++++++++--------- 14 files changed, 203 insertions(+), 147 deletions(-) create mode 100644 Assets/VRMShaders/GLTF/IO/Runtime/TextureExportKey.cs create mode 100644 Assets/VRMShaders/GLTF/IO/Runtime/TextureExportKey.cs.meta create mode 100644 Assets/VRMShaders/GLTF/IO/Runtime/TextureExportTypes.cs create mode 100644 Assets/VRMShaders/GLTF/IO/Runtime/TextureExportTypes.cs.meta diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/MaterialExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/MaterialExporter.cs index fdb43e9a6..ab5da1bf9 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/MaterialExporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/MaterialExporter.cs @@ -38,7 +38,7 @@ namespace UniGLTF if (m.HasProperty("_MainTex")) { - var index = textureManager.ExportAsSRgb(m.GetTexture("_MainTex")); + var index = textureManager.ExportAsSRgb(m.GetTexture("_MainTex"), needsAlpha: true); if (index != -1) { material.pbrMetallicRoughness.baseColorTexture = new glTFMaterialBaseColorTextureInfo() @@ -161,7 +161,7 @@ namespace UniGLTF if (m.HasProperty("_EmissionMap")) { - var index = textureExporter.ExportAsSRgb(m.GetTexture("_EmissionMap")); + var index = textureExporter.ExportAsSRgb(m.GetTexture("_EmissionMap"), needsAlpha: false); if (index != -1) { material.emissiveTexture = new glTFMaterialEmissiveTextureInfo() diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs index c29e5378d..fa769b979 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs @@ -369,9 +369,10 @@ namespace UniGLTF ExportExtensions(textureSerializer); // Extension で Texture が増える場合があるので最後に呼ぶ - for (int i = 0; i < TextureExporter.Exported.Count; ++i) + var exported = TextureExporter.Export(); + for (var exportedTextureIdx = 0; exportedTextureIdx < exported.Count; ++exportedTextureIdx) { - var (unityTexture, colorSpace) = TextureExporter.Exported[i]; + var (unityTexture, colorSpace) = exported[exportedTextureIdx]; glTF.PushGltfTexture(bufferIndex, unityTexture, colorSpace, textureSerializer); } } diff --git a/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs b/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs index ad042ed16..cfbe6bf7e 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs @@ -26,7 +26,9 @@ namespace UniGLTF var materialExporter = new MaterialExporter(); materialExporter.ExportMaterial(material, textureExporter); - var (convTex0, colorSpace) = textureExporter.Exported[0]; + var exported = textureExporter.Export(); + + var (convTex0, colorSpace) = exported[0]; var sampler = TextureSamplerUtil.Export(convTex0); Assert.AreEqual(glWrap.CLAMP_TO_EDGE, sampler.wrapS); @@ -100,7 +102,7 @@ namespace UniGLTF .ToDictionary(kv => kv.Item1, kv => kv.Item2) ; - // extractor + // extractor var extractor = new TextureExtractor(parser, UnityPath.FromUnityPath(""), textureMap); var m = context.TextureDescriptorGenerator.Get().GetEnumerable() .FirstOrDefault(x => x.SubAssetKey.Name == "texture_1.standard"); diff --git a/Assets/VRM/Runtime/IO/VRMExporter.cs b/Assets/VRM/Runtime/IO/VRMExporter.cs index c04c50bd5..e4c781c19 100644 --- a/Assets/VRM/Runtime/IO/VRMExporter.cs +++ b/Assets/VRM/Runtime/IO/VRMExporter.cs @@ -136,7 +136,7 @@ namespace VRM VRM.meta.title = meta.Title; if (meta.Thumbnail != null) { - VRM.meta.texture = TextureExporter.ExportAsSRgb(meta.Thumbnail); + VRM.meta.texture = TextureExporter.ExportAsSRgb(meta.Thumbnail, needsAlpha: true); } // ussage permission diff --git a/Assets/VRM/Runtime/IO/VRMMaterialExporter.cs b/Assets/VRM/Runtime/IO/VRMMaterialExporter.cs index 16dce2440..3f9e422b9 100644 --- a/Assets/VRM/Runtime/IO/VRMMaterialExporter.cs +++ b/Assets/VRM/Runtime/IO/VRMMaterialExporter.cs @@ -182,7 +182,7 @@ namespace VRM { var value = kv.Key == "_BumpMap" ? textureExporter.ExportAsNormal(texture) - : textureExporter.ExportAsSRgb(texture) + : textureExporter.ExportAsSRgb(texture, needsAlpha: kv.Key == "_MainTex") ; if (value == -1) { diff --git a/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialExporter.cs b/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialExporter.cs index 9c1e1505f..434d195f3 100644 --- a/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialExporter.cs +++ b/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialExporter.cs @@ -42,7 +42,7 @@ namespace UniVRM10 // Lighting dst.pbrMetallicRoughness = new glTFPbrMetallicRoughness(); dst.pbrMetallicRoughness.baseColorFactor = context.BaseColorFactorSrgb.ToFloat4(ColorSpace.sRGB, ColorSpace.Linear); - var baseColorTextureIndex = textureExporter.ExportAsSRgb(context.BaseColorTexture); + var baseColorTextureIndex = textureExporter.ExportAsSRgb(context.BaseColorTexture, needsAlpha: true); if (baseColorTextureIndex != -1) { dst.pbrMetallicRoughness.baseColorTexture = new glTFMaterialBaseColorTextureInfo @@ -51,7 +51,7 @@ namespace UniVRM10 }; } mtoon.ShadeColorFactor = context.ShadeColorFactorSrgb.ToFloat3(ColorSpace.sRGB, ColorSpace.Linear); - var shadeColorTextureIndex = textureExporter.ExportAsSRgb(context.ShadeColorTexture); + var shadeColorTextureIndex = textureExporter.ExportAsSRgb(context.ShadeColorTexture, needsAlpha: false); if (shadeColorTextureIndex != -1) { mtoon.ShadeMultiplyTexture = new TextureInfo @@ -69,7 +69,7 @@ namespace UniVRM10 }; } mtoon.ShadingShiftFactor = context.ShadingShiftFactor; - var shadingShiftTextureIndex = textureExporter.ExportAsLinear(context.ShadingShiftTexture); + var shadingShiftTextureIndex = textureExporter.ExportAsLinear(context.ShadingShiftTexture, needsAlpha: false); if (shadingShiftTextureIndex != -1) { mtoon.ShadingShiftTexture = new ShadingShiftTextureInfo @@ -86,7 +86,7 @@ namespace UniVRM10 // Emission dst.emissiveFactor = context.EmissiveFactorLinear.ToFloat3(ColorSpace.Linear, ColorSpace.Linear); - var emissiveTextureIndex = textureExporter.ExportAsSRgb(context.EmissiveTexture); + var emissiveTextureIndex = textureExporter.ExportAsSRgb(context.EmissiveTexture, needsAlpha: false); if (emissiveTextureIndex != -1) { dst.emissiveTexture = new glTFMaterialEmissiveTextureInfo @@ -96,7 +96,7 @@ namespace UniVRM10 } // Rim Lighting - var matcapTextureIndex = textureExporter.ExportAsSRgb(context.MatcapTexture); + var matcapTextureIndex = textureExporter.ExportAsSRgb(context.MatcapTexture, needsAlpha: false); if (matcapTextureIndex != -1) { mtoon.MatcapTexture = new TextureInfo @@ -107,7 +107,7 @@ namespace UniVRM10 mtoon.ParametricRimColorFactor = context.ParametricRimColorFactorSrgb.ToFloat3(ColorSpace.sRGB, ColorSpace.Linear); mtoon.ParametricRimFresnelPowerFactor = context.ParametricRimFresnelPowerFactor; mtoon.ParametricRimLiftFactor = context.ParametricRimLiftFactor; - var rimMultiplyTextureIndex = textureExporter.ExportAsSRgb(context.RimMultiplyTexture); + var rimMultiplyTextureIndex = textureExporter.ExportAsSRgb(context.RimMultiplyTexture, needsAlpha: false); if (rimMultiplyTextureIndex != -1) { mtoon.RimMultiplyTexture = new TextureInfo @@ -120,7 +120,7 @@ namespace UniVRM10 // Outline mtoon.OutlineWidthMode = ExportOutlineWidthMode(context.OutlineWidthMode); mtoon.OutlineWidthFactor = context.OutlineWidthFactor; - var outlineWidthMultiplyTextureIndex = textureExporter.ExportAsLinear(context.OutlineWidthMultiplyTexture); + var outlineWidthMultiplyTextureIndex = textureExporter.ExportAsLinear(context.OutlineWidthMultiplyTexture, needsAlpha: false); if (outlineWidthMultiplyTextureIndex != -1) { mtoon.OutlineWidthMultiplyTexture = new TextureInfo @@ -132,7 +132,7 @@ namespace UniVRM10 mtoon.OutlineLightingMixFactor = context.OutlineLightingMixFactor; // UV Animation - var uvAnimationMaskTextureIndex = textureExporter.ExportAsLinear(context.UvAnimationMaskTexture); + var uvAnimationMaskTextureIndex = textureExporter.ExportAsLinear(context.UvAnimationMaskTexture, needsAlpha: false); if (uvAnimationMaskTextureIndex != -1) { mtoon.UvAnimationMaskTexture = new TextureInfo diff --git a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs index fe47d6649..f0fc788e7 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs @@ -185,9 +185,10 @@ namespace UniVRM10 var (vrm, vrmSpringBone, thumbnailTextureIndex) = ExportVrm(root, model, converter, vrmMeta); // Extension で Texture が増える場合があるので最後に呼ぶ - for (int i = 0; i < m_textureExporter.Exported.Count; ++i) + var exportedTextures = m_textureExporter.Export(); + for (var exportedTextureIdx = 0; exportedTextureIdx < exportedTextures.Count; ++exportedTextureIdx) { - var (unityTexture, texColorSpace) = m_textureExporter.Exported[i]; + var (unityTexture, texColorSpace) = exportedTextures[exportedTextureIdx]; Storage.Gltf.PushGltfTexture(0, unityTexture, texColorSpace, m_textureSerializer); } @@ -649,7 +650,7 @@ namespace UniVRM10 int? thumbnailTextureIndex = default; if (meta.Thumbnail != null) { - thumbnailTextureIndex = m_textureExporter.ExportAsSRgb(meta.Thumbnail); + thumbnailTextureIndex = m_textureExporter.ExportAsSRgb(meta.Thumbnail, needsAlpha: true); } return thumbnailTextureIndex; } diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/ITextureExporter.cs b/Assets/VRMShaders/GLTF/IO/Runtime/ITextureExporter.cs index 0e8f30238..7c4ed7a50 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/ITextureExporter.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/ITextureExporter.cs @@ -10,20 +10,15 @@ namespace VRMShaders /// public interface ITextureExporter { - /// - /// Export する Texture2D のリスト。これが gltf.textures になる - /// - IReadOnlyList<(Texture2D, ColorSpace)> Exported { get; } - /// /// 指定の Texture を、 sRGB 色空間の値を持つ Texture に出力するように指示する。 /// - int ExportAsSRgb(Texture src); + int ExportAsSRgb(Texture src, bool needsAlpha); /// /// 指定の Texture を、 Linear の値を持つ Texture に出力するように指示する。 /// - int ExportAsLinear(Texture src); + int ExportAsLinear(Texture src, bool needsAlpha); /// /// Unity Standard Shader の Metallic, Roughness, Occlusion 情報を、 glTF 仕様に準拠した 1 枚の合成テクスチャとして出力するように指示する。 diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/TextureConverter.cs b/Assets/VRMShaders/GLTF/IO/Runtime/TextureConverter.cs index e53fdd159..95320ecb3 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/TextureConverter.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/TextureConverter.cs @@ -6,9 +6,12 @@ namespace VRMShaders { public static class TextureConverter { + public static readonly TextureFormat WithAlphaFormat = TextureFormat.ARGB32; + public static readonly TextureFormat WithoutAlphaFormat = TextureFormat.RGB24; + public static Texture2D CreateEmptyTextureWithSettings(Texture src, ColorSpace dstColorSpace, bool dstNeedsAlpha) { - var texFormat = dstNeedsAlpha ? TextureFormat.ARGB32 : TextureFormat.RGB24; + var texFormat = dstNeedsAlpha ? WithAlphaFormat : WithoutAlphaFormat; var dst = new Texture2D(src.width, src.height, texFormat, src.HasMipMap(), dstColorSpace == ColorSpace.Linear); dst.name = src.name; dst.anisoLevel = src.anisoLevel; diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/TextureExportKey.cs b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExportKey.cs new file mode 100644 index 000000000..a4d6cd683 --- /dev/null +++ b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExportKey.cs @@ -0,0 +1,39 @@ +using System; +using UnityEngine; + +namespace VRMShaders +{ + internal readonly struct TextureExportKey : IEquatable + { + public readonly Texture Src; + public readonly TextureExportTypes TextureType; + + public TextureExportKey(Texture src, TextureExportTypes type) + { + if (src == null) + { + throw new ArgumentNullException(); + } + Src = src; + TextureType = type; + } + + public bool Equals(TextureExportKey other) + { + return Equals(Src, other.Src) && TextureType == other.TextureType; + } + + public override bool Equals(object obj) + { + return obj is TextureExportKey other && Equals(other); + } + + public override int GetHashCode() + { + unchecked + { + return ((Src != null ? Src.GetHashCode() : 0) * 397) ^ (int) TextureType; + } + } + } +} \ No newline at end of file diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/TextureExportKey.cs.meta b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExportKey.cs.meta new file mode 100644 index 000000000..ba3d7179a --- /dev/null +++ b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExportKey.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3698d17d1e624396a74390f338fda684 +timeCreated: 1624456050 \ No newline at end of file diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/TextureExportTypes.cs b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExportTypes.cs new file mode 100644 index 000000000..06c3804fe --- /dev/null +++ b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExportTypes.cs @@ -0,0 +1,14 @@ +namespace VRMShaders +{ + internal enum TextureExportTypes + { + // sRGB テクスチャとして出力 + Srgb, + // Linear テクスチャとして出力 + Linear, + // Unity Standard様式 から glTF PBR様式への変換 + OcclusionMetallicRoughness, + // Assetを使うときはそのバイト列を無変換で、それ以外は DXT5nm 形式からのデコードを行う + Normal, + } +} \ No newline at end of file diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/TextureExportTypes.cs.meta b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExportTypes.cs.meta new file mode 100644 index 000000000..5be6e7ebf --- /dev/null +++ b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExportTypes.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: bf56f43baf1e4b47becb7d0ba42a72dc +timeCreated: 1624456063 \ No newline at end of file diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs index c4bdb9b2e..8cd3aca12 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs @@ -11,10 +11,9 @@ namespace VRMShaders public sealed class TextureExporter : IDisposable, ITextureExporter { private readonly ITextureSerializer m_textureSerializer; - private readonly Dictionary m_exportMap = new Dictionary(); - private readonly List<(Texture2D, ColorSpace)> m_exported = new List<(Texture2D, ColorSpace)>(); - public IReadOnlyList<(Texture2D, ColorSpace)> Exported => m_exported; + private readonly List<(TextureExportKey key, bool needsAlpha, Func creator)> _exportingList = + new List<(TextureExportKey key, bool needsAlpha, Func creator)>(); public TextureExporter(ITextureSerializer textureSerializer) { @@ -26,130 +25,110 @@ namespace VRMShaders // TODO: export 用にコピー・変換したテクスチャーをここで解放したい } - enum ExportTypes + /// + /// 実際にテクスチャを変換する + /// + public List<(Texture2D, ColorSpace)> Export() { - // sRGB テクスチャとして出力 - Srgb, - // Linear テクスチャとして出力 - Linear, - // Unity Standard様式 から glTF PBR様式への変換 - OcclusionMetallicRoughness, - // Assetを使うときはそのバイト列を無変換で、それ以外は DXT5nm 形式からのデコードを行う - Normal, + var exported = new List<(Texture2D, ColorSpace)>(); + for (var idx = 0; idx < _exportingList.Count; ++idx) + { + var (key, needsAlpha, creator) = _exportingList[idx]; + var colorSpace = key.TextureType == TextureExportTypes.Srgb ? ColorSpace.sRGB : ColorSpace.Linear; + var texture = creator(); + exported.Add((creator(), colorSpace)); + } + return exported; } - readonly struct ExportKey + public int ExportAsSRgb(Texture src, bool needsAlpha) { - public readonly Texture Src; - public readonly ExportTypes TextureType; + return ExportSimple(src, needsAlpha, isLinear: false); + } - public ExportKey(Texture src, ExportTypes type) + public int ExportAsLinear(Texture src, bool needsAlpha) + { + return ExportSimple(src, needsAlpha, isLinear: true); + } + + private int ExportSimple(Texture src, bool needsAlpha, bool isLinear) + { + if (src == null) { - if (src == null) + return -1; + } + + var exportType = isLinear ? TextureExportTypes.Linear : TextureExportTypes.Srgb; + var colorSpace = isLinear ? ColorSpace.Linear : ColorSpace.sRGB; + + var key = new TextureExportKey(src, exportType); + var existsIdx = _exportingList.FindIndex(x => key.Equals(x.key)); + if (existsIdx != -1) + { + // already marked as exporting + var cached = _exportingList[existsIdx]; + + if (needsAlpha && !cached.needsAlpha) { - throw new ArgumentNullException(); + // アルファチャンネルを必要とする使用用途が表れたため、アルファチャンネル付きで出力するように上書きする + _exportingList[existsIdx] = (cached.key, true, () => ConvertTextureSimple(src, true, colorSpace)); + return existsIdx; + } + else + { + // Return cached + return existsIdx; } - Src = src; - TextureType = type; - } - } - - public int ExportAsSRgb(Texture src) - { - if (src == null) - { - return -1; - } - - // cache - if (m_exportMap.TryGetValue(new ExportKey(src, ExportTypes.Srgb), out var index)) - { - return index; - } - - // get Texture2D - index = m_exported.Count; - var texture2D = src as Texture2D; - if (m_textureSerializer.CanExportAsEditorAssetFile(texture2D, ColorSpace.sRGB)) - { - // do nothing } else { - texture2D = TextureConverter.CopyTexture(src, ColorSpace.sRGB, true, null); + // Add + _exportingList.Add((key, needsAlpha, () => ConvertTextureSimple(src, needsAlpha, colorSpace))); + return _exportingList.Count - 1; } - m_exported.Add((texture2D, ColorSpace.sRGB)); - m_exportMap.Add(new ExportKey(src, ExportTypes.Srgb), index); - - return index; - } - - public int ExportAsLinear(Texture src) - { - if (src == null) - { - return -1; - } - - var exportKey = new ExportKey(src, ExportTypes.Linear); - - // search cache - if (m_exportMap.TryGetValue(exportKey, out var index)) - { - return index; - } - - index = m_exported.Count; - var texture2d = src as Texture2D; - if (m_textureSerializer.CanExportAsEditorAssetFile(texture2d, ColorSpace.Linear)) - { - // do nothing - } - else - { - texture2d = TextureConverter.CopyTexture(src, ColorSpace.Linear, false, null); - } - m_exported.Add((texture2d, ColorSpace.Linear)); - m_exportMap.Add(exportKey, index); - - return index; } public int ExportAsCombinedGltfPbrParameterTextureFromUnityStandardTextures(Texture metallicSmoothTexture, float smoothness, Texture occlusionTexture) { - if (metallicSmoothTexture == null && occlusionTexture == null) + if (metallicSmoothTexture != null) + { + // metallicSmoothness is available + var key = new TextureExportKey(metallicSmoothTexture, TextureExportTypes.OcclusionMetallicRoughness); + var existsIdx = _exportingList.FindIndex(x => key.Equals(x.key)); + if (existsIdx != -1) + { + // Return cached + return existsIdx; + } + else + { + // Add + _exportingList.Add((key, false, () => OcclusionMetallicRoughnessConverter.Export(metallicSmoothTexture, smoothness, occlusionTexture))); + return _exportingList.Count - 1; + } + } + else if (occlusionTexture != null) + { + // TODO 厳密なチェックをしていない + // occlusion is available + var key = new TextureExportKey(occlusionTexture, TextureExportTypes.OcclusionMetallicRoughness); + var existsIdx = _exportingList.FindIndex(x => key.Equals(x.key)); + if (existsIdx != -1) + { + // Return cached + return existsIdx; + } + else + { + // Add + _exportingList.Add((key, false, () => OcclusionMetallicRoughnessConverter.Export(metallicSmoothTexture, smoothness, occlusionTexture))); + return _exportingList.Count - 1; + } + } + else { return -1; } - - // cache - // TODO 厳密なチェックをしていない - if (metallicSmoothTexture != null && m_exportMap.TryGetValue(new ExportKey(metallicSmoothTexture, ExportTypes.OcclusionMetallicRoughness), out var index)) - { - return index; - } - if (occlusionTexture != null && m_exportMap.TryGetValue(new ExportKey(occlusionTexture, ExportTypes.OcclusionMetallicRoughness), out index)) - { - return index; - } - - // - // Unity と glTF で互換性が無いので必ず変換が必用 - // - index = m_exported.Count; - var texture2D = OcclusionMetallicRoughnessConverter.Export(metallicSmoothTexture, smoothness, occlusionTexture); - - m_exported.Add((texture2D, ColorSpace.Linear)); - if (metallicSmoothTexture != null) - { - m_exportMap.Add(new ExportKey(metallicSmoothTexture, ExportTypes.OcclusionMetallicRoughness), index); - } - if (occlusionTexture != null && occlusionTexture != metallicSmoothTexture) - { - m_exportMap.Add(new ExportKey(occlusionTexture, ExportTypes.OcclusionMetallicRoughness), index); - } - - return index; } public int ExportAsNormal(Texture src) @@ -159,21 +138,37 @@ namespace VRMShaders return -1; } - // cache - if (m_exportMap.TryGetValue(new ExportKey(src, ExportTypes.Normal), out var index)) + var key = new TextureExportKey(src, TextureExportTypes.Normal); + var existsIdx = _exportingList.FindIndex(x => key.Equals(x.key)); + + if (existsIdx != -1) { - return index; + // Return cached; + return existsIdx; } + else + { + // Add + // NormalMap Property のテクスチャは必ず NormalMap として解釈してコピーする。 + // Texture Asset の設定に依らず、Standard Shader で得られる見た目と同じ結果を得るため。 + _exportingList.Add((key, false, () => NormalConverter.Export(src))); + return _exportingList.Count - 1; + } + } - index = m_exported.Count; - // NormalMap Property のテクスチャは必ず NormalMap として解釈してコピーする。 - // Texture Asset の設定に依らず、Standard Shader で得られる見た目と同じ結果を得るため。 - var texture2D = NormalConverter.Export(src); - - m_exported.Add((texture2D, ColorSpace.Linear)); - m_exportMap.Add(new ExportKey(src, ExportTypes.Normal), index); - - return index; + private Texture2D ConvertTextureSimple(Texture src, bool needsAlpha, ColorSpace exportColorSpace) + { + // get Texture2D + var texture2D = src as Texture2D; + if (m_textureSerializer.CanExportAsEditorAssetFile(texture2D, exportColorSpace)) + { + // do nothing + } + else + { + texture2D = TextureConverter.CopyTexture(src, exportColorSpace, needsAlpha, null); + } + return texture2D; } } }