diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfMaterialDescriptorGenerator.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfMaterialDescriptorGenerator.cs index c42568d8a..baabfe3d7 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfMaterialDescriptorGenerator.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfMaterialDescriptorGenerator.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using UnityEngine; using VRMShaders; @@ -12,19 +13,22 @@ namespace UniGLTF { public MaterialDescriptor Get(GltfData data, int i) { - if (!GltfUnlitMaterialImporter.TryCreateParam(data, i, out var param)) - { - if (!GltfPbrMaterialImporter.TryCreateParam(data, i, out param)) - { - // fallback + if (GltfUnlitMaterialImporter.TryCreateParam(data, i, out var param)) return param; + if (GltfPbrMaterialImporter.TryCreateParam(data, i, out param)) return param; + // fallback #if VRM_DEVELOP - Debug.LogWarning($"material: {i} out of range. fallback"); + Debug.LogWarning($"material: {i} out of range. fallback"); #endif - return new MaterialDescriptor(GetMaterialName(i, null), GltfPbrMaterialImporter.ShaderName); - } - } + return new MaterialDescriptor( + GetMaterialName(i, null), + GltfPbrMaterialImporter.ShaderName, + null, + new Dictionary(), + new Dictionary(), + new Dictionary(), + new Dictionary(), + new Action[]{}); - return param; } public static string GetMaterialName(int index, glTFMaterial src) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfPbrMaterialImporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfPbrMaterialImporter.cs index 58b50a157..c3500eeb3 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfPbrMaterialImporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfPbrMaterialImporter.cs @@ -1,4 +1,6 @@ -using UnityEngine; +using System; +using System.Collections.Generic; +using UnityEngine; using VRMShaders; using ColorSpace = VRMShaders.ColorSpace; @@ -38,6 +40,10 @@ namespace UniGLTF /// public static class GltfPbrMaterialImporter { + private static readonly int SrcBlend = Shader.PropertyToID("_SrcBlend"); + private static readonly int DstBlend = Shader.PropertyToID("_DstBlend"); + private static readonly int ZWrite = Shader.PropertyToID("_ZWrite"); + private static readonly int Cutoff = Shader.PropertyToID("_Cutoff"); public const string ShaderName = "Standard"; private enum BlendMode @@ -57,7 +63,12 @@ namespace UniGLTF } var src = data.GLTF.materials[i]; - matDesc = new MaterialDescriptor(GltfMaterialDescriptorGenerator.GetMaterialName(i, src), ShaderName); + + var textureSlots = new Dictionary(); + var floatValues = new Dictionary(); + var colors = new Dictionary(); + var vectors = new Dictionary(); + var actions = new List>(); var standardTexDesc = default(TextureDescriptor); if (src.pbrMetallicRoughness != null || src.occlusionTexture != null) @@ -68,52 +79,55 @@ namespace UniGLTF (key, standardTexDesc) = GltfPbrTextureImporter.StandardTexture(data, src); } - if (src.pbrMetallicRoughness.baseColorFactor != null && src.pbrMetallicRoughness.baseColorFactor.Length == 4) + if (src.pbrMetallicRoughness.baseColorFactor != null && + src.pbrMetallicRoughness.baseColorFactor.Length == 4) { - matDesc.Colors.Add("_Color", + colors.Add("_Color", src.pbrMetallicRoughness.baseColorFactor.ToColor4(ColorSpace.Linear, ColorSpace.sRGB) ); } - if (src.pbrMetallicRoughness.baseColorTexture != null && src.pbrMetallicRoughness.baseColorTexture.index != -1) + if (src.pbrMetallicRoughness.baseColorTexture != null && + src.pbrMetallicRoughness.baseColorTexture.index != -1) { var (key, textureParam) = GltfPbrTextureImporter.BaseColorTexture(data, src); - matDesc.TextureSlots.Add("_MainTex", textureParam); + textureSlots.Add("_MainTex", textureParam); } - if (src.pbrMetallicRoughness.metallicRoughnessTexture != null && src.pbrMetallicRoughness.metallicRoughnessTexture.index != -1) + if (src.pbrMetallicRoughness.metallicRoughnessTexture != null && + src.pbrMetallicRoughness.metallicRoughnessTexture.index != -1) { - matDesc.Actions.Add(material => material.EnableKeyword("_METALLICGLOSSMAP")); - matDesc.TextureSlots.Add("_MetallicGlossMap", standardTexDesc); + actions.Add(material => material.EnableKeyword("_METALLICGLOSSMAP")); + textureSlots.Add("_MetallicGlossMap", standardTexDesc); // Set 1.0f as hard-coded. See: https://github.com/dwango/UniVRM/issues/212. - matDesc.FloatValues.Add("_Metallic", 1.0f); - matDesc.FloatValues.Add("_GlossMapScale", 1.0f); + floatValues.Add("_Metallic", 1.0f); + floatValues.Add("_GlossMapScale", 1.0f); } else { - matDesc.FloatValues.Add("_Metallic", src.pbrMetallicRoughness.metallicFactor); - matDesc.FloatValues.Add("_Glossiness", 1.0f - src.pbrMetallicRoughness.roughnessFactor); + floatValues.Add("_Metallic", src.pbrMetallicRoughness.metallicFactor); + floatValues.Add("_Glossiness", 1.0f - src.pbrMetallicRoughness.roughnessFactor); } } if (src.normalTexture != null && src.normalTexture.index != -1) { - matDesc.Actions.Add(material => material.EnableKeyword("_NORMALMAP")); - var (key, textureParam) = GltfPbrTextureImporter.NormalTexture(data, src); - matDesc.TextureSlots.Add("_BumpMap", textureParam); - matDesc.FloatValues.Add("_BumpScale", src.normalTexture.scale); + actions.Add(material => material.EnableKeyword("_NORMALMAP")); + var (_, textureParam) = GltfPbrTextureImporter.NormalTexture(data, src); + textureSlots.Add("_BumpMap", textureParam); + floatValues.Add("_BumpScale", src.normalTexture.scale); } if (src.occlusionTexture != null && src.occlusionTexture.index != -1) { - matDesc.TextureSlots.Add("_OcclusionMap", standardTexDesc); - matDesc.FloatValues.Add("_OcclusionStrength", src.occlusionTexture.strength); + textureSlots.Add("_OcclusionMap", standardTexDesc); + floatValues.Add("_OcclusionStrength", src.occlusionTexture.strength); } if (src.emissiveFactor != null || (src.emissiveTexture != null && src.emissiveTexture.index != -1)) { - matDesc.Actions.Add(material => + actions.Add(material => { material.EnableKeyword("_EMISSION"); material.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack; @@ -123,32 +137,34 @@ namespace UniGLTF { var emissiveFactor = src.emissiveFactor.ToColor3(ColorSpace.Linear, ColorSpace.Linear); if (UniGLTF.Extensions.VRMC_materials_hdr_emissiveMultiplier.GltfDeserializer.TryGet(src.extensions, - out UniGLTF.Extensions.VRMC_materials_hdr_emissiveMultiplier.VRMC_materials_hdr_emissiveMultiplier ex)) + out UniGLTF.Extensions.VRMC_materials_hdr_emissiveMultiplier. + VRMC_materials_hdr_emissiveMultiplier ex)) { emissiveFactor *= ex.EmissiveMultiplier.Value; } - matDesc.Colors.Add("_EmissionColor", emissiveFactor); + + colors.Add("_EmissionColor", emissiveFactor); } if (src.emissiveTexture != null && src.emissiveTexture.index != -1) { var (key, textureParam) = GltfPbrTextureImporter.EmissiveTexture(data, src); - matDesc.TextureSlots.Add("_EmissionMap", textureParam); + textureSlots.Add("_EmissionMap", textureParam); } } - matDesc.Actions.Add(material => + actions.Add(material => { - BlendMode blendMode = BlendMode.Opaque; + BlendMode blendMode; // 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.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"); @@ -158,10 +174,10 @@ namespace UniGLTF 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.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"); @@ -172,9 +188,9 @@ namespace UniGLTF 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.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"); @@ -185,7 +201,17 @@ namespace UniGLTF material.SetFloat("_Mode", (float)blendMode); }); + matDesc = new MaterialDescriptor( + GltfMaterialDescriptorGenerator.GetMaterialName(i, src), + ShaderName, + null, + textureSlots, + floatValues, + colors, + vectors, + actions); + return true; } } -} +} \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfUnlitMaterialImporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfUnlitMaterialImporter.cs index a329b6ca1..e16b1fbd9 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfUnlitMaterialImporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfUnlitMaterialImporter.cs @@ -1,4 +1,7 @@ -using UniGLTF.UniUnlit; +using System; +using System.Collections.Generic; +using UniGLTF.UniUnlit; +using UnityEngine; using VRMShaders; using ColorSpace = VRMShaders.ColorSpace; @@ -6,6 +9,8 @@ namespace UniGLTF { public static class GltfUnlitMaterialImporter { + private static readonly int Cutoff = Shader.PropertyToID("_Cutoff"); + public static bool TryCreateParam(GltfData data, int i, out MaterialDescriptor matDesc) { if (i < 0 || i >= data.GLTF.materials.Count) @@ -21,67 +26,83 @@ namespace UniGLTF return false; } - matDesc = new MaterialDescriptor(GltfMaterialDescriptorGenerator.GetMaterialName(i, src), UniUnlitUtil.ShaderName); + var textureSlots = new Dictionary(); + var colors = + src.pbrMetallicRoughness.baseColorFactor != null && + src.pbrMetallicRoughness.baseColorFactor.Length == 4 + ? new Dictionary + { + { + "_Color", + src.pbrMetallicRoughness.baseColorFactor.ToColor4(ColorSpace.Linear, ColorSpace.sRGB) + } + } + : new Dictionary(); // texture if (src.pbrMetallicRoughness.baseColorTexture != null) { - var (offset, scale) = GltfTextureImporter.GetTextureOffsetAndScale(src.pbrMetallicRoughness.baseColorTexture); - var (key, textureParam) = GltfTextureImporter.CreateSRGB(data, src.pbrMetallicRoughness.baseColorTexture.index, offset, scale); - matDesc.TextureSlots.Add("_MainTex", textureParam); + var (offset, scale) = + GltfTextureImporter.GetTextureOffsetAndScale(src.pbrMetallicRoughness.baseColorTexture); + var (key, textureParam) = GltfTextureImporter.CreateSRGB(data, + src.pbrMetallicRoughness.baseColorTexture.index, offset, scale); + textureSlots.Add("_MainTex", textureParam); } - // color - if (src.pbrMetallicRoughness.baseColorFactor != null && src.pbrMetallicRoughness.baseColorFactor.Length == 4) - { - matDesc.Colors.Add("_Color", - src.pbrMetallicRoughness.baseColorFactor.ToColor4(ColorSpace.Linear, ColorSpace.sRGB) - ); - } + matDesc = new MaterialDescriptor( + GltfMaterialDescriptorGenerator.GetMaterialName(i, src), + UniUnlitUtil.ShaderName, + null, + textureSlots, + new Dictionary(), + colors, + new Dictionary(), + new Action[] + { + //renderMode + material => + { + switch (src.alphaMode) + { + case "OPAQUE": + UniUnlitUtil.SetRenderMode(material, UniUnlitRenderMode.Opaque); + break; + case "BLEND": + UniUnlitUtil.SetRenderMode(material, UniUnlitRenderMode.Transparent); + break; + case "MASK": + UniUnlitUtil.SetRenderMode(material, UniUnlitRenderMode.Cutout); + material.SetFloat(Cutoff, src.alphaCutoff); + break; + default: + // default OPAQUE + UniUnlitUtil.SetRenderMode(material, UniUnlitRenderMode.Opaque); + break; + } - //renderMode - matDesc.Actions.Add(material => - { - if (src.alphaMode == "OPAQUE") - { - UniUnlitUtil.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Opaque); - } - else if (src.alphaMode == "BLEND") - { - UniUnlitUtil.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Transparent); - } - else if (src.alphaMode == "MASK") - { - UniUnlitUtil.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Cutout); - material.SetFloat("_Cutoff", src.alphaCutoff); - } - else - { - // default OPAQUE - UniUnlitUtil.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Opaque); - } + // culling + if (src.doubleSided) + { + UniUnlitUtil.SetCullMode(material, UniUnlitCullMode.Off); + } + else + { + UniUnlitUtil.SetCullMode(material, UniUnlitCullMode.Back); + } - // culling - if (src.doubleSided) - { - UniUnlitUtil.SetCullMode(material, UniUnlit.UniUnlitCullMode.Off); - } - else - { - UniUnlitUtil.SetCullMode(material, UniUnlit.UniUnlitCullMode.Back); - } + // VColor + var hasVertexColor = data.GLTF.MaterialHasVertexColor(i); + if (hasVertexColor) + { + UniUnlitUtil.SetVColBlendMode(material, UniUnlitVertexColorBlendOp.Multiply); + } - // VColor - var hasVertexColor = data.GLTF.MaterialHasVertexColor(i); - if (hasVertexColor) - { - UniUnlitUtil.SetVColBlendMode(material, UniUnlit.UniUnlitVertexColorBlendOp.Multiply); + UniUnlitUtil.ValidateProperties(material, true); + } } - - UniUnlitUtil.ValidateProperties(material, true); - }); + ); return true; } } -} +} \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/GltfPbrURPMaterialImporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/GltfPbrURPMaterialImporter.cs index 93c8d7a31..ab61c3053 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/GltfPbrURPMaterialImporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/GltfPbrURPMaterialImporter.cs @@ -1,4 +1,6 @@ -using UnityEngine; +using System; +using System.Collections.Generic; +using UnityEngine; using VRMShaders; using ColorSpace = VRMShaders.ColorSpace; @@ -11,6 +13,10 @@ namespace UniGLTF /// public static class GltfPbrUrpMaterialImporter { + private static readonly int SrcBlend = Shader.PropertyToID("_SrcBlend"); + private static readonly int DstBlend = Shader.PropertyToID("_DstBlend"); + private static readonly int ZWrite = Shader.PropertyToID("_ZWrite"); + private static readonly int Cutoff = Shader.PropertyToID("_Cutoff"); public const string ShaderName = "Universal Render Pipeline/Lit"; private enum BlendMode @@ -29,8 +35,12 @@ namespace UniGLTF return false; } + var textureSlots = new Dictionary(); + var floatValues = new Dictionary(); + var colors = new Dictionary(); + var vectors = new Dictionary(); + var actions = new List>(); var src = data.GLTF.materials[i]; - matDesc = new MaterialDescriptor(GltfMaterialDescriptorGenerator.GetMaterialName(i, src), ShaderName); var standardTexDesc = default(TextureDescriptor); if (src.pbrMetallicRoughness != null || src.occlusionTexture != null) @@ -44,7 +54,7 @@ namespace UniGLTF if (src.pbrMetallicRoughness.baseColorFactor != null && src.pbrMetallicRoughness.baseColorFactor.Length == 4) { // from _Color ! - matDesc.Colors.Add("_BaseColor", + colors.Add("_BaseColor", src.pbrMetallicRoughness.baseColorFactor.ToColor4(ColorSpace.Linear, ColorSpace.sRGB) ); } @@ -53,45 +63,45 @@ namespace UniGLTF { var (key, textureParam) = GltfPbrTextureImporter.BaseColorTexture(data, src); // from _MainTex ! - matDesc.TextureSlots.Add("_BaseMap", textureParam); + textureSlots.Add("_BaseMap", textureParam); } if (src.pbrMetallicRoughness.metallicRoughnessTexture != null && src.pbrMetallicRoughness.metallicRoughnessTexture.index != -1) { - matDesc.Actions.Add(material => material.EnableKeyword("_METALLICGLOSSMAP")); - matDesc.TextureSlots.Add("_MetallicGlossMap", standardTexDesc); + actions.Add(material => material.EnableKeyword("_METALLICGLOSSMAP")); + textureSlots.Add("_MetallicGlossMap", standardTexDesc); // Set 1.0f as hard-coded. See: https://github.com/dwango/UniVRM/issues/212. - matDesc.FloatValues.Add("_Metallic", 1.0f); - matDesc.FloatValues.Add("_GlossMapScale", 1.0f); + floatValues.Add("_Metallic", 1.0f); + floatValues.Add("_GlossMapScale", 1.0f); // default value is 0.5 ! - matDesc.FloatValues.Add("_Smoothness", 1.0f); + floatValues.Add("_Smoothness", 1.0f); } else { - matDesc.FloatValues.Add("_Metallic", src.pbrMetallicRoughness.metallicFactor); + floatValues.Add("_Metallic", src.pbrMetallicRoughness.metallicFactor); // from _Glossiness ! - matDesc.FloatValues.Add("_Smoothness", 1.0f - src.pbrMetallicRoughness.roughnessFactor); + floatValues.Add("_Smoothness", 1.0f - src.pbrMetallicRoughness.roughnessFactor); } } if (src.normalTexture != null && src.normalTexture.index != -1) { - matDesc.Actions.Add(material => material.EnableKeyword("_NORMALMAP")); + actions.Add(material => material.EnableKeyword("_NORMALMAP")); var (key, textureParam) = GltfPbrTextureImporter.NormalTexture(data, src); - matDesc.TextureSlots.Add("_BumpMap", textureParam); - matDesc.FloatValues.Add("_BumpScale", src.normalTexture.scale); + textureSlots.Add("_BumpMap", textureParam); + floatValues.Add("_BumpScale", src.normalTexture.scale); } if (src.occlusionTexture != null && src.occlusionTexture.index != -1) { - matDesc.TextureSlots.Add("_OcclusionMap", standardTexDesc); - matDesc.FloatValues.Add("_OcclusionStrength", src.occlusionTexture.strength); + textureSlots.Add("_OcclusionMap", standardTexDesc); + floatValues.Add("_OcclusionStrength", src.occlusionTexture.strength); } if (src.emissiveFactor != null || (src.emissiveTexture != null && src.emissiveTexture.index != -1)) { - matDesc.Actions.Add(material => + actions.Add(material => { material.EnableKeyword("_EMISSION"); material.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack; @@ -105,17 +115,17 @@ namespace UniGLTF { emissiveFactor *= ex.EmissiveMultiplier.Value; } - matDesc.Colors.Add("_EmissionColor", emissiveFactor); + colors.Add("_EmissionColor", emissiveFactor); } if (src.emissiveTexture != null && src.emissiveTexture.index != -1) { var (key, textureParam) = GltfPbrTextureImporter.EmissiveTexture(data, src); - matDesc.TextureSlots.Add("_EmissionMap", textureParam); + textureSlots.Add("_EmissionMap", textureParam); } } - matDesc.Actions.Add(material => + actions.Add(material => { BlendMode blendMode = BlendMode.Opaque; // https://forum.unity.com/threads/standard-material-shader-ignoring-setfloat-property-_mode.344557/#post-2229980 @@ -124,9 +134,9 @@ namespace UniGLTF 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.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"); @@ -136,10 +146,10 @@ namespace UniGLTF 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.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"); @@ -150,9 +160,9 @@ namespace UniGLTF 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.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"); @@ -163,6 +173,15 @@ namespace UniGLTF material.SetFloat("_Mode", (float)blendMode); }); + matDesc = new MaterialDescriptor( + GltfMaterialDescriptorGenerator.GetMaterialName(i, src), + ShaderName, + null, + textureSlots, + floatValues, + colors, + vectors, + actions); return true; } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/GltfURPMaterialDescriptorGenerator.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/GltfURPMaterialDescriptorGenerator.cs index e5422ae9a..309fc82a7 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/GltfURPMaterialDescriptorGenerator.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/URP/GltfURPMaterialDescriptorGenerator.cs @@ -1,4 +1,6 @@ +using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using UnityEngine; using VRMShaders; @@ -12,19 +14,22 @@ namespace UniGLTF { public MaterialDescriptor Get(GltfData data, int i) { - if (!GltfUnlitMaterialImporter.TryCreateParam(data, i, out var param)) - { - if (!GltfPbrUrpMaterialImporter.TryCreateParam(data, i, out param)) - { - // fallback + if (GltfUnlitMaterialImporter.TryCreateParam(data, i, out var param)) return param; + if (GltfPbrUrpMaterialImporter.TryCreateParam(data, i, out param)) return param; + // fallback #if VRM_DEVELOP - Debug.LogWarning($"material: {i} out of range. fallback"); + Debug.LogWarning($"material: {i} out of range. fallback"); #endif - return new MaterialDescriptor(GetMaterialName(i, null), GltfPbrMaterialImporter.ShaderName); - } - } + return new MaterialDescriptor( + GetMaterialName(i, null), + GltfPbrMaterialImporter.ShaderName, + null, + new Dictionary(), + new Dictionary(), + new Dictionary(), + new Dictionary(), + new Collection>()); - return param; } public static string GetMaterialName(int index, glTFMaterial src) @@ -33,7 +38,8 @@ namespace UniGLTF { return src.name; } + return $"material_{index:00}"; } } -} +} \ No newline at end of file diff --git a/Assets/VRM/Runtime/IO/VRMMToonMaterialImporter.cs b/Assets/VRM/Runtime/IO/VRMMToonMaterialImporter.cs index 7a5b2b041..21ce7553d 100644 --- a/Assets/VRM/Runtime/IO/VRMMToonMaterialImporter.cs +++ b/Assets/VRM/Runtime/IO/VRMMToonMaterialImporter.cs @@ -1,4 +1,6 @@ -using UniGLTF; +using System; +using System.Collections.Generic; +using UniGLTF; using UnityEngine; using VRMShaders; @@ -6,13 +8,15 @@ namespace VRM { public static class VRMMToonMaterialImporter { - public static bool TryCreateParam(GltfData data, glTF_VRM_extensions vrm, int materialIdx, out MaterialDescriptor matDesc) + public static bool TryCreateParam(GltfData data, glTF_VRM_extensions vrm, int materialIdx, + out MaterialDescriptor matDesc) { if (vrm?.materialProperties == null || vrm.materialProperties.Count == 0) { matDesc = default; return false; } + if (materialIdx < 0 || materialIdx >= vrm.materialProperties.Count) { matDesc = default; @@ -20,7 +24,7 @@ namespace VRM } var vrmMaterial = vrm.materialProperties[materialIdx]; - if (vrmMaterial.shader == VRM.glTF_VRM_Material.VRM_USE_GLTFSHADER) + if (vrmMaterial.shader == glTF_VRM_Material.VRM_USE_GLTFSHADER) { // fallback to gltf matDesc = default; @@ -32,30 +36,41 @@ namespace VRM // // use material.name, because material name may renamed in GltfParser. var name = data.GLTF.materials[materialIdx].name; - matDesc = new MaterialDescriptor(name, vrmMaterial.shader); - matDesc.RenderQueue = vrmMaterial.renderQueue; + var textureSlots = new Dictionary(); + var floatValues = new Dictionary(); + var colors = new Dictionary(); + var vectors = new Dictionary(); + var actions = new List>(); + matDesc = new MaterialDescriptor( + name, + vrmMaterial.shader, + vrmMaterial.renderQueue, + textureSlots, + floatValues, + colors, + vectors, + actions); foreach (var kv in vrmMaterial.floatProperties) { - matDesc.FloatValues.Add(kv.Key, kv.Value); + floatValues.Add(kv.Key, kv.Value); } foreach (var kv in vrmMaterial.vectorProperties) { // vector4 exclude TextureOffsetScale - if (!vrmMaterial.textureProperties.ContainsKey(kv.Key)) - { - var v = new Vector4(kv.Value[0], kv.Value[1], kv.Value[2], kv.Value[3]); - matDesc.Vectors.Add(kv.Key, v); - } + if (vrmMaterial.textureProperties.ContainsKey(kv.Key)) continue; + var v = new Vector4(kv.Value[0], kv.Value[1], kv.Value[2], kv.Value[3]); + vectors.Add(kv.Key, v); } foreach (var kv in vrmMaterial.textureProperties) { - if (VRMMToonTextureImporter.TryGetTextureFromMaterialProperty(data, vrmMaterial, kv.Key, out var texture)) + if (VRMMToonTextureImporter.TryGetTextureFromMaterialProperty(data, vrmMaterial, kv.Key, + out var texture)) { - matDesc.TextureSlots.Add(kv.Key, texture.Item2); + textureSlots.Add(kv.Key, texture.Item2); } } @@ -63,28 +78,27 @@ namespace VRM { if (kv.Value) { - matDesc.Actions.Add(material => material.EnableKeyword(kv.Key)); + actions.Add(material => material.EnableKeyword(kv.Key)); } else { - matDesc.Actions.Add(material => material.DisableKeyword(kv.Key)); + actions.Add(material => material.DisableKeyword(kv.Key)); } } foreach (var kv in vrmMaterial.tagMap) { - matDesc.Actions.Add(material => material.SetOverrideTag(kv.Key, kv.Value)); + actions.Add(material => material.SetOverrideTag(kv.Key, kv.Value)); } if (vrmMaterial.shader == MToon.Utils.ShaderName) { // TODO: Material拡張にMToonの項目が追加されたら旧バージョンのshaderPropから変換をかける // インポート時にUniVRMに含まれるMToonのバージョンに上書きする - matDesc.FloatValues[MToon.Utils.PropVersion] = MToon.Utils.VersionNumber; + floatValues[MToon.Utils.PropVersion] = MToon.Utils.VersionNumber; } return true; } - } -} +} \ No newline at end of file diff --git a/Assets/VRM/Runtime/IO/VRMMaterialDescriptorGenerator.cs b/Assets/VRM/Runtime/IO/VRMMaterialDescriptorGenerator.cs index 3a88732a7..80de66b31 100644 --- a/Assets/VRM/Runtime/IO/VRMMaterialDescriptorGenerator.cs +++ b/Assets/VRM/Runtime/IO/VRMMaterialDescriptorGenerator.cs @@ -1,4 +1,6 @@ -using UniGLTF; +using System; +using System.Collections.Generic; +using UniGLTF; using UnityEngine; using VRMShaders; @@ -14,10 +16,8 @@ namespace VRM public MaterialDescriptor Get(GltfData data, int i) { - MaterialDescriptor matDesc; - // legacy "VRM/UnlitTransparentZWrite" - if (VRMUnlitTransparentZWriteMaterialImporter.TryCreateParam(data, m_vrm, i, out matDesc)) + if (VRMUnlitTransparentZWriteMaterialImporter.TryCreateParam(data, m_vrm, i, out var matDesc)) { return matDesc; } @@ -42,7 +42,15 @@ namespace VRM // fallback Debug.LogWarning($"fallback"); - return new MaterialDescriptor(GltfMaterialDescriptorGenerator.GetMaterialName(i, null), GltfPbrMaterialImporter.ShaderName); + return new MaterialDescriptor( + GltfMaterialDescriptorGenerator.GetMaterialName(i, null), + GltfPbrMaterialImporter.ShaderName, + null, + new Dictionary(), + new Dictionary(), + new Dictionary(), + new Dictionary(), + new Action[]{}); } } } diff --git a/Assets/VRM/Runtime/IO/VRMURPMaterialDescriptorGenerator.cs b/Assets/VRM/Runtime/IO/VRMURPMaterialDescriptorGenerator.cs index 376198d32..1ca38753a 100644 --- a/Assets/VRM/Runtime/IO/VRMURPMaterialDescriptorGenerator.cs +++ b/Assets/VRM/Runtime/IO/VRMURPMaterialDescriptorGenerator.cs @@ -1,4 +1,6 @@ -using UniGLTF; +using System; +using System.Collections.Generic; +using UniGLTF; using UnityEngine; using VRMShaders; @@ -16,19 +18,22 @@ namespace VRM { // mtoon URP "MToon" shader is not ready. import fallback to unlit // unlit "UniUnlit" work in URP - if (!GltfUnlitMaterialImporter.TryCreateParam(data, i, out MaterialDescriptor matDesc)) - { - // pbr "Standard" to "Universal Render Pipeline/Lit" - if (!GltfPbrUrpMaterialImporter.TryCreateParam(data, i, out matDesc)) - { - // fallback + if (GltfUnlitMaterialImporter.TryCreateParam(data, i, out var matDesc)) return matDesc; + // pbr "Standard" to "Universal Render Pipeline/Lit" + if (GltfPbrUrpMaterialImporter.TryCreateParam(data, i, out matDesc)) return matDesc; + // fallback #if VRM_DEVELOP - Debug.LogWarning($"material: {i} out of range. fallback"); + Debug.LogWarning($"material: {i} out of range. fallback"); #endif - return new MaterialDescriptor(GltfMaterialDescriptorGenerator.GetMaterialName(i, null), GltfPbrMaterialImporter.ShaderName); - } - } - return matDesc; + return new MaterialDescriptor( + GltfMaterialDescriptorGenerator.GetMaterialName(i, null), + GltfPbrMaterialImporter.ShaderName, + null, + new Dictionary(), + new Dictionary(), + new Dictionary(), + new Dictionary(), + new Action[]{}); } } } diff --git a/Assets/VRM/Runtime/IO/VRMUnlitTransparentZWriteMaterialImporter.cs b/Assets/VRM/Runtime/IO/VRMUnlitTransparentZWriteMaterialImporter.cs index dee6fd95f..9d8a57780 100644 --- a/Assets/VRM/Runtime/IO/VRMUnlitTransparentZWriteMaterialImporter.cs +++ b/Assets/VRM/Runtime/IO/VRMUnlitTransparentZWriteMaterialImporter.cs @@ -1,3 +1,6 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; using MToon; using UniGLTF; using UnityEngine; @@ -11,13 +14,15 @@ namespace VRM public const string UnlitTransparentZWriteShaderName = "VRM/UnlitTransparentZWrite"; public const string UnlitTransparentZWriteMainTexturePropName = "_MainTex"; - public static bool TryCreateParam(GltfData data, glTF_VRM_extensions vrm, int materialIdx, out MaterialDescriptor matDesc) + public static bool TryCreateParam(GltfData data, glTF_VRM_extensions vrm, int materialIdx, + out MaterialDescriptor matDesc) { if (vrm?.materialProperties == null || vrm.materialProperties.Count == 0) { matDesc = default; return false; } + if (materialIdx < 0 || materialIdx >= vrm.materialProperties.Count) { matDesc = default; @@ -34,19 +39,24 @@ namespace VRM // use material.name, because material name may renamed in GltfParser. var name = data.GLTF.materials[materialIdx].name; - matDesc = new MaterialDescriptor(name, MToon.Utils.ShaderName); + var textureSlots = new Dictionary(); + var floatValues = new Dictionary(); + var colors = new Dictionary(); + var vectors = new Dictionary(); + var actions = new Collection>(); if (vrmMaterial.textureProperties.ContainsKey(UnlitTransparentZWriteMainTexturePropName)) { - if (VRMMToonTextureImporter.TryGetTextureFromMaterialProperty(data, vrmMaterial, UnlitTransparentZWriteMainTexturePropName, out var texture)) + if (VRMMToonTextureImporter.TryGetTextureFromMaterialProperty(data, vrmMaterial, + UnlitTransparentZWriteMainTexturePropName, out var texture)) { - matDesc.TextureSlots.Add(MToon.Utils.PropMainTex, texture.Item2); + textureSlots.Add(MToon.Utils.PropMainTex, texture.Item2); } } - matDesc.Actions.Add(unityMaterial => + actions.Add(unityMaterial => { - var mainTexture = (Texture2D) unityMaterial.GetTexture(MToon.Utils.PropMainTex); + var mainTexture = (Texture2D)unityMaterial.GetTexture(MToon.Utils.PropMainTex); // NOTE: Unlit のフォールバックなので // Lit/Shade 色は黒として、Alpha のために Lit にテクスチャを設定する. @@ -148,8 +158,15 @@ namespace VRM unityMaterial.renderQueue = vrmMaterial.renderQueue; }); + matDesc = new MaterialDescriptor(name, Utils.ShaderName, null, + textureSlots, + floatValues, + colors, + vectors, + actions); + Debug.LogWarning($"fallback: {UnlitTransparentZWriteShaderName} => {MToon.Utils.ShaderName}"); return true; } } -} +} \ No newline at end of file diff --git a/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialImporter.cs b/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialImporter.cs index 982c6e7ea..d1bd9d342 100644 --- a/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialImporter.cs +++ b/Assets/VRM10/Runtime/IO/Material/Vrm10MToonMaterialImporter.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using UniGLTF; using UniGLTF.Extensions.VRMC_materials_mtoon; using UnityEngine; @@ -30,33 +31,22 @@ namespace UniVRM10 } // use material.name, because material name may renamed in GltfParser. - matDesc = new MaterialDescriptor(m.name, MToon10Meta.UnityShaderName); - - foreach (var (key, (subAssetKey, value)) in Vrm10MToonTextureImporter.EnumerateAllTextures(data, m, mtoon)) - { - matDesc.TextureSlots.Add(key, value); - } - - foreach (var (key, value) in TryGetAllColors(m, mtoon)) - { - matDesc.Colors.Add(key, value); - } - - foreach (var (key, value) in TryGetAllFloats(m, mtoon)) - { - matDesc.FloatValues.Add(key, value); - } - - foreach (var (key, value) in TryGetAllFloatArrays(m, mtoon)) - { - matDesc.Vectors.Add(key, value); - } - - matDesc.Actions.Add(material => - { - // Set hidden properties, keywords from float properties. - new MToonValidator(material).Validate(); - }); + matDesc = new MaterialDescriptor( + m.name, + MToon10Meta.UnityShaderName, + null, + Vrm10MToonTextureImporter.EnumerateAllTextures(data, m, mtoon).ToDictionary(tuple => tuple.key, tuple => tuple.Item2.Item2), + TryGetAllFloats(m, mtoon).ToDictionary(tuple => tuple.key, tuple => tuple.value), + TryGetAllColors(m, mtoon).ToDictionary(tuple => tuple.key, tuple => tuple.value), + TryGetAllFloatArrays(m, mtoon).ToDictionary(tuple => tuple.key, tuple => tuple.value), + new Action[] + { + material => + { + // Set hidden properties, keywords from float properties. + new MToonValidator(material).Validate(); + } + }); return true; } diff --git a/Assets/VRM10/Runtime/IO/Material/Vrm10MaterialDescriptorGenerator.cs b/Assets/VRM10/Runtime/IO/Material/Vrm10MaterialDescriptorGenerator.cs index c15038180..2f242595b 100644 --- a/Assets/VRM10/Runtime/IO/Material/Vrm10MaterialDescriptorGenerator.cs +++ b/Assets/VRM10/Runtime/IO/Material/Vrm10MaterialDescriptorGenerator.cs @@ -1,4 +1,6 @@ -using UniGLTF; +using System; +using System.Collections.Generic; +using UniGLTF; using UnityEngine; using VRMShaders; @@ -9,23 +11,23 @@ namespace UniVRM10 public MaterialDescriptor Get(GltfData data, int i) { // mtoon - if (!Vrm10MToonMaterialImporter.TryCreateParam(data, i, out MaterialDescriptor matDesc)) - { - // unlit - if (!GltfUnlitMaterialImporter.TryCreateParam(data, i, out matDesc)) - { - // pbr - if (!GltfPbrMaterialImporter.TryCreateParam(data, i, out matDesc)) - { - // fallback + if (Vrm10MToonMaterialImporter.TryCreateParam(data, i, out MaterialDescriptor matDesc)) return matDesc; + // unlit + if (GltfUnlitMaterialImporter.TryCreateParam(data, i, out matDesc)) return matDesc; + // pbr + if (GltfPbrMaterialImporter.TryCreateParam(data, i, out matDesc)) return matDesc; + // fallback #if VRM_DEVELOP - Debug.LogWarning($"material: {i} out of range. fallback"); + Debug.LogWarning($"material: {i} out of range. fallback"); #endif - return new MaterialDescriptor(GltfMaterialDescriptorGenerator.GetMaterialName(i, null), GltfPbrMaterialImporter.ShaderName); - } - } - } - return matDesc; + return new MaterialDescriptor( + GltfMaterialDescriptorGenerator.GetMaterialName(i, null), GltfPbrMaterialImporter.ShaderName, + null, + new Dictionary(), + new Dictionary(), + new Dictionary(), + new Dictionary(), + new Action[]{}); } } diff --git a/Assets/VRM10/Runtime/IO/Material/Vrm10UrpMaterialDescriptorGenerator.cs b/Assets/VRM10/Runtime/IO/Material/Vrm10UrpMaterialDescriptorGenerator.cs index 49434506f..ca719650d 100644 --- a/Assets/VRM10/Runtime/IO/Material/Vrm10UrpMaterialDescriptorGenerator.cs +++ b/Assets/VRM10/Runtime/IO/Material/Vrm10UrpMaterialDescriptorGenerator.cs @@ -1,4 +1,6 @@ -using UniGLTF; +using System; +using System.Collections.Generic; +using UniGLTF; using UnityEngine; using VRMShaders; @@ -9,17 +11,20 @@ namespace UniVRM10 public MaterialDescriptor Get(GltfData data, int i) { // unlit - if (!GltfUnlitMaterialImporter.TryCreateParam(data, i, out MaterialDescriptor matDesc)) - { - // pbr - if (!GltfPbrUrpMaterialImporter.TryCreateParam(data, i, out matDesc)) - { - // fallback - Debug.LogWarning($"material: {i} out of range. fallback"); - return new MaterialDescriptor(GltfMaterialDescriptorGenerator.GetMaterialName(i, null), GltfPbrMaterialImporter.ShaderName); - } - } - return matDesc; + if (GltfUnlitMaterialImporter.TryCreateParam(data, i, out MaterialDescriptor matDesc)) return matDesc; + // pbr + if (GltfPbrUrpMaterialImporter.TryCreateParam(data, i, out matDesc)) return matDesc; + // fallback + Debug.LogWarning($"material: {i} out of range. fallback"); + return new MaterialDescriptor( + GltfMaterialDescriptorGenerator.GetMaterialName(i, null), + GltfPbrMaterialImporter.ShaderName, + null, + new Dictionary(), + new Dictionary(), + new Dictionary(), + new Dictionary(), + new Action[]{}); } } diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/Material/Importer/MaterialDescriptor.cs b/Assets/VRMShaders/GLTF/IO/Runtime/Material/Importer/MaterialDescriptor.cs index 5a2354c86..65b984c41 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/Material/Importer/MaterialDescriptor.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/Material/Importer/MaterialDescriptor.cs @@ -2,26 +2,65 @@ using System.Collections.Generic; using UnityEngine; - namespace VRMShaders { - public class MaterialDescriptor + public readonly struct MaterialDescriptor : IEquatable { public readonly string Name; public readonly string ShaderName; - public readonly Dictionary TextureSlots = new Dictionary(); - public readonly Dictionary FloatValues = new Dictionary(); - public readonly Dictionary Colors = new Dictionary(); - public readonly Dictionary Vectors = new Dictionary(); - public int? RenderQueue; - public readonly List> Actions = new List>(); + public readonly int? RenderQueue; + public readonly IReadOnlyDictionary TextureSlots; + public readonly IReadOnlyDictionary FloatValues; + public readonly IReadOnlyDictionary Colors; + public readonly IReadOnlyDictionary Vectors; + public readonly IReadOnlyList> Actions; public SubAssetKey SubAssetKey => new SubAssetKey(SubAssetKey.MaterialType, Name); - public MaterialDescriptor(string name, string shaderName) + public MaterialDescriptor( + string name, + string shaderName, + int? renderQueue, + IReadOnlyDictionary textureSlots, + IReadOnlyDictionary floatValues, + IReadOnlyDictionary colors, + IReadOnlyDictionary vectors, + IReadOnlyList> actions) { Name = name; ShaderName = shaderName; + RenderQueue = renderQueue; + TextureSlots = textureSlots; + FloatValues = floatValues; + Colors = colors; + Vectors = vectors; + Actions = actions; + } + + public bool Equals(MaterialDescriptor other) + { + return Name == other.Name && ShaderName == other.ShaderName && RenderQueue == other.RenderQueue && Equals(TextureSlots, other.TextureSlots) && Equals(FloatValues, other.FloatValues) && Equals(Colors, other.Colors) && Equals(Vectors, other.Vectors) && Equals(Actions, other.Actions); + } + + public override bool Equals(object obj) + { + return obj is MaterialDescriptor other && Equals(other); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = (Name != null ? Name.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (ShaderName != null ? ShaderName.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ RenderQueue.GetHashCode(); + hashCode = (hashCode * 397) ^ (TextureSlots != null ? TextureSlots.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (FloatValues != null ? FloatValues.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (Colors != null ? Colors.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (Vectors != null ? Vectors.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (Actions != null ? Actions.GetHashCode() : 0); + return hashCode; + } } } -} +} \ No newline at end of file