From d589f6bb46aee54c59feaa18d4ddf52dd5f5196f Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 12 Mar 2021 18:28:46 +0900 Subject: [PATCH] OcclusionMetallicRoughnessConverter --- .../ScriptedImporter/ScriptedImporterImpl.cs | 3 +- .../ScriptedImporter/TextureExtractor.cs | 8 +- .../Runtime/UniGLTF/IO/MaterialExporter.cs | 58 ++-- .../IO/MaterialLoader/PBRMaterialItem.cs | 274 +++++++++--------- .../IO/MaterialLoader/UnlitMaterialItem.cs | 2 +- .../MetallicRoughnessConverter.cs | 82 ------ .../IO/TextureConverter/OcclusionConverter.cs | 42 --- .../OcclusionConverter.cs.meta | 11 - .../OcclusionMetallicRoughnessConverter.cs | 65 +++++ ...clusionMetallicRoughnessConverter.cs.meta} | 2 +- .../IO/TextureLoader/GetTextureParam.cs | 58 ++-- .../IO/TextureLoader/TextureFactory.cs | 27 +- Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs | 16 +- Assets/VRM/Runtime/IO/VRMImporterContext.cs | 2 +- 14 files changed, 285 insertions(+), 365 deletions(-) delete mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/MetallicRoughnessConverter.cs delete mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/OcclusionConverter.cs delete mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/OcclusionConverter.cs.meta create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/OcclusionMetallicRoughnessConverter.cs rename Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/{MetallicRoughnessConverter.cs.meta => OcclusionMetallicRoughnessConverter.cs.meta} (83%) diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ScriptedImporterImpl.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ScriptedImporterImpl.cs index a2dba9f0c..666defaaf 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ScriptedImporterImpl.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/ScriptedImporterImpl.cs @@ -64,8 +64,7 @@ namespace UniGLTF { switch (texParam.TextureType) { - case GetTextureParam.METALLIC_GLOSS_PROP: - case GetTextureParam.OCCLUSION_PROP: + case GetTextureParam.TextureTypes.StandardMap: break; default: diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/TextureExtractor.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/TextureExtractor.cs index dd14e8894..a74736131 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/TextureExtractor.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/TextureExtractor.cs @@ -70,8 +70,7 @@ namespace UniGLTF switch (param.TextureType) { - case GetTextureParam.METALLIC_GLOSS_PROP: - case GetTextureParam.OCCLUSION_PROP: + case GetTextureParam.TextureTypes.StandardMap: { // write converted texture targetPath = $"{m_path}/{param.ConvertedName}.png"; @@ -141,8 +140,7 @@ namespace UniGLTF { switch (param.TextureType) { - case GetTextureParam.OCCLUSION_PROP: - case GetTextureParam.METALLIC_GLOSS_PROP: + case GetTextureParam.TextureTypes.StandardMap: #if VRM_DEVELOP Debug.Log($"{targetPath} => linear"); #endif @@ -150,7 +148,7 @@ namespace UniGLTF targetTextureImporter.SaveAndReimport(); break; - case GetTextureParam.NORMAL_PROP: + case GetTextureParam.TextureTypes.NormalMap: #if VRM_DEVELOP Debug.Log($"{targetPath} => normalmap"); #endif diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialExporter.cs index 3bc1861d3..ee06e8c59 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialExporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialExporter.cs @@ -27,10 +27,9 @@ namespace UniGLTF // common params material.name = m.name; Export_Color(m, textureManager, material); - Export_Metallic(m, textureManager, material); - Export_Normal(m, textureManager, material); - Export_Occlusion(m, textureManager, material); Export_Emission(m, textureManager, material); + Export_Normal(m, textureManager, material); + Export_PBR(m, textureManager, material); return material; } @@ -57,7 +56,13 @@ namespace UniGLTF } } - static void Export_Metallic(Material m, TextureExportManager textureManager, glTFMaterial material) + /// + /// Occlusion, Metallic, Roughness + /// + /// + /// + /// + static void Export_PBR(Material m, TextureExportManager textureManager, glTFMaterial material) { int index = -1; if (m.HasProperty("_MetallicGlossMap")) @@ -69,7 +74,7 @@ namespace UniGLTF } // Bake smoothness values into a texture. - var converter = new MetallicRoughnessConverter(smoothness); + var converter = new OcclusionMetallicRoughnessConverter(smoothness); index = textureManager.ConvertAndGetIndex(m.GetTexture("_MetallicGlossMap"), converter); if (index != -1) { @@ -102,6 +107,27 @@ namespace UniGLTF } } } + // static void Export_Occlusion(Material m, TextureExportManager textureManager, glTFMaterial material) + // { + // if (m.HasProperty("_OcclusionMap")) + // { + // var index = textureManager.ConvertAndGetIndex(m.GetTexture("_OcclusionMap"), new OcclusionConverter()); + // if (index != -1) + // { + // material.occlusionTexture = new glTFMaterialOcclusionTextureInfo() + // { + // index = index, + // }; + + // Export_MainTextureTransform(m, material.occlusionTexture); + // } + + // if (index != -1 && m.HasProperty("_OcclusionStrength")) + // { + // material.occlusionTexture.strength = m.GetFloat("_OcclusionStrength"); + // } + // } + // } static void Export_Normal(Material m, TextureExportManager textureManager, glTFMaterial material) { @@ -125,28 +151,6 @@ namespace UniGLTF } } - static void Export_Occlusion(Material m, TextureExportManager textureManager, glTFMaterial material) - { - if (m.HasProperty("_OcclusionMap")) - { - var index = textureManager.ConvertAndGetIndex(m.GetTexture("_OcclusionMap"), new OcclusionConverter()); - if (index != -1) - { - material.occlusionTexture = new glTFMaterialOcclusionTextureInfo() - { - index = index, - }; - - Export_MainTextureTransform(m, material.occlusionTexture); - } - - if (index != -1 && m.HasProperty("_OcclusionStrength")) - { - material.occlusionTexture.strength = m.GetFloat("_OcclusionStrength"); - } - } - } - static void Export_Emission(Material m, TextureExportManager textureManager, glTFMaterial material) { if (m.IsKeywordEnabled("_EMISSION") == false) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/PBRMaterialItem.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/PBRMaterialItem.cs index 4ea932bb5..e79c9997c 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/PBRMaterialItem.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/PBRMaterialItem.cs @@ -45,21 +45,16 @@ namespace UniGLTF public static GetTextureParam BaseColorTexture(glTF gltf, glTFMaterial src) { - return GetTextureParam.Create(gltf, src.pbrMetallicRoughness.baseColorTexture.index); + return GetTextureParam.CreateSRGB(gltf, src.pbrMetallicRoughness.baseColorTexture.index); } - public static GetTextureParam MetallicRoughnessTexture(glTF gltf, glTFMaterial src) + public static GetTextureParam StandardTexture(glTF gltf, glTFMaterial src) { - return GetTextureParam.CreateMetallic(gltf, + return GetTextureParam.CreateStandard(gltf, src.pbrMetallicRoughness.metallicRoughnessTexture.index, src.pbrMetallicRoughness.metallicFactor); } - public static GetTextureParam OcclusionTexture(glTF gltf, glTFMaterial src) - { - return GetTextureParam.CreateOcclusion(gltf, src.occlusionTexture.index); - } - public static GetTextureParam NormalTexture(glTF gltf, glTFMaterial src) { return GetTextureParam.CreateNormal(gltf, src.normalTexture.index); @@ -69,156 +64,153 @@ namespace UniGLTF { if (getTexture == null) { - getTexture = (_x, _y, _z) => Task.FromResult(null); + getTexture = (IAwaitCaller _awaitCaller, glTF _gltf, GetTextureParam _param) => Task.FromResult(null); } - // PBR material - var material = default(Material); - if (i >= 0 && i < gltf.materials.Count) + if (i < 0 || i >= gltf.materials.Count) { - var src = gltf.materials[i]; - material = MaterialFactory.CreateMaterial(i, src, ShaderName); - if (src.pbrMetallicRoughness != null) + return MaterialFactory.CreateMaterial(i, null, ShaderName); + } + + var src = gltf.materials[i]; + var material = MaterialFactory.CreateMaterial(i, src, ShaderName); + var standardParam = StandardTexture(gltf, src); + if (src.pbrMetallicRoughness != null) + { + if (src.pbrMetallicRoughness.baseColorFactor != null && src.pbrMetallicRoughness.baseColorFactor.Length == 4) { - if (src.pbrMetallicRoughness.baseColorFactor != null && src.pbrMetallicRoughness.baseColorFactor.Length == 4) - { - var color = src.pbrMetallicRoughness.baseColorFactor; - material.color = (new Color(color[0], color[1], color[2], color[3])).gamma; - } - - if (src.pbrMetallicRoughness.baseColorTexture != null && src.pbrMetallicRoughness.baseColorTexture.index != -1) - { - material.mainTexture = await getTexture(awaitCaller, gltf, BaseColorTexture(gltf, src)); - - // Texture Offset and Scale - MaterialFactory.SetTextureOffsetAndScale(material, src.pbrMetallicRoughness.baseColorTexture, "_MainTex"); - } - - if (src.pbrMetallicRoughness.metallicRoughnessTexture != null && src.pbrMetallicRoughness.metallicRoughnessTexture.index != -1) - { - material.EnableKeyword("_METALLICGLOSSMAP"); - - var texture = await getTexture(awaitCaller, gltf, MetallicRoughnessTexture(gltf, src)); - if (texture != null) - { - material.SetTexture(GetTextureParam.METALLIC_GLOSS_PROP, texture); - } - - material.SetFloat("_Metallic", 1.0f); - // Set 1.0f as hard-coded. See: https://github.com/dwango/UniVRM/issues/212. - material.SetFloat("_GlossMapScale", 1.0f); - - // Texture Offset and Scale - MaterialFactory.SetTextureOffsetAndScale(material, src.pbrMetallicRoughness.metallicRoughnessTexture, "_MetallicGlossMap"); - } - else - { - material.SetFloat("_Metallic", src.pbrMetallicRoughness.metallicFactor); - material.SetFloat("_Glossiness", 1.0f - src.pbrMetallicRoughness.roughnessFactor); - } + var color = src.pbrMetallicRoughness.baseColorFactor; + material.color = (new Color(color[0], color[1], color[2], color[3])).gamma; } - if (src.normalTexture != null && src.normalTexture.index != -1) + if (src.pbrMetallicRoughness.baseColorTexture != null && src.pbrMetallicRoughness.baseColorTexture.index != -1) { - material.EnableKeyword("_NORMALMAP"); - var texture = await getTexture(awaitCaller, gltf, NormalTexture(gltf, src)); + material.mainTexture = await getTexture(awaitCaller, gltf, BaseColorTexture(gltf, src)); + + // Texture Offset and Scale + MaterialFactory.SetTextureOffsetAndScale(material, src.pbrMetallicRoughness.baseColorTexture, "_MainTex"); + } + + if (src.pbrMetallicRoughness.metallicRoughnessTexture != null && src.pbrMetallicRoughness.metallicRoughnessTexture.index != -1) + { + material.EnableKeyword("_METALLICGLOSSMAP"); + + var texture = await getTexture(awaitCaller, gltf, standardParam); if (texture != null) { - material.SetTexture(GetTextureParam.NORMAL_PROP, texture); - material.SetFloat("_BumpScale", src.normalTexture.scale); + material.SetTexture(GetTextureParam.METALLIC_GLOSS_PROP, texture); + } + + material.SetFloat("_Metallic", 1.0f); + // Set 1.0f as hard-coded. See: https://github.com/dwango/UniVRM/issues/212. + material.SetFloat("_GlossMapScale", 1.0f); + + // Texture Offset and Scale + MaterialFactory.SetTextureOffsetAndScale(material, src.pbrMetallicRoughness.metallicRoughnessTexture, "_MetallicGlossMap"); + } + else + { + material.SetFloat("_Metallic", src.pbrMetallicRoughness.metallicFactor); + material.SetFloat("_Glossiness", 1.0f - src.pbrMetallicRoughness.roughnessFactor); + } + } + + if (src.normalTexture != null && src.normalTexture.index != -1) + { + material.EnableKeyword("_NORMALMAP"); + var texture = await getTexture(awaitCaller, gltf, NormalTexture(gltf, src)); + if (texture != null) + { + material.SetTexture(GetTextureParam.NORMAL_PROP, texture); + material.SetFloat("_BumpScale", src.normalTexture.scale); + } + + // Texture Offset and Scale + MaterialFactory.SetTextureOffsetAndScale(material, src.normalTexture, "_BumpMap"); + } + + if (src.occlusionTexture != null && src.occlusionTexture.index != -1) + { + var texture = await getTexture(awaitCaller, gltf, standardParam); + if (texture != null) + { + material.SetTexture(GetTextureParam.OCCLUSION_PROP, texture); + material.SetFloat("_OcclusionStrength", src.occlusionTexture.strength); + } + + // Texture Offset and Scale + MaterialFactory.SetTextureOffsetAndScale(material, src.occlusionTexture, "_OcclusionMap"); + } + + if (src.emissiveFactor != null + || (src.emissiveTexture != null && src.emissiveTexture.index != -1)) + { + material.EnableKeyword("_EMISSION"); + material.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack; + + if (src.emissiveFactor != null && src.emissiveFactor.Length == 3) + { + material.SetColor("_EmissionColor", new Color(src.emissiveFactor[0], src.emissiveFactor[1], src.emissiveFactor[2])); + } + + if (src.emissiveTexture != null && src.emissiveTexture.index != -1) + { + var texture = await getTexture(awaitCaller, gltf, GetTextureParam.CreateSRGB(gltf, src.emissiveTexture.index)); + if (texture != null) + { + material.SetTexture("_EmissionMap", texture); } // Texture Offset and Scale - MaterialFactory.SetTextureOffsetAndScale(material, src.normalTexture, "_BumpMap"); + MaterialFactory.SetTextureOffsetAndScale(material, src.emissiveTexture, "_EmissionMap"); } - - if (src.occlusionTexture != null && src.occlusionTexture.index != -1) - { - var texture = await getTexture(awaitCaller, gltf, OcclusionTexture(gltf, src)); - if (texture != null) - { - material.SetTexture(GetTextureParam.OCCLUSION_PROP, texture); - material.SetFloat("_OcclusionStrength", src.occlusionTexture.strength); - } - - // Texture Offset and Scale - MaterialFactory.SetTextureOffsetAndScale(material, src.occlusionTexture, "_OcclusionMap"); - } - - if (src.emissiveFactor != null - || (src.emissiveTexture != null && src.emissiveTexture.index != -1)) - { - material.EnableKeyword("_EMISSION"); - material.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack; - - if (src.emissiveFactor != null && src.emissiveFactor.Length == 3) - { - material.SetColor("_EmissionColor", new Color(src.emissiveFactor[0], src.emissiveFactor[1], src.emissiveFactor[2])); - } - - if (src.emissiveTexture != null && src.emissiveTexture.index != -1) - { - var texture = await getTexture(awaitCaller, gltf, GetTextureParam.Create(gltf, src.emissiveTexture.index)); - if (texture != null) - { - material.SetTexture("_EmissionMap", texture); - } - - // Texture Offset and Scale - MaterialFactory.SetTextureOffsetAndScale(material, src.emissiveTexture, "_EmissionMap"); - } - } - - BlendMode blendMode = BlendMode.Opaque; - // https://forum.unity.com/threads/standard-material-shader-ignoring-setfloat-property-_mode.344557/#post-2229980 - switch (src.alphaMode) - { - case "BLEND": - blendMode = BlendMode.Fade; - material.SetOverrideTag("RenderType", "Transparent"); - material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); - material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); - material.SetInt("_ZWrite", 0); - material.DisableKeyword("_ALPHATEST_ON"); - material.EnableKeyword("_ALPHABLEND_ON"); - material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); - material.renderQueue = 3000; - break; - - case "MASK": - blendMode = BlendMode.Cutout; - material.SetOverrideTag("RenderType", "TransparentCutout"); - material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); - material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); - material.SetInt("_ZWrite", 1); - material.SetFloat("_Cutoff", src.alphaCutoff); - material.EnableKeyword("_ALPHATEST_ON"); - material.DisableKeyword("_ALPHABLEND_ON"); - material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); - material.renderQueue = 2450; - - break; - - default: // OPAQUE - blendMode = BlendMode.Opaque; - material.SetOverrideTag("RenderType", ""); - material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); - material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); - material.SetInt("_ZWrite", 1); - material.DisableKeyword("_ALPHATEST_ON"); - material.DisableKeyword("_ALPHABLEND_ON"); - material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); - material.renderQueue = -1; - break; - } - - material.SetFloat("_Mode", (float)blendMode); } - else + + BlendMode blendMode = BlendMode.Opaque; + // https://forum.unity.com/threads/standard-material-shader-ignoring-setfloat-property-_mode.344557/#post-2229980 + switch (src.alphaMode) { - material = MaterialFactory.CreateMaterial(i, null, ShaderName); + case "BLEND": + blendMode = BlendMode.Fade; + material.SetOverrideTag("RenderType", "Transparent"); + material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); + material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); + material.SetInt("_ZWrite", 0); + material.DisableKeyword("_ALPHATEST_ON"); + material.EnableKeyword("_ALPHABLEND_ON"); + material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); + material.renderQueue = 3000; + break; + + case "MASK": + blendMode = BlendMode.Cutout; + material.SetOverrideTag("RenderType", "TransparentCutout"); + material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); + material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); + material.SetInt("_ZWrite", 1); + material.SetFloat("_Cutoff", src.alphaCutoff); + material.EnableKeyword("_ALPHATEST_ON"); + material.DisableKeyword("_ALPHABLEND_ON"); + material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); + material.renderQueue = 2450; + + break; + + default: // OPAQUE + blendMode = BlendMode.Opaque; + material.SetOverrideTag("RenderType", ""); + material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); + material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); + material.SetInt("_ZWrite", 1); + material.DisableKeyword("_ALPHATEST_ON"); + material.DisableKeyword("_ALPHABLEND_ON"); + material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); + material.renderQueue = -1; + break; } + material.SetFloat("_Mode", (float)blendMode); + return material; } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/UnlitMaterialItem.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/UnlitMaterialItem.cs index 2cca1aab4..8960e8b27 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/UnlitMaterialItem.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/UnlitMaterialItem.cs @@ -21,7 +21,7 @@ namespace UniGLTF // texture if (src.pbrMetallicRoughness.baseColorTexture != null) { - material.mainTexture = await getTexture(awaitCaller, gltf, GetTextureParam.Create(gltf, src.pbrMetallicRoughness.baseColorTexture.index)); + material.mainTexture = await getTexture(awaitCaller, gltf, GetTextureParam.CreateSRGB(gltf, src.pbrMetallicRoughness.baseColorTexture.index)); // Texture Offset and Scale MaterialFactory.SetTextureOffsetAndScale(material, src.pbrMetallicRoughness.baseColorTexture, "_MainTex"); diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/MetallicRoughnessConverter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/MetallicRoughnessConverter.cs deleted file mode 100644 index ee078b880..000000000 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/MetallicRoughnessConverter.cs +++ /dev/null @@ -1,82 +0,0 @@ -#define SIMPLE_CONV -using UnityEngine; - -namespace UniGLTF -{ - /// - /// - /// * https://github.com/dwango/UniVRM/issues/212. - /// * https://blogs.unity3d.com/jp/2016/01/25/ggx-in-unity-5-3/ - /// * https://github.com/vrm-c/UniVRM/issues/388 - /// - /// Occlusion(glTF): src.r - /// Roughness(glTF): src.g -> Smoothness(Unity): dst.a (bake smoothnessOrRoughness) - /// Metallic(glTF) : src.b -> Metallic(Unity) : dst.r - /// - public class MetallicRoughnessConverter : ITextureConverter - { - private readonly float _smoothnessOrRoughness; - private readonly float _smoothnessOrRoughnessInverse; - - public MetallicRoughnessConverter(float smoothnessOrRoughness) - { - _smoothnessOrRoughness = smoothnessOrRoughness; - _smoothnessOrRoughnessInverse = 1.0f / _smoothnessOrRoughness; - } - - public Texture2D GetImportTexture(Texture2D texture) - { - var converted = TextureConverter.Convert(texture, glTFTextureTypes.Metallic, Import, null); - return converted; - } - - public Texture2D GetExportTexture(Texture2D texture) - { - var converted = TextureConverter.Convert(texture, glTFTextureTypes.Metallic, Export, null); - return converted; - } - - public Color32 Import(Color32 src) - { - var dst = new Color32 - { - r = src.b, - g = 0, - b = 0, - }; - - // Bake _smoothnessOrRoughness into a texture. -#if SIMPLE_CONV - dst.a = (byte)(255 - src.g * _smoothnessOrRoughness); -#else - var pixelRoughnessFactor = (src.g * _smoothnessOrRoughness) / 255.0f; // roughness - var pixelSmoothness = 1.0f - Mathf.Sqrt(pixelRoughnessFactor); - dst.a = (byte)Mathf.Clamp(pixelSmoothness * 255, 0, 255); -#endif - return dst; - } - - public Color32 Export(Color32 src) - { - - var dst = new Color32 - { - r = 0, - b = src.r, - a = 255, - }; - - // Bake divide _smoothnessOrRoughness from a texture. -#if SIMPLE_CONV - dst.g = (byte)(255 - src.a); -#else - var pixelSmoothness = (src.a * _smoothnessOrRoughness) / 255.0f; // smoothness - var pixelRoughnessFactorSqrt = (1.0f - pixelSmoothness); - var pixelRoughnessFactor = pixelRoughnessFactorSqrt * pixelRoughnessFactorSqrt; - dst.g = (byte)Mathf.Clamp(pixelRoughnessFactor * 255, 0, 255); -#endif - - return dst; - } - } -} diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/OcclusionConverter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/OcclusionConverter.cs deleted file mode 100644 index 2e4768f3a..000000000 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/OcclusionConverter.cs +++ /dev/null @@ -1,42 +0,0 @@ -using UnityEngine; - -namespace UniGLTF -{ - public class OcclusionConverter : ITextureConverter - { - - public Texture2D GetImportTexture(Texture2D texture) - { - var converted = TextureConverter.Convert(texture, glTFTextureTypes.Occlusion, Import, null); - return converted; - } - - public Texture2D GetExportTexture(Texture2D texture) - { - var converted = TextureConverter.Convert(texture, glTFTextureTypes.Occlusion, Export, null); - return converted; - } - - public Color32 Import(Color32 src) - { - return new Color32 - { - r = 0, - g = src.r, - b = 0, - a = 255, - }; - } - - public Color32 Export(Color32 src) - { - return new Color32 - { - r = src.g, - g = 0, - b = 0, - a = 255, - }; - } - } -} \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/OcclusionConverter.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/OcclusionConverter.cs.meta deleted file mode 100644 index 2a97dd0d2..000000000 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/OcclusionConverter.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 268e807d3ea7f0f45882d20bf318cf8b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/OcclusionMetallicRoughnessConverter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/OcclusionMetallicRoughnessConverter.cs new file mode 100644 index 000000000..2888f0f35 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/OcclusionMetallicRoughnessConverter.cs @@ -0,0 +1,65 @@ +using UnityEngine; + +namespace UniGLTF +{ + /// + /// + /// * https://github.com/dwango/UniVRM/issues/212. + /// * https://blogs.unity3d.com/jp/2016/01/25/ggx-in-unity-5-3/ + /// * https://github.com/vrm-c/UniVRM/issues/388 + /// + /// glTF = Unity + /// Occlusion: src.r -> dst.g + /// Roughness: src.g -> dst.a (bake smoothnessOrRoughness) + /// Metallic : src.b -> dst.r + /// + public class OcclusionMetallicRoughnessConverter : ITextureConverter + { + private readonly float _smoothnessOrRoughness; + + public OcclusionMetallicRoughnessConverter(float smoothnessOrRoughness) + { + _smoothnessOrRoughness = smoothnessOrRoughness; + } + + public Texture2D GetImportTexture(Texture2D texture) + { + var converted = TextureConverter.Convert(texture, glTFTextureTypes.Metallic, Import, null); + return converted; + } + + public Texture2D GetExportTexture(Texture2D texture) + { + var converted = TextureConverter.Convert(texture, glTFTextureTypes.Metallic, Export, null); + return converted; + } + + public Color32 Import(Color32 src) + { + var dst = new Color32 + { + r = src.b, // Metallic + g = src.r, // Occlusion + b = 0, // not used + // Roughness to Smoothness. Bake _smoothnessOrRoughness into a texture. + a = (byte)(255 - src.g * _smoothnessOrRoughness), + }; + + return dst; + } + + public Color32 Export(Color32 src) + { + var dst = new Color32 + { + r = src.g, // Occlusion + // Roughness from Smoothness. Bake divide _smoothnessOrRoughness from a texture. + g = (byte)(255 - src.a), + b = src.r, // Metallic + a = 255, // not used + }; + + return dst; + } + } +} diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/MetallicRoughnessConverter.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/OcclusionMetallicRoughnessConverter.cs.meta similarity index 83% rename from Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/MetallicRoughnessConverter.cs.meta rename to Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/OcclusionMetallicRoughnessConverter.cs.meta index 7a089ba89..1c32f4f89 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/MetallicRoughnessConverter.cs.meta +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/OcclusionMetallicRoughnessConverter.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ae1f69c4441f3a74292499f75467c057 +guid: 55d0c8cd2f5154f488e47f7bb1e6fa60 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/GetTextureParam.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/GetTextureParam.cs index b5334756d..931d75522 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/GetTextureParam.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/GetTextureParam.cs @@ -2,14 +2,25 @@ namespace UniGLTF { + /// + /// STANDARD(Pbr) texture = occlusion + metallic + smoothness + /// public struct GetTextureParam { public const string NORMAL_PROP = "_BumpMap"; public const string NORMAL_SUFFIX = ".normal"; + public const string METALLIC_GLOSS_PROP = "_MetallicGlossMap"; - public const string METALLIC_GLOSS_SUFFIX = ".metallicRoughness"; public const string OCCLUSION_PROP = "_OcclusionMap"; - public const string OCCLUSION_SUFFIX = ".occlusion"; + public const string STANDARD_SUFFIX = ".standard"; + + public enum TextureTypes + { + sRGB, + NormalMap, + // Occlusion + Metallic + Smoothness + StandardMap, + } public static string RemoveSuffix(string src) { @@ -17,13 +28,9 @@ namespace UniGLTF { return src.Substring(0, src.Length - NORMAL_SUFFIX.Length); } - else if (src.EndsWith(METALLIC_GLOSS_SUFFIX)) + else if (src.EndsWith(STANDARD_SUFFIX)) { - return src.Substring(0, src.Length - METALLIC_GLOSS_SUFFIX.Length); - } - else if (src.EndsWith(OCCLUSION_SUFFIX)) - { - return src.Substring(0, src.Length - OCCLUSION_SUFFIX.Length); + return src.Substring(0, src.Length - STANDARD_SUFFIX.Length); } else { @@ -41,15 +48,14 @@ namespace UniGLTF { switch (TextureType) { - case METALLIC_GLOSS_PROP: return $"{m_name}{METALLIC_GLOSS_SUFFIX}"; - case OCCLUSION_PROP: return $"{m_name}{OCCLUSION_SUFFIX}"; - case NORMAL_PROP: return $"{m_name}{NORMAL_SUFFIX}"; + case TextureTypes.StandardMap: return $"{m_name}{STANDARD_SUFFIX}"; + case TextureTypes.NormalMap: return $"{m_name}{NORMAL_SUFFIX}"; default: return m_name; } } } - public readonly string TextureType; + public readonly TextureTypes TextureType; public readonly float MetallicFactor; public readonly ushort? Index0; public readonly ushort? Index1; @@ -59,11 +65,11 @@ namespace UniGLTF public readonly ushort? Index5; /// - /// この2種類は変換済みをExtract + /// この種類は RGB チャンネルの組み換えが必用 /// - public bool ExtractConverted => TextureType == OCCLUSION_PROP || TextureType == METALLIC_GLOSS_PROP; + public bool ExtractConverted => TextureType == TextureTypes.StandardMap; - public GetTextureParam(string name, string textureType, float metallicFactor, int i0, int i1, int i2, int i3, int i4, int i5) + public GetTextureParam(string name, TextureTypes textureType, float metallicFactor, int i0, int i1, int i2, int i3, int i4, int i5) { if (string.IsNullOrEmpty(name)) { @@ -81,10 +87,10 @@ namespace UniGLTF Index5 = (ushort)i5; } - public static GetTextureParam Create(glTF gltf, int textureIndex) + public static GetTextureParam CreateSRGB(glTF gltf, int textureIndex) { var name = gltf.textures[textureIndex].name; - return new GetTextureParam(name, default, default, textureIndex, default, default, default, default, default); + return new GetTextureParam(name, TextureTypes.sRGB, default, textureIndex, default, default, default, default, default); } public static GetTextureParam Create(glTF gltf, int index, string prop) @@ -95,32 +101,24 @@ namespace UniGLTF return CreateNormal(gltf, index); case OCCLUSION_PROP: - return CreateOcclusion(gltf, index); - case METALLIC_GLOSS_PROP: - return CreateMetallic(gltf, index, 1); + return CreateStandard(gltf, index, 1); default: - return Create(gltf, index); + return CreateSRGB(gltf, index); } } public static GetTextureParam CreateNormal(glTF gltf, int textureIndex) { var name = gltf.textures[textureIndex].name; - return new GetTextureParam(name, NORMAL_PROP, default, textureIndex, default, default, default, default, default); + return new GetTextureParam(name, TextureTypes.NormalMap, default, textureIndex, default, default, default, default, default); } - public static GetTextureParam CreateMetallic(glTF gltf, int textureIndex, float metallicFactor) + public static GetTextureParam CreateStandard(glTF gltf, int textureIndex, float metallicFactor) { var name = gltf.textures[textureIndex].name; - return new GetTextureParam(name, METALLIC_GLOSS_PROP, metallicFactor, textureIndex, default, default, default, default, default); - } - - public static GetTextureParam CreateOcclusion(glTF gltf, int textureIndex) - { - var name = gltf.textures[textureIndex].name; - return new GetTextureParam(name, OCCLUSION_PROP, default, textureIndex, default, default, default, default, default); + return new GetTextureParam(name, TextureTypes.StandardMap, metallicFactor, textureIndex, default, default, default, default, default); } } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/TextureFactory.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/TextureFactory.cs index f8310b717..c70bea707 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/TextureFactory.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/TextureFactory.cs @@ -52,7 +52,7 @@ namespace UniGLTF if (param.Index0.HasValue && m_externalMap != null) { var cacheName = param.ConvertedName; - if (param.TextureType == GetTextureParam.NORMAL_PROP) + if (param.TextureType == GetTextureParam.TextureTypes.NormalMap) { cacheName = param.GltflName; if (m_textureCache.TryGetValue(cacheName, out TextureLoadInfo normalInfo)) @@ -165,7 +165,7 @@ namespace UniGLTF switch (param.TextureType) { - case GetTextureParam.NORMAL_PROP: + case GetTextureParam.TextureTypes.NormalMap: { var baseTexture = await GetOrCreateBaseTexture(awaitCaller, gltf, param.Index0.Value, false); var converted = new NormalConverter().GetImportTexture(baseTexture.Texture); @@ -175,26 +175,25 @@ namespace UniGLTF return info.Texture; } - case GetTextureParam.METALLIC_GLOSS_PROP: + case GetTextureParam.TextureTypes.StandardMap: { - // Bake roughnessFactor values into a texture. var baseTexture = await GetOrCreateBaseTexture(awaitCaller, gltf, param.Index0.Value, false); - var converted = new MetallicRoughnessConverter(param.MetallicFactor).GetImportTexture(baseTexture.Texture); + var converted = new OcclusionMetallicRoughnessConverter(param.MetallicFactor).GetImportTexture(baseTexture.Texture); converted.name = param.ConvertedName; var info = new TextureLoadInfo(converted, true, false); m_textureCache.Add(converted.name, info); return info.Texture; } - case GetTextureParam.OCCLUSION_PROP: - { - var baseTexture = await GetOrCreateBaseTexture(awaitCaller, gltf, param.Index0.Value, false); - var converted = new OcclusionConverter().GetImportTexture(baseTexture.Texture); - converted.name = param.ConvertedName; - var info = new TextureLoadInfo(converted, true, false); - m_textureCache.Add(converted.name, info); - return info.Texture; - } + // case GetTextureParam.OCCLUSION_PROP: + // { + // var baseTexture = await GetOrCreateBaseTexture(awaitCaller, gltf, param.Index0.Value, false); + // var converted = new OcclusionConverter().GetImportTexture(baseTexture.Texture); + // converted.name = param.ConvertedName; + // var info = new TextureLoadInfo(converted, true, false); + // m_textureCache.Add(converted.name, info); + // return info.Texture; + // } default: { diff --git a/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs b/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs index edc28a891..08a4a114f 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs @@ -14,7 +14,7 @@ namespace UniGLTF wrapMode = TextureWrapMode.Clamp, filterMode = FilterMode.Trilinear, }; - var textureManager = new TextureExportManager(new Texture[] {tex0}); + var textureManager = new TextureExportManager(new Texture[] { tex0 }); var material = new Material(Shader.Find("Standard")); material.mainTexture = tex0; @@ -39,7 +39,7 @@ namespace UniGLTF { { var smoothness = 1.0f; - var conv = new MetallicRoughnessConverter(smoothness); + var conv = new OcclusionMetallicRoughnessConverter(smoothness); Assert.That( conv.Export(new Color32(255, 255, 255, 255)), // r <- 0 : (Unused) @@ -51,7 +51,7 @@ namespace UniGLTF { var smoothness = 0.5f; - var conv = new MetallicRoughnessConverter(smoothness); + var conv = new OcclusionMetallicRoughnessConverter(smoothness); Assert.That( conv.Export(new Color32(255, 255, 255, 255)), // r <- 0 : (Unused) @@ -63,7 +63,7 @@ namespace UniGLTF { var smoothness = 0.0f; - var conv = new MetallicRoughnessConverter(smoothness); + var conv = new OcclusionMetallicRoughnessConverter(smoothness); Assert.That( conv.Export(new Color32(255, 255, 255, 255)), // r <- 0 : (Unused) @@ -79,7 +79,7 @@ namespace UniGLTF { { var roughnessFactor = 1.0f; - var conv = new MetallicRoughnessConverter(roughnessFactor); + var conv = new OcclusionMetallicRoughnessConverter(roughnessFactor); Assert.That( conv.Import(new Color32(255, 255, 255, 255)), // r <- 255 : Same metallic (src.r) @@ -91,7 +91,7 @@ namespace UniGLTF { var roughnessFactor = 1.0f; - var conv = new MetallicRoughnessConverter(roughnessFactor); + var conv = new OcclusionMetallicRoughnessConverter(roughnessFactor); Assert.That( conv.Import(new Color32(255, 63, 255, 255)), // r <- 255 : Same metallic (src.r) @@ -103,7 +103,7 @@ namespace UniGLTF { var roughnessFactor = 0.5f; - var conv = new MetallicRoughnessConverter(roughnessFactor); + var conv = new OcclusionMetallicRoughnessConverter(roughnessFactor); Assert.That( conv.Import(new Color32(255, 255, 255, 255)), // r <- 255 : Same metallic (src.r) @@ -115,7 +115,7 @@ namespace UniGLTF { var roughnessFactor = 0.0f; - var conv = new MetallicRoughnessConverter(roughnessFactor); + var conv = new OcclusionMetallicRoughnessConverter(roughnessFactor); Assert.That( conv.Import(new Color32(255, 255, 255, 255)), // r <- 255 : Same metallic (src.r) diff --git a/Assets/VRM/Runtime/IO/VRMImporterContext.cs b/Assets/VRM/Runtime/IO/VRMImporterContext.cs index 3c59f3ecd..15af9f0b8 100644 --- a/Assets/VRM/Runtime/IO/VRMImporterContext.cs +++ b/Assets/VRM/Runtime/IO/VRMImporterContext.cs @@ -292,7 +292,7 @@ namespace VRM meta.Title = gltfMeta.title; if (gltfMeta.texture >= 0) { - meta.Thumbnail = await TextureFactory.GetTextureAsync(awaitCaller, GLTF, GetTextureParam.Create(GLTF, gltfMeta.texture)); + meta.Thumbnail = await TextureFactory.GetTextureAsync(awaitCaller, GLTF, GetTextureParam.CreateSRGB(GLTF, gltfMeta.texture)); } meta.AllowedUser = gltfMeta.allowedUser; meta.ViolentUssage = gltfMeta.violentUssage;