Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Editor/AvatarAidNdmfPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class AvatarAidNdmfPlugin : Plugin<AvatarAidNdmfPlugin>
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));
}
}
}
75 changes: 75 additions & 0 deletions Editor/LiltoonDistanceFadeProcessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
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<Runtime.ApplyLiltoonDistanceFade>();
if (installerComponent == null) return;

Apply(context, installerComponent);

UnityEngine.Object.DestroyImmediate(installerComponent);
}

protected void Apply(BuildContext context, Runtime.ApplyLiltoonDistanceFade installer)
{
ProcessRecursively(context.AvatarRootObject.transform, installer);
}

protected void ProcessRecursively(Transform parent, Runtime.ApplyLiltoonDistanceFade installer)
{
var children = parent.GetComponentsInChildren<Transform>(true);
foreach (var child in children.Skip(1))
{
ProcessRecursively(child, installer);
}

ApplyDistanceFade(parent.gameObject, installer);
}

protected void ApplyDistanceFade(GameObject gameObject, Runtime.ApplyLiltoonDistanceFade installer)
{
var meshRenderer = gameObject.GetComponent<Renderer>();
if (meshRenderer == null) return;

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;
}

meshRenderer.sharedMaterials = newMats;
}

protected void ApplyDistanceFadeToMaterial(Material mat, Runtime.ApplyLiltoonDistanceFade 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);
}
}
}
11 changes: 11 additions & 0 deletions Editor/LiltoonDistanceFadeProcessor.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions Runtime/ApplyLiltoonDistanceFade.cs
Original file line number Diff line number Diff line change
@@ -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 ApplyLiltoonDistanceFade : MonoBehaviour, IEditorOnly
{
}
}
11 changes: 11 additions & 0 deletions Runtime/ApplyLiltoonDistanceFade.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 44 additions & 0 deletions Tests/LiltoonDistanceFadeProcessorTest.cs
Original file line number Diff line number Diff line change
@@ -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<MeshRenderer>();
renderer.sharedMaterial = mat;
Assert.AreEqual(0, mat.GetColor("_DistanceFade").b);

var installerComponent = gameObject.AddComponent<Runtime.ApplyLiltoonDistanceFade>();

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<Runtime.ApplyLiltoonDistanceFade>());

// 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<Renderer>();
var fadeParamColor = modifiedRenderer.sharedMaterial.GetColor("_DistanceFade");
Assert.AreEqual(1, fadeParamColor.b);
}
}
}
11 changes: 11 additions & 0 deletions Tests/LiltoonDistanceFadeProcessorTest.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 54 additions & 0 deletions Tests/MockLiltoon.shader
Original file line number Diff line number Diff line change
@@ -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"
}
9 changes: 9 additions & 0 deletions Tests/MockLiltoon.shader.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.