From 7ad3ab81326b29ea8fd19652be1d726423ccd274 Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Thu, 13 May 2021 18:36:25 +0900 Subject: [PATCH 1/7] Throw Exception if exporting non-readable Texture2D. --- .../GLTF/IO/Runtime/TextureExporter.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs index a8f089f4a..0a7b49f6e 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs @@ -200,7 +200,6 @@ namespace VRMShaders /// /// 画像のバイト列を得る /// - /// /// /// public static (byte[] bytes, string mime) GetTextureBytesWithMime(Texture2D texture) @@ -213,20 +212,21 @@ namespace VRMShaders return (png, "image/png"); } } - catch (Exception ex) + catch (ArgumentException ex) { // fail to EncodeToPng // System.ArgumentException: not readable, the texture memory can not be accessed from scripts. You can make the texture readable in the Texture Import Settings. Debug.LogWarning(ex); + + // Read/Write が許可されていない Texture2D オブジェクトはこの関数に渡されるべきではない。 + // なぜなら Texture2D の色空間は、対応する glTF プロパティ指定の色空間と一致していなければならないが + // Read/Write が許可されていない場合、その条件を守って変換することができないからである。 + // したがって、この関数に渡す前に glTF プロパティ指定の色空間を加味して Copy Texture して、それを渡すべきである。 + + throw; } - { - // try copy and EncodeToPng - var copy = TextureConverter.CopyTexture(texture, TextureImportTypes.sRGB, null); - var png = copy.EncodeToPNG(); - UnityEngine.Object.DestroyImmediate(copy); - return (png, "image/png"); - } + throw new ArgumentException("Invalid Texture2D"); } } } From 72a922ded9ad83baaa3f08f21ddb35fdb2bb4239 Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Thu, 13 May 2021 19:20:38 +0900 Subject: [PATCH 2/7] Divide ColorSpace enum --- .../Runtime/Extensions/ColorConversionExtensions.cs | 6 ------ Assets/VRMShaders/GLTF/IO/Runtime/ColorSpace.cs | 8 ++++++++ Assets/VRMShaders/GLTF/IO/Runtime/ColorSpace.cs.meta | 3 +++ 3 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 Assets/VRMShaders/GLTF/IO/Runtime/ColorSpace.cs create mode 100644 Assets/VRMShaders/GLTF/IO/Runtime/ColorSpace.cs.meta diff --git a/Assets/UniGLTF/Runtime/Extensions/ColorConversionExtensions.cs b/Assets/UniGLTF/Runtime/Extensions/ColorConversionExtensions.cs index 6de7f163b..0391b4fea 100644 --- a/Assets/UniGLTF/Runtime/Extensions/ColorConversionExtensions.cs +++ b/Assets/UniGLTF/Runtime/Extensions/ColorConversionExtensions.cs @@ -3,12 +3,6 @@ using UnityEngine; namespace UniGLTF { - public enum ColorSpace - { - sRGB, - Linear, - } - public static class ColorConversionExtensions { public static float[] ToFloat4(this Color src, ColorSpace srcColorSpace, ColorSpace dstColorSpace) diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/ColorSpace.cs b/Assets/VRMShaders/GLTF/IO/Runtime/ColorSpace.cs new file mode 100644 index 000000000..68d124b6e --- /dev/null +++ b/Assets/VRMShaders/GLTF/IO/Runtime/ColorSpace.cs @@ -0,0 +1,8 @@ +namespace UniGLTF +{ + public enum ColorSpace + { + sRGB, + Linear, + } +} \ No newline at end of file diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/ColorSpace.cs.meta b/Assets/VRMShaders/GLTF/IO/Runtime/ColorSpace.cs.meta new file mode 100644 index 000000000..1feb2b186 --- /dev/null +++ b/Assets/VRMShaders/GLTF/IO/Runtime/ColorSpace.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5e97eeb2080e43e18ba57f1a3820a7e6 +timeCreated: 1620901197 \ No newline at end of file From b8f2d37ccf1834fc0d23d3e7329450835440cd5a Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Thu, 13 May 2021 20:57:35 +0900 Subject: [PATCH 3/7] Export Texture with specified Color Space. --- .../IO/TextureIO/GltfTextureExporter.cs | 4 +- .../Runtime/UniGLTF/IO/gltfExporter.cs | 17 +++-- Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs | 2 +- Assets/VRM/Runtime/IO/VRMExporter.cs | 7 +- Assets/VRM10/Runtime/IO/Vrm10Exporter.cs | 8 +-- .../GLTF/IO/Editor/AssetTextureUtil.cs | 5 +- .../GLTF/IO/Runtime/TextureConverter.cs | 24 ++++++- .../GLTF/IO/Runtime/TextureExporter.cs | 71 +++++++++++++++---- .../GLTF/IO/Runtime/TextureImportTypes.cs | 7 +- 9 files changed, 108 insertions(+), 37 deletions(-) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfTextureExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfTextureExporter.cs index cd7df68be..c80a0fd67 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfTextureExporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfTextureExporter.cs @@ -21,9 +21,9 @@ namespace UniGLTF /// /// /// gltf texture index - public static int PushGltfTexture(this glTF gltf, int bufferIndex, Texture2D texture, Func getTextureBytes) + public static int PushGltfTexture(this glTF gltf, int bufferIndex, Texture2D texture, ColorSpace textureColorSpace, gltfExporter.GetBytesWithMimeFromTexture2D getTextureBytes) { - var bytesWithMime = getTextureBytes(texture); + var bytesWithMime = getTextureBytes(texture, textureColorSpace); // add view var view = gltf.buffers[bufferIndex].Append(bytesWithMime.bytes, glBufferTarget.NONE); diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs index 4174e7ae2..b109dd140 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs @@ -214,12 +214,21 @@ namespace UniGLTF return false; } - public virtual void ExportExtensions(Func getTextureBytes) + public virtual void ExportExtensions(GetBytesWithMimeFromTexture2D getTextureBytes) { // do nothing } - public virtual void Export(MeshExportSettings meshExportSettings, Func useAsset, Func getTextureBytes) + /// + /// Texture2D から実際のバイト列を取得するデリゲート。 + /// + /// textureColorSpace は Texture2D をコピーする際に用いる。 + /// Texture2D 単体では、色空間を知ることができないため。 + /// 一般には、その Texture2D がアサインされる glTF のプロパティの仕様が定める色空間と一致する。 + /// + public delegate (byte[] bytes, string mime) GetBytesWithMimeFromTexture2D(Texture2D texture, ColorSpace textureColorSpace); + + public virtual void Export(MeshExportSettings meshExportSettings, Func useAsset, GetBytesWithMimeFromTexture2D getTextureBytes) { var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]); var bufferIndex = glTF.AddBuffer(bytesBuffer); @@ -362,8 +371,8 @@ namespace UniGLTF // Extension で Texture が増える場合があるので最後に呼ぶ for (int i = 0; i < TextureManager.Exported.Count; ++i) { - var unityTexture = TextureManager.Exported[i]; - glTF.PushGltfTexture(bufferIndex, unityTexture, getTextureBytes); + var (unityTexture, colorSpace) = TextureManager.Exported[i]; + glTF.PushGltfTexture(bufferIndex, unityTexture, colorSpace, getTextureBytes); } } #endregion diff --git a/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs b/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs index 2ccb579e8..43232395c 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs @@ -26,7 +26,7 @@ namespace UniGLTF var materialExporter = new MaterialExporter(); materialExporter.ExportMaterial(material, textureManager); - var convTex0 = textureManager.Exported[0]; + var (convTex0, colorSpace) = textureManager.Exported[0]; var sampler = TextureSamplerUtil.Export(convTex0); Assert.AreEqual(glWrap.CLAMP_TO_EDGE, sampler.wrapS); diff --git a/Assets/VRM/Runtime/IO/VRMExporter.cs b/Assets/VRM/Runtime/IO/VRMExporter.cs index ed567d485..87b02bcce 100644 --- a/Assets/VRM/Runtime/IO/VRMExporter.cs +++ b/Assets/VRM/Runtime/IO/VRMExporter.cs @@ -3,6 +3,7 @@ using System.Linq; using UniGLTF; using UniJSON; using UnityEngine; +using ColorSpace = UniGLTF.ColorSpace; namespace VRM @@ -14,7 +15,7 @@ namespace VRM return new VRMMaterialExporter(); } - public static glTF Export(MeshExportSettings configuration, GameObject go, Func useAsset, Func getTextureBytes) + public static glTF Export(MeshExportSettings configuration, GameObject go, Func useAsset, GetBytesWithMimeFromTexture2D getTextureBytes) { var gltf = new glTF(); using (var exporter = new VRMExporter(gltf)) @@ -32,7 +33,7 @@ namespace VRM gltf.extensionsUsed.Add(glTF_VRM_extensions.ExtensionName); } - public override void ExportExtensions(Func getTextureBytes) + public override void ExportExtensions(GetBytesWithMimeFromTexture2D getTextureBytes) { // avatar var animator = Copy.GetComponent(); @@ -110,7 +111,7 @@ namespace VRM VRM.meta.title = meta.Title; if (meta.Thumbnail != null) { - VRM.meta.texture = glTF.PushGltfTexture(glTF.buffers.Count - 1, meta.Thumbnail, getTextureBytes); + VRM.meta.texture = glTF.PushGltfTexture(glTF.buffers.Count - 1, meta.Thumbnail, ColorSpace.sRGB, getTextureBytes); } VRM.meta.licenseType = meta.LicenseType; diff --git a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs index 042e72e5a..da0c5b722 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs @@ -127,7 +127,7 @@ namespace UniVRM10 return new float[] { -v.x, v.y, v.z }; } - public void Export(GameObject root, Model model, ModelExporter converter, ExportArgs option, Func getTextureBytes, VRM10MetaObject metaObject = null) + public void Export(GameObject root, Model model, ModelExporter converter, ExportArgs option, gltfExporter.GetBytesWithMimeFromTexture2D getTextureBytes, VRM10MetaObject metaObject = null) { ExportAsset(model); @@ -180,8 +180,8 @@ namespace UniVRM10 // Extension で Texture が増える場合があるので最後に呼ぶ for (int i = 0; i < m_textureExporter.Exported.Count; ++i) { - var unityTexture = m_textureExporter.Exported[i]; - Storage.Gltf.PushGltfTexture(0, unityTexture, getTextureBytes); + var (unityTexture, texColorSpace) = m_textureExporter.Exported[i]; + Storage.Gltf.PushGltfTexture(0, unityTexture, texColorSpace, getTextureBytes); } if (thumbnailTextureIndex.HasValue) @@ -775,7 +775,7 @@ namespace UniVRM10 /// /// /// - public static byte[] Export(GameObject go, Func getTextureBytes = null) + public static byte[] Export(GameObject go, gltfExporter.GetBytesWithMimeFromTexture2D getTextureBytes = null) { if (getTextureBytes == null) { diff --git a/Assets/VRMShaders/GLTF/IO/Editor/AssetTextureUtil.cs b/Assets/VRMShaders/GLTF/IO/Editor/AssetTextureUtil.cs index c69ae48ed..b736e0d1c 100644 --- a/Assets/VRMShaders/GLTF/IO/Editor/AssetTextureUtil.cs +++ b/Assets/VRMShaders/GLTF/IO/Editor/AssetTextureUtil.cs @@ -2,6 +2,7 @@ using System.IO; using System.Reflection; using UnityEditor; using UnityEngine; +using ColorSpace = UniGLTF.ColorSpace; namespace VRMShaders { @@ -107,14 +108,14 @@ namespace VRMShaders return false; } - public static (byte[], string) GetTextureBytesWithMime(Texture2D texture) + public static (byte[], string) GetTextureBytesWithMime(Texture2D texture, ColorSpace colorSpace) { if (TryGetBytesWithMime(texture, out byte[] bytes, out string mime)) { return (bytes, mime); } - return TextureExporter.GetTextureBytesWithMime(texture); + return TextureExporter.GetTextureBytesWithMime(texture, colorSpace); } } } diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/TextureConverter.cs b/Assets/VRMShaders/GLTF/IO/Runtime/TextureConverter.cs index 54ac445f9..67d0eb6f0 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/TextureConverter.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/TextureConverter.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using UnityEngine; +using ColorSpace = UniGLTF.ColorSpace; namespace VRMShaders @@ -22,10 +23,27 @@ namespace VRMShaders } public static Texture2D CopyTexture(Texture src, TextureImportTypes textureType, Material material) + { + return CopyTexture(src, textureType.GetColorSpace(), material); + } + + public static Texture2D CopyTexture(Texture src, ColorSpace colorSpace, Material material) { Texture2D dst = null; - RenderTextureReadWrite colorSpace = textureType.GetColorSpace(); - var renderTexture = new RenderTexture(src.width, src.height, 0, RenderTextureFormat.ARGB32, colorSpace); + RenderTextureReadWrite readWrite; + switch (colorSpace) + { + case ColorSpace.sRGB: + readWrite = RenderTextureReadWrite.sRGB; + break; + case ColorSpace.Linear: + readWrite = RenderTextureReadWrite.Linear; + break; + default: + throw new ArgumentOutOfRangeException(nameof(colorSpace), colorSpace, null); + } + + var renderTexture = new RenderTexture(src.width, src.height, 0, RenderTextureFormat.ARGB32, readWrite); if (material != null) { @@ -36,7 +54,7 @@ namespace VRMShaders Graphics.Blit(src, renderTexture); } - dst = new Texture2D(src.width, src.height, TextureFormat.ARGB32, false, colorSpace == RenderTextureReadWrite.Linear); + dst = new Texture2D(src.width, src.height, TextureFormat.ARGB32, false, readWrite == RenderTextureReadWrite.Linear); dst.ReadPixels(new Rect(0, 0, src.width, src.height), 0, 0); dst.name = src.name; dst.anisoLevel = src.anisoLevel; diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs index 0a7b49f6e..8434e456e 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using UnityEngine; +using ColorSpace = UniGLTF.ColorSpace; namespace VRMShaders @@ -55,7 +56,7 @@ namespace VRMShaders /// /// /// - public readonly List Exported = new List(); + public readonly List<(Texture2D, ColorSpace)> Exported = new List<(Texture2D, ColorSpace)>(); /// /// Texture の export index を得る @@ -101,7 +102,7 @@ namespace VRMShaders { texture2D = TextureConverter.CopyTexture(src, TextureImportTypes.sRGB, null); } - Exported.Add(texture2D); + Exported.Add((texture2D, ColorSpace.sRGB)); m_exportMap.Add(new ExportKey(src, ConvertTypes.None), index); return index; @@ -114,7 +115,33 @@ namespace VRMShaders /// public int ExportLinear(Texture src) { - throw new NotImplementedException(); + if (src == null) + { + return -1; + } + + var exportKey = new ExportKey(src, ConvertTypes.None); + + // search cache + if (m_exportMap.TryGetValue(exportKey, out var index)) + { + return index; + } + + index = Exported.Count; + var texture2d = src as Texture2D; + if (m_useAsset(texture2d)) + { + // do nothing + } + else + { + texture2d = TextureConverter.CopyTexture(src, TextureImportTypes.Linear, null); + } + Exported.Add((texture2d, ColorSpace.Linear)); + m_exportMap.Add(exportKey, index); + + return index; } /// @@ -147,7 +174,7 @@ namespace VRMShaders index = Exported.Count; var texture2D = OcclusionMetallicRoughnessConverter.Export(metallicSmoothTexture, smoothness, occlusionTexture); - Exported.Add(texture2D); + Exported.Add((texture2D, ColorSpace.Linear)); if (metallicSmoothTexture != null) { m_exportMap.Add(new ExportKey(metallicSmoothTexture, ConvertTypes.OcclusionMetallicRoughness), index); @@ -191,7 +218,7 @@ namespace VRMShaders texture2D = NormalConverter.Export(src); } - Exported.Add(texture2D); + Exported.Add((texture2D, ColorSpace.Linear)); m_exportMap.Add(new ExportKey(src, ConvertTypes.Normal), index); return index; @@ -200,9 +227,7 @@ namespace VRMShaders /// /// 画像のバイト列を得る /// - /// - /// - public static (byte[] bytes, string mime) GetTextureBytesWithMime(Texture2D texture) + public static (byte[] bytes, string mime) GetTextureBytesWithMime(Texture2D texture, ColorSpace colorSpace) { try { @@ -211,22 +236,38 @@ namespace VRMShaders { return (png, "image/png"); } + else + { + // 単純に EncodeToPNG できないため、コピーしてから EncodeToPNG する。 + return CopyTextureAndGetBytesWithMime(texture, colorSpace); + } } catch (ArgumentException ex) { // fail to EncodeToPng // System.ArgumentException: not readable, the texture memory can not be accessed from scripts. You can make the texture readable in the Texture Import Settings. + // example, ".DDS" Texture object in Editor. Debug.LogWarning(ex); - - // Read/Write が許可されていない Texture2D オブジェクトはこの関数に渡されるべきではない。 - // なぜなら Texture2D の色空間は、対応する glTF プロパティ指定の色空間と一致していなければならないが - // Read/Write が許可されていない場合、その条件を守って変換することができないからである。 - // したがって、この関数に渡す前に glTF プロパティ指定の色空間を加味して Copy Texture して、それを渡すべきである。 - throw; + // 単純に EncodeToPNG できないため、コピーしてから EncodeToPNG する。 + return CopyTextureAndGetBytesWithMime(texture, colorSpace); + } + } + + private static (byte[] bytes, string mime) CopyTextureAndGetBytesWithMime(Texture2D texture, ColorSpace colorSpace) + { + var copiedTex = TextureConverter.CopyTexture(texture, colorSpace, null); + var bytes = copiedTex.EncodeToPNG(); + if (Application.isPlaying) + { + UnityEngine.Object.Destroy(copiedTex); + } + else + { + UnityEngine.Object.DestroyImmediate(copiedTex); } - throw new ArgumentException("Invalid Texture2D"); + return (bytes, "image/png"); } } } diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/TextureImportTypes.cs b/Assets/VRMShaders/GLTF/IO/Runtime/TextureImportTypes.cs index 4b928153b..c47f14a51 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/TextureImportTypes.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/TextureImportTypes.cs @@ -1,5 +1,6 @@ using System; using UnityEngine; +using ColorSpace = UniGLTF.ColorSpace; namespace VRMShaders { @@ -31,16 +32,16 @@ namespace VRMShaders public static class TextureImportTypesExtensions { - public static RenderTextureReadWrite GetColorSpace(this TextureImportTypes textureType) + public static ColorSpace GetColorSpace(this TextureImportTypes textureType) { switch (textureType) { case TextureImportTypes.sRGB: - return RenderTextureReadWrite.sRGB; + return ColorSpace.sRGB; case TextureImportTypes.Linear: case TextureImportTypes.StandardMap: case TextureImportTypes.NormalMap: - return RenderTextureReadWrite.Linear; + return ColorSpace.Linear; default: throw new NotImplementedException(); } From 0b812fa778c01b47ca3d448536796cd41467a79b Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Thu, 13 May 2021 20:58:00 +0900 Subject: [PATCH 4/7] Use TextureExporter in Texture Saver. --- Assets/UniGLTF/Editor/MeshUtility/TextureSaver.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Assets/UniGLTF/Editor/MeshUtility/TextureSaver.cs b/Assets/UniGLTF/Editor/MeshUtility/TextureSaver.cs index e2425f1d6..02e8b35e9 100644 --- a/Assets/UniGLTF/Editor/MeshUtility/TextureSaver.cs +++ b/Assets/UniGLTF/Editor/MeshUtility/TextureSaver.cs @@ -1,6 +1,8 @@ using System.IO; using UnityEditor; using UnityEngine; +using VRMShaders; +using ColorSpace = UniGLTF.ColorSpace; namespace MeshUtility { @@ -34,7 +36,9 @@ namespace MeshUtility return; } - File.WriteAllBytes(path, texture.EncodeToPNG()); + var (tex, mime) = TextureExporter.GetTextureBytesWithMime(texture, sRGB ? ColorSpace.sRGB : ColorSpace.Linear); + + File.WriteAllBytes(path, tex); Debug.Log($"save: {path}"); var assetsPath = AssetsPath.FromFullpath(path); From 2e338a78e9c4143159c054af45080f6c6c758bb2 Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Thu, 13 May 2021 21:00:56 +0900 Subject: [PATCH 5/7] Don't Compress texture for UnitTests. --- Assets/VRMShaders/GLTF/IO/Tests/4x4.png.meta | 14 +++++++------- .../GLTF/IO/Tests/4x4compressed.DDS.meta | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Assets/VRMShaders/GLTF/IO/Tests/4x4.png.meta b/Assets/VRMShaders/GLTF/IO/Tests/4x4.png.meta index 3daaec290..f3ee693e4 100644 --- a/Assets/VRMShaders/GLTF/IO/Tests/4x4.png.meta +++ b/Assets/VRMShaders/GLTF/IO/Tests/4x4.png.meta @@ -6,7 +6,7 @@ TextureImporter: serializedVersion: 9 mipmaps: mipMapMode: 0 - enableMipMap: 1 + enableMipMap: 0 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 @@ -31,12 +31,12 @@ TextureImporter: maxTextureSize: 2048 textureSettings: serializedVersion: 2 - filterMode: -1 + filterMode: 0 aniso: -1 mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 + wrapU: 1 + wrapV: 1 + wrapW: 1 nPOTScale: 1 lightmap: 0 compressionQuality: 50 @@ -48,7 +48,7 @@ TextureImporter: spritePixelsToUnits: 100 spriteBorder: {x: 0, y: 0, z: 0, w: 0} spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 + alphaUsage: 0 alphaIsTransparency: 0 spriteTessellationDetail: -1 textureType: 0 @@ -63,7 +63,7 @@ TextureImporter: maxTextureSize: 2048 resizeAlgorithm: 0 textureFormat: -1 - textureCompression: 1 + textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 diff --git a/Assets/VRMShaders/GLTF/IO/Tests/4x4compressed.DDS.meta b/Assets/VRMShaders/GLTF/IO/Tests/4x4compressed.DDS.meta index ef44f51d6..75d25104f 100644 --- a/Assets/VRMShaders/GLTF/IO/Tests/4x4compressed.DDS.meta +++ b/Assets/VRMShaders/GLTF/IO/Tests/4x4compressed.DDS.meta @@ -4,7 +4,7 @@ IHVImageFormatImporter: externalObjects: {} textureSettings: serializedVersion: 2 - filterMode: 1 + filterMode: 0 aniso: 1 mipBias: 0 wrapU: 0 From 099a4600c111e11a8eb48de9e44f6b81181f9b5a Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Thu, 13 May 2021 21:13:34 +0900 Subject: [PATCH 6/7] Add CopyTexture Tests. --- .../GLTF/IO/Tests/CopyTextureTests.cs | 66 +++++++++++++++++++ .../GLTF/IO/Tests/CopyTextureTests.cs.meta | 3 + .../GLTF/IO/Tests/TextureBytesTests.cs | 13 ++-- 3 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 Assets/VRMShaders/GLTF/IO/Tests/CopyTextureTests.cs create mode 100644 Assets/VRMShaders/GLTF/IO/Tests/CopyTextureTests.cs.meta diff --git a/Assets/VRMShaders/GLTF/IO/Tests/CopyTextureTests.cs b/Assets/VRMShaders/GLTF/IO/Tests/CopyTextureTests.cs new file mode 100644 index 000000000..a5a69b284 --- /dev/null +++ b/Assets/VRMShaders/GLTF/IO/Tests/CopyTextureTests.cs @@ -0,0 +1,66 @@ +using System.Linq; +using NUnit.Framework; +using UnityEditor; +using UnityEngine; +using ColorSpace = UniGLTF.ColorSpace; + +namespace VRMShaders +{ + public sealed class CopyTextureTests + { + private static string AssetPath = "Assets/VRMShaders/GLTF/IO/Tests"; + + private static readonly Color32 Black = new Color32(0, 0, 0, 255); + private static readonly Color32 Gray = new Color32(127, 127, 127, 255); + private static readonly Color32 White = new Color32(255, 255, 255, 255); + + private static readonly Color32[] PngTextureValues = new Color32[] + { + White, White, White, White, + Gray, Gray, Gray, Gray, + Gray, Gray, Gray, Gray, + Black, Black, Black, Black, + }; + + // DDS のテクスチャ圧縮によって別の色になっている + private static readonly Color32 CompressedBlack = new Color32(24, 24, 24, 255); + private static readonly Color32 CompressedGray = new Color32(101, 96, 101, 255); + private static readonly Color32 CompressedWhite = new Color32(255, 255, 255, 255); + + private static readonly Color32[] DdsTextureValues = new Color32[] + { + CompressedBlack, CompressedBlack, CompressedBlack, CompressedBlack, + CompressedGray, CompressedGray, CompressedGray, CompressedGray, + CompressedGray, CompressedGray, CompressedGray, CompressedGray, + CompressedWhite, CompressedWhite, CompressedWhite, CompressedWhite, + }; + + [Test] + public void CopyFromNonReadableSRgbPng() + { + var nonReadableTex = AssetDatabase.LoadAssetAtPath($"{AssetPath}/4x4.png"); + Assert.False(nonReadableTex.isReadable); + var copiedTex = TextureConverter.CopyTexture(nonReadableTex, ColorSpace.sRGB, null); + var pixels = copiedTex.GetPixels32(miplevel: 0); + Assert.AreEqual(pixels.Length, PngTextureValues.Length); + for (var idx = 0; idx < pixels.Length; ++idx) + { + Assert.AreEqual(PngTextureValues[idx], pixels[idx]); + } + } + + [Test] + public void CopyFromNonReadableSRgbDds() + { + var compressedTex = AssetDatabase.LoadAssetAtPath($"{AssetPath}/4x4compressed.dds"); + Assert.False(compressedTex.isReadable); + var copiedTex = TextureConverter.CopyTexture(compressedTex, ColorSpace.sRGB, null); + var pixels = copiedTex.GetPixels32(miplevel: 0); + Assert.AreEqual(pixels.Length, DdsTextureValues.Length); + for (var idx = 0; idx < pixels.Length; ++idx) + { + Assert.AreEqual(DdsTextureValues[idx], pixels[idx]); + } + } + } +} \ No newline at end of file diff --git a/Assets/VRMShaders/GLTF/IO/Tests/CopyTextureTests.cs.meta b/Assets/VRMShaders/GLTF/IO/Tests/CopyTextureTests.cs.meta new file mode 100644 index 000000000..77c2e167c --- /dev/null +++ b/Assets/VRMShaders/GLTF/IO/Tests/CopyTextureTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3b001f23191141369d3482cfebfaae2f +timeCreated: 1620903873 \ No newline at end of file diff --git a/Assets/VRMShaders/GLTF/IO/Tests/TextureBytesTests.cs b/Assets/VRMShaders/GLTF/IO/Tests/TextureBytesTests.cs index 7f14db73d..e22afe166 100644 --- a/Assets/VRMShaders/GLTF/IO/Tests/TextureBytesTests.cs +++ b/Assets/VRMShaders/GLTF/IO/Tests/TextureBytesTests.cs @@ -1,6 +1,7 @@ using NUnit.Framework; using UnityEditor; using UnityEngine; +using ColorSpace = UniGLTF.ColorSpace; namespace VRMShaders { @@ -9,20 +10,20 @@ namespace VRMShaders static string AssetPath = "Assets/VRMShaders/GLTF/IO/Tests"; [Test] - public void NotReadable() + public void NonReadablePng() { - var readonlyTexture = AssetDatabase.LoadAssetAtPath($"{AssetPath}/4x4.png"); - Assert.False(readonlyTexture.isReadable); - var (bytes, mime) = AssetTextureUtil.GetTextureBytesWithMime(readonlyTexture); + var nonReadableTex = AssetDatabase.LoadAssetAtPath($"{AssetPath}/4x4.png"); + Assert.False(nonReadableTex.isReadable); + var (bytes, mime) = AssetTextureUtil.GetTextureBytesWithMime(nonReadableTex, ColorSpace.sRGB); Assert.NotNull(bytes); } [Test] - public void Compressed() + public void NonReadableDds() { var readonlyTexture = AssetDatabase.LoadAssetAtPath($"{AssetPath}/4x4compressed.dds"); Assert.False(readonlyTexture.isReadable); - var (bytes, mime) = AssetTextureUtil.GetTextureBytesWithMime(readonlyTexture); + var (bytes, mime) = AssetTextureUtil.GetTextureBytesWithMime(readonlyTexture, ColorSpace.sRGB); Assert.NotNull(bytes); } } From 257b5d71e218dd31c609c944251d02e1f0f11d13 Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Thu, 13 May 2021 21:24:26 +0900 Subject: [PATCH 7/7] Add comments. --- Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs index 8434e456e..566a0aecc 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs @@ -238,15 +238,16 @@ namespace VRMShaders } else { - // 単純に EncodeToPNG できないため、コピーしてから EncodeToPNG する。 + // Failed, because texture is compressed. + // ex. ".DDS" file, or Compression is enabled in Texture Import Settings. return CopyTextureAndGetBytesWithMime(texture, colorSpace); } } catch (ArgumentException ex) { - // fail to EncodeToPng // System.ArgumentException: not readable, the texture memory can not be accessed from scripts. You can make the texture readable in the Texture Import Settings. - // example, ".DDS" Texture object in Editor. + + // Failed, because texture is not readable. Debug.LogWarning(ex); // 単純に EncodeToPNG できないため、コピーしてから EncodeToPNG する。