Import art/VFX asset packs + game-feel systems; normalize texture extensions to lowercase for LFS

Add BefourStudios SciFi environment packs, Gabriel Aguiar VFX, and the
ShaderCrew Toon Shader embedded packages, plus combat/enemy/wave/death
gameplay systems and supporting vault docs/screenshots.

Rename 11 vendor textures from uppercase .PNG/.HDR to lowercase so the
case-sensitive Git LFS filters (*.png/*.hdr) match on case-sensitive
filesystems (Linux CI, case-sensitive macOS), not just locally where
core.ignorecase=true masks the gap. Each .meta moved with its asset so
GUID references are preserved. All ~1000 binaries tracked via LFS.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-02 22:50:43 -07:00
parent dd0064c377
commit e362aaeb43
4830 changed files with 1293057 additions and 38 deletions
@@ -0,0 +1,396 @@
using System.Collections;
using System.Collections.Generic;
using System.Security.Cryptography;
using UnityEditor;
using UnityEngine;
namespace ShaderCrew.TheToonShader
{
public static class EditorUtils
{
public static void usualStart(string name)
{
LogoOnlyStart(name);
Rect rect = EditorGUILayout.BeginVertical();
GUI.Box(rect, GUIContent.none);
}
public static void LogoOnlyStart(string name)
{
Rect screenRect = GUILayoutUtility.GetRect(1, 1);
Rect vertRect = EditorGUILayout.BeginVertical();
Color backgroundColor = new Color(0.4f, 0.4f, 0.4f);
EditorGUI.DrawRect(new Rect(screenRect.x - 20, screenRect.y - 5, screenRect.width + 25, vertRect.height + 9), backgroundColor);
Sprite test = Resources.Load<Sprite>("logo-the-toon-shader-small");
GUIStyle headStyle = new GUIStyle();
headStyle.normal.textColor = Color.white;
headStyle.fontSize = 13;
headStyle.alignment = TextAnchor.MiddleCenter;
headStyle.fontStyle = FontStyle.Italic;
//GUILayout.Label(Strings.THE_TOON_SHADER_TITLE, headStyle);
//GUILayout.Label(Strings.SHADER_CREW_TITLE, headStyle);
headStyle.fontStyle = FontStyle.Bold;
headStyle.fontSize = 14;
GUILayout.Label(name, headStyle);
if (test != null)
{
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
//GUILayout.Label(test.texture, GUILayout.Width(250), GUILayout.Height(150));
GUILayout.Label(test.texture, GUILayout.Width(300), GUILayout.Height(200));
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
//EditorGUILayout.Space(30);
}
public static bool LogoOnlyStartWithDescription(string name, string description, bool showDescription)
{
LogoOnlyStart(name);
if (description != null && description != "")
{
Rect rectt = EditorGUILayout.BeginVertical(EditorStyles.helpBox);
GUI.Box(rectt, GUIContent.none);
string title = " Description:";
GUIStyle style = EditorStyles.foldout;
FontStyle previousStyle = style.fontStyle;
style.fontStyle = FontStyle.Bold;
showDescription = EditorGUILayout.Foldout(showDescription, title, style); //, EditorStyles.boldLabel);
style.fontStyle = previousStyle;
//showDescription = EditorGUILayout.Foldout(showDescription, title);
if (showDescription)
{
GUIStyle textStyle = EditorStyles.label;
textStyle.wordWrap = true;
textStyle.richText = true;
textStyle.fontStyle = FontStyle.Normal;
GUILayout.Space(10);
GUILayout.Label(description, textStyle);
GUILayout.Space(10);
}
EditorGUILayout.EndVertical();
EditorUtils.makeHorizontalSeparation();
return showDescription;
}
else
{
return false;
}
}
public static bool usualStartWithDescription(string name, string description, bool showDescription)
{
usualStart(name);
if (description != null && description != "")
{
string title = " Description:";
GUIStyle style = EditorStyles.foldout;
FontStyle previousStyle = style.fontStyle;
style.fontStyle = FontStyle.Bold;
showDescription = EditorGUILayout.Foldout(showDescription, title, style); //, EditorStyles.boldLabel);
style.fontStyle = previousStyle;
//showDescription = EditorGUILayout.Foldout(showDescription, title);
if (showDescription)
{
GUIStyle textStyle = EditorStyles.label;
textStyle.wordWrap = true;
textStyle.richText = true;
textStyle.fontStyle = FontStyle.Normal;
GUILayout.Space(10);
GUILayout.Label(description, textStyle);
GUILayout.Space(10);
}
return showDescription;
}
else
{
return false;
}
}
public static void usualEnd()
{
EditorGUILayout.EndVertical();
EditorGUILayout.EndVertical();
}
public static void LogoOnlyEnd()
{
EditorGUILayout.EndVertical();
}
public static void Header(string title, GUIStyle style)
{
Rect rectt = EditorGUILayout.BeginVertical();
//rectt.y = rectt.y - 2f;
//rectt.width = rectt.width + 6;
//rectt.x = rectt.x - 3;
rectt.width = rectt.width + 20;
rectt.x = 0;
//EditorUtils.DrawUILineFullWidth(Color.black, thickness: 1, padding: -3);
Color lightBlue = new Color(1.5f, 1.6f, 1.7f, 2);
EditorUtils.DrawUILineBottom(rectt, new Color(0.25f, 0.25f, 0.25f, 1f));
var c = GUI.color;
if (EditorGUIUtility.isProSkin)
{
GUI.color = new Color(0.5f, 1.5f, 2.5f, 1f);
GUI.color = new Color(1.5f, 1.6f, 1.7f, 2);
GUI.color = Color.black;
GUI.color = new Color(0.5f, 1.5f, 2.5f, 1.5f);
}
else
{
GUI.color = new Color(0.5f, 0.7f, 0.9f, 1f);
}
Color myStyleColor = new Color(0.8f, 0.95f, 1f, 1f);// *0.9f;
myStyleColor = Color.white;
style.fontStyle = FontStyle.BoldAndItalic;
style.fontSize = 14;
style.normal.textColor = myStyleColor;
style.onNormal.textColor = myStyleColor;
style.hover.textColor = myStyleColor;
style.onHover.textColor = myStyleColor;
style.focused.textColor = myStyleColor;
style.onFocused.textColor = myStyleColor;
style.active.textColor = myStyleColor;
style.onActive.textColor = myStyleColor;
GUI.Box(rectt, GUIContent.none);
GUI.color = c;
GUILayout.Space(5);
GUILayout.Label(title, style);
GUILayout.Space(5);
EditorGUILayout.EndVertical();
//Color color = Color.black;
//Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(1));
//r.y = r.y - 4f;
//r.width = r.width + 6;
//r.x = r.x - 3;
//EditorGUI.DrawRect(r, color);
lightBlue = new Color(1.1f, 1.2f, 1.7f, 0.5f);
EditorUtils.DrawUILineBottom(rectt, lightBlue, 1);
}
public static void DrawUILine(int thickness = 1, int padding = 10)
{
Color color = Color.black;
Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(padding + thickness));
r.height = thickness;
r.y += padding / 2;
EditorGUI.DrawRect(r, color);
}
public static void DrawUILineFull(int thickness = 1, int padding = 10)
{
Color color = Color.black;
Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(padding + thickness));
r.width = Screen.width;
r.x = 0;
r.height = thickness;
r.y += padding / 2;
EditorGUI.DrawRect(r, color);
}
public static void DrawUILineFull(Color color, int thickness = 1, int padding = 10)
{
Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(padding + thickness));
r.width = Screen.width;
r.x = 0;
r.height = thickness;
r.y += padding / 2;
EditorGUI.DrawRect(r, color);
}
public static void DrawUILineGray(int thickness = 2, int padding = 10)
{
Color color = new Color(0.2f, 0.2f, 0.2f, 1);
Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(padding + thickness));
r.height = thickness;
r.y += padding / 2;
EditorGUI.DrawRect(r, color);
}
public static void DrawUILineLightBlue(int thickness = 1, int padding = 0)
{
Color color = new Color(0.5f, 0.6f, 0.7f, 1);
Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(padding + thickness));
r.height = thickness;
r.y += padding / 2;
EditorGUI.DrawRect(r, color);
}
public static void DrawUILineFullWidth(Color color, int thickness = 2, int padding = -1)
{
Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(padding + thickness));
r.x = 0;
r.width += 30;
r.height = thickness;
r.y += padding / 2;
EditorGUI.DrawRect(r, color);
}
public static void DrawUILine(Color color, int thickness = 2, int padding = -1)
{
Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(padding + thickness));
r.height = thickness;
r.y += padding / 2;
EditorGUI.DrawRect(r, color);
}
public static void DrawUILineBottom(Rect rect, Color color, int thickness = 2, int padding = -1)
{
Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(padding + thickness));
r.height = thickness;
r.y += padding / 2;
r.x = rect.x;
r.width = rect.width;
EditorGUI.DrawRect(r, color);
}
public static void DrawUILine(Rect rect, Color color, int thickness = 2, int padding = -1)
{
Rect r = rect;
r.height = thickness;
r.y += padding / 2;
EditorGUI.DrawRect(r, color);
}
public static void DrawSubMenuSeparation()
{
//EditorGUILayout.Space();
EditorUtils.DrawUILineSubMenu(1, -1, 10);
EditorUtils.DrawUILineSubMenu(Color.gray, 1, 2, 10);
}
public static void DrawSubMenuSeparation2()
{
//EditorGUILayout.Space();
//Color color = new Color(0.28f, 0.28f, 0.28f, 1);
//EditorUtils.DrawUILineSubMenu(color, 1, -2, 10);
EditorUtils.DrawUILineSubMenu(4, -1, 0);
EditorUtils.DrawUILineSubMenu(Color.gray, 1, 2, 0);
}
public static void DrawUILineSubMenu(int thickness = 2, int padding = 1)
{
Color color = new Color(0.28f, 0.28f, 0.28f, 1);
DrawUILineSubMenu(color, thickness, padding);
}
public static void DrawUILineSubMenu(int thickness = 2, int padding = 1, float margin = 20)
{
Color color = new Color(0.28f, 0.28f, 0.28f, 1);
DrawUILineSubMenu(color, thickness, padding, margin);
}
public static void DrawUILineSubMenu(Color color, int thickness = 2, int padding = 1)
{
Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(padding + thickness));
r.height = thickness;
//r.y += padding / 2;
float marginLeft = 20;
r.width = r.width - marginLeft;
r.x += marginLeft;
EditorGUI.DrawRect(r, color);
}
public static void DrawUILineSubMenu(Color color, int thickness = 2, int padding = 1, float margin = 20)
{
Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(padding + thickness));
r.height = thickness;
//r.y += padding / 2;
float marginLeft = margin;
r.width = r.width - marginLeft;
r.x += marginLeft;
EditorGUI.DrawRect(r, color);
}
public static void DrawUILineCenter(Color color, int thickness = 2, int padding = 1)
{
Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(padding + thickness));
r.height = thickness;
//r.y += padding / 2;
float marginLeft = 20;
r.width = r.width - marginLeft * 2;
r.x += marginLeft;
EditorGUI.DrawRect(r, color);
}
public static void makeHorizontalSeparation(Color color)
{
GUIStyle horizontalLine;
horizontalLine = new GUIStyle();
horizontalLine.normal.background = EditorGUIUtility.whiteTexture;
horizontalLine.margin = new RectOffset(0, 0, 4, 4);
horizontalLine.fixedHeight = 10;
var c = GUI.color;
GUI.color = color;
GUILayout.Box(GUIContent.none, horizontalLine);
GUI.color = c;
}
public static void makeHorizontalSeparation()
{
makeHorizontalSeparation(new Color(0.4f, 0.4f, 0.4f));
}
public static void DrawBox(Rect position, Color color)
{
Color oldColor = GUI.color;
GUI.color = color;
GUI.Box(position, GUIContent.none);
GUI.color = oldColor;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 2751e2e41ac5ec2468893425195204b0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.core/Scripts/Editor/Common/EditorUtils.cs
uploadId: 919972
@@ -0,0 +1,12 @@
using UnityEngine;
namespace ShaderCrew.TheToonShader
{
public class GradientSO : ScriptableObject
{
[SerializeField]
public Gradient gradient;
[SerializeField]
public bool isBakedToTexture = false;
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: abb55f1f10b566340bf309a09598fc57
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.core/Scripts/Editor/Common/GradientSO.cs
uploadId: 919972
@@ -0,0 +1,93 @@
using System;
using System.IO;
using System.Reflection;
using System.Text;
using UnityEditor;
using UnityEngine;
namespace ShaderCrew.TheToonShader
{
// Source: https://discussions.unity.com/t/how-to-get-shader-source-code-from-script/839046/5
public static class ShaderGraphToShaderExporterUtil
{
private static object GetGraphData(string shaderAssetPath)
{
var importer = AssetImporter.GetAtPath(shaderAssetPath);
var textGraph = File.ReadAllText(importer.assetPath, Encoding.UTF8);
var graphObjectType = Type.GetType("UnityEditor.Graphing.GraphObject, Unity.ShaderGraph.Editor")!;
// var graphObject = CreateInstance<GraphObject>();
var graphObject = ScriptableObject.CreateInstance(graphObjectType);
graphObject.hideFlags = HideFlags.HideAndDontSave;
bool isSubGraph;
var extension = Path.GetExtension(importer.assetPath).Replace(".", "");
switch (extension)
{
case "shadergraph":
isSubGraph = false;
break;
case "ShaderGraph":
isSubGraph = false;
break;
case "shadersubgraph":
isSubGraph = true;
break;
default:
throw new Exception($"Invalid file extension {extension}");
}
var assetGuid = AssetDatabase.AssetPathToGUID(importer.assetPath);
// graphObject.graph = new GraphData { assetGuid = assetGuid, isSubGraph = isSubGraph, messageManager = null };
var graphObject_graphProperty = graphObjectType.GetProperty("graph")!;
var graphDataType = Type.GetType("UnityEditor.ShaderGraph.GraphData, Unity.ShaderGraph.Editor")!;
var graphDataInstance = Activator.CreateInstance(graphDataType);
graphDataType.GetProperty("assetGuid")!.SetValue(graphDataInstance, assetGuid);
graphDataType.GetProperty("isSubGraph")!.SetValue(graphDataInstance, isSubGraph);
graphDataType.GetProperty("messageManager")!.SetValue(graphDataInstance, null);
graphObject_graphProperty.SetValue(graphObject, graphDataInstance);
// MultiJson.Deserialize(graphObject.graph, textGraph);
// = MultiJson.Deserialize<JsonObject>(graphObject.graph, textGraph, null, false);
var multiJsonType = Type.GetType("UnityEditor.ShaderGraph.Serialization.MultiJson, Unity.ShaderGraph.Editor")!;
var deserializeMethod = multiJsonType.GetMethod("Deserialize")!;
var descrializeGenericMethod = deserializeMethod.MakeGenericMethod(graphDataType);
descrializeGenericMethod.Invoke(null, new object[] { graphDataInstance, textGraph, null, false });
// graphObject.graph.OnEnable();
graphDataType.GetMethod("OnEnable")!.Invoke(graphDataInstance, null);
// graphObject.graph.ValidateGraph();
graphDataType.GetMethod("ValidateGraph")!.Invoke(graphDataInstance, null);
// return graphData.graph
return graphDataInstance;
}
public static string GenerateShaderCode(string shaderAssetPath, string shaderName = null)
{
Type generatorType =
Type.GetType("UnityEditor.ShaderGraph.Generator, Unity.ShaderGraph.Editor")!;
Type modeType =
Type.GetType("UnityEditor.ShaderGraph.GenerationMode, Unity.ShaderGraph.Editor")!;
shaderName ??= Path.GetFileNameWithoutExtension(shaderAssetPath);
object graphData = GetGraphData(shaderAssetPath);
// new Generator(graphData, null, GenerationMode.ForReals, assetName, target:null, assetCollection:null, humanReadable: true);
object forReals = ((FieldInfo)modeType.GetMember("ForReals")[0]).GetValue(null);
object generator = Activator.CreateInstance(
generatorType,
new object[] { graphData, null, forReals, shaderName, null, null, true }
);
object shaderCode = generatorType
.GetProperty("generatedShader", BindingFlags.Public | BindingFlags.Instance)!
.GetValue(generator);
return (string)shaderCode;
}
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: a5cda48d5367852448bb16514360fc9f
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.core/Scripts/Editor/Common/ShaderGraphToShaderExporterUtil.cs
uploadId: 919972
@@ -0,0 +1,386 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;
using static ShaderCrew.TheToonShader.ShaderUtils;
namespace ShaderCrew.TheToonShader
{
public class TheToonShaderGenerator
{
public TheToonShaderGenerator() { }
//public bool _USE_OPTIMIZATION_DEFINES;
public bool _ENABLE_TOON_SHADING;
public int _LIGHT_SOURCE = -1;
public int _SHADING_FUNCTION;
public bool _SHADING_TERMINATORPOSITION;
public bool _ENABLE_SHADOWS;
public bool _ENABLE_CAST_SHADOWS;
public bool _ENABLE_SPECULAR;
public int _SPECULAR_BLENDING = -1;
public bool _ENABLE_RIM;
public int _RIM_BLENDING = -1;
public bool _SUM_LIGHTS_BEFORE_POSTERIZATION;
public bool _SHADING_USE_LIGHT_COLORS;
public bool _SPECULAR_USE_LIGHT_COLORS;
public bool _STYLING_SPECULAR_USE_LIGHT_COLORS;
public bool _ENABLE_STYLING;
public int _STYLING_CASTSHADOWS_SYNC_WITH_OTHER_STYLING = -1;
public bool _ENABLE_STYLING_DISTANCEFADE;
public bool _ENABLE_SHADING_STYLING;
public bool _SHADING_STYLING_TERMINATORPOSITION;
public int _SHADING_STYLING_BLENDING = -1;
public int _SHADING_STYLING_DRAWSPACE = -1;
public int _SHADING_STYLING_UVSET = -1;
public int _SHADING_STYLING_COORDINATESYSTEM = -1;
public int _SHADING_STYLE = -1;
public int _SHADING_STYLING_NUMBER_OF_CELLS_HATCHING = -1;
public bool _SHADING_STYLING_RANDOMIZER;
public bool _SHADING_STYLING_RANDOMIZER_PERLIN;
public bool _SHADING_STYLING_RANDOMIZER_PERLIN_FLOORED;
public bool _SHADING_STYLING_RANDOMIZER_WHITE;
public bool _SHADING_STYLING_RANDOMIZER_WHITE_FLOORED;
public bool _SHADING_STYLING_ENABLE_DASHES;
public int _SHADING_STYLING_DASHES_TYPE = -1;
public bool _ENABLE_CASTSHADOWS_STYLING;
public int _CASTSHADOWS_STYLING_BLENDING = -1;
public int _CASTSHADOWS_STYLING_DRAWSPACE = -1;
public int _CASTSHADOWS_STYLING_UVSET = -1;
public int _CASTSHADOWS_STYLING_COORDINATESYSTEM = -1;
public int _CASTSHADOWS_STYLE = -1;
public int _CASTSHADOWS_STYLING_NUMBER_OF_CELLS_HATCHING = -1;
public bool _CASTSHADOWS_STYLING_RANDOMIZER;
public bool _CASTSHADOWS_STYLING_RANDOMIZER_PERLIN;
public bool _CASTSHADOWS_STYLING_RANDOMIZER_PERLIN_FLOORED;
public bool _CASTSHADOWS_STYLING_RANDOMIZER_WHITE;
public bool _CASTSHADOWS_STYLING_RANDOMIZER_WHITE_FLOORED;
public bool _CASTSHADOWS_STYLING_ENABLE_DASHES;
public int _CASTSHADOWS_STYLING_DASHES_TYPE = -1;
public bool _ENABLE_SPECULAR_STYLING;
public int _SPECULAR_STYLING_BLENDING = -1;
public int _SPECULAR_STYLING_DRAWSPACE = -1;
public int _SPECULAR_STYLING_UVSET = -1;
public int _SPECULAR_STYLING_COORDINATESYSTEM = -1;
public int _SPECULAR_STYLE = -1;
public bool _SPECULAR_STYLING_RANDOMIZER;
public bool _SPECULAR_STYLING_RANDOMIZER_PERLIN;
public bool _SPECULAR_STYLING_RANDOMIZER_PERLIN_FLOORED;
public bool _SPECULAR_STYLING_RANDOMIZER_WHITE;
public bool _SPECULAR_STYLING_RANDOMIZER_WHITE_FLOORED;
public bool _SPECULAR_STYLING_ENABLE_DASHES;
public int _SPECULAR_STYLING_DASHES_TYPE = -1;
public bool _ENABLE_RIM_STYLING;
public int _RIM_STYLING_BLENDING = -1;
public int _RIM_STYLING_DRAWSPACE = -1;
public int _RIM_STYLING_UVSET = -1;
public int _RIM_STYLING_COORDINATESYSTEM = -1;
public int _RIM_STYLE = -1;
public bool _RIM_STYLING_RANDOMIZER;
public bool _RIM_STYLING_RANDOMIZER_PERLIN;
public bool _RIM_STYLING_RANDOMIZER_PERLIN_FLOORED;
public bool _RIM_STYLING_RANDOMIZER_WHITE;
public bool _RIM_STYLING_RANDOMIZER_WHITE_FLOORED;
public bool _RIM_STYLING_ENABLE_DASHES;
public int _RIM_STYLING_DASHES_TYPE = -1;
#if USING_URP2D
public int _MAX_LIGHT_COUNT = -1;
public int _CELL_METHOD = -1;
public bool _ENABLE_MAINTEX_POSTERIZATION;
public bool _EMISSION;
public bool _NORMALMAP;
public bool _USE_MAINTEX;
public bool _CONVERT_NORMAL_TO_ALBEDO;
public bool _USE_CORE_SHADOW_COLOR;
public bool _ENABLE_LIGHT_PARTITIONING;
public int _ROUND_METHOD = -1;
#endif
public bool _ENABLE_OUTLINE;
public static bool CheckIfShaderIsAlreadyOptimized(Material material)
{
if (material != null && material.shader != null)
{
string dataPathWithoutAssets = Application.dataPath;
if (dataPathWithoutAssets.EndsWith("/Assets"))
{
dataPathWithoutAssets = dataPathWithoutAssets.Substring(0, dataPathWithoutAssets.LastIndexOf("/Assets"));
}
string realPath = null;
string shaderAssetPath = UnityEditor.AssetDatabase.GetAssetPath(material.shader);
string fileName = Path.GetFileName(shaderAssetPath);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(shaderAssetPath);
string extension = Path.GetExtension(shaderAssetPath);
if (fileName != null && !fileName.Equals("") && extension != null && extension.Equals(".shader"))
{
realPath = dataPathWithoutAssets + "/" + shaderAssetPath;
}
//if (material.shader.name == "Dev/TheToonShaderDev")
//{
// realPath = dataPathWithoutAssets + "/Packages/com.shadercrew.the-toon-shader.core/Scripts/Shaders/Native/URP/TheToonShader_URP2020.shader";
//}
//else // remove in final
//{
// Debug.Log("Remove me in final");
// return false;
//}
//Debug.Log(realPath);
string fileContent = File.ReadAllText(realPath);
//Debug.Log(fileContent);
//string pattern = @"\b#define\s+_USE_OPTIMIZATION_DEFINES\s+1\b";
string pattern = @"#\bdefine\s+_USE_OPTIMIZATION_DEFINES\s+1\b";
Regex regex = new Regex(pattern);
bool lineFound = regex.IsMatch(fileContent);
return lineFound;
}
return false;
}
public static bool CheckIfShaderIsAlreadyOptimizedPropertyBased(Material material)
{
if (material != null && material.shader != null)
{
return material.HasProperty("_IsOptimized");
}
return false;
}
public Shader GenerateOptimizedShaderFile(Material material) // return generated shader
{
if(material != null && material.shader != null)
{
RenderPipelineOptions rp = getCurrentRenderPipeline();
string shaderAssetPath = UnityEditor.AssetDatabase.GetAssetPath(material.shader);
string fileName = Path.GetFileName(shaderAssetPath);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(shaderAssetPath);
string extension = Path.GetExtension(shaderAssetPath);
string dataPathWithoutAssets = Application.dataPath;
if (dataPathWithoutAssets.EndsWith("/Assets"))
{
dataPathWithoutAssets = dataPathWithoutAssets.Substring(0, dataPathWithoutAssets.LastIndexOf("/Assets"));
}
string realPath = null;
if (fileName != null && !fileName.Equals("") && extension != null && (extension.Equals(".shader") || extension.Equals(".shadergraph")))
{
realPath = dataPathWithoutAssets + "/" + shaderAssetPath;
}
////cause debug:
////realPath = dataPathWithoutAssets + "/Packages/com.shadercrew.the-toon-shader.core/Scripts/Shaders/Native/URP/TheToonShader_URP2020.shader";
//if(material.shader.name == "Dev/TheToonShaderDev")
//{
// realPath = dataPathWithoutAssets + "/Packages/com.shadercrew.the-toon-shader.core/Scripts/Shaders/Native/URP/TheToonShader_URP2020.shader";
//}
if (realPath != null && !realPath.Equals(""))
{
string content = null;
if (rp == RenderPipelineOptions.URP2D)
{
content = ShaderGraphToShaderExporterUtil.GenerateShaderCode(shaderAssetPath, fileNameWithoutExtension);
}
else
{
content = File.ReadAllText(realPath);
}
string optimizedShaderName = "";
//string patternShaderName = @"Shader\s*""([^""]+)""";
//string patternShaderName = @"(\r\n|\r|\n)\s*Shader\s*""([^""]+)""";
//Regex regex = new Regex(patternShaderName);
Regex regex = new Regex(@"^\s*Shader\s*""([^""]+)""", RegexOptions.Multiline);
Match matchShaderName = regex.Match(content);
if (matchShaderName.Success)
{
string shaderName = matchShaderName.Groups[1].Value;
string modifiedShaderName = shaderName + "_" + material.name + "_Optimized";
optimizedShaderName = modifiedShaderName;
//Debug.Log("optimizedShaderName: " + optimizedShaderName);
List<string> parts = optimizedShaderName.Split('/').ToList();
parts.Insert(1, "Optimized");
optimizedShaderName = string.Join("/", parts);
content = regex.Replace(content, matchShaderName.Value.Replace(shaderName, optimizedShaderName));
}
string patternProperties = @"Properties\s*\{\s*";
Match matchProperties = Regex.Match(content, patternProperties);
if (matchProperties.Success)
{
int insertPosition = matchProperties.Index + matchProperties.Length;
content = content.Insert(insertPosition, "[HideInInspector] _IsOptimized(\"_IsOptimized\", Float) = 1.0" + "\n");
}
string pattern = @"SubShader\s*\{\s*";
Match match = Regex.Match(content, pattern);
if (match.Success)
{
int insertPosition = match.Index + match.Length;
StringBuilder defineDefinitions = new StringBuilder(2000);
if (rp == RenderPipelineOptions.BiRP)
{
defineDefinitions.AppendLine("\tCGINCLUDE");
}
else
{
defineDefinitions.AppendLine("\tHLSLINCLUDE");
}
defineDefinitions.AppendLine("\t\t#define _USE_OPTIMIZATION_DEFINES 1");
Type type = this.GetType();
FieldInfo[] properties = type.GetFields();
foreach (FieldInfo property in properties)
{
//if(!property.Name.Equals("_ENABLE_OUTLINE"))
//{
if (property.GetValue(this).GetType() == typeof(bool))
{
//Debug.Log("name: " + property.Name + " - " + (bool)property.GetValue(this));
if ((bool)property.GetValue(this) == true)
{
defineDefinitions.AppendLine("\t\t#define " + property.Name + " 1");
}
}
else if (property.GetValue(this).GetType() == typeof(int))
{
if ((int)property.GetValue(this) != -1)
{
defineDefinitions.AppendLine("\t\t#define " + property.Name + " " + (int)property.GetValue(this));
}
//}
}
}
if (rp == RenderPipelineOptions.BiRP)
{
defineDefinitions.AppendLine("\tENDCG");
}
else
{
defineDefinitions.AppendLine("\tENDHLSL");
}
string modifiedContent = content.Insert(insertPosition, "\n" + defineDefinitions.ToString() + "\n");
//if (_ENABLE_OUTLINE == false)
//{
// string outlinePassPattern = @"Pass\s*\{\s*Name\s*""Outline""[\s\S]*?ENDCG[\s\S]*?\}";
// modifiedContent = Regex.Replace(modifiedContent, outlinePassPattern, "", RegexOptions.Singleline);
//}
//string filePathModfied = Application.dataPath + "/ToonShaderBuilder/ShaderCreatorTest/ShaderCreatorPlain_URP2020Optimized.shader";
string filePathModfied;
if (rp == RenderPipelineOptions.URP2D && material.HasProperty(TheToonShaderConstants.THETOONSHADER2D_IDENTIFIER_PROPERTY))
{
filePathModfied = dataPathWithoutAssets + "/Packages/com.shadercrew.the-toon-shader.2d/Scripts/Resources/OptimizedShaders/";
}
else
{
filePathModfied = dataPathWithoutAssets + "/Packages/com.shadercrew.the-toon-shader.3d/Scripts/Resources/OptimizedShaders/";
}
if (!Directory.Exists(filePathModfied))
{
Directory.CreateDirectory(filePathModfied);
}
filePathModfied += fileNameWithoutExtension + "_" + material.name + "_Optimized";
filePathModfied += ".shader";
File.WriteAllText(filePathModfied, modifiedContent);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
Shader optimizedShader = Shader.Find(optimizedShaderName);
//Debug.Log(optimizedShaderName);
return optimizedShader;
}
}
}
return null;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: b4ccf604a3bf34b4982530526b1d037a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.core/Scripts/Editor/Common/TheToonShaderGenerator.cs
uploadId: 919972
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: cf2c77cd8430cac489c071ca03240422
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 269238
packageName: The Toon Shader
packageVersion: 1.4.2
assetPath: Packages/com.shadercrew.the-toon-shader.core/Scripts/Editor/Common/ToonEditorUtils.cs
uploadId: 919972