From 59d84cb78b2c92f4da730ba2ca3e002d5ae8b2a4 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 12 Mar 2021 21:14:36 +0900 Subject: [PATCH] glTFTextureTypes, Export_PBR --- .../Editor/UniGLTF/AssetTextureLoader.cs | 8 +-- .../Runtime/UniGLTF/Format/glTFMaterial.cs | 27 ++----- .../Runtime/UniGLTF/IO/MaterialExporter.cs | 70 ++++++++++++++----- .../IO/TextureConverter/NormalConverter.cs | 2 +- .../OcclusionMetallicRoughnessConverter.cs | 4 +- .../IO/TextureConverter/TextureConverter.cs | 2 +- .../UniGLTF/IO/TextureExportManager.cs | 4 +- .../UniGLTF/Runtime/UniGLTF/IO/TextureIO.cs | 48 ++++++++----- .../IO/TextureLoader/GltfTextureLoader.cs | 10 ++- Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs | 6 +- Assets/VRM/Runtime/IO/VRMExporter.cs | 4 +- 11 files changed, 108 insertions(+), 77 deletions(-) diff --git a/Assets/UniGLTF/Editor/UniGLTF/AssetTextureLoader.cs b/Assets/UniGLTF/Editor/UniGLTF/AssetTextureLoader.cs index caf03659d..818307d5d 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/AssetTextureLoader.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/AssetTextureLoader.cs @@ -8,10 +8,7 @@ namespace UniGLTF public static Task LoadTaskAsync(UnityPath m_assetPath, glTF gltf, int textureIndex) { - var textureType = TextureIO.GetglTFTextureType(gltf, textureIndex); - var colorSpace = TextureIO.GetColorSpace(textureType); - var isLinear = colorSpace == RenderTextureReadWrite.Linear; - var sampler = gltf.GetSamplerFromTextureIndex(textureIndex); + var colorSpace = TextureIO.GetColorSpace(gltf, textureIndex); // // texture from assets @@ -25,7 +22,7 @@ namespace UniGLTF else { importer.maxTextureSize = 8192; - importer.sRGBTexture = !isLinear; + importer.sRGBTexture = colorSpace == RenderTextureReadWrite.sRGB; importer.SaveAndReimport(); } @@ -50,6 +47,7 @@ namespace UniGLTF importer.SaveAndReimport(); } + var sampler = gltf.GetSamplerFromTextureIndex(textureIndex); if (sampler != null) { TextureSamplerUtil.SetSampler(Texture, sampler); diff --git a/Assets/UniGLTF/Runtime/UniGLTF/Format/glTFMaterial.cs b/Assets/UniGLTF/Runtime/UniGLTF/Format/glTFMaterial.cs index e6a74042b..f91dd9d41 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/Format/glTFMaterial.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/Format/glTFMaterial.cs @@ -5,12 +5,9 @@ namespace UniGLTF { public enum glTFTextureTypes { - BaseColor, - Metallic, + OcclusionMetallicRoughness, Normal, - Occlusion, - Emissive, - Unknown + SRGB, } public interface IglTFTextureinfo @@ -38,19 +35,13 @@ namespace UniGLTF [Serializable] public class glTFMaterialBaseColorTextureInfo : glTFTextureInfo { - public override glTFTextureTypes TextureType - { - get { return glTFTextureTypes.BaseColor; } - } + public override glTFTextureTypes TextureType => glTFTextureTypes.SRGB; } [Serializable] public class glTFMaterialMetallicRoughnessTextureInfo : glTFTextureInfo { - public override glTFTextureTypes TextureType - { - get { return glTFTextureTypes.Metallic; } - } + public override glTFTextureTypes TextureType => glTFTextureTypes.OcclusionMetallicRoughness; } [Serializable] @@ -70,19 +61,13 @@ namespace UniGLTF [JsonSchema(Minimum = 0.0, Maximum = 1.0)] public float strength = 1.0f; - public override glTFTextureTypes TextureType - { - get { return glTFTextureTypes.Occlusion; } - } + public override glTFTextureTypes TextureType => glTFTextureTypes.OcclusionMetallicRoughness; } [Serializable] public class glTFMaterialEmissiveTextureInfo : glTFTextureInfo { - public override glTFTextureTypes TextureType - { - get { return glTFTextureTypes.Emissive; } - } + public override glTFTextureTypes TextureType => glTFTextureTypes.SRGB; } [Serializable] diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialExporter.cs index 190231c35..cc2940318 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialExporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialExporter.cs @@ -1,4 +1,5 @@ -using UniGLTF.UniUnlit; +using System; +using UniGLTF.UniUnlit; using UnityEngine; @@ -27,7 +28,7 @@ namespace UniGLTF Export_Color(m, textureManager, material); Export_Emission(m, textureManager, material); Export_Normal(m, textureManager, material); - Export_PBR(m, textureManager, material); + Export_OcclusionMetallicRoughness(m, textureManager, material); return material; } @@ -60,35 +61,61 @@ namespace UniGLTF /// /// /// - static void Export_PBR(Material m, TextureExportManager textureManager, glTFMaterial material) + static void Export_OcclusionMetallicRoughness(Material m, TextureExportManager textureManager, glTFMaterial material) { - int index = -1; + Texture metallicSmoothTexture = default; + float smoothness = 1.0f; if (m.HasProperty("_MetallicGlossMap")) { - float smoothness = 1.0f; if (m.HasProperty("_GlossMapScale")) { smoothness = m.GetFloat("_GlossMapScale"); } + metallicSmoothTexture = m.GetTexture("_MetallicGlossMap"); + } - // Bake smoothness values into a texture. - index = textureManager.ConvertAndGetIndex(m.GetTexture("_MetallicGlossMap"), x => OcclusionMetallicRoughnessConverter.GetExportTexture(x, smoothness)); - if (index != -1) + Texture occlusionTexture = default; + if (m.HasProperty("_OcclusionMap")) + { + occlusionTexture = m.GetTexture("_OcclusionMap"); + if (occlusionTexture != null && m.HasProperty("_OcclusionStrength")) { - material.pbrMetallicRoughness.metallicRoughnessTexture = - new glTFMaterialMetallicRoughnessTextureInfo() - { - index = index, - }; - - Export_MainTextureTransform(m, material.pbrMetallicRoughness.metallicRoughnessTexture); + material.occlusionTexture.strength = m.GetFloat("_OcclusionStrength"); } } - if (index != -1) + int index = -1; + if (metallicSmoothTexture != null && occlusionTexture != null) { - material.pbrMetallicRoughness.metallicFactor = 1.0f; + if (metallicSmoothTexture != occlusionTexture) + { + throw new NotImplementedException(); + } + else + { + throw new NotImplementedException(); + } + } + else if (metallicSmoothTexture) + { + index = textureManager.ConvertAndGetIndex(metallicSmoothTexture, x => OcclusionMetallicRoughnessConverter.Export(x, smoothness)); + } + else if (occlusionTexture) + { + throw new NotImplementedException(); + } + + if (index != -1 && metallicSmoothTexture != null) + { + material.pbrMetallicRoughness.metallicRoughnessTexture = + new glTFMaterialMetallicRoughnessTextureInfo() + { + index = index, + }; + Export_MainTextureTransform(m, material.pbrMetallicRoughness.metallicRoughnessTexture); + // Set 1.0f as hard-coded. See: https://github.com/dwango/UniVRM/issues/212. + material.pbrMetallicRoughness.metallicFactor = 1.0f; material.pbrMetallicRoughness.roughnessFactor = 1.0f; } else @@ -103,6 +130,15 @@ namespace UniGLTF material.pbrMetallicRoughness.roughnessFactor = 1.0f - m.GetFloat("_Glossiness"); } } + + if (index != -1 && occlusionTexture != null) + { + material.occlusionTexture = new glTFMaterialOcclusionTextureInfo() + { + index = index, + }; + Export_MainTextureTransform(m, material.occlusionTexture); + } } static void Export_Normal(Material m, TextureExportManager textureManager, glTFMaterial material) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/NormalConverter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/NormalConverter.cs index 29a78c695..6345a8c3a 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/NormalConverter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/NormalConverter.cs @@ -39,7 +39,7 @@ namespace UniGLTF // Unity texture to GLTF data // ConvertToRawColorWhenNormalValueIsCompressed - public static Texture2D Export(Texture2D texture) + public static Texture2D Export(Texture texture) { return TextureConverter.Convert(texture, glTFTextureTypes.Normal, null, Decoder); } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/OcclusionMetallicRoughnessConverter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/OcclusionMetallicRoughnessConverter.cs index 2e27b6105..1af3e7f60 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/OcclusionMetallicRoughnessConverter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/OcclusionMetallicRoughnessConverter.cs @@ -90,9 +90,9 @@ namespace UniGLTF return dst; } - public static Texture2D Export(Texture2D texture, float smoothness) + public static Texture2D Export(Texture texture, float smoothness) { - var converted = TextureConverter.Convert(texture, glTFTextureTypes.Metallic, x => ExportPixel(x, smoothness), null); + var converted = TextureConverter.Convert(texture, glTFTextureTypes.OcclusionMetallicRoughness, x => ExportPixel(x, smoothness), null); return converted; } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/TextureConverter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/TextureConverter.cs index 449edd6bc..8c99b07a0 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/TextureConverter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/TextureConverter.cs @@ -14,7 +14,7 @@ namespace UniGLTF { public delegate Color32 ColorConversion(Color32 color); - public static Texture2D Convert(Texture2D texture, glTFTextureTypes textureType, ColorConversion colorConversion, Material convertMaterial) + public static Texture2D Convert(Texture texture, glTFTextureTypes textureType, ColorConversion colorConversion, Material convertMaterial) { var copyTexture = CopyTexture(texture, TextureIO.GetColorSpace(textureType), convertMaterial); if (colorConversion != null) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureExportManager.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureExportManager.cs index 3b1ad9829..deb2adc12 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureExportManager.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureExportManager.cs @@ -71,7 +71,7 @@ namespace UniGLTF return index; } - public int ConvertAndGetIndex(Texture texture, Func converter) + public int ConvertAndGetIndex(Texture texture, Func converter) { if (texture == null) { @@ -85,7 +85,7 @@ namespace UniGLTF return -1; } - m_exportTextures[index] = converter(texture as Texture2D); + m_exportTextures[index] = converter(texture); return index; } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO.cs index aff199ce9..aef9d5c4b 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO.cs @@ -17,15 +17,25 @@ namespace UniGLTF { switch (textureType) { - case glTFTextureTypes.Metallic: + case glTFTextureTypes.SRGB: + return RenderTextureReadWrite.sRGB; + case glTFTextureTypes.OcclusionMetallicRoughness: case glTFTextureTypes.Normal: - case glTFTextureTypes.Occlusion: return RenderTextureReadWrite.Linear; - case glTFTextureTypes.BaseColor: - case glTFTextureTypes.Emissive: - return RenderTextureReadWrite.sRGB; default: - return RenderTextureReadWrite.sRGB; + throw new NotImplementedException(); + } + } + + public static RenderTextureReadWrite GetColorSpace(glTF gltf, int textureIndex) + { + if (TextureIO.TryGetglTFTextureType(gltf, textureIndex, out glTFTextureTypes textureType)) + { + return GetColorSpace(textureType); + } + else + { + return RenderTextureReadWrite.sRGB; } } @@ -33,32 +43,35 @@ namespace UniGLTF { switch (propName) { - case "_Color": - return glTFTextureTypes.BaseColor; case "_MetallicGlossMap": - return glTFTextureTypes.Metallic; + case "_OcclusionMap": + return glTFTextureTypes.OcclusionMetallicRoughness; case "_BumpMap": return glTFTextureTypes.Normal; - case "_OcclusionMap": - return glTFTextureTypes.Occlusion; + case "_Color": case "_EmissionMap": - return glTFTextureTypes.Emissive; + return glTFTextureTypes.SRGB; default: - return glTFTextureTypes.Unknown; + Debug.LogWarning($"unknown texture property: {propName} as sRGB"); + return glTFTextureTypes.SRGB; } } - public static glTFTextureTypes GetglTFTextureType(glTF glTf, int textureIndex) + public static bool TryGetglTFTextureType(glTF glTf, int textureIndex, out glTFTextureTypes textureType) { foreach (var material in glTf.materials) { var textureInfo = material.GetTextures().FirstOrDefault(x => (x != null) && x.index == textureIndex); if (textureInfo != null) { - return textureInfo.TextureType; + textureType = textureInfo.TextureType; + return true; } } - return glTFTextureTypes.Unknown; + + // textureIndex is not used by Material. + textureType = default; + return false; } #if UNITY_EDITOR @@ -86,7 +99,8 @@ namespace UniGLTF var props = ShaderPropExporter.PreShaderPropExporter.GetPropsForSupportedShader(m.shader.name); if (props == null) { - yield return (m.mainTexture, glTFTextureTypes.BaseColor); + // unknown shader + yield return (m.mainTexture, glTFTextureTypes.SRGB); } foreach (var prop in props.Properties) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/GltfTextureLoader.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/GltfTextureLoader.cs index d700a8edf..c5ff2934f 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/GltfTextureLoader.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/GltfTextureLoader.cs @@ -36,17 +36,15 @@ namespace UniGLTF // // texture from image(png etc) bytes // - var textureType = TextureIO.GetglTFTextureType(gltf, textureIndex); - var colorSpace = TextureIO.GetColorSpace(textureType); - var isLinear = colorSpace == RenderTextureReadWrite.Linear; - var sampler = gltf.GetSamplerFromTextureIndex(textureIndex); - - var texture = new Texture2D(2, 2, TextureFormat.ARGB32, false, isLinear); + var colorSpace = TextureIO.GetColorSpace(gltf, textureIndex); + var texture = new Texture2D(2, 2, TextureFormat.ARGB32, false, colorSpace == RenderTextureReadWrite.Linear); texture.name = gltf.textures[textureIndex].name; if (imageBytes != null) { texture.LoadImage(imageBytes); } + + var sampler = gltf.GetSamplerFromTextureIndex(textureIndex); if (sampler != null) { TextureSamplerUtil.SetSampler(texture, sampler); diff --git a/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs b/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs index ba559e61a..683a17ddf 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs @@ -40,7 +40,7 @@ namespace UniGLTF { var smoothness = 1.0f; Assert.That( - OcclusionMetallicRoughnessConverter.Export(new Color32(255, 255, 255, 255), smoothness), + OcclusionMetallicRoughnessConverter.ExportPixel(new Color32(255, 255, 255, 255), smoothness), // r <- 0 : (Unused) // g <- 0 : ((1 - src.a(as float) * smoothness) ^ 2)(as uint8) // b <- 255 : Same metallic (src.r) @@ -51,7 +51,7 @@ namespace UniGLTF { var smoothness = 0.5f; Assert.That( - OcclusionMetallicRoughnessConverter.Export(new Color32(255, 255, 255, 255), smoothness), + OcclusionMetallicRoughnessConverter.ExportPixel(new Color32(255, 255, 255, 255), smoothness), // r <- 0 : (Unused) // g <- 63 : ((1 - src.a(as float) * smoothness) ^ 2)(as uint8) // b <- 255 : Same metallic (src.r) @@ -62,7 +62,7 @@ namespace UniGLTF { var smoothness = 0.0f; Assert.That( - OcclusionMetallicRoughnessConverter.Export(new Color32(255, 255, 255, 255), smoothness), + OcclusionMetallicRoughnessConverter.ExportPixel(new Color32(255, 255, 255, 255), smoothness), // r <- 0 : (Unused) // g <- 255 : ((1 - src.a(as float) * smoothness) ^ 2)(as uint8) // b <- 255 : Same metallic (src.r) diff --git a/Assets/VRM/Runtime/IO/VRMExporter.cs b/Assets/VRM/Runtime/IO/VRMExporter.cs index 2c45816bf..dbf164cf0 100644 --- a/Assets/VRM/Runtime/IO/VRMExporter.cs +++ b/Assets/VRM/Runtime/IO/VRMExporter.cs @@ -113,7 +113,7 @@ namespace VRM VRM.meta.title = meta.Title; if (meta.Thumbnail != null) { - VRM.meta.texture = TextureExporter.ExportTexture(glTF, glTF.buffers.Count - 1, meta.Thumbnail, glTFTextureTypes.Unknown); + VRM.meta.texture = TextureExporter.ExportTexture(glTF, glTF.buffers.Count - 1, meta.Thumbnail, glTFTextureTypes.SRGB); } VRM.meta.licenseType = meta.LicenseType; @@ -138,7 +138,7 @@ namespace VRM VRM.meta.title = meta.Title; if (meta.Thumbnail != null) { - VRM.meta.texture = TextureExporter.ExportTexture(glTF, glTF.buffers.Count - 1, meta.Thumbnail, glTFTextureTypes.Unknown); + VRM.meta.texture = TextureExporter.ExportTexture(glTF, glTF.buffers.Count - 1, meta.Thumbnail, glTFTextureTypes.SRGB); } // ussage permission