diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/TextureExportKey.cs b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExportKey.cs deleted file mode 100644 index a4d6cd683..000000000 --- a/Assets/VRMShaders/GLTF/IO/Runtime/TextureExportKey.cs +++ /dev/null @@ -1,39 +0,0 @@ -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/TextureExportParam.cs b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExportParam.cs new file mode 100644 index 000000000..65f2d9475 --- /dev/null +++ b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExportParam.cs @@ -0,0 +1,48 @@ +using System; +using UnityEngine; + +namespace VRMShaders +{ + internal class TextureExportParam + { + public TextureExportTypes ExportType { get; } + public ColorSpace ExportColorSpace { get; } + public Texture PrimaryTexture { get; } + public Texture SecondaryTexture { get; } + public float OptionFactor { get; } + + public bool NeedsAlpha { get; set; } + public Func Creator { get; set; } + + public TextureExportParam(TextureExportTypes exportType, ColorSpace exportColorSpace, Texture primaryTexture, Texture secondaryTexture, float optionFactor, bool needsAlpha, Func creator) + { + ExportType = exportType; + ExportColorSpace = exportColorSpace; + PrimaryTexture = primaryTexture; + SecondaryTexture = secondaryTexture; + OptionFactor = optionFactor; + NeedsAlpha = needsAlpha; + Creator = creator; + } + + public bool EqualsAsKey(TextureExportParam other) + { + if (ExportType != other.ExportType) return false; + + switch (ExportType) + { + case TextureExportTypes.Srgb: + case TextureExportTypes.Linear: + case TextureExportTypes.Normal: + return PrimaryTexture == other.PrimaryTexture; + case TextureExportTypes.OcclusionMetallicRoughness: + var primaryDifference = PrimaryTexture != other.PrimaryTexture ? 1 : 0; + var secondaryDifference = SecondaryTexture != other.SecondaryTexture ? 1 : 0; + var difference = primaryDifference + secondaryDifference; + return difference < 2; + default: + throw new ArgumentOutOfRangeException(); + } + } + } +} \ No newline at end of file diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/TextureExportKey.cs.meta b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExportParam.cs.meta similarity index 100% rename from Assets/VRMShaders/GLTF/IO/Runtime/TextureExportKey.cs.meta rename to Assets/VRMShaders/GLTF/IO/Runtime/TextureExportParam.cs.meta diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs index 8cd3aca12..9902747b7 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs @@ -11,9 +11,7 @@ namespace VRMShaders public sealed class TextureExporter : IDisposable, ITextureExporter { private readonly ITextureSerializer m_textureSerializer; - - private readonly List<(TextureExportKey key, bool needsAlpha, Func creator)> _exportingList = - new List<(TextureExportKey key, bool needsAlpha, Func creator)>(); + private readonly List _exportingList = new List(); public TextureExporter(ITextureSerializer textureSerializer) { @@ -22,7 +20,6 @@ namespace VRMShaders public void Dispose() { - // TODO: export 用にコピー・変換したテクスチャーをここで解放したい } /// @@ -30,15 +27,14 @@ namespace VRMShaders /// public List<(Texture2D, ColorSpace)> Export() { - var exported = new List<(Texture2D, ColorSpace)>(); + var exportedTextures = 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)); + var exporting = _exportingList[idx]; + var texture = exporting.Creator(); + exportedTextures.Add((texture, exporting.ExportColorSpace)); } - return exported; + return exportedTextures; } public int ExportAsSRgb(Texture src, bool needsAlpha) @@ -61,17 +57,18 @@ namespace VRMShaders 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) + var param = new TextureExportParam(exportType, colorSpace, src, default, default, + needsAlpha, () => ConvertTextureSimple(src, needsAlpha, colorSpace)); + + if (TryGetExistsParam(param, out var existsIdx)) { // already marked as exporting var cached = _exportingList[existsIdx]; - if (needsAlpha && !cached.needsAlpha) + if (needsAlpha && !cached.NeedsAlpha) { // アルファチャンネルを必要とする使用用途が表れたため、アルファチャンネル付きで出力するように上書きする - _exportingList[existsIdx] = (cached.key, true, () => ConvertTextureSimple(src, true, colorSpace)); + _exportingList[existsIdx] = param; return existsIdx; } else @@ -83,51 +80,31 @@ namespace VRMShaders else { // Add - _exportingList.Add((key, needsAlpha, () => ConvertTextureSimple(src, needsAlpha, colorSpace))); + _exportingList.Add(param); return _exportingList.Count - 1; } } public int ExportAsCombinedGltfPbrParameterTextureFromUnityStandardTextures(Texture metallicSmoothTexture, float smoothness, Texture occlusionTexture) { - if (metallicSmoothTexture != null) + if (metallicSmoothTexture == null && occlusionTexture == 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; - } + return -1; } - else if (occlusionTexture != null) + + var param = new TextureExportParam(TextureExportTypes.OcclusionMetallicRoughness, ColorSpace.Linear, + metallicSmoothTexture, occlusionTexture, smoothness, false, + () => OcclusionMetallicRoughnessConverter.Export(metallicSmoothTexture, smoothness, occlusionTexture)); + if (TryGetExistsParam(param, out var existsIdx)) { - // 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; - } + // Return cacehd + return existsIdx; } else { - return -1; + // Add + _exportingList.Add(param); + return _exportingList.Count - 1; } } @@ -138,10 +115,9 @@ namespace VRMShaders return -1; } - var key = new TextureExportKey(src, TextureExportTypes.Normal); - var existsIdx = _exportingList.FindIndex(x => key.Equals(x.key)); - - if (existsIdx != -1) + var param = new TextureExportParam(TextureExportTypes.Normal, ColorSpace.Linear, src, default, default, + false, () => NormalConverter.Export(src)); + if (TryGetExistsParam(param, out var existsIdx)) { // Return cached; return existsIdx; @@ -151,7 +127,7 @@ namespace VRMShaders // Add // NormalMap Property のテクスチャは必ず NormalMap として解釈してコピーする。 // Texture Asset の設定に依らず、Standard Shader で得られる見た目と同じ結果を得るため。 - _exportingList.Add((key, false, () => NormalConverter.Export(src))); + _exportingList.Add(param); return _exportingList.Count - 1; } } @@ -170,5 +146,11 @@ namespace VRMShaders } return texture2D; } + + private bool TryGetExistsParam(TextureExportParam param, out int existsIdx) + { + existsIdx = _exportingList.FindIndex(param.EqualsAsKey); + return existsIdx != -1; + } } }