From d2e560aca4022b495b1949932f86e052d9a7ae08 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 12 Mar 2021 19:39:25 +0900 Subject: [PATCH] OcclusionMetallicRoughnessConverter.Convert #781 --- .../IO/MaterialLoader/PBRMaterialItem.cs | 14 +++- .../OcclusionMetallicRoughnessConverter.cs | 75 ++++++++++++++++--- .../IO/TextureLoader/GetTextureParam.cs | 30 +++++--- .../IO/TextureLoader/TextureFactory.cs | 17 ++--- Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs | 8 +- 5 files changed, 105 insertions(+), 39 deletions(-) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/PBRMaterialItem.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/PBRMaterialItem.cs index c2fc530fd..38968b4e6 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/PBRMaterialItem.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/PBRMaterialItem.cs @@ -50,10 +50,18 @@ namespace UniGLTF public static GetTextureParam StandardTexture(glTF gltf, glTFMaterial src) { + var metallicFactor = 1.0f; + var roughnessFactor = 1.0f; + if (src.pbrMetallicRoughness != null) + { + metallicFactor = src.pbrMetallicRoughness.metallicFactor; + roughnessFactor = src.pbrMetallicRoughness.roughnessFactor; + } return GetTextureParam.CreateStandard(gltf, - src.pbrMetallicRoughness.metallicRoughnessTexture.index, - src.pbrMetallicRoughness.metallicFactor, - src.pbrMetallicRoughness.roughnessFactor); + src.pbrMetallicRoughness?.metallicRoughnessTexture?.index, + src.occlusionTexture?.index, + metallicFactor, + roughnessFactor); } public static GetTextureParam NormalTexture(glTF gltf, glTFMaterial src) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/OcclusionMetallicRoughnessConverter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/OcclusionMetallicRoughnessConverter.cs index e8749cdfb..cd4b5c0c5 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/OcclusionMetallicRoughnessConverter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureConverter/OcclusionMetallicRoughnessConverter.cs @@ -1,3 +1,5 @@ +using System; +using System.Linq; using UnityEngine; namespace UniGLTF @@ -26,14 +28,67 @@ namespace UniGLTF _smoothnessOrRoughness = smoothnessOrRoughness; } - public static Texture2D GetImportTexture(Texture2D texture, float metallicFactor, float roughnessFactor) + public delegate Color32 ColorConversion(Color32 metallicRoughness, Color32 occlusion); + + public static Texture2D Convert(Texture2D metallicRoughnessTexture, Texture2D occlusionTexture, Material convertMaterial, + float metallicFactor, float roughnessFactor) { - TextureConverter.ColorConversion convert = src => + if (metallicRoughnessTexture != null && occlusionTexture != null) { - return Import(src, metallicFactor, roughnessFactor); - }; - var converted = TextureConverter.Convert(texture, glTFTextureTypes.Metallic, convert, null); - return converted; + if (metallicRoughnessTexture != occlusionTexture) + { + var copyMetallicRoughness = TextureConverter.CopyTexture(metallicRoughnessTexture, RenderTextureReadWrite.Linear, convertMaterial); + var metallicRoughnessPixels = copyMetallicRoughness.GetPixels32(); + var copyOcclusion = TextureConverter.CopyTexture(occlusionTexture, RenderTextureReadWrite.Linear, convertMaterial); + var occlusionPixels = copyOcclusion.GetPixels32(); + if (metallicRoughnessPixels.Length != occlusionPixels.Length) + { + throw new NotImplementedException(); + } + for (int i = 0; i < metallicRoughnessPixels.Length; ++i) + { + metallicRoughnessPixels[i] = Import(metallicRoughnessPixels[i], metallicFactor, roughnessFactor, occlusionPixels[i]); + } + copyMetallicRoughness.SetPixels32(metallicRoughnessPixels); + copyMetallicRoughness.Apply(); + copyMetallicRoughness.name = metallicRoughnessTexture.name; + return copyMetallicRoughness; + } + else + { + var copyMetallicRoughness = TextureConverter.CopyTexture(metallicRoughnessTexture, RenderTextureReadWrite.Linear, convertMaterial); + var metallicRoughnessPixels = copyMetallicRoughness.GetPixels32(); + for (int i = 0; i < metallicRoughnessPixels.Length; ++i) + { + metallicRoughnessPixels[i] = Import(metallicRoughnessPixels[i], metallicFactor, roughnessFactor, metallicRoughnessPixels[i]); + } + copyMetallicRoughness.SetPixels32(metallicRoughnessPixels); + copyMetallicRoughness.Apply(); + copyMetallicRoughness.name = metallicRoughnessTexture.name; + return copyMetallicRoughness; + } + } + else if (metallicRoughnessTexture != null) + { + var copyTexture = TextureConverter.CopyTexture(metallicRoughnessTexture, RenderTextureReadWrite.Linear, convertMaterial); + copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => Import(x, metallicFactor, roughnessFactor, default)).ToArray()); + copyTexture.Apply(); + copyTexture.name = metallicRoughnessTexture.name; + return copyTexture; + } + else if (occlusionTexture != null) + { + throw new NotImplementedException("occlusion only"); + } + else + { + throw new ArgumentNullException("no texture"); + } + } + + public static Texture2D GetImportTexture(Texture2D metallicRoughnessTexture, float metallicFactor, float roughnessFactor, Texture2D occlusionTexture) + { + return Convert(metallicRoughnessTexture, occlusionTexture, null, metallicFactor, roughnessFactor); } public Texture2D GetExportTexture(Texture2D texture) @@ -42,14 +97,14 @@ namespace UniGLTF return converted; } - public static Color32 Import(Color32 src, float metallicFactor, float roughnessFactor) + public static Color32 Import(Color32 metallicRoughness, float metallicFactor, float roughnessFactor, Color32 occlusion) { var dst = new Color32 { - r = (byte)(src.b * metallicFactor), // Metallic - g = src.r, // Occlusion + r = (byte)(metallicRoughness.b * metallicFactor), // Metallic + g = occlusion.r, // Occlusion b = 0, // not used - a = (byte)(255 - src.g * roughnessFactor), // Roughness to Smoothness + a = (byte)(255 - metallicRoughness.g * roughnessFactor), // Roughness to Smoothness }; return dst; diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/GetTextureParam.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/GetTextureParam.cs index c888366fa..eb4e5264a 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/GetTextureParam.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/GetTextureParam.cs @@ -70,7 +70,7 @@ namespace UniGLTF /// public bool ExtractConverted => TextureType == TextureTypes.StandardMap; - public GetTextureParam(string name, TextureTypes textureType, float metallicFactor, float roughnessFactor, int i0, int i1, int i2, int i3, int i4, int i5) + public GetTextureParam(string name, TextureTypes textureType, float metallicFactor, float roughnessFactor, int? i0, int? i1, int? i2, int? i3, int? i4, int? i5) { if (string.IsNullOrEmpty(name)) { @@ -81,12 +81,12 @@ namespace UniGLTF TextureType = textureType; MetallicFactor = metallicFactor; RoughnessFactor = roughnessFactor; - Index0 = (ushort)i0; - Index1 = (ushort)i1; - Index2 = (ushort)i2; - Index3 = (ushort)i3; - Index4 = (ushort)i4; - Index5 = (ushort)i5; + Index0 = (ushort?)i0; + Index1 = (ushort?)i1; + Index2 = (ushort?)i2; + Index3 = (ushort?)i3; + Index4 = (ushort?)i4; + Index5 = (ushort?)i5; } public static GetTextureParam CreateSRGB(glTF gltf, int textureIndex) @@ -104,7 +104,7 @@ namespace UniGLTF case OCCLUSION_PROP: case METALLIC_GLOSS_PROP: - return CreateStandard(gltf, index, metallicFactor, roughnessFactor); + return CreateStandard(gltf, index, default, metallicFactor, roughnessFactor); default: return CreateSRGB(gltf, index); @@ -117,10 +117,18 @@ namespace UniGLTF return new GetTextureParam(name, TextureTypes.NormalMap, default, default, textureIndex, default, default, default, default, default); } - public static GetTextureParam CreateStandard(glTF gltf, int textureIndex, float metallicFactor, float roughnessFactor) + public static GetTextureParam CreateStandard(glTF gltf, int? metallicRoughnessTextureIndex, int? occlusionTextureIndex, float metallicFactor, float roughnessFactor) { - var name = gltf.textures[textureIndex].name; - return new GetTextureParam(name, TextureTypes.StandardMap, metallicFactor, roughnessFactor, textureIndex, default, default, default, default, default); + string name = default; + if (metallicRoughnessTextureIndex.HasValue) + { + name = gltf.textures[metallicRoughnessTextureIndex.Value].name; + } + else if (occlusionTextureIndex.HasValue) + { + name = gltf.textures[occlusionTextureIndex.Value].name; + } + return new GetTextureParam(name, TextureTypes.StandardMap, metallicFactor, roughnessFactor, metallicRoughnessTextureIndex, occlusionTextureIndex, 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 ff666a8dc..87e922785 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/TextureFactory.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/TextureFactory.cs @@ -178,23 +178,18 @@ namespace UniGLTF case GetTextureParam.TextureTypes.StandardMap: { var baseTexture = await GetOrCreateBaseTexture(awaitCaller, gltf, param.Index0.Value, false); - var converted = OcclusionMetallicRoughnessConverter.GetImportTexture(baseTexture.Texture, param.MetallicFactor, param.RoughnessFactor); + TextureLoadInfo occlusionBaseTexture = default; + if (param.Index1.HasValue) + { + occlusionBaseTexture = await GetOrCreateBaseTexture(awaitCaller, gltf, param.Index1.Value, false); + } + var converted = OcclusionMetallicRoughnessConverter.GetImportTexture(baseTexture.Texture, param.MetallicFactor, param.RoughnessFactor, occlusionBaseTexture.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: { var baseTexture = await GetOrCreateBaseTexture(awaitCaller, gltf, param.Index0.Value, true); diff --git a/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs b/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs index a8018e826..01f6cba6c 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/TextureTests.cs @@ -80,7 +80,7 @@ namespace UniGLTF { var roughnessFactor = 1.0f; Assert.That( - OcclusionMetallicRoughnessConverter.Import(new Color32(255, 255, 255, 255), roughnessFactor), + OcclusionMetallicRoughnessConverter.Import(new Color32(255, 255, 255, 255), 1.0f, roughnessFactor, default), // r <- 255 : Same metallic (src.r) // g <- 0 : (Unused) // b <- 0 : (Unused) @@ -91,7 +91,7 @@ namespace UniGLTF { var roughnessFactor = 1.0f; Assert.That( - OcclusionMetallicRoughnessConverter.Import(new Color32(255, 63, 255, 255), roughnessFactor), + OcclusionMetallicRoughnessConverter.Import(new Color32(255, 63, 255, 255), 1.0f, roughnessFactor, default), // r <- 255 : Same metallic (src.r) // g <- 0 : (Unused) // b <- 0 : (Unused) @@ -102,7 +102,7 @@ namespace UniGLTF { var roughnessFactor = 0.5f; Assert.That( - OcclusionMetallicRoughnessConverter.Import(new Color32(255, 255, 255, 255), roughnessFactor), + OcclusionMetallicRoughnessConverter.Import(new Color32(255, 255, 255, 255), 1.0f, roughnessFactor, default), // r <- 255 : Same metallic (src.r) // g <- 0 : (Unused) // b <- 0 : (Unused) @@ -113,7 +113,7 @@ namespace UniGLTF { var roughnessFactor = 0.0f; Assert.That( - OcclusionMetallicRoughnessConverter.Import(new Color32(255, 255, 255, 255), roughnessFactor), + OcclusionMetallicRoughnessConverter.Import(new Color32(255, 255, 255, 255), 1.0f, roughnessFactor, default), // r <- 255 : Same metallic (src.r) // g <- 0 : (Unused) // b <- 0 : (Unused)