Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
f502c92
Added AlphaToCoverage shaders
d-b Aug 6, 2020
75d0983
Added some test stippling code
d-b Aug 7, 2020
f46ff45
Updated gitignore
d-b Aug 7, 2020
2280125
Added toggles for stippling & crosshatching
d-b Aug 7, 2020
01f04c1
Added Stipple & Crosshatch mask/texture & settings
d-b Aug 7, 2020
3fbe996
Move texture accesses outside of conditionals
d-b Aug 8, 2020
61a3719
Added stipple/crosshatch emission map support
d-b Aug 8, 2020
05f7234
Add emission intensity and animation
d-b Aug 8, 2020
92a92ef
Emission scroll & stipple animation
d-b Aug 9, 2020
1a2f228
Add "wave" stipple animation
d-b Aug 9, 2020
cd40a2e
Added stipple mode & speed/freq settings
d-b Aug 11, 2020
3863a7c
Raise max stipple speed
d-b Aug 11, 2020
cf36251
Added fix to avoid poles
d-b Aug 13, 2020
2f2dc09
Add tiling/offset to GUI
d-b Aug 24, 2020
0849e41
Added Hue Shift functionality
d-b Aug 24, 2020
962f6f2
Added Hue Shift modes
d-b Aug 24, 2020
b0901b4
Add Base, Stipple & Crosshatch modes & fix outline
d-b Aug 25, 2020
90eb042
Add parallax mode
d-b Aug 25, 2020
07f06b5
Added full HSV control
d-b Aug 25, 2020
71c1b2e
Added vertex color alpha control
d-b Sep 4, 2020
3cc4628
Fix OL VOUT definition
d-b Sep 4, 2020
96bdde7
Add Vertex Alpha settings foldout
d-b Sep 4, 2020
aed4735
Added dithering to AlphaToCoverage
d-b Sep 4, 2020
a2b008f
Add color conversion and fix shadow casting
d-b Sep 5, 2020
6223687
Added configurable threshold
d-b Sep 5, 2020
b5b82ee
Improved threshold UI element
d-b Sep 5, 2020
46bf4fb
Conditional optimizations
d-b Sep 8, 2020
0dd9fdf
Added shader optimizer
d-b Sep 12, 2020
cb5b118
Added optimizations
d-b Sep 12, 2020
d7209ad
Prefix GUID with dash
d-b Sep 22, 2020
09a1cf3
Use dedicated sampler for HSV mask
d-b Oct 4, 2020
7c48c79
Add disable outline option in stippling
d-b Oct 8, 2020
06189db
Updates for 1.4.0
d-b Oct 19, 2020
fdb2d8f
Added mirror control feature
d-b Oct 24, 2020
7cb0db9
Added Toon Specular effect (#1)
d-b Nov 3, 2020
3d4a636
SH fixes & add vertex lights to toon specular
d-b Nov 3, 2020
b781a0f
Added specular HSV shift mode
d-b Nov 3, 2020
732fd44
Fix shader params
d-b Nov 3, 2020
c781b94
Fix badly named variable
d-b Nov 4, 2020
30a357d
Added GGX toon specular mode
d-b Nov 27, 2020
3e6e890
Fixed tangent/bitangent supplied to GGX spec
d-b Nov 28, 2020
d23ca4c
Change roughness defaults
d-b Nov 28, 2020
75ae7fb
Added decal support to HSV adjustment
d-b Dec 1, 2020
babe71a
Added metallic property to toon specular
d-b Dec 5, 2020
2b295ca
Refactor anisotropic specular
d-b Dec 11, 2020
dabb788
Refactor to imporove consistency & documentation
d-b Dec 11, 2020
560fa27
Added missing _MinimumLight property
d-b Dec 22, 2020
54c40be
Added TransClipping shader variants
d-b Jan 5, 2021
d13930c
Fixed SHToonSpec type
d-b Jan 7, 2021
a7eedf1
Added tangent map support
d-b Jan 10, 2021
d70839c
Whitespace fix & removed comment
d-b Jan 10, 2021
e747b01
Added standard tangent map support
d-b Jan 10, 2021
1a1f3f6
Boost TransClipping queue value
d-b Jan 11, 2021
75f3086
Fixes for Sunao 1.4.2
d-b Mar 5, 2021
2a7f688
Fixed tangent rotation map bug
d-b Mar 7, 2021
8ab512c
Modify MIT URL
shujisado Mar 27, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.meta
153 changes: 153 additions & 0 deletions Editor/ShaderOptimizer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Text;
using System.Globalization;

namespace SunaoShader
{
public class ShaderOptimizer
{
public static bool Lock(Material material, MaterialProperty[] props)
{
// File filepaths and names
Shader shader = material.shader;
string shaderFilePath = AssetDatabase.GetAssetPath(shader);
string materialFilePath = AssetDatabase.GetAssetPath(material);
string materialFolder = Path.GetDirectoryName(materialFilePath);
string guid = Guid.NewGuid().ToString();
string newShaderName = shader.name + ".Optimized/" + material.name + "-" + guid;
string newShaderFileName = Path.GetFileNameWithoutExtension(shaderFilePath) + "_" + material.name + "-" + guid + ".shader";
string newShaderFilePath = materialFolder + "/Optimized/" + newShaderFileName;

// Generate the new shader
string newShaderBody = GenerateShader(shaderFilePath, newShaderName, props);

// Write the shader to disk
(new FileInfo(newShaderFilePath)).Directory.Create();
try {
StreamWriter sw = new StreamWriter(newShaderFilePath);
sw.Write(newShaderBody);
sw.Close();
}
catch (IOException e) {
Debug.LogError("Optimized shader " + newShaderFilePath + " could not be written: " + e.ToString());
return false;
}

AssetDatabase.Refresh();
// Write original shader to override tag
material.SetOverrideTag("OriginalShader", shader.name);
// Write the new shader path in an override tag so it will be deleted
material.SetOverrideTag("OptimizedShaderPath", newShaderFilePath);

// For some reason when shaders are swapped on a material the RenderType override tag gets completely deleted and render queue set back to -1
// So these are saved as temp values and reassigned after switching shaders
string renderType = material.GetTag("RenderType", false, "");
int renderQueue = material.renderQueue;

// Actually switch the shader
Shader newShader = Shader.Find(newShaderName);
if (newShader == null) {
Debug.LogError("Optimized shader " + newShaderName + " could not be found");
return false;
}
material.shader = newShader;
material.SetOverrideTag("RenderType", renderType);
material.renderQueue = renderQueue;

return true;
}

private static string GenerateDefines(MaterialProperty[] props) {
StringBuilder sb = new StringBuilder();

sb.AppendLine("#define OPTIMIZED_SHADER 1");
foreach (MaterialProperty prop in props) {
if (prop != null && prop.type == MaterialProperty.PropType.Float)
sb.AppendLine("#define PROP_" + ToSnakeCase(prop.name) + " " + prop.floatValue);
}

return sb.ToString();
}

private static string ToSnakeCase(string str)
{
Regex pattern = new Regex(@"[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+");
return string.Join("_", pattern.Matches(str).Cast<Match>().Select(m => m.Value)).ToUpper();
}

private static string GenerateShader(string shaderPath, string shaderName, MaterialProperty[] props) {
string basePath = Path.GetDirectoryName(shaderPath).Replace("\\", "/") + "/";

Regex shaderPattern = new Regex(@"\s*Shader\s+""(.*?)""(.*)");
Regex includePattern = new Regex(@"\s*#include\s+""(?i)(?!Assets[\\/])(.[\\/])?(.*?)""");
Regex cgprogramPattern = new Regex(@"\s*CGPROGRAM\s*");

StringBuilder sb = new StringBuilder();
List<string> shaderLines = File.ReadAllLines(shaderPath).ToList();

string generatedDefines = GenerateDefines(props);

foreach(string line in shaderLines) {
MatchCollection shaderMatches = shaderPattern.Matches(line);
MatchCollection includeMatches = includePattern.Matches(line);

if (shaderMatches.Count > 0) {
sb.AppendLine("Shader \"" + shaderName + "\"" + shaderMatches[0].Groups[2].Captures[0].Value);
} else if (includeMatches.Count > 0) {
string path = Path.Combine(basePath, includeMatches[0].Groups[2].Captures[0].Value);
sb.AppendLine("#include \"" + path + "\"");
} else {
sb.AppendLine(line);
}

MatchCollection matches = cgprogramPattern.Matches(line);
if (matches.Count > 0) sb.Append(generatedDefines);
}

return sb.ToString();
}

public static bool Unlock(Material material)
{
// Revert to original shader
string originalShaderName = material.GetTag("OriginalShader", false, "");
if (originalShaderName == "") {
Debug.LogError("Original shader not saved to material, could not unlock shader");
return false;
}

Shader orignalShader = Shader.Find(originalShaderName);
if (orignalShader == null) {
Debug.LogError("Original shader " + originalShaderName + " could not be found");
return false;
}

// For some reason when shaders are swapped on a material the RenderType override tag gets completely deleted and render queue set back to -1
// So these are saved as temp values and reassigned after switching shaders
string renderType = material.GetTag("RenderType", false, "");
int renderQueue = material.renderQueue;
material.shader = orignalShader;
material.SetOverrideTag("RenderType", renderType);
material.renderQueue = renderQueue;

// Delete the optimized shader file
string shaderFilePath = material.GetTag("OptimizedShaderPath", false, "");
if (shaderFilePath == "") {
Debug.LogError("Optimized shader folder could not be found, not deleting anything");
return false;
}

AssetDatabase.DeleteAsset(shaderFilePath);
AssetDatabase.Refresh();

return true;
}
}
}
Loading