From 9fcd2abc580b6ca680a69a98c1e9aa20aac7105a Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Fri, 21 May 2021 20:51:13 +0900 Subject: [PATCH] Force copy texture if texture type was "Normal map". --- .../UniGLTF/EditorTextureSerializerTests.cs | 45 +++++++++++-------- .../GLTF/IO/Editor/EditorTextureSerializer.cs | 16 ++----- .../GLTF/IO/Runtime/TextureExporter.cs | 14 ++---- 3 files changed, 34 insertions(+), 41 deletions(-) diff --git a/Assets/UniGLTF/Tests/UniGLTF/EditorTextureSerializerTests.cs b/Assets/UniGLTF/Tests/UniGLTF/EditorTextureSerializerTests.cs index e763e74c9..4824ac31c 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/EditorTextureSerializerTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/EditorTextureSerializerTests.cs @@ -13,13 +13,16 @@ namespace UniGLTF private static readonly string AssetPath = "Assets/UniGLTF/Tests/UniGLTF"; private static readonly string SrgbGrayImageName = "4x4_gray_import_as_srgb"; private static readonly string LinearGrayImageName = "4x4_gray_import_as_linear"; + private static readonly string NormalMapGrayImageName = "4x4_gray_import_as_normal_map"; private static readonly Texture2D SrgbGrayTex = AssetDatabase.LoadAssetAtPath($"{AssetPath}/{SrgbGrayImageName}.png"); private static readonly Texture2D LinearGrayTex = AssetDatabase.LoadAssetAtPath($"{AssetPath}/{LinearGrayImageName}.png"); + private static readonly Texture2D NormalMapGrayTex = AssetDatabase.LoadAssetAtPath($"{AssetPath}/{NormalMapGrayImageName}.png"); private static readonly Color32 JustGray = new Color32(127, 127, 127, 255); private static readonly Color32 SrgbGrayInSrgb = JustGray; private static readonly Color32 SrgbGrayInLinear = ((Color) SrgbGrayInSrgb).linear; private static readonly Color32 LinearGrayInLinear = JustGray; private static readonly Color32 LinearGrayInSrgb = ((Color) LinearGrayInLinear).gamma; + private static readonly Color32 NormalizedLinearGrayInLinear = new Color32(127, 127, 255, 255); [Test] public void InputAssetsRawImage() @@ -77,31 +80,37 @@ namespace UniGLTF [Test] public void AssignSrgbImageToLinearTextureProperty() { - var exportedTex = AssignTextureToMaterialPropertyAndExportAndExtract(SrgbGrayTex, SrgbGrayImageName, "_BumpMap"); - Assert.AreEqual(SrgbGrayInLinear.r, GetFirstPixelInTexture2D(exportedTex).r); - Assert.AreEqual(SrgbGrayInLinear.g, GetFirstPixelInTexture2D(exportedTex).g); - // B channel is different. Because it will be normalized as normal vector. - UnityEngine.Object.DestroyImmediate(exportedTex); - - var exportedTex2 = AssignTextureToMaterialPropertyAndExportAndExtract(SrgbGrayTex, SrgbGrayImageName, "_OcclusionMap"); + var exportedTex = AssignTextureToMaterialPropertyAndExportAndExtract(SrgbGrayTex, SrgbGrayImageName, "_OcclusionMap"); // R channel is occlusion in glTF spec. - Assert.AreEqual(SrgbGrayInLinear.r, GetFirstPixelInTexture2D(exportedTex2).r); - UnityEngine.Object.DestroyImmediate(exportedTex2); + Assert.AreEqual(SrgbGrayInLinear.r, GetFirstPixelInTexture2D(exportedTex).r); + UnityEngine.Object.DestroyImmediate(exportedTex); } [Test] public void AssignLinearImageToLinearTextureProperty() { - var exportedTex = AssignTextureToMaterialPropertyAndExportAndExtract(LinearGrayTex, LinearGrayImageName, "_BumpMap"); - Assert.AreEqual(LinearGrayInLinear.r, GetFirstPixelInTexture2D(exportedTex).r); - Assert.AreEqual(LinearGrayInLinear.g, GetFirstPixelInTexture2D(exportedTex).g); - // B channel is different. Because it will be normalized as normal vector. - UnityEngine.Object.DestroyImmediate(exportedTex); - - var exportedTex2 = AssignTextureToMaterialPropertyAndExportAndExtract(LinearGrayTex, LinearGrayImageName, "_OcclusionMap"); + var exportedTex = AssignTextureToMaterialPropertyAndExportAndExtract(LinearGrayTex, LinearGrayImageName, "_OcclusionMap"); // R channel is occlusion in glTF spec. - Assert.AreEqual(LinearGrayInLinear.r, GetFirstPixelInTexture2D(exportedTex2).r); - UnityEngine.Object.DestroyImmediate(exportedTex2); + Assert.AreEqual(LinearGrayInLinear.r, GetFirstPixelInTexture2D(exportedTex).r); + UnityEngine.Object.DestroyImmediate(exportedTex); + } + + [Test] + public void AssignLinearImageToNormalTextureProperty() + { + var exportedTex = AssignTextureToMaterialPropertyAndExportAndExtract(LinearGrayTex, LinearGrayImageName, "_BumpMap"); + Assert.AreEqual(NormalizedLinearGrayInLinear, GetFirstPixelInTexture2D(exportedTex)); + // B channel is different from 127. Because it will be normalized as normal vector. + UnityEngine.Object.DestroyImmediate(exportedTex); + } + + [Test] + public void AssignLinearImageAsNormalMapSettingsToNormalTextureProperty() + { + var exportedTex = AssignTextureToMaterialPropertyAndExportAndExtract(NormalMapGrayTex, NormalMapGrayImageName, "_BumpMap"); + Assert.AreEqual(NormalizedLinearGrayInLinear, GetFirstPixelInTexture2D(exportedTex)); + // B channel is different from 127. Because it will be normalized as normal vector. + UnityEngine.Object.DestroyImmediate(exportedTex); } private static Texture2D AssignTextureToMaterialPropertyAndExportAndExtract(Texture2D srcTex, string srcImageName, string propertyName) diff --git a/Assets/VRMShaders/GLTF/IO/Editor/EditorTextureSerializer.cs b/Assets/VRMShaders/GLTF/IO/Editor/EditorTextureSerializer.cs index 88da013ea..ffcf7a0b7 100644 --- a/Assets/VRMShaders/GLTF/IO/Editor/EditorTextureSerializer.cs +++ b/Assets/VRMShaders/GLTF/IO/Editor/EditorTextureSerializer.cs @@ -19,6 +19,7 @@ namespace VRMShaders /// * TextureAsset が存在する /// * TextureImporter の maxSize が画像の縦横サイズ以上 /// * TextureImporter の色空間設定が exportColorSpace と一致する + /// * 各 Texture Type ごとの判定 /// /// Unity の Texture2D のデータは、その参照元であるテクスチャアセットファイルのデータと一致することはむしろ稀。 /// @@ -39,8 +40,9 @@ namespace VRMShaders case TextureImporterType.Default: break; case TextureImporterType.NormalMap: - if (!IsCorrectNormalMap(texture2D, textureImporter)) return false; - break; + // A texture has "Normal map" TextureType is ALWAYS converted into normalized normal pixel by Unity. + // So we must copy it. + return false; case TextureImporterType.GUI: case TextureImporterType.Sprite: case TextureImporterType.Cursor: @@ -162,15 +164,5 @@ namespace VRMShaders throw new ArgumentOutOfRangeException(nameof(colorSpace), colorSpace, null); } } - - private bool IsCorrectNormalMap(Texture2D texture, TextureImporter textureImporter) - { - if (textureImporter.textureType != TextureImporterType.NormalMap) return false; - - // Is Not generated from HeightMap ? - if (textureImporter.convertToNormalmap) return false; - - return true; - } } } diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs index 9b526536b..dd07e350d 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs @@ -168,18 +168,10 @@ namespace VRMShaders return index; } - // get Texture2D index = m_exported.Count; - var texture2D = src as Texture2D; - if (m_textureSerializer.CanExportAsEditorAssetFile(texture2D, ColorSpace.Linear)) - { - // EditorAsset を使うので変換不要 - } - else - { - // 後で Bitmap を使うために変換する - texture2D = NormalConverter.Export(src); - } + // 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);