Streamingle_URP/Assets/NiloToonURP/Editor/ShaderGUI/NiloToonCharacterFurShaderGUI.cs
2025-12-15 01:52:59 +09:00

299 lines
14 KiB
C#

// NiloToon Character Fur Shader - Custom ShaderGUI
// Clean, organized material inspector with foldable sections
using UnityEngine;
using UnityEditor;
using System;
namespace NiloToonURP.ShaderGUI
{
public class NiloToonCharacterFurShaderGUI : UnityEditor.ShaderGUI
{
// Foldout states
private static bool showBaseColor = true;
private static bool showNormalMap = false;
private static bool showFurShape = true;
private static bool showFurRim = false;
private static bool showCelShading = true;
private static bool showShadowColor = false;
private static bool showMatCap = false;
private static bool showRimLight = false;
private static bool showEmission = false;
private static bool showOcclusion = false;
private static bool showOutline = false;
private static bool showRendering = false;
// Styles
private static GUIStyle headerStyle;
private static GUIStyle foldoutStyle;
private static bool stylesInitialized = false;
private static void InitStyles()
{
if (stylesInitialized) return;
headerStyle = new GUIStyle(EditorStyles.boldLabel)
{
fontSize = 12,
margin = new RectOffset(0, 0, 10, 5)
};
foldoutStyle = new GUIStyle(EditorStyles.foldout)
{
fontStyle = FontStyle.Bold,
fontSize = 11
};
stylesInitialized = true;
}
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
InitStyles();
Material material = materialEditor.target as Material;
EditorGUILayout.Space(5);
// Header
EditorGUILayout.LabelField("NiloToon Character Fur Shader", EditorStyles.boldLabel);
EditorGUILayout.HelpBox(
"Single-material fur shader with Base + Fur Shell rendering.\n\n" +
"Setup:\n" +
"1. Add 'NiloToonFurRendererFeature' to your URP Renderer Asset\n" +
"2. Apply this shader to your mesh material (single material slot)\n\n" +
"The shader will render base mesh first, then fur shells on top.",
MessageType.Info);
DrawSeparator();
// Base Color Section
showBaseColor = DrawSection("Base Color", showBaseColor, () =>
{
DrawProperty(materialEditor, properties, "_BaseMap", "Base Map");
DrawProperty(materialEditor, properties, "_BaseColor", "Base Color");
DrawProperty(materialEditor, properties, "_Cutoff", "Alpha Cutoff");
});
// Normal Map Section
showNormalMap = DrawSection("Normal Map", showNormalMap, () =>
{
DrawToggleProperty(materialEditor, properties, "_UseNormalMap", "Enable Normal Map", "_NORMALMAP", material);
if (material.IsKeywordEnabled("_NORMALMAP"))
{
EditorGUI.indentLevel++;
DrawProperty(materialEditor, properties, "_BumpMap", "Normal Map");
DrawProperty(materialEditor, properties, "_BumpScale", "Normal Scale");
EditorGUI.indentLevel--;
}
});
// Fur Shape Section
showFurShape = DrawSection("Fur Shape", showFurShape, () =>
{
DrawProperty(materialEditor, properties, "_FurNoiseMask", "Fur Noise Mask");
DrawProperty(materialEditor, properties, "_FurMask", "Fur Mask");
DrawProperty(materialEditor, properties, "_FurLengthMask", "Fur Length Mask");
EditorGUILayout.Space(5);
DrawProperty(materialEditor, properties, "_FurVector", "Fur Direction (XYZ) + Length (W)");
DrawProperty(materialEditor, properties, "_FurVectorTex", "Fur Direction Map");
DrawProperty(materialEditor, properties, "_FurVectorScale", "Fur Direction Scale");
EditorGUILayout.Space(5);
DrawProperty(materialEditor, properties, "_FurGravity", "Fur Gravity");
DrawProperty(materialEditor, properties, "_FurRandomize", "Fur Randomize");
DrawProperty(materialEditor, properties, "_FurAO", "Fur Ambient Occlusion");
EditorGUILayout.Space(5);
DrawProperty(materialEditor, properties, "_FurLayerNum", "Fur Layer Count");
DrawProperty(materialEditor, properties, "_FurRootOffset", "Fur Root Offset");
});
// Fur Rim Section
showFurRim = DrawSection("Fur Rim Light", showFurRim, () =>
{
DrawProperty(materialEditor, properties, "_FurRimColor", "Fur Rim Color");
DrawProperty(materialEditor, properties, "_FurRimFresnelPower", "Fur Rim Fresnel Power");
DrawProperty(materialEditor, properties, "_FurRimAntiLight", "Fur Rim Anti-Light");
});
// Cel Shading Section
showCelShading = DrawSection("Cel Shading", showCelShading, () =>
{
DrawProperty(materialEditor, properties, "_CelShadeMidPoint", "Cel Shade Mid Point");
DrawProperty(materialEditor, properties, "_CelShadeSoftness", "Cel Shade Softness");
});
// Shadow Color Section
showShadowColor = DrawSection("Shadow Color", showShadowColor, () =>
{
DrawToggleProperty(materialEditor, properties, "_EnableShadowColor", "Enable Shadow Color", "_SHADOW_COLOR", material);
if (material.IsKeywordEnabled("_SHADOW_COLOR"))
{
EditorGUI.indentLevel++;
DrawProperty(materialEditor, properties, "_ShadowColor", "Shadow Tint Color");
DrawProperty(materialEditor, properties, "_ShadowBrightness", "Shadow Brightness");
EditorGUILayout.Space(5);
EditorGUILayout.LabelField("HSV Adjustment", EditorStyles.miniLabel);
DrawProperty(materialEditor, properties, "_ShadowHueShift", "Hue Shift");
DrawProperty(materialEditor, properties, "_ShadowSaturationBoost", "Saturation Boost");
DrawProperty(materialEditor, properties, "_ShadowValueMultiplier", "Value Multiplier");
EditorGUI.indentLevel--;
}
});
// MatCap Section
showMatCap = DrawSection("MatCap", showMatCap, () =>
{
EditorGUILayout.LabelField("MatCap Additive", EditorStyles.miniLabel);
DrawToggleProperty(materialEditor, properties, "_UseMatCapAdd", "Enable MatCap (Add)", "_MATCAP_ADD", material);
if (material.IsKeywordEnabled("_MATCAP_ADD"))
{
EditorGUI.indentLevel++;
DrawProperty(materialEditor, properties, "_MatCapAddMap", "MatCap Add Map");
DrawProperty(materialEditor, properties, "_MatCapAddColor", "MatCap Add Color");
DrawProperty(materialEditor, properties, "_MatCapAddIntensity", "MatCap Add Intensity");
DrawProperty(materialEditor, properties, "_MatCapAddMask", "MatCap Add Mask");
EditorGUI.indentLevel--;
}
EditorGUILayout.Space(5);
EditorGUILayout.LabelField("MatCap Multiply", EditorStyles.miniLabel);
DrawToggleProperty(materialEditor, properties, "_UseMatCapMul", "Enable MatCap (Multiply)", "_MATCAP_MUL", material);
if (material.IsKeywordEnabled("_MATCAP_MUL"))
{
EditorGUI.indentLevel++;
DrawProperty(materialEditor, properties, "_MatCapMulMap", "MatCap Multiply Map");
DrawProperty(materialEditor, properties, "_MatCapMulIntensity", "MatCap Multiply Intensity");
EditorGUI.indentLevel--;
}
});
// Rim Light Section
showRimLight = DrawSection("Rim Light (General)", showRimLight, () =>
{
DrawToggleProperty(materialEditor, properties, "_UseRimLight", "Enable Rim Light", "_RIMLIGHT", material);
if (material.IsKeywordEnabled("_RIMLIGHT"))
{
EditorGUI.indentLevel++;
DrawProperty(materialEditor, properties, "_RimLightColor", "Rim Light Color");
DrawProperty(materialEditor, properties, "_RimLightPower", "Rim Light Power");
DrawProperty(materialEditor, properties, "_RimLightIntensity", "Rim Light Intensity");
EditorGUI.indentLevel--;
}
});
// Emission Section
showEmission = DrawSection("Emission", showEmission, () =>
{
DrawToggleProperty(materialEditor, properties, "_UseEmission", "Enable Emission", "_EMISSION", material);
if (material.IsKeywordEnabled("_EMISSION"))
{
EditorGUI.indentLevel++;
DrawProperty(materialEditor, properties, "_EmissionMap", "Emission Map");
DrawProperty(materialEditor, properties, "_EmissionColor", "Emission Color");
DrawProperty(materialEditor, properties, "_EmissionIntensity", "Emission Intensity");
EditorGUI.indentLevel--;
}
});
// Occlusion Section
showOcclusion = DrawSection("Occlusion", showOcclusion, () =>
{
DrawToggleProperty(materialEditor, properties, "_UseOcclusion", "Enable Occlusion Map", "_OCCLUSIONMAP", material);
if (material.IsKeywordEnabled("_OCCLUSIONMAP"))
{
EditorGUI.indentLevel++;
DrawProperty(materialEditor, properties, "_OcclusionMap", "Occlusion Map");
DrawProperty(materialEditor, properties, "_OcclusionStrength", "Occlusion Strength");
EditorGUI.indentLevel--;
}
});
// Outline Section
showOutline = DrawSection("Outline", showOutline, () =>
{
DrawProperty(materialEditor, properties, "_OutlineWidth", "Outline Width");
DrawProperty(materialEditor, properties, "_OutlineColor", "Outline Color");
DrawProperty(materialEditor, properties, "_OutlineWidthMask", "Outline Width Mask");
});
// Rendering Options Section
showRendering = DrawSection("Rendering Options", showRendering, () =>
{
DrawProperty(materialEditor, properties, "_Cull", "Cull Mode");
DrawProperty(materialEditor, properties, "_FurCull", "Fur Cull Mode");
DrawProperty(materialEditor, properties, "_ZWrite", "ZWrite");
DrawProperty(materialEditor, properties, "_FurZWrite", "Fur ZWrite");
DrawProperty(materialEditor, properties, "_ZTest", "ZTest");
});
EditorGUILayout.Space(10);
// Render Queue
materialEditor.RenderQueueField();
materialEditor.EnableInstancingField();
materialEditor.DoubleSidedGIField();
}
private bool DrawSection(string title, bool foldout, Action drawContent)
{
EditorGUILayout.Space(2);
// Section header with foldout
Rect headerRect = EditorGUILayout.GetControlRect(false, 20);
headerRect.x -= 2;
headerRect.width += 4;
// Background
EditorGUI.DrawRect(headerRect, new Color(0.22f, 0.22f, 0.22f, 1f));
// Foldout
headerRect.x += 4;
foldout = EditorGUI.Foldout(headerRect, foldout, title, true, foldoutStyle);
if (foldout)
{
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
EditorGUI.indentLevel++;
drawContent?.Invoke();
EditorGUI.indentLevel--;
EditorGUILayout.EndVertical();
}
return foldout;
}
private void DrawProperty(MaterialEditor editor, MaterialProperty[] properties, string propertyName, string label)
{
MaterialProperty prop = FindProperty(propertyName, properties, false);
if (prop != null)
{
editor.ShaderProperty(prop, label);
}
}
private void DrawToggleProperty(MaterialEditor editor, MaterialProperty[] properties, string propertyName, string label, string keyword, Material material)
{
MaterialProperty prop = FindProperty(propertyName, properties, false);
if (prop != null)
{
EditorGUI.BeginChangeCheck();
editor.ShaderProperty(prop, label);
if (EditorGUI.EndChangeCheck())
{
if (prop.floatValue > 0.5f)
material.EnableKeyword(keyword);
else
material.DisableKeyword(keyword);
}
}
}
private void DrawSeparator()
{
EditorGUILayout.Space(5);
Rect rect = EditorGUILayout.GetControlRect(false, 1);
EditorGUI.DrawRect(rect, new Color(0.5f, 0.5f, 0.5f, 0.5f));
EditorGUILayout.Space(5);
}
}
}