From bc399f4723a19a09dfc4ae23eae1eddcd8846841 Mon Sep 17 00:00:00 2001 From: Paralleltree Date: Sun, 16 Feb 2025 16:49:42 +0900 Subject: [PATCH 1/5] Add LiltoonDistanceFadeProcessor --- Editor/AvatarAidNdmfPlugin.cs | 1 + Editor/LiltoonDistanceFadeProcessor.cs | 66 +++++++++++++++++++++ Editor/LiltoonDistanceFadeProcessor.cs.meta | 11 ++++ Runtime/ApplyDistanceFade.cs | 16 +++++ Runtime/ApplyDistanceFade.cs.meta | 11 ++++ 5 files changed, 105 insertions(+) create mode 100644 Editor/LiltoonDistanceFadeProcessor.cs create mode 100644 Editor/LiltoonDistanceFadeProcessor.cs.meta create mode 100644 Runtime/ApplyDistanceFade.cs create mode 100644 Runtime/ApplyDistanceFade.cs.meta diff --git a/Editor/AvatarAidNdmfPlugin.cs b/Editor/AvatarAidNdmfPlugin.cs index 5c83cdb..286eb6f 100644 --- a/Editor/AvatarAidNdmfPlugin.cs +++ b/Editor/AvatarAidNdmfPlugin.cs @@ -15,6 +15,7 @@ public class AvatarAidNdmfPlugin : Plugin protected override void Configure() { InPhase(BuildPhase.Generating).Run("Apply FaceEmote", ctx => new FaceEmoteProcessor().Process(ctx)); + InPhase(BuildPhase.Transforming).Run("Apply DistanceFade", ctx => new LiltoonDistanceFadeProcessor().Process(ctx)); } } } diff --git a/Editor/LiltoonDistanceFadeProcessor.cs b/Editor/LiltoonDistanceFadeProcessor.cs new file mode 100644 index 0000000..95673e3 --- /dev/null +++ b/Editor/LiltoonDistanceFadeProcessor.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using nadena.dev.ndmf; + +namespace Paltee.AvatarAid +{ + public class LiltoonDistanceFadeProcessor + { + protected readonly string DistanceFadeParamName = "_DistanceFade"; + public void Process(BuildContext context) + { + var installerComponent = context.AvatarRootObject.GetComponent(); + if (installerComponent == null) return; + + Apply(context, installerComponent); + + UnityEngine.Object.DestroyImmediate(installerComponent); + } + + protected void Apply(BuildContext context, Runtime.ApplyDistanceFade installer) + { + ProcessRecursively(context.AvatarRootObject.transform, installer); + } + + protected void ProcessRecursively(Transform parent, Runtime.ApplyDistanceFade installer) + { + var children = parent.GetComponentsInChildren(true); + foreach (var child in children.Skip(1)) + { + ProcessRecursively(child, installer); + } + + ApplyDistanceFade(parent.gameObject, installer); + } + + protected void ApplyDistanceFade(GameObject gameObject, Runtime.ApplyDistanceFade installer) + { + var meshRenderer = gameObject.GetComponent(); + if (meshRenderer == null) return; + + foreach (var mat in meshRenderer.sharedMaterials) + { + ApplyDistanceFadeToMaterial(mat, installer); + } + } + + protected void ApplyDistanceFadeToMaterial(Material mat, Runtime.ApplyDistanceFade installer) + { + var names = mat.GetPropertyNames(MaterialPropertyType.Vector); + if (!names.Contains(DistanceFadeParamName)) + { + Debug.LogWarning($"_DistanceFade parameter not found: {mat.name}"); + } + var color = mat.GetColor(DistanceFadeParamName); + // R: 開始距離 [0-1] + // G: 終了距離 [0-1] + // B: 強度 [0-1] + color.b = 1; + mat.SetColor(DistanceFadeParamName, color); + } + } +} diff --git a/Editor/LiltoonDistanceFadeProcessor.cs.meta b/Editor/LiltoonDistanceFadeProcessor.cs.meta new file mode 100644 index 0000000..2cc591e --- /dev/null +++ b/Editor/LiltoonDistanceFadeProcessor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: da0e53173407a55449e573dd7ba44d62 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/ApplyDistanceFade.cs b/Runtime/ApplyDistanceFade.cs new file mode 100644 index 0000000..500fff5 --- /dev/null +++ b/Runtime/ApplyDistanceFade.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using VRC.SDKBase; + +namespace Paltee.AvatarAid.Runtime +{ + [DisallowMultipleComponent] + [AddComponentMenu("ApplyDistanceFade")] + public class ApplyDistanceFade : MonoBehaviour, IEditorOnly + { + } +} diff --git a/Runtime/ApplyDistanceFade.cs.meta b/Runtime/ApplyDistanceFade.cs.meta new file mode 100644 index 0000000..f60bca1 --- /dev/null +++ b/Runtime/ApplyDistanceFade.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 53e175169ac9499409b447fde7de27ed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From a144cad720a3af7208491ba95ed8d1fe1ae9efc7 Mon Sep 17 00:00:00 2001 From: Paralleltree Date: Sun, 16 Feb 2025 17:36:18 +0900 Subject: [PATCH 2/5] Fix modifying material --- Editor/LiltoonDistanceFadeProcessor.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Editor/LiltoonDistanceFadeProcessor.cs b/Editor/LiltoonDistanceFadeProcessor.cs index 95673e3..93b9f59 100644 --- a/Editor/LiltoonDistanceFadeProcessor.cs +++ b/Editor/LiltoonDistanceFadeProcessor.cs @@ -42,10 +42,15 @@ protected void ApplyDistanceFade(GameObject gameObject, Runtime.ApplyDistanceFad var meshRenderer = gameObject.GetComponent(); if (meshRenderer == null) return; - foreach (var mat in meshRenderer.sharedMaterials) + var newMats = new Material[meshRenderer.sharedMaterials.Length]; + for (int i = 0; i < meshRenderer.sharedMaterials.Length; i++) { - ApplyDistanceFadeToMaterial(mat, installer); + var newMat = new Material(meshRenderer.sharedMaterials[i]); + ApplyDistanceFadeToMaterial(newMat, installer); + newMats[i] = newMat; } + + meshRenderer.sharedMaterials = newMats; } protected void ApplyDistanceFadeToMaterial(Material mat, Runtime.ApplyDistanceFade installer) From 035460b87dc44a64580911b1b03f42810a878fbd Mon Sep 17 00:00:00 2001 From: Paralleltree Date: Tue, 18 Feb 2025 17:46:36 +0900 Subject: [PATCH 3/5] Rename ApplyDistanceFade --- Editor/LiltoonDistanceFadeProcessor.cs | 10 +++++----- ...pplyDistanceFade.cs => ApplyLiltoonDistanceFade.cs} | 2 +- ...ceFade.cs.meta => ApplyLiltoonDistanceFade.cs.meta} | 0 3 files changed, 6 insertions(+), 6 deletions(-) rename Runtime/{ApplyDistanceFade.cs => ApplyLiltoonDistanceFade.cs} (79%) rename Runtime/{ApplyDistanceFade.cs.meta => ApplyLiltoonDistanceFade.cs.meta} (100%) diff --git a/Editor/LiltoonDistanceFadeProcessor.cs b/Editor/LiltoonDistanceFadeProcessor.cs index 93b9f59..5419d3d 100644 --- a/Editor/LiltoonDistanceFadeProcessor.cs +++ b/Editor/LiltoonDistanceFadeProcessor.cs @@ -13,7 +13,7 @@ public class LiltoonDistanceFadeProcessor protected readonly string DistanceFadeParamName = "_DistanceFade"; public void Process(BuildContext context) { - var installerComponent = context.AvatarRootObject.GetComponent(); + var installerComponent = context.AvatarRootObject.GetComponent(); if (installerComponent == null) return; Apply(context, installerComponent); @@ -21,12 +21,12 @@ public void Process(BuildContext context) UnityEngine.Object.DestroyImmediate(installerComponent); } - protected void Apply(BuildContext context, Runtime.ApplyDistanceFade installer) + protected void Apply(BuildContext context, Runtime.ApplyLiltoonDistanceFade installer) { ProcessRecursively(context.AvatarRootObject.transform, installer); } - protected void ProcessRecursively(Transform parent, Runtime.ApplyDistanceFade installer) + protected void ProcessRecursively(Transform parent, Runtime.ApplyLiltoonDistanceFade installer) { var children = parent.GetComponentsInChildren(true); foreach (var child in children.Skip(1)) @@ -37,7 +37,7 @@ protected void ProcessRecursively(Transform parent, Runtime.ApplyDistanceFade in ApplyDistanceFade(parent.gameObject, installer); } - protected void ApplyDistanceFade(GameObject gameObject, Runtime.ApplyDistanceFade installer) + protected void ApplyDistanceFade(GameObject gameObject, Runtime.ApplyLiltoonDistanceFade installer) { var meshRenderer = gameObject.GetComponent(); if (meshRenderer == null) return; @@ -53,7 +53,7 @@ protected void ApplyDistanceFade(GameObject gameObject, Runtime.ApplyDistanceFad meshRenderer.sharedMaterials = newMats; } - protected void ApplyDistanceFadeToMaterial(Material mat, Runtime.ApplyDistanceFade installer) + protected void ApplyDistanceFadeToMaterial(Material mat, Runtime.ApplyLiltoonDistanceFade installer) { var names = mat.GetPropertyNames(MaterialPropertyType.Vector); if (!names.Contains(DistanceFadeParamName)) diff --git a/Runtime/ApplyDistanceFade.cs b/Runtime/ApplyLiltoonDistanceFade.cs similarity index 79% rename from Runtime/ApplyDistanceFade.cs rename to Runtime/ApplyLiltoonDistanceFade.cs index 500fff5..e8180f7 100644 --- a/Runtime/ApplyDistanceFade.cs +++ b/Runtime/ApplyLiltoonDistanceFade.cs @@ -10,7 +10,7 @@ namespace Paltee.AvatarAid.Runtime { [DisallowMultipleComponent] [AddComponentMenu("ApplyDistanceFade")] - public class ApplyDistanceFade : MonoBehaviour, IEditorOnly + public class ApplyLiltoonDistanceFade : MonoBehaviour, IEditorOnly { } } diff --git a/Runtime/ApplyDistanceFade.cs.meta b/Runtime/ApplyLiltoonDistanceFade.cs.meta similarity index 100% rename from Runtime/ApplyDistanceFade.cs.meta rename to Runtime/ApplyLiltoonDistanceFade.cs.meta From 8b4267c629d381b0af856e9c67a8027ad95d5cf9 Mon Sep 17 00:00:00 2001 From: Paralleltree Date: Sat, 22 Feb 2025 14:08:52 +0900 Subject: [PATCH 4/5] Add test script --- Tests/LiltoonDistanceFadeProcessorTest.cs | 44 +++++++++++++++ .../LiltoonDistanceFadeProcessorTest.cs.meta | 11 ++++ Tests/MockLiltoon.shader | 54 +++++++++++++++++++ Tests/MockLiltoon.shader.meta | 9 ++++ 4 files changed, 118 insertions(+) create mode 100644 Tests/LiltoonDistanceFadeProcessorTest.cs create mode 100644 Tests/LiltoonDistanceFadeProcessorTest.cs.meta create mode 100644 Tests/MockLiltoon.shader create mode 100644 Tests/MockLiltoon.shader.meta diff --git a/Tests/LiltoonDistanceFadeProcessorTest.cs b/Tests/LiltoonDistanceFadeProcessorTest.cs new file mode 100644 index 0000000..43fec4d --- /dev/null +++ b/Tests/LiltoonDistanceFadeProcessorTest.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NUnit.Framework; +using UnityEngine; +using nadena.dev.ndmf; + +namespace Paltee.AvatarAid.Tests +{ + public class LiltoonDistanceFadeProcessorTest + { + [Test] + public void TestProcess_SetsMaterialParameters() + { + var gameObject = new GameObject("Test Target"); + var shader = Shader.Find("Custom/MockLiltoon"); + var mat = new Material(shader); + var renderer = gameObject.AddComponent(); + renderer.sharedMaterial = mat; + Assert.AreEqual(0, mat.GetColor("_DistanceFade").b); + + var installerComponent = gameObject.AddComponent(); + + var context = new BuildContext(gameObject, "Assets/_TestingResources"); + + // act + var errors = ErrorReport.CaptureErrors(() => new LiltoonDistanceFadeProcessor().Process(context)); + + // assert + Assert.Zero(errors.Count); + Assert.IsNull(gameObject.GetComponentInChildren()); + + // ensure the original material was not modified + var originalFadeParamColor = mat.GetColor("_DistanceFade"); + Assert.AreEqual(0, originalFadeParamColor.b); + // check modified parameter value + var modifiedRenderer = gameObject.GetComponent(); + var fadeParamColor = modifiedRenderer.sharedMaterial.GetColor("_DistanceFade"); + Assert.AreEqual(1, fadeParamColor.b); + } + } +} diff --git a/Tests/LiltoonDistanceFadeProcessorTest.cs.meta b/Tests/LiltoonDistanceFadeProcessorTest.cs.meta new file mode 100644 index 0000000..016cc66 --- /dev/null +++ b/Tests/LiltoonDistanceFadeProcessorTest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 23f3c59efc6cef346add4b1eb1dc6270 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/MockLiltoon.shader b/Tests/MockLiltoon.shader new file mode 100644 index 0000000..006fb85 --- /dev/null +++ b/Tests/MockLiltoon.shader @@ -0,0 +1,54 @@ +Shader "Custom/MockLiltoon" +{ + 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 + _DistanceFade("DistanceFade", Color) = (0,0,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 + + // Use shader model 3.0 target, to get nicer looking lighting + #pragma target 3.0 + + sampler2D _MainTex; + + struct Input + { + float2 uv_MainTex; + }; + + 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 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; + // Metallic and smoothness come from slider variables + o.Metallic = _Metallic; + o.Smoothness = _Glossiness; + o.Alpha = c.a; + } + ENDCG + } + FallBack "Diffuse" +} diff --git a/Tests/MockLiltoon.shader.meta b/Tests/MockLiltoon.shader.meta new file mode 100644 index 0000000..12a590f --- /dev/null +++ b/Tests/MockLiltoon.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 3988efc3f1bdade47857cf0e85c53583 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: From 887c38ee6de90a77f5295ca144775a5c16730f59 Mon Sep 17 00:00:00 2001 From: Paralleltree Date: Sat, 1 Mar 2025 17:27:29 +0900 Subject: [PATCH 5/5] Fix handling for null references to a material --- Editor/LiltoonDistanceFadeProcessor.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Editor/LiltoonDistanceFadeProcessor.cs b/Editor/LiltoonDistanceFadeProcessor.cs index 5419d3d..68d0786 100644 --- a/Editor/LiltoonDistanceFadeProcessor.cs +++ b/Editor/LiltoonDistanceFadeProcessor.cs @@ -45,6 +45,10 @@ protected void ApplyDistanceFade(GameObject gameObject, Runtime.ApplyLiltoonDist var newMats = new Material[meshRenderer.sharedMaterials.Length]; for (int i = 0; i < meshRenderer.sharedMaterials.Length; i++) { + if (meshRenderer.sharedMaterials[i] == null) + { + continue; + } var newMat = new Material(meshRenderer.sharedMaterials[i]); ApplyDistanceFadeToMaterial(newMat, installer); newMats[i] = newMat;