diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/MaterialExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/MaterialExporter.cs index 44ad11029..d54d65d5f 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/MaterialExporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/MaterialExporter.cs @@ -15,12 +15,12 @@ namespace UniGLTF public interface IMaterialExporter { - glTFMaterial ExportMaterial(Material m, TextureExporter textureExporter); + glTFMaterial ExportMaterial(Material m, ITextureExporter textureExporter); } public class MaterialExporter : IMaterialExporter { - public virtual glTFMaterial ExportMaterial(Material m, TextureExporter textureExporter) + public virtual glTFMaterial ExportMaterial(Material m, ITextureExporter textureExporter) { var material = CreateMaterial(m); @@ -34,7 +34,7 @@ namespace UniGLTF return material; } - static void Export_Color(Material m, TextureExporter textureManager, glTFMaterial material) + static void Export_Color(Material m, ITextureExporter textureManager, glTFMaterial material) { if (m.HasProperty("_Color")) { @@ -43,7 +43,7 @@ namespace UniGLTF if (m.HasProperty("_MainTex")) { - var index = textureManager.ExportSRGB(m.GetTexture("_MainTex")); + var index = textureManager.ExportAsSRgb(m.GetTexture("_MainTex")); if (index != -1) { material.pbrMetallicRoughness.baseColorTexture = new glTFMaterialBaseColorTextureInfo() @@ -60,9 +60,9 @@ namespace UniGLTF /// Occlusion, Metallic, Roughness /// /// - /// + /// /// - static void Export_OcclusionMetallicRoughness(Material m, TextureExporter textureManager, glTFMaterial material) + static void Export_OcclusionMetallicRoughness(Material m, ITextureExporter textureExporter, glTFMaterial material) { Texture metallicSmoothTexture = default; float smoothness = 1.0f; @@ -88,7 +88,7 @@ namespace UniGLTF } } - int index = textureManager.ExportMetallicSmoothnessOcclusion(metallicSmoothTexture, smoothness, occlusionTexture); + int index = textureExporter.ExportAsGltfMetallicSmoothnessOcclusionCombined(metallicSmoothTexture, smoothness, occlusionTexture); if (index != -1 && metallicSmoothTexture != null) { @@ -127,11 +127,11 @@ namespace UniGLTF } } - static void Export_Normal(Material m, TextureExporter textureManager, glTFMaterial material) + static void Export_Normal(Material m, ITextureExporter textureExporter, glTFMaterial material) { if (m.HasProperty("_BumpMap")) { - var index = textureManager.ExportNormal(m.GetTexture("_BumpMap")); + var index = textureExporter.ExportAsNormal(m.GetTexture("_BumpMap")); if (index != -1) { material.normalTexture = new glTFMaterialNormalTextureInfo() @@ -149,7 +149,7 @@ namespace UniGLTF } } - static void Export_Emission(Material m, TextureExporter textureManager, glTFMaterial material) + static void Export_Emission(Material m, ITextureExporter textureExporter, glTFMaterial material) { if (m.IsKeywordEnabled("_EMISSION") == false) return; @@ -166,7 +166,7 @@ namespace UniGLTF if (m.HasProperty("_EmissionMap")) { - var index = textureManager.ExportSRGB(m.GetTexture("_EmissionMap")); + var index = textureExporter.ExportAsSRgb(m.GetTexture("_EmissionMap")); 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 e6dc21271..3fabfb438 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs @@ -43,7 +43,11 @@ namespace UniGLTF private set; } - public TextureExporter TextureManager; + public TextureExporter TextureExporter + { + get; + private set; + } protected virtual IMaterialExporter CreateMaterialExporter() { @@ -238,10 +242,10 @@ namespace UniGLTF #region Materials and Textures Materials = uniqueUnityMeshes.SelectMany(x => x.Renderer.sharedMaterials).Where(x => x != null).Distinct().ToList(); - TextureManager = new TextureExporter(textureSerializer); + TextureExporter = new TextureExporter(textureSerializer); var materialExporter = CreateMaterialExporter(); - glTF.materials = Materials.Select(x => materialExporter.ExportMaterial(x, TextureManager)).ToList(); + glTF.materials = Materials.Select(x => materialExporter.ExportMaterial(x, TextureExporter)).ToList(); #endregion #region Meshes @@ -360,9 +364,9 @@ namespace UniGLTF ExportExtensions(textureSerializer); // Extension で Texture が増える場合があるので最後に呼ぶ - for (int i = 0; i < TextureManager.Exported.Count; ++i) + for (int i = 0; i < TextureExporter.Exported.Count; ++i) { - var (unityTexture, colorSpace) = TextureManager.Exported[i]; + var (unityTexture, colorSpace) = TextureExporter.Exported[i]; glTF.PushGltfTexture(bufferIndex, unityTexture, colorSpace, textureSerializer); } } diff --git a/Assets/UniGLTF/Tests/UniGLTF/MaterialTests.cs b/Assets/UniGLTF/Tests/UniGLTF/MaterialTests.cs index 67f11aa27..88d0e8508 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/MaterialTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/MaterialTests.cs @@ -18,7 +18,7 @@ namespace UniGLTF filterMode = FilterMode.Bilinear, }; - var textureManager = new TextureExporter(new EditorTextureSerializer()); + var textureExporter = new TextureExporter(new EditorTextureSerializer()); var srcMaterial = new Material(Shader.Find("Standard")); var offset = new Vector2(0.3f, 0.2f); @@ -29,7 +29,7 @@ namespace UniGLTF srcMaterial.mainTextureScale = scale; var materialExporter = new MaterialExporter(); - var gltfMaterial = materialExporter.ExportMaterial(srcMaterial, textureManager); + var gltfMaterial = materialExporter.ExportMaterial(srcMaterial, textureExporter); gltfMaterial.pbrMetallicRoughness.baseColorTexture.extensions = gltfMaterial.pbrMetallicRoughness.baseColorTexture.extensions.Deserialize(); Assert.IsTrue(glTF_KHR_texture_transform.TryGet(gltfMaterial.pbrMetallicRoughness.baseColorTexture, out glTF_KHR_texture_transform t)); @@ -242,8 +242,8 @@ namespace UniGLTF material.SetColor("_EmissionColor", new Color(0, 1, 2, 1)); material.EnableKeyword("_EMISSION"); var materialExporter = new MaterialExporter(); - var textureExportManager = new TextureExporter(new EditorTextureSerializer()); - var gltfMaterial = materialExporter.ExportMaterial(material, textureExportManager); + var textureExporter = new TextureExporter(new EditorTextureSerializer()); + var gltfMaterial = materialExporter.ExportMaterial(material, textureExporter); Assert.AreEqual(gltfMaterial.emissiveFactor, new float[] { 0, 0.5f, 1 }); } diff --git a/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs b/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs index f8dfb46ed..f18c6704d 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs @@ -18,15 +18,15 @@ namespace UniGLTF wrapMode = TextureWrapMode.Clamp, filterMode = FilterMode.Trilinear, }; - var textureManager = new TextureExporter(new EditorTextureSerializer()); + var textureExporter = new TextureExporter(new EditorTextureSerializer()); var material = new Material(Shader.Find("Standard")); material.mainTexture = tex0; var materialExporter = new MaterialExporter(); - materialExporter.ExportMaterial(material, textureManager); + materialExporter.ExportMaterial(material, textureExporter); - var (convTex0, colorSpace) = textureManager.Exported[0]; + var (convTex0, colorSpace) = textureExporter.Exported[0]; var sampler = TextureSamplerUtil.Export(convTex0); Assert.AreEqual(glWrap.CLAMP_TO_EDGE, sampler.wrapS); diff --git a/Assets/VRM.Samples/Editor/Tests/VRMMaterialTests.cs b/Assets/VRM.Samples/Editor/Tests/VRMMaterialTests.cs index 3dc99c542..bfa2ee0b7 100644 --- a/Assets/VRM.Samples/Editor/Tests/VRMMaterialTests.cs +++ b/Assets/VRM.Samples/Editor/Tests/VRMMaterialTests.cs @@ -11,8 +11,8 @@ namespace VRM.Samples { var material = Resources.Load(resourceName); var exporter = new VRMMaterialExporter(); - var textureManager = new TextureExporter(new EditorTextureSerializer()); - var exported = exporter.ExportMaterial(material, textureManager); + var textureExporter = new TextureExporter(new EditorTextureSerializer()); + var exported = exporter.ExportMaterial(material, textureExporter); // parse glTFExtensionExport to glTFExtensionImport exported.extensions = exported.extensions.Deserialize(); diff --git a/Assets/VRM/Runtime/IO/VRMExporter.cs b/Assets/VRM/Runtime/IO/VRMExporter.cs index 3089ee051..2b1e05359 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 = TextureManager.ExportSRGB(meta.Thumbnail); + VRM.meta.texture = TextureExporter.ExportAsSRgb(meta.Thumbnail); } // ussage permission @@ -199,7 +199,7 @@ namespace VRM // materials foreach (var m in Materials) { - VRM.materialProperties.Add(VRMMaterialExporter.CreateFromMaterial(m, TextureManager)); + VRM.materialProperties.Add(VRMMaterialExporter.CreateFromMaterial(m, TextureExporter)); } // Serialize VRM diff --git a/Assets/VRM/Runtime/IO/VRMMaterialExporter.cs b/Assets/VRM/Runtime/IO/VRMMaterialExporter.cs index 7b65783d2..75a52b895 100644 --- a/Assets/VRM/Runtime/IO/VRMMaterialExporter.cs +++ b/Assets/VRM/Runtime/IO/VRMMaterialExporter.cs @@ -126,7 +126,7 @@ namespace VRM // "Queue", }; - public static glTF_VRM_Material CreateFromMaterial(Material m, TextureExporter textureExporter) + public static glTF_VRM_Material CreateFromMaterial(Material m, ITextureExporter textureExporter) { var material = new glTF_VRM_Material { @@ -181,8 +181,8 @@ namespace VRM if (texture != null) { var value = kv.Key == "_BumpMap" - ? textureExporter.ExportNormal(texture) - : textureExporter.ExportSRGB(texture) + ? textureExporter.ExportAsNormal(texture) + : textureExporter.ExportAsSRgb(texture) ; if (value == -1) { diff --git a/Assets/VRM/Tests/MToonTest.cs b/Assets/VRM/Tests/MToonTest.cs index 73686c489..c0f52b0e3 100644 --- a/Assets/VRM/Tests/MToonTest.cs +++ b/Assets/VRM/Tests/MToonTest.cs @@ -18,7 +18,7 @@ namespace VRM filterMode = FilterMode.Bilinear, }; - var textureManager = new TextureExporter(new EditorTextureSerializer()); + var textureExporter = new TextureExporter(new EditorTextureSerializer()); var srcMaterial = new Material(Shader.Find("VRM/MToon")); var offset = new Vector2(0.3f, 0.2f); @@ -29,7 +29,7 @@ namespace VRM srcMaterial.mainTextureScale = scale; var materialExporter = new VRMMaterialExporter(); - var vrmMaterial = VRMMaterialExporter.CreateFromMaterial(srcMaterial, textureManager); + var vrmMaterial = VRMMaterialExporter.CreateFromMaterial(srcMaterial, textureExporter); Assert.AreEqual(vrmMaterial.vectorProperties["_MainTex"], new float[] { 0.3f, 0.2f, 0.5f, 0.6f }); var materialImporter = new VRMMaterialImporter(new glTF_VRM_extensions diff --git a/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialExporter.cs b/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialExporter.cs index f4fb55ac4..5c1d8e5f7 100644 --- a/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialExporter.cs +++ b/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialExporter.cs @@ -12,7 +12,7 @@ namespace UniVRM10 { public static class Vrm10MToonMaterialExporter { - public static bool TryExportMaterialAsMToon(Material src, TextureExporter textureExporter, out glTFMaterial dst) + public static bool TryExportMaterialAsMToon(Material src, ITextureExporter textureExporter, out glTFMaterial dst) { try { @@ -41,13 +41,13 @@ namespace UniVRM10 baseColorFactor = def.Color.LitColor.ToFloat4(ColorSpace.sRGB, ColorSpace.Linear), baseColorTexture = new glTFMaterialBaseColorTextureInfo { - index = textureExporter.ExportSRGB(def.Color.LitMultiplyTexture), + index = textureExporter.ExportAsSRgb(def.Color.LitMultiplyTexture), }, }, normalTexture = new glTFMaterialNormalTextureInfo { - index = textureExporter.ExportNormal(def.Lighting.Normal.NormalTexture), + index = textureExporter.ExportAsNormal(def.Lighting.Normal.NormalTexture), scale = def.Lighting.Normal.NormalScaleValue, }, @@ -55,7 +55,7 @@ namespace UniVRM10 emissiveFactor = def.Emission.EmissionColor.ToFloat3(ColorSpace.Linear, ColorSpace.Linear), emissiveTexture = new glTFMaterialEmissiveTextureInfo { - index = textureExporter.ExportSRGB(def.Emission.EmissionMultiplyTexture), + index = textureExporter.ExportAsSRgb(def.Emission.EmissionMultiplyTexture), }, }; @@ -75,7 +75,7 @@ namespace UniVRM10 ShadeColorFactor = def.Color.ShadeColor.ToFloat3(ColorSpace.sRGB, ColorSpace.Linear), ShadeMultiplyTexture = new TextureInfo { - Index = textureExporter.ExportSRGB(def.Color.ShadeMultiplyTexture), + Index = textureExporter.ExportAsSRgb(def.Color.ShadeMultiplyTexture), }, ShadingToonyFactor = def.Lighting.LitAndShadeMixing.ShadingToonyValue, ShadingShiftFactor = def.Lighting.LitAndShadeMixing.ShadingShiftValue, @@ -87,14 +87,14 @@ namespace UniVRM10 // Rim Lighting MatcapTexture = new TextureInfo { - Index = textureExporter.ExportSRGB(def.MatCap.AdditiveTexture), + Index = textureExporter.ExportAsSRgb(def.MatCap.AdditiveTexture), }, ParametricRimColorFactor = def.Rim.RimColor.ToFloat3(ColorSpace.Linear, ColorSpace.Linear), ParametricRimFresnelPowerFactor = def.Rim.RimFresnelPowerValue, ParametricRimLiftFactor = def.Rim.RimLiftValue, RimMultiplyTexture = new TextureInfo { - Index = textureExporter.ExportSRGB(def.Rim.RimMultiplyTexture), + Index = textureExporter.ExportAsSRgb(def.Rim.RimMultiplyTexture), }, RimLightingMixFactor = def.Rim.RimLightingMixValue, @@ -103,7 +103,7 @@ namespace UniVRM10 OutlineWidthFactor = def.Outline.OutlineWidthValue * centimeterToMeter, OutlineWidthMultiplyTexture = new TextureInfo { - Index = textureExporter.ExportLinear(def.Outline.OutlineWidthMultiplyTexture), + Index = textureExporter.ExportAsLinear(def.Outline.OutlineWidthMultiplyTexture), }, OutlineColorFactor = def.Outline.OutlineColor.ToFloat3(ColorSpace.sRGB, ColorSpace.Linear), OutlineLightingMixFactor = ExportOutlineLightingMixFactor(def.Outline.OutlineColorMode, def.Outline.OutlineLightingMixValue), @@ -111,7 +111,7 @@ namespace UniVRM10 // UV Anim UvAnimationMaskTexture = new TextureInfo { - Index = textureExporter.ExportLinear(def.TextureOption.UvAnimationMaskTexture), + Index = textureExporter.ExportAsLinear(def.TextureOption.UvAnimationMaskTexture), }, UvAnimationScrollXSpeedFactor = def.TextureOption.UvAnimationScrollXSpeedValue, UvAnimationScrollYSpeedFactor = def.TextureOption.UvAnimationScrollYSpeedValue * invertY, diff --git a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs index 5b68808bd..15339fd4a 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs @@ -651,7 +651,7 @@ namespace UniVRM10 int? thumbnailTextureIndex = default; if (meta.Thumbnail != null) { - thumbnailTextureIndex = m_textureExporter.ExportSRGB(meta.Thumbnail); + thumbnailTextureIndex = m_textureExporter.ExportAsSRgb(meta.Thumbnail); } return thumbnailTextureIndex; } diff --git a/Assets/VRM10/Runtime/IO/Vrm10MaterialExporter.cs b/Assets/VRM10/Runtime/IO/Vrm10MaterialExporter.cs index 8be4a96a4..5dccd34e5 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10MaterialExporter.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10MaterialExporter.cs @@ -6,7 +6,7 @@ namespace UniVRM10 { public class Vrm10MaterialExporter : MaterialExporter { - public override glTFMaterial ExportMaterial(Material m, TextureExporter textureExporter) + public override glTFMaterial ExportMaterial(Material m, ITextureExporter textureExporter) { if (Vrm10MToonMaterialExporter.TryExportMaterialAsMToon(m, textureExporter, out var dst)) { diff --git a/Assets/VRMShaders/GLTF/IO/Editor/EditorTextureSerializer.cs b/Assets/VRMShaders/GLTF/IO/Editor/EditorTextureSerializer.cs index f4315ce81..0314c451c 100644 --- a/Assets/VRMShaders/GLTF/IO/Editor/EditorTextureSerializer.cs +++ b/Assets/VRMShaders/GLTF/IO/Editor/EditorTextureSerializer.cs @@ -44,7 +44,7 @@ namespace VRMShaders public (byte[] bytes, string mime) ExportBytesWithMime(Texture2D texture, ColorSpace textureColorSpace) { - if (TryGetBytesWithMime(texture, out byte[] bytes, out string mime)) + if (CanExportAsEditorAssetFile(texture) && TryGetBytesWithMime(texture, out byte[] bytes, out string mime)) { return (bytes, mime); } diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/ITextureExporter.cs b/Assets/VRMShaders/GLTF/IO/Runtime/ITextureExporter.cs new file mode 100644 index 000000000..7efda4b77 --- /dev/null +++ b/Assets/VRMShaders/GLTF/IO/Runtime/ITextureExporter.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace VRMShaders +{ + /// + /// Texture を用途別に変換の要不要を判断して gltf.textures の index に対応させる機能。 + /// + /// glTF 拡張で Texture の用途を増やす必要がある場合は、この interface を継承して実装すればよい。 + /// + public interface ITextureExporter + { + /// + /// Export する Texture2D のリスト。これが gltf.textures になる + /// + IReadOnlyList<(Texture2D, UniGLTF.ColorSpace)> Exported { get; } + + /// + /// 指定の Texture を、 sRGB 色空間の値を持つ Texture に出力するように指示する。 + /// + int ExportAsSRgb(Texture src); + + /// + /// 指定の Texture を、 Linear の値を持つ Texture に出力するように指示する。 + /// + int ExportAsLinear(Texture src); + + /// + /// 指定の Metallic, Roughness, Occlusion 情報を、 glTF 仕様に準拠した 1 枚の合成テクスチャとして出力するように指示する。 + /// + int ExportAsGltfMetallicSmoothnessOcclusionCombined(Texture metallicSmoothTexture, float smoothness, Texture occlusionTexture); + + /// + /// 指定の Texture を、glTF 仕様に準拠した Normal Texture に出力するように指示する。 + /// + int ExportAsNormal(Texture src); + } +} diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/ITextureExporter.cs.meta b/Assets/VRMShaders/GLTF/IO/Runtime/ITextureExporter.cs.meta new file mode 100644 index 000000000..e498daf62 --- /dev/null +++ b/Assets/VRMShaders/GLTF/IO/Runtime/ITextureExporter.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4e22c9906e3e42038724e1bcf46450bf +timeCreated: 1621507967 \ No newline at end of file diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/ITextureSerializer.cs b/Assets/VRMShaders/GLTF/IO/Runtime/ITextureSerializer.cs index 5d748c65d..ac26d6c74 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/ITextureSerializer.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/ITextureSerializer.cs @@ -2,17 +2,20 @@ namespace UniGLTF { + /// + /// Texture2D を入力として byte[] を得る機能 + /// public interface ITextureSerializer { /// - /// Texture をファイルのバイト列そのまま出力してよいかどうか判断するデリゲート。 + /// Texture をファイルのバイト列そのまま出力してよいかどうか判断する。 /// /// Runtime 出力では常に false が望ましい。 /// bool CanExportAsEditorAssetFile(Texture texture); /// - /// Texture2D から実際のバイト列を取得するデリゲート。 + /// Texture2D から実際のバイト列を取得する。 /// /// textureColorSpace はその Texture2D がアサインされる glTF プロパティの仕様が定める色空間を指定する。 /// 具体的には Texture2D をコピーする際に、コピー先の Texture2D の色空間を決定するために使用する。 diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/NormalConverter.cs b/Assets/VRMShaders/GLTF/IO/Runtime/NormalConverter.cs index 4a08f3d42..6dad706b1 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/NormalConverter.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/NormalConverter.cs @@ -1,4 +1,5 @@ using UnityEngine; +using ColorSpace = UniGLTF.ColorSpace; namespace VRMShaders @@ -35,14 +36,14 @@ namespace VRMShaders // ConvertToNormalValueFromRawColorWhenCompressionIsRequired public static Texture2D Import(Texture2D texture) { - return TextureConverter.Convert(texture, TextureImportTypes.NormalMap, null, Encoder); + return TextureConverter.Convert(texture, ColorSpace.Linear, null, Encoder); } // Unity texture to GLTF data // ConvertToRawColorWhenNormalValueIsCompressed public static Texture2D Export(Texture texture) { - return TextureConverter.Convert(texture, TextureImportTypes.NormalMap, null, Decoder); + return TextureConverter.Convert(texture, ColorSpace.Linear, null, Decoder); } } } diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/OcclusionMetallicRoughnessConverter.cs b/Assets/VRMShaders/GLTF/IO/Runtime/OcclusionMetallicRoughnessConverter.cs index 787eba8f2..20483665c 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/OcclusionMetallicRoughnessConverter.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/OcclusionMetallicRoughnessConverter.cs @@ -1,24 +1,25 @@ using System; using System.Linq; using UnityEngine; +using ColorSpace = UniGLTF.ColorSpace; namespace VRMShaders { /// - /// - /// * https://github.com/vrm-c/UniVRM/issues/781 - /// + /// + /// * https://github.com/vrm-c/UniVRM/issues/781 + /// /// Unity = glTF /// Occlusion: unity.g = glTF.r /// Roughness: unity.a = 1 - glTF.g * roughnessFactor /// Metallic : unity.r = glTF.b * metallicFactor - /// + /// /// glTF = Unity /// Occlusion: glTF.r = unity.g /// Roughness: glTF.g = 1 - unity.a * smoothness /// Metallic : glTF.b = unity.r - /// + /// /// public static class OcclusionMetallicRoughnessConverter { @@ -29,7 +30,7 @@ namespace VRMShaders { if (metallicRoughnessTexture == occlusionTexture) { - var copyMetallicRoughness = TextureConverter.CopyTexture(metallicRoughnessTexture, TextureImportTypes.StandardMap, null); + var copyMetallicRoughness = TextureConverter.CopyTexture(metallicRoughnessTexture, ColorSpace.Linear, null); var metallicRoughnessPixels = copyMetallicRoughness.GetPixels32(); for (int i = 0; i < metallicRoughnessPixels.Length; ++i) { @@ -42,9 +43,9 @@ namespace VRMShaders } else { - var copyMetallicRoughness = TextureConverter.CopyTexture(metallicRoughnessTexture, TextureImportTypes.StandardMap, null); + var copyMetallicRoughness = TextureConverter.CopyTexture(metallicRoughnessTexture, ColorSpace.Linear, null); var metallicRoughnessPixels = copyMetallicRoughness.GetPixels32(); - var copyOcclusion = TextureConverter.CopyTexture(occlusionTexture, TextureImportTypes.StandardMap, null); + var copyOcclusion = TextureConverter.CopyTexture(occlusionTexture, ColorSpace.Linear, null); var occlusionPixels = copyOcclusion.GetPixels32(); if (metallicRoughnessPixels.Length != occlusionPixels.Length) { @@ -62,7 +63,7 @@ namespace VRMShaders } else if (metallicRoughnessTexture != null) { - var copyTexture = TextureConverter.CopyTexture(metallicRoughnessTexture, TextureImportTypes.StandardMap, null); + var copyTexture = TextureConverter.CopyTexture(metallicRoughnessTexture, ColorSpace.Linear, null); copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => ImportPixel(x, metallicFactor, roughnessFactor, default)).ToArray()); copyTexture.Apply(); copyTexture.name = metallicRoughnessTexture.name; @@ -70,7 +71,7 @@ namespace VRMShaders } else if (occlusionTexture != null) { - var copyTexture = TextureConverter.CopyTexture(occlusionTexture, TextureImportTypes.StandardMap, null); + var copyTexture = TextureConverter.CopyTexture(occlusionTexture, ColorSpace.Linear, null); copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => ImportPixel(default, metallicFactor, roughnessFactor, x)).ToArray()); copyTexture.Apply(); copyTexture.name = occlusionTexture.name; @@ -88,7 +89,7 @@ namespace VRMShaders { r = (byte)(metallicRoughness.b * metallicFactor), // Metallic g = occlusion.r, // Occlusion - b = 0, // not used + b = 0, // not used a = (byte)(255 - metallicRoughness.g * roughnessFactor), // Roughness to Smoothness }; @@ -101,7 +102,7 @@ namespace VRMShaders { if (metallicSmoothTexture == occlusionTexture) { - var copyTexture = TextureConverter.CopyTexture(metallicSmoothTexture, TextureImportTypes.StandardMap, null); + var copyTexture = TextureConverter.CopyTexture(metallicSmoothTexture, ColorSpace.Linear, null); copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => ExportPixel(x, smoothness, x)).ToArray()); copyTexture.Apply(); copyTexture.name = metallicSmoothTexture.name; @@ -109,9 +110,9 @@ namespace VRMShaders } else { - var copyMetallicSmooth = TextureConverter.CopyTexture(metallicSmoothTexture, TextureImportTypes.StandardMap, null); + var copyMetallicSmooth = TextureConverter.CopyTexture(metallicSmoothTexture, ColorSpace.Linear, null); var metallicSmoothPixels = copyMetallicSmooth.GetPixels32(); - var copyOcclusion = TextureConverter.CopyTexture(occlusionTexture, TextureImportTypes.StandardMap, null); + var copyOcclusion = TextureConverter.CopyTexture(occlusionTexture, ColorSpace.Linear, null); var occlusionPixels = copyOcclusion.GetPixels32(); if (metallicSmoothPixels.Length != occlusionPixels.Length) { @@ -129,7 +130,7 @@ namespace VRMShaders } else if (metallicSmoothTexture) { - var copyTexture = TextureConverter.CopyTexture(metallicSmoothTexture, TextureImportTypes.StandardMap, null); + var copyTexture = TextureConverter.CopyTexture(metallicSmoothTexture, ColorSpace.Linear, null); copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => ExportPixel(x, smoothness, default)).ToArray()); copyTexture.Apply(); copyTexture.name = metallicSmoothTexture.name; @@ -137,7 +138,7 @@ namespace VRMShaders } else if (occlusionTexture) { - var copyTexture = TextureConverter.CopyTexture(occlusionTexture, TextureImportTypes.StandardMap, null); + var copyTexture = TextureConverter.CopyTexture(occlusionTexture, ColorSpace.Linear, null); copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => ExportPixel(default, smoothness, x)).ToArray()); copyTexture.Apply(); copyTexture.name = occlusionTexture.name; @@ -153,7 +154,7 @@ namespace VRMShaders { var dst = new Color32 { - r = occlusion.g, // Occlusion + r = occlusion.g, // Occlusion g = (byte)(255 - metallicSmooth.a * smoothness), // Roughness from Smoothness b = metallicSmooth.r, // Metallic a = 255, // not used diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/TextureConverter.cs b/Assets/VRMShaders/GLTF/IO/Runtime/TextureConverter.cs index 67d0eb6f0..1e958d16e 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/TextureConverter.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/TextureConverter.cs @@ -10,9 +10,9 @@ namespace VRMShaders { public delegate Color32 ColorConversion(Color32 color); - public static Texture2D Convert(Texture texture, TextureImportTypes textureType, ColorConversion colorConversion, Material convertMaterial) + public static Texture2D Convert(Texture texture, ColorSpace dstColorSpace, ColorConversion colorConversion, Material convertMaterial) { - var copyTexture = CopyTexture(texture, textureType, convertMaterial); + var copyTexture = CopyTexture(texture, dstColorSpace, convertMaterial); if (colorConversion != null) { copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => colorConversion(x)).ToArray()); @@ -22,16 +22,11 @@ namespace VRMShaders return copyTexture; } - 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) + public static Texture2D CopyTexture(Texture src, ColorSpace dstColorSpace, Material material) { Texture2D dst = null; RenderTextureReadWrite readWrite; - switch (colorSpace) + switch (dstColorSpace) { case ColorSpace.sRGB: readWrite = RenderTextureReadWrite.sRGB; @@ -40,7 +35,7 @@ namespace VRMShaders readWrite = RenderTextureReadWrite.Linear; break; default: - throw new ArgumentOutOfRangeException(nameof(colorSpace), colorSpace, null); + throw new ArgumentOutOfRangeException(nameof(dstColorSpace), dstColorSpace, null); } var renderTexture = new RenderTexture(src.width, src.height, 0, RenderTextureFormat.ARGB32, readWrite); @@ -78,4 +73,4 @@ namespace VRMShaders return dst; } } -} \ 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 d52cdd574..5688362c4 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/TextureExporter.cs @@ -11,9 +11,13 @@ namespace VRMShaders /// glTF にエクスポートする Texture2D を蓄えて index を確定させる。 /// Exporter の最後でまとめて Texture2D から bytes 列を得て出力する。 /// - public class TextureExporter : IDisposable + public sealed class TextureExporter : IDisposable, ITextureExporter { - private ITextureSerializer m_textureSerializer; + 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; public TextureExporter(ITextureSerializer textureSerializer) { @@ -25,22 +29,24 @@ namespace VRMShaders // TODO: export 用にコピー・変換したテクスチャーをここで解放したい } - public enum ConvertTypes + enum ExportTypes { - // 無変換 - None, + // sRGB テクスチャとして出力 + Srgb, + // Linear テクスチャとして出力 + Linear, // Unity Standard様式 から glTF PBR様式への変換 OcclusionMetallicRoughness, // Assetを使うときはそのバイト列を無変換で、それ以外は DXT5nm 形式からのデコードを行う Normal, } - struct ExportKey + readonly struct ExportKey { public readonly Texture Src; - public readonly ConvertTypes TextureType; + public readonly ExportTypes TextureType; - public ExportKey(Texture src, ConvertTypes type) + public ExportKey(Texture src, ExportTypes type) { if (src == null) { @@ -50,36 +56,13 @@ namespace VRMShaders TextureType = type; } } - Dictionary m_exportMap = new Dictionary(); - - /// - /// Export する Texture2D のリスト。これが gltf.textures になる - /// - /// - /// - public readonly List<(Texture2D, ColorSpace)> Exported = new List<(Texture2D, ColorSpace)>(); - - /// - /// Texture の export index を得る - /// - /// - /// - /// - public int GetTextureIndex(Texture src, ConvertTypes textureType) - { - if (src == null) - { - return -1; - } - return m_exportMap[new ExportKey(src, textureType)]; - } /// /// sRGBなテクスチャーを処理し、index を確定させる /// /// /// - public int ExportSRGB(Texture src) + public int ExportAsSRgb(Texture src) { if (src == null) { @@ -87,13 +70,13 @@ namespace VRMShaders } // cache - if (m_exportMap.TryGetValue(new ExportKey(src, ConvertTypes.None), out var index)) + if (m_exportMap.TryGetValue(new ExportKey(src, ExportTypes.Srgb), out var index)) { return index; } // get Texture2D - index = Exported.Count; + index = m_exported.Count; var texture2D = src as Texture2D; if (m_textureSerializer.CanExportAsEditorAssetFile(texture2D)) { @@ -101,10 +84,10 @@ namespace VRMShaders } else { - texture2D = TextureConverter.CopyTexture(src, TextureImportTypes.sRGB, null); + texture2D = TextureConverter.CopyTexture(src, ColorSpace.sRGB, null); } - Exported.Add((texture2D, ColorSpace.sRGB)); - m_exportMap.Add(new ExportKey(src, ConvertTypes.None), index); + m_exported.Add((texture2D, ColorSpace.sRGB)); + m_exportMap.Add(new ExportKey(src, ExportTypes.Srgb), index); return index; } @@ -114,14 +97,14 @@ namespace VRMShaders /// /// /// - public int ExportLinear(Texture src) + public int ExportAsLinear(Texture src) { if (src == null) { return -1; } - var exportKey = new ExportKey(src, ConvertTypes.None); + var exportKey = new ExportKey(src, ExportTypes.Linear); // search cache if (m_exportMap.TryGetValue(exportKey, out var index)) @@ -129,7 +112,7 @@ namespace VRMShaders return index; } - index = Exported.Count; + index = m_exported.Count; var texture2d = src as Texture2D; if (m_textureSerializer.CanExportAsEditorAssetFile(texture2d)) { @@ -137,9 +120,9 @@ namespace VRMShaders } else { - texture2d = TextureConverter.CopyTexture(src, TextureImportTypes.Linear, null); + texture2d = TextureConverter.CopyTexture(src, ColorSpace.Linear, null); } - Exported.Add((texture2d, ColorSpace.Linear)); + m_exported.Add((texture2d, ColorSpace.Linear)); m_exportMap.Add(exportKey, index); return index; @@ -152,7 +135,7 @@ namespace VRMShaders /// /// /// - public int ExportMetallicSmoothnessOcclusion(Texture metallicSmoothTexture, float smoothness, Texture occlusionTexture) + public int ExportAsGltfMetallicSmoothnessOcclusionCombined(Texture metallicSmoothTexture, float smoothness, Texture occlusionTexture) { if (metallicSmoothTexture == null && occlusionTexture == null) { @@ -160,11 +143,12 @@ namespace VRMShaders } // cache - if (metallicSmoothTexture != null && m_exportMap.TryGetValue(new ExportKey(metallicSmoothTexture, ConvertTypes.OcclusionMetallicRoughness), out var index)) + // 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, ConvertTypes.OcclusionMetallicRoughness), out index)) + if (occlusionTexture != null && m_exportMap.TryGetValue(new ExportKey(occlusionTexture, ExportTypes.OcclusionMetallicRoughness), out index)) { return index; } @@ -172,17 +156,17 @@ namespace VRMShaders // // Unity と glTF で互換性が無いので必ず変換が必用 // - index = Exported.Count; + index = m_exported.Count; var texture2D = OcclusionMetallicRoughnessConverter.Export(metallicSmoothTexture, smoothness, occlusionTexture); - Exported.Add((texture2D, ColorSpace.Linear)); + m_exported.Add((texture2D, ColorSpace.Linear)); if (metallicSmoothTexture != null) { - m_exportMap.Add(new ExportKey(metallicSmoothTexture, ConvertTypes.OcclusionMetallicRoughness), index); + m_exportMap.Add(new ExportKey(metallicSmoothTexture, ExportTypes.OcclusionMetallicRoughness), index); } if (occlusionTexture != null && occlusionTexture != metallicSmoothTexture) { - m_exportMap.Add(new ExportKey(occlusionTexture, ConvertTypes.OcclusionMetallicRoughness), index); + m_exportMap.Add(new ExportKey(occlusionTexture, ExportTypes.OcclusionMetallicRoughness), index); } return index; @@ -193,7 +177,7 @@ namespace VRMShaders /// /// /// - public int ExportNormal(Texture src) + public int ExportAsNormal(Texture src) { if (src == null) { @@ -201,13 +185,13 @@ namespace VRMShaders } // cache - if (m_exportMap.TryGetValue(new ExportKey(src, ConvertTypes.Normal), out var index)) + if (m_exportMap.TryGetValue(new ExportKey(src, ExportTypes.Normal), out var index)) { return index; } // get Texture2D - index = Exported.Count; + index = m_exported.Count; var texture2D = src as Texture2D; if (m_textureSerializer.CanExportAsEditorAssetFile(texture2D)) { @@ -219,8 +203,8 @@ namespace VRMShaders texture2D = NormalConverter.Export(src); } - Exported.Add((texture2D, ColorSpace.Linear)); - m_exportMap.Add(new ExportKey(src, ConvertTypes.Normal), index); + m_exported.Add((texture2D, ColorSpace.Linear)); + m_exportMap.Add(new ExportKey(src, ExportTypes.Normal), index); return index; } diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/TextureImportTypes.cs b/Assets/VRMShaders/GLTF/IO/Runtime/TextureImportTypes.cs index c47f14a51..d4d1d3c3e 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/TextureImportTypes.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/TextureImportTypes.cs @@ -29,22 +29,4 @@ namespace VRMShaders // TextureImporter.sRGBTexture = false; Linear, } - - public static class TextureImportTypesExtensions - { - public static ColorSpace GetColorSpace(this TextureImportTypes textureType) - { - switch (textureType) - { - case TextureImportTypes.sRGB: - return ColorSpace.sRGB; - case TextureImportTypes.Linear: - case TextureImportTypes.StandardMap: - case TextureImportTypes.NormalMap: - return ColorSpace.Linear; - default: - throw new NotImplementedException(); - } - } - } } diff --git a/Assets/VRMShaders/GLTF/IO/Tests/MetallicRoughnessConverterTests.cs b/Assets/VRMShaders/GLTF/IO/Tests/MetallicRoughnessConverterTests.cs index 20164dc63..ef9fc566e 100644 --- a/Assets/VRMShaders/GLTF/IO/Tests/MetallicRoughnessConverterTests.cs +++ b/Assets/VRMShaders/GLTF/IO/Tests/MetallicRoughnessConverterTests.cs @@ -99,18 +99,18 @@ namespace VRMShaders { var exporter = new TextureExporter(new EditorTextureSerializer()); - Assert.AreEqual(-1, exporter.ExportMetallicSmoothnessOcclusion(null, 0, null)); + Assert.AreEqual(-1, exporter.ExportAsGltfMetallicSmoothnessOcclusionCombined(null, 0, null)); } { var exporter = new TextureExporter(new EditorTextureSerializer()); - Assert.AreEqual(0, exporter.ExportMetallicSmoothnessOcclusion(null, 0, occlusion)); - Assert.AreEqual(1, exporter.ExportMetallicSmoothnessOcclusion(metallic, 0, null)); + Assert.AreEqual(0, exporter.ExportAsGltfMetallicSmoothnessOcclusionCombined(null, 0, occlusion)); + Assert.AreEqual(1, exporter.ExportAsGltfMetallicSmoothnessOcclusionCombined(metallic, 0, null)); } { var exporter = new TextureExporter(new EditorTextureSerializer()); - Assert.AreEqual(0, exporter.ExportMetallicSmoothnessOcclusion(metallic, 0, occlusion)); - Assert.AreEqual(0, exporter.ExportMetallicSmoothnessOcclusion(null, 0, occlusion)); - Assert.AreEqual(0, exporter.ExportMetallicSmoothnessOcclusion(metallic, 0, null)); + Assert.AreEqual(0, exporter.ExportAsGltfMetallicSmoothnessOcclusionCombined(metallic, 0, occlusion)); + Assert.AreEqual(0, exporter.ExportAsGltfMetallicSmoothnessOcclusionCombined(null, 0, occlusion)); + Assert.AreEqual(0, exporter.ExportAsGltfMetallicSmoothnessOcclusionCombined(metallic, 0, null)); } } }