summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Editor/shader_inliner.cs207
-rw-r--r--shader_inliner.cs207
-rw-r--r--tooner.shader2
3 files changed, 208 insertions, 208 deletions
diff --git a/Editor/shader_inliner.cs b/Editor/shader_inliner.cs
new file mode 100644
index 0000000..cecf9b8
--- /dev/null
+++ b/Editor/shader_inliner.cs
@@ -0,0 +1,207 @@
+// !! AI ARTIFACT !!
+// This code was originally generated by Claude 3.5 Sonnet.
+// I wanted to write this tooling like I want a fucking hole in the head so I
+// kindly asked Claude to write it for me. It's shitty and poorly designed, but
+// it works well enough for my purposes.
+// It has been slightly tweaked by me, and validated on *this* codebase. It is
+// provided with no warranty.
+using UnityEngine;
+using UnityEditor;
+using System.IO;
+using System.Text.RegularExpressions;
+using System.Collections.Generic;
+using System.Linq;
+
+public class ShaderInliner : EditorWindow
+{
+ private string inputShaderPath;
+ private string outputShaderPath;
+
+ [MenuItem("Tools/yum_food/Shader Inliner")]
+ public static void ShowWindow()
+ {
+ GetWindow<ShaderInliner>("Shader Inliner");
+ }
+
+ private void OnGUI()
+ {
+ GUILayout.Label("Shader Inliner", EditorStyles.boldLabel);
+
+ inputShaderPath = EditorGUILayout.TextField("Input Shader Path", inputShaderPath);
+ if (GUILayout.Button("Select Input Shader"))
+ {
+ inputShaderPath = EditorUtility.OpenFilePanel("Select Shader", "", "shader");
+ }
+
+ if (GUILayout.Button("Inline Shader"))
+ {
+ if (string.IsNullOrEmpty(inputShaderPath))
+ {
+ EditorUtility.DisplayDialog("Error", "Please select an input shader.", "OK");
+ return;
+ }
+
+ InlineShader();
+ }
+ }
+
+ private void InlineShader()
+ {
+ string shaderContent = File.ReadAllText(inputShaderPath);
+ string inlinedShader = ProcessShader(shaderContent, Path.GetDirectoryName(inputShaderPath));
+
+ string fileName = Path.GetFileNameWithoutExtension(inputShaderPath);
+ outputShaderPath = Path.Combine(Path.GetDirectoryName(inputShaderPath), $"{fileName}_inlined.shader");
+ File.WriteAllText(outputShaderPath, inlinedShader);
+
+ AssetDatabase.Refresh();
+ EditorUtility.DisplayDialog("Success", $"Inlined shader saved to:\n{outputShaderPath}", "OK");
+ }
+
+ private string ProcessShader(string content, string basePath)
+ {
+ // Update shader name
+ content = Regex.Replace(content, @"Shader\s+""(.+?)""", match =>
+ {
+ string shaderName = match.Groups[1].Value;
+ return $"Shader \"{shaderName}_inlined\"";
+ });
+
+ // Process each Pass independently
+ content = Regex.Replace(content, @"(CGPROGRAM.*?ENDCG)", match =>
+ {
+ return ProcessPass(match.Value, basePath);
+ }, RegexOptions.Singleline);
+
+ // Check for mismatched preprocessor macros in the entire shader
+ CheckMismatchedMacros(content);
+
+ return content;
+ }
+
+ private string ProcessPass(string passContent, string basePath)
+ {
+ HashSet<string> includedFiles = new HashSet<string>();
+
+ string pattern = @"#include\s+""(.+?)""";
+ return Regex.Replace(passContent, pattern, match =>
+ {
+ string includePath = match.Groups[1].Value;
+ string fullPath = Path.Combine(basePath, includePath);
+
+ if (File.Exists(fullPath))
+ {
+ if (!includedFiles.Contains(fullPath))
+ {
+ includedFiles.Add(fullPath);
+ string includeContent = File.ReadAllText(fullPath);
+ return ProcessInclude(includeContent, Path.GetDirectoryName(fullPath), includedFiles);
+ }
+ else
+ {
+ return "// Already included in this pass: " + includePath;
+ }
+ }
+ else
+ {
+ Debug.LogWarning($"Include file not found: {fullPath}");
+ return match.Value;
+ }
+ });
+ }
+
+ private string ProcessInclude(string content, string basePath, HashSet<string> includedFiles)
+ {
+ string pattern = @"#include\s+""(.+?)""";
+ return Regex.Replace(content, pattern, match =>
+ {
+ string includePath = match.Groups[1].Value;
+ string fullPath = Path.Combine(basePath, includePath);
+
+ if (File.Exists(fullPath))
+ {
+ if (!includedFiles.Contains(fullPath))
+ {
+ includedFiles.Add(fullPath);
+ string includeContent = File.ReadAllText(fullPath);
+ return ProcessInclude(includeContent, Path.GetDirectoryName(fullPath), includedFiles);
+ }
+ else
+ {
+ return "// Already included in this pass: " + includePath;
+ }
+ }
+ else
+ {
+ Debug.LogWarning($"Include file not found: {fullPath}");
+ return match.Value;
+ }
+ });
+ }
+
+ private void CheckMismatchedMacros(string content)
+ {
+ var stack = new Stack<string>();
+ var lines = content.Split('\n');
+ var macroPattern = @"^\s*#(if|ifdef|ifndef|elif|else|endif|if\s+defined)";
+
+ for (int i = 0; i < lines.Length; i++)
+ {
+ var line = lines[i].Trim();
+ var match = Regex.Match(line, macroPattern);
+
+ if (match.Success)
+ {
+ var directive = match.Groups[1].Value;
+
+ switch (directive)
+ {
+ case "if":
+ case "ifdef":
+ case "ifndef":
+ case "if defined":
+ stack.Push(directive);
+ break;
+ case "elif":
+ if (stack.Count == 0 || (stack.Peek() != "if" && stack.Peek() != "elif"))
+ {
+ Debug.LogError($"Mismatched #elif at line {i + 1}");
+ }
+ else
+ {
+ stack.Pop();
+ stack.Push("elif");
+ }
+ break;
+ case "else":
+ if (stack.Count == 0 || (stack.Peek() != "if" && stack.Peek() != "elif"))
+ {
+ Debug.LogError($"Mismatched #else at line {i + 1}");
+ }
+ else
+ {
+ stack.Pop();
+ stack.Push("else");
+ }
+ break;
+ case "endif":
+ if (stack.Count == 0)
+ {
+ Debug.LogError($"Mismatched #endif at line {i + 1}");
+ }
+ else
+ {
+ stack.Pop();
+ }
+ break;
+ }
+ }
+ }
+
+ if (stack.Count > 0)
+ {
+ Debug.LogError($"Unclosed preprocessor directives: {string.Join(", ", stack)}");
+ }
+ }
+}
+
diff --git a/shader_inliner.cs b/shader_inliner.cs
deleted file mode 100644
index 6bfb5a3..0000000
--- a/shader_inliner.cs
+++ /dev/null
@@ -1,207 +0,0 @@
-// !! AI ARTIFACT !!
-// This code was originally generated by Claude 3.5 Sonnet.
-// I wanted to write this tooling like I want a fucking hole in the head so I
-// kindly asked Claude to write it for me. It's shitty and poorly designed, but
-// it works well enough for my purposes.
-// It has been slightly tweaked by me, and validated on *this* codebase. It is
-// provided with no warranty.
-using UnityEngine;
-using UnityEditor;
-using System.IO;
-using System.Text.RegularExpressions;
-using System.Collections.Generic;
-using System.Linq;
-
-public class ShaderInliner : EditorWindow
-{
- private string inputShaderPath;
- private string outputShaderPath;
-
- [MenuItem("Tools/yum_food/Shader Inliner")]
- public static void ShowWindow()
- {
- GetWindow<ShaderInliner>("Shader Inliner");
- }
-
- private void OnGUI()
- {
- GUILayout.Label("Shader Inliner", EditorStyles.boldLabel);
-
- inputShaderPath = EditorGUILayout.TextField("Input Shader Path", inputShaderPath);
- if (GUILayout.Button("Select Input Shader"))
- {
- inputShaderPath = EditorUtility.OpenFilePanel("Select Shader", "", "shader");
- }
-
- if (GUILayout.Button("Inline Shader"))
- {
- if (string.IsNullOrEmpty(inputShaderPath))
- {
- EditorUtility.DisplayDialog("Error", "Please select an input shader.", "OK");
- return;
- }
-
- InlineShader();
- }
- }
-
- private void InlineShader()
- {
- string shaderContent = File.ReadAllText(inputShaderPath);
- string inlinedShader = ProcessShader(shaderContent, Path.GetDirectoryName(inputShaderPath));
-
- string fileName = Path.GetFileNameWithoutExtension(inputShaderPath);
- outputShaderPath = Path.Combine(Path.GetDirectoryName(inputShaderPath), $"{fileName}_inlined.shader");
- File.WriteAllText(outputShaderPath, inlinedShader);
-
- AssetDatabase.Refresh();
- EditorUtility.DisplayDialog("Success", $"Inlined shader saved to:\n{outputShaderPath}", "OK");
- }
-
- private string ProcessShader(string content, string basePath)
- {
- // Update shader name
- content = Regex.Replace(content, @"Shader\s+""(.+?)""", match =>
- {
- string shaderName = match.Groups[1].Value;
- return $"Shader \"{shaderName}_inlined\"";
- });
-
- // Process each Pass independently
- content = Regex.Replace(content, @"(CGPROGRAM.*?ENDCG)", match =>
- {
- return ProcessPass(match.Value, basePath);
- }, RegexOptions.Singleline);
-
- // Check for mismatched preprocessor macros in the entire shader
- CheckMismatchedMacros(content);
-
- return content;
- }
-
- private string ProcessPass(string passContent, string basePath)
- {
- HashSet<string> includedFiles = new HashSet<string>();
-
- string pattern = @"#include\s+""(.+?)""";
- return Regex.Replace(passContent, pattern, match =>
- {
- string includePath = match.Groups[1].Value;
- string fullPath = Path.Combine(basePath, includePath);
-
- if (File.Exists(fullPath))
- {
- if (!includedFiles.Contains(fullPath))
- {
- includedFiles.Add(fullPath);
- string includeContent = File.ReadAllText(fullPath);
- return ProcessInclude(includeContent, Path.GetDirectoryName(fullPath), includedFiles);
- }
- else
- {
- return "// Already included in this pass: " + includePath;
- }
- }
- else
- {
- Debug.LogWarning($"Include file not found: {fullPath}");
- return match.Value;
- }
- });
- }
-
- private string ProcessInclude(string content, string basePath, HashSet<string> includedFiles)
- {
- string pattern = @"#include\s+""(.+?)""";
- return Regex.Replace(content, pattern, match =>
- {
- string includePath = match.Groups[1].Value;
- string fullPath = Path.Combine(basePath, includePath);
-
- if (File.Exists(fullPath))
- {
- if (!includedFiles.Contains(fullPath))
- {
- includedFiles.Add(fullPath);
- string includeContent = File.ReadAllText(fullPath);
- return ProcessInclude(includeContent, Path.GetDirectoryName(fullPath), includedFiles);
- }
- else
- {
- return "// Already included in this pass: " + includePath;
- }
- }
- else
- {
- Debug.LogWarning($"Include file not found: {fullPath}");
- return match.Value;
- }
- });
- }
-
- private void CheckMismatchedMacros(string content)
- {
- var stack = new Stack<string>();
- var lines = content.Split('\n');
- var macroPattern = @"^\s*#(if|ifdef|ifndef|elif|else|endif|if\s+defined)";
-
- for (int i = 0; i < lines.Length; i++)
- {
- var line = lines[i].Trim();
- var match = Regex.Match(line, macroPattern);
-
- if (match.Success)
- {
- var directive = match.Groups[1].Value;
-
- switch (directive)
- {
- case "if":
- case "ifdef":
- case "ifndef":
- case "if defined":
- stack.Push(directive);
- break;
- case "elif":
- if (stack.Count == 0 || (stack.Peek() != "if" && stack.Peek() != "elif"))
- {
- Debug.LogError($"Mismatched #elif at line {i + 1}");
- }
- else
- {
- stack.Pop();
- stack.Push("elif");
- }
- break;
- case "else":
- if (stack.Count == 0 || (stack.Peek() != "if" && stack.Peek() != "elif"))
- {
- Debug.LogError($"Mismatched #else at line {i + 1}");
- }
- else
- {
- stack.Pop();
- stack.Push("else");
- }
- break;
- case "endif":
- if (stack.Count == 0)
- {
- Debug.LogError($"Mismatched #endif at line {i + 1}");
- }
- else
- {
- stack.Pop();
- }
- break;
- }
- }
- }
-
- if (stack.Count > 0)
- {
- Debug.LogError($"Unclosed preprocessor directives: {string.Join(", ", stack)}");
- }
- }
-}
-
diff --git a/tooner.shader b/tooner.shader
index 47043ca..64faef1 100644
--- a/tooner.shader
+++ b/tooner.shader
@@ -3,7 +3,7 @@ Shader "yum_food/tooner"
// Unity fucking sucks ass and sometimes incorrectly uses an old cached
// version of the shader. Bump the nonce below to encourage it to use the
// current version.
- // Build nonce: 31
+ // Build nonce: 32
Properties
{
_Color("Base color", Color) = (0.8, 0.8, 0.8, 1)