From 589d5504a7243543f910d071b2ab12011a7d5349 Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Thu, 27 May 2021 21:44:09 +0900 Subject: [PATCH 1/5] Rename normal map exporter --- .../Resources/Shaders/NormalMapDecoder.shader | 54 ------------------ .../Shaders/NormalMapExporter.shader | 55 +++++++++++++++++++ ...der.meta => NormalMapExporter.shader.meta} | 0 .../GLTF/IO/Runtime/NormalConverter.cs | 12 ++-- 4 files changed, 61 insertions(+), 60 deletions(-) delete mode 100644 Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/NormalMapDecoder.shader create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/NormalMapExporter.shader rename Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/{NormalMapDecoder.shader.meta => NormalMapExporter.shader.meta} (100%) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/NormalMapDecoder.shader b/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/NormalMapDecoder.shader deleted file mode 100644 index 76b76f285..000000000 --- a/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/NormalMapDecoder.shader +++ /dev/null @@ -1,54 +0,0 @@ -Shader "UniGLTF/NormalMapDecoder" -{ - Properties - { - _MainTex ("Texture", 2D) = "white" {} - } - SubShader - { - // No culling or depth - Cull Off ZWrite Off ZTest Always - - Pass - { - CGPROGRAM - #pragma vertex vert - #pragma fragment frag - - #include "UnityCG.cginc" - - struct appdata - { - float4 vertex : POSITION; - float2 uv : TEXCOORD0; - }; - - struct v2f - { - float2 uv : TEXCOORD0; - float4 vertex : SV_POSITION; - }; - - v2f vert (appdata v) - { - v2f o; - o.vertex = UnityObjectToClipPos(v.vertex); - o.uv = v.uv; - return o; - } - - sampler2D _MainTex; - - fixed4 frag (v2f i) : SV_Target - { - half4 col = tex2D(_MainTex, i.uv); - - col.xyz = (UnpackNormal(col) + 1) * 0.5; - col.w = 1; - - return col; - } - ENDCG - } - } -} diff --git a/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/NormalMapExporter.shader b/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/NormalMapExporter.shader new file mode 100644 index 000000000..4480b321e --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/NormalMapExporter.shader @@ -0,0 +1,55 @@ +Shader "Hidden/UniGLTF/NormalMapExporter" +{ + Properties + { + _MainTex ("Texture", 2D) = "white" {} + } + SubShader + { + // No culling or depth + Cull Off ZWrite Off ZTest Always + + Pass + { + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + + #include "UnityCG.cginc" + + struct appdata + { + float4 vertex : POSITION; + float2 uv : TEXCOORD0; + }; + + struct v2f + { + float2 uv : TEXCOORD0; + float4 vertex : SV_POSITION; + }; + + v2f vert (appdata v) + { + v2f o; + o.vertex = UnityObjectToClipPos(v.vertex); + o.uv = v.uv; + return o; + } + + sampler2D _MainTex; + + fixed4 frag (v2f i) : SV_Target + { + half4 col = tex2D(_MainTex, i.uv); + + // Convert from compressed normal value to usual normal value. + col.xyz = (UnpackNormal(col) + 1) * 0.5; + col.w = 1; + + return col; + } + ENDCG + } + } +} diff --git a/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/NormalMapDecoder.shader.meta b/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/NormalMapExporter.shader.meta similarity index 100% rename from Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/NormalMapDecoder.shader.meta rename to Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/NormalMapExporter.shader.meta diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/NormalConverter.cs b/Assets/VRMShaders/GLTF/IO/Runtime/NormalConverter.cs index d87b40ff4..ebb7589c6 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/NormalConverter.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/NormalConverter.cs @@ -4,23 +4,23 @@ namespace VRMShaders { public static class NormalConverter { - private static Material m_decoder; - private static Material Decoder + private static Material _exporter; + private static Material Exporter { get { - if (m_decoder == null) + if (_exporter == null) { - m_decoder = new Material(Shader.Find("UniGLTF/NormalMapDecoder")); + _exporter = new Material(Shader.Find("Hidden/UniGLTF/NormalMapExporter")); } - return m_decoder; + return _exporter; } } // Unity texture to GLTF data public static Texture2D Export(Texture texture) { - return TextureConverter.CopyTexture(texture, ColorSpace.Linear, false, Decoder); + return TextureConverter.CopyTexture(texture, ColorSpace.Linear, false, Exporter); } } } From 283efdeadb5817f2467b7a689327eac34fb3da3f Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Thu, 27 May 2021 21:44:55 +0900 Subject: [PATCH 2/5] Remove unused shader --- .../Resources/Shaders/StandardVColor.shader | 56 ------------------- .../Shaders/StandardVColor.shader.meta | 9 --- 2 files changed, 65 deletions(-) delete mode 100644 Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/StandardVColor.shader delete mode 100644 Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/StandardVColor.shader.meta diff --git a/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/StandardVColor.shader b/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/StandardVColor.shader deleted file mode 100644 index 2cf04f963..000000000 --- a/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/StandardVColor.shader +++ /dev/null @@ -1,56 +0,0 @@ -// Upgrade NOTE: upgraded instancing buffer 'Props' to new syntax. - -Shader "UniGLTF/StandardVColor" { - Properties { - _Color ("Color", Color) = (1,1,1,1) - _MainTex ("Albedo (RGB)", 2D) = "white" {} - _Glossiness ("Smoothness", Range(0,1)) = 0.5 - _Metallic ("Metallic", Range(0,1)) = 0.0 - } - SubShader { - Tags { "RenderType"="Opaque" } - LOD 200 - - CGPROGRAM - // Physically based Standard lighting model, and enable shadows on all light types - #pragma surface surf Standard fullforwardshadows vertex:vert - - // Use shader model 3.0 target, to get nicer looking lighting - #pragma target 3.0 - - sampler2D _MainTex; - - struct Input { - float2 uv_MainTex; - float4 v_Color; - }; - - half _Glossiness; - half _Metallic; - fixed4 _Color; - - // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader. - // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing. - // #pragma instancing_options assumeuniformscaling - UNITY_INSTANCING_BUFFER_START(Props) - // put more per-instance properties here - UNITY_INSTANCING_BUFFER_END(Props) - - void vert(inout appdata_full v, out Input o){ - UNITY_INITIALIZE_OUTPUT(Input, o); - o.v_Color = v.color; - } - - void surf (Input IN, inout SurfaceOutputStandard o) { - // Albedo comes from a texture tinted by color - fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color; - o.Albedo = c.rgb * IN.v_Color.rgb; - // Metallic and smoothness come from slider variables - o.Metallic = _Metallic; - o.Smoothness = _Glossiness; - o.Alpha = c.a; - } - ENDCG - } - FallBack "Diffuse" -} diff --git a/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/StandardVColor.shader.meta b/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/StandardVColor.shader.meta deleted file mode 100644 index 2efb7376e..000000000 --- a/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/StandardVColor.shader.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 5ef7bdb14a8f23043805e41692d10787 -timeCreated: 1528269709 -licenseType: Pro -ShaderImporter: - defaultTextures: [] - userData: - assetBundleName: - assetBundleVariant: From 06715ab77b3cf9e354ab872e66522465a914818b Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Thu, 27 May 2021 22:24:25 +0900 Subject: [PATCH 3/5] fix bug --- .../GLTF/IO/Runtime/OcclusionMetallicRoughnessConverter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/OcclusionMetallicRoughnessConverter.cs b/Assets/VRMShaders/GLTF/IO/Runtime/OcclusionMetallicRoughnessConverter.cs index 3d4635081..539500883 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/OcclusionMetallicRoughnessConverter.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/OcclusionMetallicRoughnessConverter.cs @@ -146,7 +146,7 @@ namespace VRMShaders } else if (occlusionTexture) { - var dst = TextureConverter.CreateEmptyTextureWithSettings(metallicSmoothTexture, ColorSpace.Linear, false); + var dst = TextureConverter.CreateEmptyTextureWithSettings(occlusionTexture, ColorSpace.Linear, false); var linearOcclusion = TextureConverter.CopyTexture(occlusionTexture, ColorSpace.Linear, false, null); dst.SetPixels32(linearOcclusion.GetPixels32().Select(x => ExportPixel(default, smoothness, x)).ToArray()); dst.Apply(); From 9aee0b1ea33ec0ca2733d85b971866c327792ada Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Thu, 27 May 2021 22:27:51 +0900 Subject: [PATCH 4/5] Implements standard texture importing with shader --- .../Shaders/StandardMapImporter.shader | 68 ++++++++++++++ .../Shaders/StandardMapImporter.shader.meta | 9 ++ .../OcclusionMetallicRoughnessConverter.cs | 89 ++++++------------- .../Tests/MetallicRoughnessConverterTests.cs | 35 +++++++- 4 files changed, 135 insertions(+), 66 deletions(-) create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/StandardMapImporter.shader create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/StandardMapImporter.shader.meta diff --git a/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/StandardMapImporter.shader b/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/StandardMapImporter.shader new file mode 100644 index 000000000..3115bd222 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/StandardMapImporter.shader @@ -0,0 +1,68 @@ +Shader "Hidden/UniGLTF/StandardMapImporter" +{ + Properties + { + _MainTex ("Texture", 2D) = "white" {} + _GltfMetallicFactor ("glTF Metallic Factor", Float) = 0.0 + _GltfRoughnessFactor ("glTF Roughness Factor", Float) = 0.0 + _GltfMetallicRoughnessTexture ("glTF Metallic Roughness Texture", 2D) = "black" {} + _GltfOcclusionTexture ("glTF Occlusion Texture", 2D) = "black" {} + } + SubShader + { + // No culling or depth + Cull Off ZWrite Off ZTest Always + + Pass + { + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + + #include "UnityCG.cginc" + + struct appdata + { + float4 vertex : POSITION; + float2 uv : TEXCOORD0; + }; + + struct v2f + { + float2 uv : TEXCOORD0; + float4 vertex : SV_POSITION; + }; + + v2f vert (appdata v) + { + v2f o; + o.vertex = UnityObjectToClipPos(v.vertex); + o.uv = v.uv; + return o; + } + + sampler2D _MainTex; + half _GltfMetallicFactor; + half _GltfRoughnessFactor; + sampler2D _GltfMetallicRoughnessTexture; + sampler2D _GltfOcclusionTexture; + + fixed4 frag (v2f i) : SV_Target + { + half4 metallicRoughness = tex2D(_GltfMetallicRoughnessTexture, i.uv); + half metallic = metallicRoughness.b * _GltfMetallicFactor; + half roughness = metallicRoughness.g * _GltfRoughnessFactor; + half occlusion = tex2D(_GltfOcclusionTexture, i.uv).r; + + fixed4 result; + result.r = metallic; // R: Unity Metallic + result.g = occlusion; // G: Unity Occlusion + result.b = 0; // B: Unity Heightmap (no use) + result.a = 1.0 - roughness; // A: Unity Smoothness + + return result; + } + ENDCG + } + } +} diff --git a/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/StandardMapImporter.shader.meta b/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/StandardMapImporter.shader.meta new file mode 100644 index 000000000..a3de647a4 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/StandardMapImporter.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: fa5d94522a5d93442a7515698d7ab799 +timeCreated: 1533558728 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/OcclusionMetallicRoughnessConverter.cs b/Assets/VRMShaders/GLTF/IO/Runtime/OcclusionMetallicRoughnessConverter.cs index 539500883..72d4e8e8f 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/OcclusionMetallicRoughnessConverter.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/OcclusionMetallicRoughnessConverter.cs @@ -21,77 +21,42 @@ namespace VRMShaders /// public static class OcclusionMetallicRoughnessConverter { - public static Texture2D Import(Texture2D metallicRoughnessTexture, - float metallicFactor, float roughnessFactor, Texture2D occlusionTexture) + private static Material exporter; + private static Material Exporter { - // TODO: Replace with Shader implementation - if (metallicRoughnessTexture != null && occlusionTexture != null) + get { - if (metallicRoughnessTexture == occlusionTexture) + if (exporter == null) { - var copyMetallicRoughness = TextureConverter.CopyTexture(metallicRoughnessTexture, ColorSpace.Linear, true, null); - var metallicRoughnessPixels = copyMetallicRoughness.GetPixels32(); - for (int i = 0; i < metallicRoughnessPixels.Length; ++i) - { - metallicRoughnessPixels[i] = ImportPixel(metallicRoughnessPixels[i], metallicFactor, roughnessFactor, metallicRoughnessPixels[i]); - } - copyMetallicRoughness.SetPixels32(metallicRoughnessPixels); - copyMetallicRoughness.Apply(); - copyMetallicRoughness.name = metallicRoughnessTexture.name; - return copyMetallicRoughness; + exporter = new Material(Shader.Find("Hidden/UniGLTF/StandardMapImporter")); } - else - { - var copyMetallicRoughness = TextureConverter.CopyTexture(metallicRoughnessTexture, ColorSpace.Linear, true, null); - var metallicRoughnessPixels = copyMetallicRoughness.GetPixels32(); - var copyOcclusion = TextureConverter.CopyTexture(occlusionTexture, ColorSpace.Linear, false, null); - var occlusionPixels = copyOcclusion.GetPixels32(); - if (metallicRoughnessPixels.Length != occlusionPixels.Length) - { - throw new NotImplementedException(); - } - for (int i = 0; i < metallicRoughnessPixels.Length; ++i) - { - metallicRoughnessPixels[i] = ImportPixel(metallicRoughnessPixels[i], metallicFactor, roughnessFactor, occlusionPixels[i]); - } - copyMetallicRoughness.SetPixels32(metallicRoughnessPixels); - copyMetallicRoughness.Apply(); - copyMetallicRoughness.name = metallicRoughnessTexture.name; - DestroyTexture(copyOcclusion); - return copyMetallicRoughness; - } - } - else if (metallicRoughnessTexture != null) - { - var copyTexture = TextureConverter.CopyTexture(metallicRoughnessTexture, ColorSpace.Linear, true, null); - copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => ImportPixel(x, metallicFactor, roughnessFactor, default)).ToArray()); - copyTexture.Apply(); - copyTexture.name = metallicRoughnessTexture.name; - return copyTexture; - } - else if (occlusionTexture != null) - { - var copyTexture = TextureConverter.CopyTexture(occlusionTexture, ColorSpace.Linear, true, null); - copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => ImportPixel(default, metallicFactor, roughnessFactor, x)).ToArray()); - copyTexture.Apply(); - copyTexture.name = occlusionTexture.name; - return copyTexture; - } - else - { - throw new ArgumentNullException("no texture"); + return exporter; } } - public static Color32 ImportPixel(Color32 metallicRoughness, float metallicFactor, float roughnessFactor, Color32 occlusion) + public static Texture2D Import(Texture2D metallicRoughnessTexture, + float metallicFactor, float roughnessFactor, Texture2D occlusionTexture) { - var dst = new Color32 + if (metallicRoughnessTexture == null && occlusionTexture == null) { - r = (byte)(metallicRoughness.b * metallicFactor), // Metallic - g = occlusion.r, // Occlusion - b = 0, // not used - a = (byte)(255 - metallicRoughness.g * roughnessFactor), // Roughness to Smoothness - }; + throw new ArgumentNullException("no texture"); + } + + var src = metallicRoughnessTexture != null ? metallicRoughnessTexture : occlusionTexture; + + Exporter.mainTexture = src; + Exporter.SetTexture("_GltfMetallicRoughnessTexture", metallicRoughnessTexture); + Exporter.SetTexture("_GltfOcclusionTexture", occlusionTexture); + Exporter.SetFloat("_GltfMetallicFactor", metallicFactor); + Exporter.SetFloat("_GltfRoughnessFactor", roughnessFactor); + + var dst = TextureConverter.CopyTexture(src, ColorSpace.Linear, true, Exporter); + + Exporter.mainTexture = null; + Exporter.SetTexture("_GltfMetallicRoughnessTexture", null); + Exporter.SetTexture("_GltfOcclusionTexture", null); + Exporter.SetFloat("_GltfMetallicFactor", 0); + Exporter.SetFloat("_GltfRoughnessFactor", 0); return dst; } diff --git a/Assets/VRMShaders/GLTF/IO/Tests/MetallicRoughnessConverterTests.cs b/Assets/VRMShaders/GLTF/IO/Tests/MetallicRoughnessConverterTests.cs index 7c90a8943..e44377f01 100644 --- a/Assets/VRMShaders/GLTF/IO/Tests/MetallicRoughnessConverterTests.cs +++ b/Assets/VRMShaders/GLTF/IO/Tests/MetallicRoughnessConverterTests.cs @@ -1,3 +1,4 @@ +using System.Linq; using NUnit.Framework; using UnityEngine; @@ -5,6 +6,32 @@ namespace VRMShaders { public class MetallicRoughnessConverterTests { + private Color32 ImportPixel(Color32 metallicRoughnessPixel, float metallicFactor, float roughnessFactor, Color32 occlusionPixel) + { + var metallicRoughnessTexture = new Texture2D(4, 4, TextureFormat.ARGB32, mipChain: false, linear: true); + metallicRoughnessTexture.SetPixels32(Enumerable.Range(0, 16).Select(_ => metallicRoughnessPixel).ToArray()); + metallicRoughnessTexture.Apply(); + + var occlusionTexture = new Texture2D(4, 4, TextureFormat.ARGB32, mipChain: false, linear: true); + occlusionTexture.SetPixels32(Enumerable.Range(0, 16).Select(_ => occlusionPixel).ToArray()); + occlusionTexture.Apply(); + + var converted = OcclusionMetallicRoughnessConverter.Import( + metallicRoughnessTexture, + metallicFactor, + roughnessFactor, + occlusionTexture + ); + + var result = converted.GetPixels32()[0]; + + UnityEngine.Object.DestroyImmediate(metallicRoughnessTexture); + UnityEngine.Object.DestroyImmediate(occlusionTexture); + UnityEngine.Object.DestroyImmediate(converted); + + return result; + } + [Test] public void ExportingColorTest() { @@ -48,7 +75,7 @@ namespace VRMShaders { var roughnessFactor = 1.0f; Assert.That( - OcclusionMetallicRoughnessConverter.ImportPixel(new Color32(255, 255, 255, 255), 1.0f, roughnessFactor, default), + ImportPixel(new Color32(255, 255, 255, 255), 1.0f, roughnessFactor, default), // r <- 255 : Same metallic (src.r) // g <- 0 : (Unused) // b <- 0 : (Unused) @@ -59,7 +86,7 @@ namespace VRMShaders { var roughnessFactor = 1.0f; Assert.That( - OcclusionMetallicRoughnessConverter.ImportPixel(new Color32(255, 128, 255, 255), 1.0f, roughnessFactor, default), + ImportPixel(new Color32(255, 128, 255, 255), 1.0f, roughnessFactor, default), // r <- 255 : Same metallic (src.r) // g <- 0 : (Unused) // b <- 0 : (Unused) @@ -70,7 +97,7 @@ namespace VRMShaders { var roughnessFactor = 0.5f; Assert.That( - OcclusionMetallicRoughnessConverter.ImportPixel(new Color32(255, 255, 255, 255), 1.0f, roughnessFactor, default), + ImportPixel(new Color32(255, 255, 255, 255), 1.0f, roughnessFactor, default), // r <- 255 : Same metallic (src.r) // g <- 0 : (Unused) // b <- 0 : (Unused) @@ -81,7 +108,7 @@ namespace VRMShaders { var roughnessFactor = 0.0f; Assert.That( - OcclusionMetallicRoughnessConverter.ImportPixel(new Color32(255, 255, 255, 255), 1.0f, roughnessFactor, default), + ImportPixel(new Color32(255, 255, 255, 255), 1.0f, roughnessFactor, default), // r <- 255 : Same metallic (src.r) // g <- 0 : (Unused) // b <- 0 : (Unused) From 388a7fbc6e283680f90d2b14a024e4d10fe13734 Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Thu, 27 May 2021 22:45:21 +0900 Subject: [PATCH 5/5] Add complex test to MetallicRoughnessConverter --- .../Shaders/StandardMapImporter.shader | 16 +++---- .../Tests/MetallicRoughnessConverterTests.cs | 42 ++++++++++++------- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/StandardMapImporter.shader b/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/StandardMapImporter.shader index 3115bd222..f42507579 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/StandardMapImporter.shader +++ b/Assets/UniGLTF/Runtime/UniGLTF/Resources/Shaders/StandardMapImporter.shader @@ -49,15 +49,17 @@ fixed4 frag (v2f i) : SV_Target { - half4 metallicRoughness = tex2D(_GltfMetallicRoughnessTexture, i.uv); - half metallic = metallicRoughness.b * _GltfMetallicFactor; - half roughness = metallicRoughness.g * _GltfRoughnessFactor; - half occlusion = tex2D(_GltfOcclusionTexture, i.uv).r; + half4 metallicRoughnessTex = tex2D(_GltfMetallicRoughnessTexture, i.uv); + half4 occlusionTex = tex2D(_GltfOcclusionTexture, i.uv); + + half occlusion = occlusionTex.r; // R: glTF Occlusion + half roughness = metallicRoughnessTex.g * _GltfRoughnessFactor; // G: glTF Roughness + half metallic = metallicRoughnessTex.b * _GltfMetallicFactor; // B: glTF Metallic fixed4 result; - result.r = metallic; // R: Unity Metallic - result.g = occlusion; // G: Unity Occlusion - result.b = 0; // B: Unity Heightmap (no use) + result.r = metallic; // R: Unity Metallic + result.g = occlusion; // G: Unity Occlusion + result.b = 0; // B: Unity Heightmap (no use) result.a = 1.0 - roughness; // A: Unity Smoothness return result; diff --git a/Assets/VRMShaders/GLTF/IO/Tests/MetallicRoughnessConverterTests.cs b/Assets/VRMShaders/GLTF/IO/Tests/MetallicRoughnessConverterTests.cs index e44377f01..4199cbd5c 100644 --- a/Assets/VRMShaders/GLTF/IO/Tests/MetallicRoughnessConverterTests.cs +++ b/Assets/VRMShaders/GLTF/IO/Tests/MetallicRoughnessConverterTests.cs @@ -76,45 +76,55 @@ namespace VRMShaders var roughnessFactor = 1.0f; Assert.That( ImportPixel(new Color32(255, 255, 255, 255), 1.0f, roughnessFactor, default), - // r <- 255 : Same metallic (src.r) - // g <- 0 : (Unused) + // r <- 255 : metallic (metallicRoughness.b * metallicFactor) + // g <- 0 : occlusion (occlusion.r) // b <- 0 : (Unused) - // a <- 0 : ((1 - sqrt(src.g(as float) * roughnessFactor)))(as uint8) + // a <- 0 : smoothness (1.0 - (metallicRoughness.g * roughnessFactor)) Is.EqualTo(new Color32(255, 0, 0, 0))); } { var roughnessFactor = 1.0f; Assert.That( - ImportPixel(new Color32(255, 128, 255, 255), 1.0f, roughnessFactor, default), - // r <- 255 : Same metallic (src.r) - // g <- 0 : (Unused) + ImportPixel(new Color32(255, 127, 255, 255), 1.0f, roughnessFactor, default), + // r <- 255 : metallic (metallicRoughness.b * metallicFactor) + // g <- 0 : occlusion (occlusion.r) // b <- 0 : (Unused) - // a <- 128 : ((1 - sqrt(src.g(as float) * roughnessFactor)))(as uint8) - Is.EqualTo(new Color32(255, 0, 0, 127))); // smoothness 0.5 * src.a 1.0 + // a <- 128 : smoothness (1.0 - (metallicRoughness.g * roughnessFactor)) + Is.EqualTo(new Color32(255, 0, 0, 128))); // A:smoothness = 1.0 - (0.5 * 1.0) = 0.5 } { var roughnessFactor = 0.5f; Assert.That( - ImportPixel(new Color32(255, 255, 255, 255), 1.0f, roughnessFactor, default), - // r <- 255 : Same metallic (src.r) - // g <- 0 : (Unused) + ImportPixel(new Color32(255, 127, 255, 255), 1.0f, roughnessFactor, default), + // r <- 255 : metallic (metallicRoughness.b * metallicFactor) + // g <- 0 : occlusion (occlusion.r) // b <- 0 : (Unused) - // a <- 74 : ((1 - sqrt(src.g(as float) * roughnessFactor)))(as uint8) - Is.EqualTo(new Color32(255, 0, 0, 127))); + // a <- 191 : smoothness (1.0 - (metallicRoughness.g * roughnessFactor)) + Is.EqualTo(new Color32(255, 0, 0, 191))); // A:smoothness = 1.0 - (0.5 * 0.5) = 0.75 } { var roughnessFactor = 0.0f; Assert.That( ImportPixel(new Color32(255, 255, 255, 255), 1.0f, roughnessFactor, default), - // r <- 255 : Same metallic (src.r) - // g <- 0 : (Unused) + // r <- 255 : metallic (metallicRoughness.b * metallicFactor) + // g <- 0 : occlusion (occlusion.r) // b <- 0 : (Unused) - // a <- 255 : ((1 - sqrt(src.g(as float) * roughnessFactor)))(as uint8) + // a <- 255 : smoothness (1.0 - (metallicRoughness.g * roughnessFactor)) Is.EqualTo(new Color32(255, 0, 0, 255))); } + + { + Assert.That( + ImportPixel(new Color32(222, 200, 100, 255), 0.5f, 0.25f, new Color32(127, 0, 0, 0)), + // r <- 50 : metallic (metallicRoughness.b * metallicFactor) + // g <- 127 : occlusion (occlusion.r) + // b <- 0 : (Unused) + // a <- 205 : smoothness (1.0 - (metallicRoughness.g * roughnessFactor)) + Is.EqualTo(new Color32(50, 127, 0, 205))); + } } [Test]