Polishes
This commit is contained in:
@@ -0,0 +1,205 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace ProjectM.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// EDITOR-ONLY live tuner for the "3D pixel art" full-screen render style — the
|
||||
/// <c>Hidden/ProjectM/PixelOutline</c> shader driven by <c>PixelOutline.mat</c> via the
|
||||
/// PC_Renderer <c>FullScreenPassRendererFeature</c>. Self-spawns on Play (no scene wiring),
|
||||
/// so it works in Game.unity and DevSandbox.unity alike. Toggle the panel with <b>F3</b>.
|
||||
///
|
||||
/// It writes straight to the shared material ASSET, so every drag applies to the running
|
||||
/// game instantly AND sticks after you exit Play mode (material assets aren't reverted the
|
||||
/// way scene objects are). "Save Asset" force-writes to disk now; "Reset" restores the
|
||||
/// shader's shipped defaults. Stripped from player builds (#if UNITY_EDITOR).
|
||||
/// </summary>
|
||||
public class PixelArtDevControls : MonoBehaviour
|
||||
{
|
||||
const string MaterialPath = "Assets/_Project/Shaders/PixelOutline.mat";
|
||||
|
||||
static PixelArtDevControls _instance;
|
||||
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
|
||||
static void Bootstrap()
|
||||
{
|
||||
if (_instance != null)
|
||||
return;
|
||||
var go = new GameObject("~PixelArtDevControls") { hideFlags = HideFlags.HideAndDontSave };
|
||||
DontDestroyOnLoad(go);
|
||||
_instance = go.AddComponent<PixelArtDevControls>();
|
||||
}
|
||||
|
||||
Material _mat;
|
||||
bool _open;
|
||||
Vector2 _scroll;
|
||||
GUIStyle _wrap;
|
||||
|
||||
Material Mat
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_mat == null)
|
||||
_mat = AssetDatabase.LoadAssetAtPath<Material>(MaterialPath);
|
||||
return _mat;
|
||||
}
|
||||
}
|
||||
|
||||
GUIStyle Wrap => _wrap ??= new GUIStyle(GUI.skin.label) { wordWrap = true, fontSize = 10 };
|
||||
|
||||
void OnDisable() => AimPresentation.ForceCursorVisible = false;
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (Input.GetKeyDown(KeyCode.F3))
|
||||
_open = !_open;
|
||||
}
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
if (GUI.Button(new Rect(10, 10, 128, 24), _open ? "PIXEL ▲ (F3)" : "PIXEL ▼ (F3)"))
|
||||
_open = !_open;
|
||||
|
||||
if (!_open)
|
||||
return;
|
||||
|
||||
AimPresentation.ForceCursorVisible = true;
|
||||
|
||||
var mat = Mat;
|
||||
if (mat == null)
|
||||
{
|
||||
GUILayout.BeginArea(new Rect(10, 40, 270, 64), GUI.skin.box);
|
||||
GUILayout.Label("PixelOutline.mat not found at\n" + MaterialPath, Wrap);
|
||||
GUILayout.EndArea();
|
||||
return;
|
||||
}
|
||||
|
||||
float panelH = Mathf.Min(660f, Screen.height - 60f);
|
||||
GUILayout.BeginArea(new Rect(10, 40, 272, panelH), GUI.skin.box);
|
||||
GUILayout.Label("PIXEL-ART RENDER STYLE (live)");
|
||||
_scroll = GUILayout.BeginScrollView(_scroll);
|
||||
|
||||
Toggle(mat, "_MasterEnabled", "MASTER (whole effect on/off)");
|
||||
GUILayout.Space(6);
|
||||
|
||||
GUILayout.Label("- Toggles -");
|
||||
Toggle(mat, "_PixelateEnabled", "Pixelate");
|
||||
Toggle(mat, "_PosterizeEnabled", "Posterize (banded color)");
|
||||
Toggle(mat, "_DepthEdgesEnabled", "Depth edges (silhouette)");
|
||||
Toggle(mat, "_NormalEdgesEnabled", "Normal edges (creases)");
|
||||
|
||||
GUILayout.Space(6);
|
||||
GUILayout.Label("- Pixelation -");
|
||||
Slider(mat, "_PixelHeight", "Grid height (px)", 40f, 720f, "0");
|
||||
|
||||
GUILayout.Space(6);
|
||||
GUILayout.Label("- Color / tone -");
|
||||
Slider(mat, "_ColorLevels", "Posterize levels", 2f, 64f, "0");
|
||||
Slider(mat, "_Brightness", "Brightness", 0.5f, 2f, "0.00");
|
||||
Slider(mat, "_Contrast", "Contrast", 0.5f, 2f, "0.00");
|
||||
Slider(mat, "_Saturation", "Saturation", 0f, 2f, "0.00");
|
||||
|
||||
GUILayout.Space(6);
|
||||
GUILayout.Label("- Outlines -");
|
||||
Slider(mat, "_DepthThreshold", "Depth threshold", 0f, 1f, "0.000");
|
||||
Slider(mat, "_NormalThreshold", "Normal threshold", 0f, 4f, "0.00");
|
||||
Slider(mat, "_OutlineThickness", "Thickness (texels)", 0.25f, 4f, "0.00");
|
||||
Slider(mat, "_EdgeStrength", "Edge strength", 0f, 1f, "0.00");
|
||||
ColorRow(mat, "_OutlineColorOuter", "Silhouette color");
|
||||
ColorRow(mat, "_OutlineColorInner", "Crease color");
|
||||
|
||||
GUILayout.Space(8);
|
||||
GUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Reset defaults"))
|
||||
ResetDefaults(mat);
|
||||
if (GUILayout.Button("Save Asset"))
|
||||
SaveAsset(mat);
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.Label("Drags apply live and persist after Play. 'Save Asset' writes to disk now.", Wrap);
|
||||
|
||||
GUILayout.EndScrollView();
|
||||
GUILayout.EndArea();
|
||||
}
|
||||
|
||||
static void Toggle(Material mat, string prop, string label)
|
||||
{
|
||||
bool cur = mat.GetFloat(prop) > 0.5f;
|
||||
bool now = GUILayout.Toggle(cur, " " + label);
|
||||
if (now != cur)
|
||||
{
|
||||
mat.SetFloat(prop, now ? 1f : 0f);
|
||||
EditorUtility.SetDirty(mat);
|
||||
}
|
||||
}
|
||||
|
||||
static void Slider(Material mat, string prop, string label, float min, float max, string fmt)
|
||||
{
|
||||
float cur = mat.GetFloat(prop);
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label(label, GUILayout.Width(126));
|
||||
GUILayout.Label(cur.ToString(fmt), GUILayout.Width(48));
|
||||
GUILayout.EndHorizontal();
|
||||
float now = GUILayout.HorizontalSlider(cur, min, max);
|
||||
if (!Mathf.Approximately(now, cur))
|
||||
{
|
||||
mat.SetFloat(prop, now);
|
||||
EditorUtility.SetDirty(mat);
|
||||
}
|
||||
}
|
||||
|
||||
static void ColorRow(Material mat, string prop, string label)
|
||||
{
|
||||
Color c = mat.GetColor(prop);
|
||||
GUILayout.Label(label);
|
||||
Color n = c;
|
||||
n.r = ChannelSlider("R", c.r);
|
||||
n.g = ChannelSlider("G", c.g);
|
||||
n.b = ChannelSlider("B", c.b);
|
||||
if (n != c)
|
||||
{
|
||||
n.a = 1f;
|
||||
mat.SetColor(prop, n);
|
||||
EditorUtility.SetDirty(mat);
|
||||
}
|
||||
}
|
||||
|
||||
static float ChannelSlider(string label, float v)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label(label, GUILayout.Width(14));
|
||||
float r = GUILayout.HorizontalSlider(v, 0f, 1f);
|
||||
GUILayout.EndHorizontal();
|
||||
return r;
|
||||
}
|
||||
|
||||
// Shipped defaults from PixelOutline.shader / .mat.
|
||||
static void ResetDefaults(Material mat)
|
||||
{
|
||||
mat.SetFloat("_MasterEnabled", 1f);
|
||||
mat.SetFloat("_PixelHeight", 200f);
|
||||
mat.SetFloat("_PosterizeEnabled", 1f);
|
||||
mat.SetFloat("_ColorLevels", 12f);
|
||||
mat.SetFloat("_Brightness", 1.1f);
|
||||
mat.SetFloat("_Contrast", 1.05f);
|
||||
mat.SetFloat("_Saturation", 1.35f);
|
||||
mat.SetFloat("_DepthThreshold", 0.08f);
|
||||
mat.SetFloat("_NormalThreshold", 1f);
|
||||
mat.SetFloat("_OutlineThickness", 1f);
|
||||
mat.SetFloat("_EdgeStrength", 1f);
|
||||
mat.SetFloat("_PixelateEnabled", 1f);
|
||||
mat.SetFloat("_DepthEdgesEnabled", 1f);
|
||||
mat.SetFloat("_NormalEdgesEnabled", 1f);
|
||||
mat.SetColor("_OutlineColorOuter", Color.black);
|
||||
mat.SetColor("_OutlineColorInner", Color.black);
|
||||
EditorUtility.SetDirty(mat);
|
||||
}
|
||||
|
||||
static void SaveAsset(Material mat)
|
||||
{
|
||||
EditorUtility.SetDirty(mat);
|
||||
AssetDatabase.SaveAssetIfDirty(mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user