Skip to content

Commit

Permalink
9.0.61
Browse files Browse the repository at this point in the history
  • Loading branch information
poiyomi committed Sep 18, 2024
1 parent 9cc389e commit 52b73ed
Show file tree
Hide file tree
Showing 25 changed files with 741 additions and 410 deletions.
2 changes: 1 addition & 1 deletion _PoiyomiShaders/Scripts.meta

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

2 changes: 1 addition & 1 deletion _PoiyomiShaders/Scripts/ThryEditor/Editor/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class Config
{
// consts
private const string PATH_CONFIG_FILE = "Thry/Config.json";
private const string VERSION = "2.56.5";
private const string VERSION = "2.57.0";

// static
private static Config config;
Expand Down
244 changes: 138 additions & 106 deletions _PoiyomiShaders/Scripts/ThryEditor/Editor/CrossEditor.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
Expand All @@ -7,37 +8,39 @@ namespace Thry
{
public class CrossEditor : EditorWindow
{
private static CrossEditor GetInstance()
{
CrossEditor window = GetWindow(typeof(CrossEditor)) as CrossEditor;
window.name = "Cross Shader Editor";

return window;
}

[MenuItem("Thry/Cross Shader Editor", priority = -20)]
public static void ShowWindow()
{
CrossEditor window = EditorWindow.GetWindow(typeof(CrossEditor)) as CrossEditor;
window.name = "Cross Shader Editor";
GetInstance();
}

[MenuItem("Assets/Thry/Materials/Open in Cross Shader Editor", false , 400)]
public static void OpenInCrossShaderEditor()
[MenuItem("Assets/Thry/Materials/Add to Cross Shader Editor", false , 400)]
private static void OpenInCrossShaderEditor()
{
CrossEditor window = EditorWindow.GetWindow(typeof(CrossEditor)) as CrossEditor;
window.name = "Cross Shader Editor";
window._materialList = Selection.objects.Where(o => o is Material).Cast<Material>().ToList();
window.UpdateTargets();
window._shaderEditor = null;
List<Material> materials = ShaderOptimizer.FindMaterials(ShaderOptimizer.GetSelectedFolders());
materials.AddRange(Selection.objects.Where(o => o is Material).Cast<Material>());

GetInstance().UpdateTargets(materials, true);
}

[MenuItem("Assets/Thry/Materials/Open in Cross Shader Editor", true, 400)]
public static bool OpenInCrossShaderEditorValidation()
[MenuItem("Assets/Thry/Materials/Add to Cross Shader Editor", true, 400)]
private static bool OpenInCrossShaderEditorValidation()
{
return Selection.objects.All(o => o is Material);
return Selection.objects.Any(o => o is Material) || ShaderOptimizer.GetSelectedFolders().Any();
}

[MenuItem("GameObject/Thry/Materials/Open All in Cross Shader Editor", false, 10)]
public static void OpenAllInCrossShaderEditor()
private static void OpenAllInCrossShaderEditor()
{
CrossEditor window = EditorWindow.GetWindow(typeof(CrossEditor)) as CrossEditor;
window.name = "Cross Shader Editor";
window._materialList = Selection.gameObjects.SelectMany(o => o.GetComponentsInChildren<Renderer>(true)).SelectMany(r => r.sharedMaterials).ToList();
window.UpdateTargets();
window._shaderEditor = null;
GetInstance().UpdateTargets(Selection.gameObjects.SelectMany(o => o.GetComponentsInChildren<Renderer>(true)).SelectMany(r => r.sharedMaterials));
}

List<Material> _materialList = new List<Material>();
Expand All @@ -48,124 +51,153 @@ public static void OpenAllInCrossShaderEditor()
MaterialProperty[] _materialProperties = null;
Vector2 _scrollPosition = Vector2.zero;
bool _showMaterials = true;
Lazy<GUIStyle> LeftMargin = new Lazy<GUIStyle>(() => new GUIStyle() { margin = new RectOffset(30, 0, 0, 0) });

void UpdateTargets()
private void UpdateTargets(IEnumerable<Material> materials, bool add = false)
{
bool isShaderBroken (Shader s) => s == null || s.name == "Hidden/InternalErrorShader";
_materialList = (add ?
_materialList.Concat(materials) : // add
materials) // replace
.Distinct().ToList(); // deduplicate

UpdateTargets();
}

private void UpdateTargets()
{
bool isShaderBroken(Shader s) => s == null || s.name == "Hidden/InternalErrorShader";

_targets = _materialList.Where(t => t != null && !isShaderBroken(t.shader)).ToList();
foreach(Material m in _materialList.Where(t => t != null && isShaderBroken(t.shader)))
Debug.LogWarning("Material " + m.name + " has no shader assigned");

_shaderEditor = null;
}

private void OnGUI()
{
// List of materials, remove button next to each
// Add button at bottom

_scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition);
_showMaterials = EditorGUILayout.Foldout(_showMaterials, "Materials");

EditorGUI.BeginChangeCheck();
if(_showMaterials)
DrawMaterials();

// Check if targets have changed
bool didShadersChange = EditorGUI.EndChangeCheck();
foreach (Material m in _materialList)
{
EditorGUILayout.BeginVertical();
for (int i = 0; i < _materialList.Count; i++)
{
EditorGUILayout.BeginHorizontal();
GUILayout.Space(30);
_materialList[i] = (Material)EditorGUILayout.ObjectField(_materialList[i], typeof(Material), false);
if (GUILayout.Button("Remove", GUILayout.Width(70)))
{
_materialList.RemoveAt(i);
}
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.BeginHorizontal();
GUILayout.Space(30);
if (GUILayout.Button("Add", GUILayout.Width(70)))
{
_materialList.Add(null);
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
if (m == null || // Material is null
_targetShaders.ContainsKey(m) && _targetShaders[m] == m.shader) // Shader hasn't changed
continue;

didShadersChange = true;
_targetShaders[m] = m.shader;
}

// Check if targets have changed
bool didShadersChange = false;
foreach(Material m in _materialList)
if (didShadersChange) UpdateTargets();

DrawShaderEditor();

EditorGUILayout.EndScrollView();
}

// List of materials, remove button next to each
// Add and Remove All buttons at bottom
private void DrawMaterials()
{
if (!_showMaterials) return;

using (new EditorGUILayout.VerticalScope(LeftMargin.Value))
{
if(m != null && (!_targetShaders.ContainsKey(m) || _targetShaders[m] != m.shader))
for (int i = 0; i < _materialList.Count; i++) DrawMaterial(i);

using (new EditorGUILayout.HorizontalScope())
{
didShadersChange = true;
_targetShaders[m] = m.shader;
if (GUILayout.Button("Add", GUILayout.Width(100))) _materialList.Add(null);

GUILayout.FlexibleSpace();

if (GUILayout.Button("Remove All", GUILayout.Width(100))) _materialList.Clear();
}
}
if (EditorGUI.EndChangeCheck() || didShadersChange)
{
_shaderEditor = null;
UpdateTargets();
}
}

// Draw shader editor
if (_targets.Count > 0)
private void DrawMaterial(int i)
{
using (new EditorGUILayout.HorizontalScope())
{
// Create shader editor
if (_shaderEditor == null)
Material material = (Material)EditorGUILayout.ObjectField(_materialList[i], typeof(Material), false);

if (material != _materialList[i])
{
_shaderEditor = new ShaderEditor();
_materialEditor = MaterialEditor.CreateEditor(_targets.ToArray()) as MaterialEditor;

// group targets by shader, take one material per shader
IEnumerable<Material> materialsToSearchProperties = _targets.GroupBy(t => t.shader).Select(g => g.First());
// get properties for each shader
Dictionary<Shader, HashSet<string>> shaderProperties = materialsToSearchProperties.ToDictionary(m => m.shader, m => new HashSet<string>(MaterialEditor.GetMaterialProperties(new UnityEngine.Object[] { m }).Select(p => p.name)));
// get values of dict as string arrays
IEnumerable<string[]> propertiesPerShader = shaderProperties.Values.Select(v => v.ToArray());
// create intersection of all properties
List<string> propertiesOrdered = propertiesPerShader.Aggregate((a, b) => a.Intersect(b).ToArray()).ToList();
// expand the intersection to be a union, but add each property after the occurence of their predecessor
foreach (string[] properties in propertiesPerShader)
{
int index = 0;
foreach (string property in properties)
{
if (!propertiesOrdered.Contains(property))
{
if (index == 0)
propertiesOrdered.Insert(0, property);
else
propertiesOrdered.Insert(propertiesOrdered.IndexOf(properties[index - 1]) + 1, property);
}
index++;
}
}
// For each property get all materials, whos shader has this property
Dictionary<string, List<Material>> propertyMaterials = new Dictionary<string, List<Material>>();
foreach (string property in propertiesOrdered)
{
propertyMaterials[property] = _targets.Where(t => shaderProperties[t.shader].Contains(property)).ToList();
}
// Get MaterialProperties of all materials
_materialProperties = propertiesOrdered.Select(p => MaterialEditor.GetMaterialProperty(propertyMaterials[p].ToArray(), p)).ToArray();
if (_materialList.Contains(material)) material = null;

_materialList[i] = material;
}

// Seperator
EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
if (GUILayout.Button("Remove", GUILayout.Width(100))) _materialList.RemoveAt(i);
}
}

private void DrawShaderEditor()
{
if (_targets.Count == 0) return;

// Cursed but makes it render similar to the inspector

EditorGUILayout.BeginHorizontal();
EditorGUILayout.Space(30);
EditorGUILayout.BeginVertical();
// Create shader editor
CreateShaderEditor();

// Seperator
EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);

// Cursed but makes it render similar to the inspector
using (new EditorGUILayout.VerticalScope(LeftMargin.Value))
{
bool wideMode = EditorGUIUtility.wideMode;
EditorGUIUtility.wideMode = true;
_shaderEditor.OnGUI(_materialEditor, _materialProperties);
EditorGUIUtility.wideMode = wideMode;
EditorGUILayout.EndVertical();
EditorGUILayout.EndHorizontal();

}
}

EditorGUILayout.EndScrollView();
private void CreateShaderEditor()
{
if (_shaderEditor != null) return;

_shaderEditor = new ShaderEditor();
_materialEditor = Editor.CreateEditor(_targets.ToArray()) as MaterialEditor;

// group targets by shader, take one material per shader
IEnumerable<Material> materialsToSearchProperties = _targets.GroupBy(t => t.shader).Select(g => g.First());
// get properties for each shader
Dictionary<Shader, HashSet<string>> shaderProperties = materialsToSearchProperties.ToDictionary(m => m.shader, m => new HashSet<string>(MaterialEditor.GetMaterialProperties(new UnityEngine.Object[] { m }).Select(p => p.name)));
// get values of dict as string arrays
IEnumerable<string[]> propertiesPerShader = shaderProperties.Values.Select(v => v.ToArray());
// create intersection of all properties
List<string> propertiesOrdered = propertiesPerShader.Aggregate((a, b) => a.Intersect(b).ToArray()).ToList();
// expand the intersection to be a union, but add each property after the occurence of their predecessor
foreach (string[] properties in propertiesPerShader)
{
int index = 0;
foreach (string property in properties)
{
if (!propertiesOrdered.Contains(property))
{
if (index == 0)
propertiesOrdered.Insert(0, property);
else
propertiesOrdered.Insert(propertiesOrdered.IndexOf(properties[index - 1]) + 1, property);
}
index++;
}
}
// For each property get all materials, whos shader has this property
Dictionary<string, List<Material>> propertyMaterials = new Dictionary<string, List<Material>>();
foreach (string property in propertiesOrdered)
{
propertyMaterials[property] = _targets.Where(t => shaderProperties[t.shader].Contains(property)).ToList();
}
// Get MaterialProperties of all materials
_materialProperties = propertiesOrdered.Select(p => MaterialEditor.GetMaterialProperty(propertyMaterials[p].ToArray(), p)).ToArray();
}
}
}
35 changes: 35 additions & 0 deletions _PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Vector31.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using static Thry.GradientEditor;
using static Thry.TexturePacker;

namespace Thry
{
public class Vector31Drawer : MaterialPropertyDrawer
{
public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor)
{
string[] labels = label.text.Split('|');

EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = prop.hasMixedValue;
Vector4 vec = EditorGUI.Vector3Field(position, labels[0], prop.vectorValue);
float single = EditorGUI.FloatField(EditorGUILayout.GetControlRect(), labels.Length > 1 ? labels[1] : labels[0], prop.vectorValue.w);
if (EditorGUI.EndChangeCheck())
{
prop.vectorValue = new Vector4(vec.x, vec.y, vec.z, single);
}
}

public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor)
{
DrawingData.LastPropertyUsedCustomDrawer = true;
return base.GetPropertyHeight(prop, label, editor);
}
}

}
11 changes: 11 additions & 0 deletions _PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Vector31.cs.meta

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

Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ public static List<Texture2D> GetGifFrames(string path)
List<Texture2D> gifFrames = new List<Texture2D>();
#if SYSTEM_DRAWING
var gifImage = System.Drawing.Image.FromFile(path);
var dimension = new System.Drawing.Imaging.FrameDimension(gifImage.FrameDimensionsList[0]);
var dimension = System.Drawing.Imaging.FrameDimension.Time;

int width = Mathf.ClosestPowerOfTwo(gifImage.Width - 1);
int height = Mathf.ClosestPowerOfTwo(gifImage.Height - 1);
Expand All @@ -390,7 +390,8 @@ public static List<Texture2D> GetGifFrames(string path)
{
gifImage.SelectActiveFrame(dimension, i);
var ogframe = new System.Drawing.Bitmap(gifImage.Width, gifImage.Height);
System.Drawing.Graphics.FromImage(ogframe).DrawImage(gifImage, System.Drawing.Point.Empty);
var canvas = System.Drawing.Graphics.FromImage(ogframe);
canvas.DrawImage(gifImage, canvas.RenderingOrigin);
var frame = ResizeBitmap(ogframe, width, height);

Texture2D frameTexture = new Texture2D(frame.Width, frame.Height);
Expand Down
Loading

0 comments on commit 52b73ed

Please sign in to comment.