154 lines
5.8 KiB
C#
154 lines
5.8 KiB
C#
|
|
// 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);
|
|||
|
|
}
|
|||
|
|
}
|