Files
ichni_Creator_Studio/Assets/Shaders/Editor/BlendUnlitShaderGUI.cs
SoulliesOfficial 7954ec800c 爆修
2026-03-30 03:23:36 -04:00

154 lines
5.8 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// BlendUnlitShaderGUI.cs
// Custom Material Inspector for Soullies/BlendUnlit
// Drives the GPU Blend equation based on the user-selected Blend Mode.
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
public class BlendUnlitShaderGUI : ShaderGUI
{
// -------------------------------------------------------------------------
// Blend mode definitions
// -------------------------------------------------------------------------
enum BlendMode
{
Alpha = 0, // SrcAlpha, OneMinusSrcAlpha standard transparency
Additive = 1, // SrcAlpha, One additive / glow, black = invisible
Multiply = 2, // DstColor, Zero darkens below
Premultiplied = 3, // One, OneMinusSrcAlpha pre-multiplied alpha / HDR
}
static readonly string[] BlendModeNames =
{
"Alpha (SrcAlpha, 1-SrcAlpha)",
"Additive (SrcAlpha, One)",
"Multiply (DstColor, Zero)",
"Premultiplied (One, 1-SrcAlpha)",
};
// Src / Dst for each BlendMode entry
static readonly (UnityEngine.Rendering.BlendMode src, UnityEngine.Rendering.BlendMode dst)[] BlendEquations =
{
(UnityEngine.Rendering.BlendMode.SrcAlpha, UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha), // Alpha
(UnityEngine.Rendering.BlendMode.SrcAlpha, UnityEngine.Rendering.BlendMode.One), // Additive
(UnityEngine.Rendering.BlendMode.DstColor, UnityEngine.Rendering.BlendMode.Zero), // Multiply
(UnityEngine.Rendering.BlendMode.One, UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha), // Premultiplied
};
// -------------------------------------------------------------------------
// GUI
// -------------------------------------------------------------------------
public override void OnGUI(MaterialEditor editor, MaterialProperty[] props)
{
Material mat = editor.target as Material;
EditorGUI.BeginChangeCheck();
// Draw all standard properties EXCEPT our hidden blend props
foreach (var prop in props)
{
// Hide internal blend-equation float props from inspector
if (prop.name == "_SrcBlendRGB" || prop.name == "_DstBlendRGB")
continue;
// Replace the raw _BlendMode float with our friendly enum popup
if (prop.name == "_BlendMode")
{
EditorGUILayout.Space(4);
DrawBlendModePopup(editor, mat, prop);
EditorGUILayout.Space(4);
continue;
}
editor.ShaderProperty(prop, prop.displayName);
}
if (EditorGUI.EndChangeCheck())
{
// Apply blend equations to all selected materials
foreach (Object obj in editor.targets)
{
ApplyBlendMode((Material)obj);
}
}
EditorGUILayout.Space(8);
editor.RenderQueueField();
editor.EnableInstancingField();
editor.DoubleSidedGIField();
}
// -------------------------------------------------------------------------
// Helpers
// -------------------------------------------------------------------------
static void DrawBlendModePopup(MaterialEditor editor, Material mat, MaterialProperty prop)
{
int current = (int)prop.floatValue;
current = Mathf.Clamp(current, 0, BlendModeNames.Length - 1);
EditorGUI.BeginChangeCheck();
int selected = EditorGUILayout.Popup("Blend Mode", current, BlendModeNames);
if (EditorGUI.EndChangeCheck())
{
editor.RegisterPropertyChangeUndo("Blend Mode");
prop.floatValue = selected;
}
}
static void ApplyBlendMode(Material mat)
{
int index = Mathf.Clamp((int)mat.GetFloat("_BlendMode"), 0, BlendEquations.Length - 1);
BlendMode mode = (BlendMode)index;
// Disable all keyword variants, then enable the correct one
mat.DisableKeyword("_BLENDMODE_ALPHA");
mat.DisableKeyword("_BLENDMODE_ADDITIVE");
mat.DisableKeyword("_BLENDMODE_MULTIPLY");
mat.DisableKeyword("_BLENDMODE_PREMULTIPLIED");
switch (mode)
{
case BlendMode.Alpha:
mat.EnableKeyword("_BLENDMODE_ALPHA");
break;
case BlendMode.Additive:
mat.EnableKeyword("_BLENDMODE_ADDITIVE");
break;
case BlendMode.Multiply:
mat.EnableKeyword("_BLENDMODE_MULTIPLY");
break;
case BlendMode.Premultiplied:
mat.EnableKeyword("_BLENDMODE_PREMULTIPLIED");
break;
}
// Write the actual Blend equation floats that the Shader reads
var (src, dst) = BlendEquations[index];
mat.SetFloat("_SrcBlendRGB", (float)src);
mat.SetFloat("_DstBlendRGB", (float)dst);
// Adjust RenderQueue hint for Multiply mode
// (Multiply should typically not write ZBuffer and renders as transparent)
if (mode == BlendMode.Multiply)
{
mat.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
}
else
{
// Keep queue at Transparent for all other modes (default)
if (mat.renderQueue < (int)UnityEngine.Rendering.RenderQueue.Transparent)
mat.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
}
EditorUtility.SetDirty(mat);
}
// Called when the Shader is assigned to a material for the first time
public override void AssignNewShaderToMaterial(Material mat, Shader oldShader, Shader newShader)
{
base.AssignNewShaderToMaterial(mat, oldShader, newShader);
ApplyBlendMode(mat);
}
}