374 lines
14 KiB
C#
374 lines
14 KiB
C#
//////////////////////////////////////////////////////
|
|
// MicroSplat
|
|
// Copyright (c) Jason Booth
|
|
//////////////////////////////////////////////////////
|
|
|
|
|
|
using UnityEngine;
|
|
using System.Collections;
|
|
using UnityEditor;
|
|
using UnityEditor.Callbacks;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace JBooth.MicroSplat
|
|
{
|
|
#if __MICROSPLAT__
|
|
[InitializeOnLoad]
|
|
public class MicroSplatLowPoly : FeatureDescriptor
|
|
{
|
|
const string sDefine = "__MICROSPLAT_LOWPOLY__";
|
|
static MicroSplatLowPoly()
|
|
{
|
|
MicroSplatDefines.InitDefine(sDefine);
|
|
}
|
|
[PostProcessSceneAttribute (0)]
|
|
public static void OnPostprocessScene()
|
|
{
|
|
MicroSplatDefines.InitDefine(sDefine);
|
|
}
|
|
public override string ModuleName()
|
|
{
|
|
return "Low Poly";
|
|
}
|
|
|
|
public override string GetHelpPath ()
|
|
{
|
|
return "https://docs.google.com/document/d/1t_NNr9dRjLZ9OKqoKq3igkRI3iVefcynU1ebtdYO7gw/edit?usp=sharing";
|
|
}
|
|
|
|
public enum DefineFeature
|
|
{
|
|
_TOONHARDEDGENORMAL,
|
|
_TOONHARDEDGENORMALQUAD,
|
|
_TOONWIREFRAME,
|
|
_TOONWIREQUADS,
|
|
_TOONWIREWORLDSPACE,
|
|
_TOONPOLYEDGE,
|
|
_TOONFLATTEXTURE,
|
|
_TOONFLATTEXTUREQUAD,
|
|
_WIRESATURATIONBRIGHTNESS,
|
|
_TOONWIREFADE,
|
|
kNumFeatures,
|
|
};
|
|
|
|
public enum EdgeMode
|
|
{
|
|
None,
|
|
Triangle,
|
|
Quads,
|
|
Poly
|
|
}
|
|
|
|
public enum WireSpace
|
|
{
|
|
ScreenSpace,
|
|
WorldSpace
|
|
}
|
|
|
|
public enum WireColorMode
|
|
{
|
|
Color,
|
|
SaturationBrightness
|
|
}
|
|
|
|
|
|
|
|
public EdgeMode hardNormalEdge = EdgeMode.None;
|
|
public EdgeMode flatTexture = EdgeMode.None;
|
|
public EdgeMode wireframe = EdgeMode.None;
|
|
public WireSpace wireSpace = WireSpace.ScreenSpace;
|
|
public WireColorMode wireColor = WireColorMode.Color;
|
|
public bool wireFade;
|
|
|
|
public TextAsset properties_hardedge;
|
|
public TextAsset functions_hardedge;
|
|
public TextAsset cbuffer_hardedge;
|
|
|
|
|
|
GUIContent CHardEdge = new GUIContent("Hard Edge Normals", "Render normals as hard edged quads or triangles, or from actual triangles, which LOD when used on terrain");
|
|
GUIContent CFlatTexture = new GUIContent("Flat Texture", "Texture each face with a single color from the texture");
|
|
GUIContent CTerrainSize = new GUIContent("Terrain Size", "Size of terrain for virtual quads, usually matched to terrain aphamap size, but doesn't have to be");
|
|
GUIContent CWireFrame = new GUIContent("Wireframe Mode", "Draw Wireframe edges on terrain, as either triangles or quads");
|
|
GUIContent CWireSpace = new GUIContent("Wireframe Space", "Can fixed in screenspace, so wires are always the same size on screen, or in world space, where they get smaller in the distance");
|
|
GUIContent CWireColor = new GUIContent("Wireframe Blend", "Color overlay, or adjust the terrain underneith?");
|
|
GUIContent CBrightness = new GUIContent("Wireframe Brightness", "Modify brightness of texture along wireframe edge");
|
|
GUIContent CSaturation = new GUIContent("Wireframe Saturation", "Modify saturation of texture along wireframe edge");
|
|
GUIContent CWireFade = new GUIContent("Wireframe Fade", "Fade wireframe over distance?");
|
|
|
|
static Dictionary<DefineFeature, string> sFeatureNames = new Dictionary<DefineFeature, string>();
|
|
public static string GetFeatureName(DefineFeature feature)
|
|
{
|
|
string ret;
|
|
if (sFeatureNames.TryGetValue(feature, out ret))
|
|
{
|
|
return ret;
|
|
}
|
|
string fn = System.Enum.GetName(typeof(DefineFeature), feature);
|
|
sFeatureNames[feature] = fn;
|
|
return fn;
|
|
}
|
|
|
|
public static bool HasFeature(string[] keywords, DefineFeature feature)
|
|
{
|
|
string f = GetFeatureName(feature);
|
|
for (int i = 0; i < keywords.Length; ++i)
|
|
{
|
|
if (keywords[i] == f)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
public override string GetVersion()
|
|
{
|
|
return "3.9";
|
|
}
|
|
|
|
public override void DrawFeatureGUI(MicroSplatKeywords keywords)
|
|
{
|
|
hardNormalEdge = (EdgeMode)EditorGUILayout.EnumPopup(CHardEdge, hardNormalEdge);
|
|
flatTexture = (EdgeMode)EditorGUILayout.EnumPopup(CFlatTexture, flatTexture);
|
|
wireframe = (EdgeMode)EditorGUILayout.EnumPopup(CWireFrame, wireframe);
|
|
if (wireframe != EdgeMode.None)
|
|
{
|
|
EditorGUI.indentLevel++;
|
|
wireSpace = (WireSpace)EditorGUILayout.EnumPopup(CWireSpace, wireSpace);
|
|
wireColor = (WireColorMode)EditorGUILayout.EnumPopup(CWireColor, wireColor);
|
|
wireFade = EditorGUILayout.Toggle(CWireFade, wireFade);
|
|
EditorGUI.indentLevel--;
|
|
}
|
|
}
|
|
|
|
|
|
public override void DrawShaderGUI(MicroSplatShaderGUI shaderGUI, MicroSplatKeywords keywords, Material mat, MaterialEditor materialEditor, MaterialProperty[] props)
|
|
{
|
|
if ((hardNormalEdge != EdgeMode.None || wireframe != EdgeMode.None || flatTexture != EdgeMode.None) && MicroSplatUtilities.DrawRollup("Low Poly"))
|
|
{
|
|
if (mat.HasProperty("_ToonTerrainSize"))
|
|
{
|
|
var sizeProp = shaderGUI.FindProp("_ToonTerrainSize", props);
|
|
EditorGUI.BeginChangeCheck();
|
|
Vector2 v2 = sizeProp.vectorValue;
|
|
v2 = EditorGUILayout.Vector2Field(CTerrainSize, v2);
|
|
if (v2.x <= 0)
|
|
{
|
|
v2.x = 1;
|
|
}
|
|
if (v2.y < 0)
|
|
{
|
|
v2.y = 1;
|
|
}
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
sizeProp.vectorValue = v2;
|
|
}
|
|
}
|
|
|
|
if (hardNormalEdge != EdgeMode.None && mat.HasProperty("_ToonEdgeHardness"))
|
|
{
|
|
materialEditor.RangeProperty(shaderGUI.FindProp("_ToonEdgeHardness", props), "Edge Hardness");
|
|
}
|
|
if (wireframe != EdgeMode.None && mat.HasProperty("_ToonWireSmoothing"))
|
|
{
|
|
if (mat.HasProperty("_ToonWireColor"))
|
|
{
|
|
materialEditor.ColorProperty(shaderGUI.FindProp("_ToonWireColor", props), "Wire Color");
|
|
}
|
|
if (mat.HasProperty("_ToonWireFade"))
|
|
{
|
|
|
|
var prop = shaderGUI.FindProp("_ToonWireFade", props);
|
|
EditorGUI.BeginChangeCheck();
|
|
Vector2 v2 = prop.vectorValue;
|
|
v2.x = EditorGUILayout.FloatField("Fade Start", v2.x);
|
|
v2.y = EditorGUILayout.FloatField("Fade Range", v2.y);
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
prop.vectorValue = v2;
|
|
}
|
|
}
|
|
|
|
materialEditor.RangeProperty(shaderGUI.FindProp("_ToonWireSmoothing", props), "Wire Smoothness");
|
|
materialEditor.RangeProperty(shaderGUI.FindProp("_ToonWireThickness", props), "Wire Thickness");
|
|
|
|
if (mat.HasProperty("_ToonWireSaturationBrightness"))
|
|
{
|
|
var prop = shaderGUI.FindProp("_ToonWireSaturationBrightness", props);
|
|
EditorGUI.BeginChangeCheck();
|
|
Vector2 v2 = prop.vectorValue;
|
|
v2.x = EditorGUILayout.Slider(CSaturation, v2.x, 0, 2);
|
|
v2.y = EditorGUILayout.Slider(CBrightness, v2.y, 0, 2);
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
prop.vectorValue = v2;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void InitCompiler(string[] paths)
|
|
{
|
|
for (int i = 0; i < paths.Length; ++i)
|
|
{
|
|
string p = paths[i];
|
|
if (p.EndsWith("microsplat_func_edges.txt"))
|
|
{
|
|
functions_hardedge = AssetDatabase.LoadAssetAtPath<TextAsset>(p);
|
|
}
|
|
if (p.EndsWith ("microsplat_cbuffer_edges.txt"))
|
|
{
|
|
cbuffer_hardedge = AssetDatabase.LoadAssetAtPath<TextAsset> (p);
|
|
}
|
|
if (p.EndsWith("microsplat_properties_edges.txt"))
|
|
{
|
|
properties_hardedge = AssetDatabase.LoadAssetAtPath<TextAsset>(p);
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void WriteProperties(string[] features, System.Text.StringBuilder sb)
|
|
{
|
|
if (hardNormalEdge != EdgeMode.None || wireframe != EdgeMode.None || flatTexture != EdgeMode.None)
|
|
{
|
|
sb.AppendLine(" _ToonTerrainSize(\"Toon Terrain Size\", Vector) = (512,512,0,0)");
|
|
}
|
|
|
|
if (hardNormalEdge != EdgeMode.None)
|
|
{
|
|
sb.AppendLine(properties_hardedge.text);
|
|
}
|
|
if (wireframe != EdgeMode.None)
|
|
{
|
|
if (wireColor == WireColorMode.Color)
|
|
{
|
|
sb.AppendLine(" _ToonWireColor(\"Wire Color\", Color) = (0,0,0,1)");
|
|
}
|
|
else
|
|
{
|
|
sb.AppendLine(" _ToonWireSaturationBrightness(\"Wire Params\", Vector) = (1,1,0,0)");
|
|
}
|
|
if (wireFade)
|
|
{
|
|
sb.AppendLine(" _ToonWireFade(\"Wire Fade\", Vector) = (50, 200, 0, 0)");
|
|
}
|
|
sb.AppendLine(" _ToonWireSmoothing(\"Wire Smooth\", Range(0.01, 10)) = 1");
|
|
sb.AppendLine(" _ToonWireThickness(\"Wire Thickness\", Range(0.01, 10)) = 1");
|
|
}
|
|
}
|
|
|
|
public override void ComputeSampleCounts(string[] features, ref int arraySampleCount, ref int textureSampleCount, ref int maxSamples, ref int tessellationSamples, ref int depTexReadLevel)
|
|
{
|
|
|
|
}
|
|
|
|
public override string[] Pack()
|
|
{
|
|
List<string> features = new List<string>();
|
|
if (hardNormalEdge != EdgeMode.None)
|
|
{
|
|
if (hardNormalEdge == EdgeMode.Poly)
|
|
{
|
|
features.Add (GetFeatureName (DefineFeature._TOONPOLYEDGE));
|
|
}
|
|
else
|
|
{
|
|
features.Add (GetFeatureName (DefineFeature._TOONHARDEDGENORMAL));
|
|
if (hardNormalEdge == EdgeMode.Quads)
|
|
{
|
|
features.Add (GetFeatureName (DefineFeature._TOONHARDEDGENORMALQUAD));
|
|
}
|
|
}
|
|
}
|
|
if (wireframe != EdgeMode.None)
|
|
{
|
|
features.Add(GetFeatureName(DefineFeature._TOONWIREFRAME));
|
|
if (wireframe == EdgeMode.Quads)
|
|
{
|
|
features.Add(GetFeatureName(DefineFeature._TOONWIREQUADS));
|
|
}
|
|
if (wireSpace == WireSpace.WorldSpace)
|
|
{
|
|
features.Add(GetFeatureName(DefineFeature._TOONWIREWORLDSPACE));
|
|
}
|
|
if (wireColor == WireColorMode.SaturationBrightness)
|
|
{
|
|
features.Add(GetFeatureName(DefineFeature._WIRESATURATIONBRIGHTNESS));
|
|
}
|
|
if (wireFade)
|
|
{
|
|
features.Add(GetFeatureName(DefineFeature._TOONWIREFADE));
|
|
}
|
|
}
|
|
|
|
if (flatTexture != EdgeMode.None)
|
|
{
|
|
features.Add(GetFeatureName(DefineFeature._TOONFLATTEXTURE));
|
|
if (flatTexture == EdgeMode.Quads)
|
|
{
|
|
features.Add(GetFeatureName(DefineFeature._TOONFLATTEXTUREQUAD));
|
|
}
|
|
}
|
|
return features.ToArray();
|
|
}
|
|
|
|
public override void WritePerMaterialCBuffer (string[] features, System.Text.StringBuilder sb)
|
|
{
|
|
if (hardNormalEdge != EdgeMode.None || wireframe != EdgeMode.None)
|
|
{
|
|
sb.AppendLine(cbuffer_hardedge.text);
|
|
}
|
|
if (hardNormalEdge != EdgeMode.None || wireframe != EdgeMode.None || flatTexture != EdgeMode.None)
|
|
{
|
|
sb.AppendLine(" float2 _ToonTerrainSize;");
|
|
}
|
|
}
|
|
|
|
public override void WriteFunctions(string [] features, System.Text.StringBuilder sb)
|
|
{
|
|
if (hardNormalEdge != EdgeMode.None || wireframe != EdgeMode.None)
|
|
{
|
|
sb.AppendLine(functions_hardedge.text);
|
|
}
|
|
}
|
|
|
|
public override void Unpack(string[] keywords)
|
|
{
|
|
hardNormalEdge = HasFeature(keywords, DefineFeature._TOONHARDEDGENORMAL) ? EdgeMode.Triangle : EdgeMode.None;
|
|
if (hardNormalEdge != EdgeMode.None && HasFeature(keywords, DefineFeature._TOONHARDEDGENORMALQUAD))
|
|
{
|
|
hardNormalEdge = EdgeMode.Quads;
|
|
}
|
|
if (HasFeature(keywords, DefineFeature._TOONPOLYEDGE))
|
|
{
|
|
hardNormalEdge = EdgeMode.Poly;
|
|
}
|
|
|
|
wireframe = HasFeature(keywords, DefineFeature._TOONWIREFRAME) ? EdgeMode.Triangle : EdgeMode.None;
|
|
if (wireframe == EdgeMode.Triangle && HasFeature(keywords, DefineFeature._TOONWIREQUADS))
|
|
{
|
|
wireframe = EdgeMode.Quads;
|
|
}
|
|
if (wireframe != EdgeMode.None)
|
|
{
|
|
wireSpace = WireSpace.ScreenSpace;
|
|
if (HasFeature(keywords, DefineFeature._TOONWIREWORLDSPACE))
|
|
wireSpace = WireSpace.WorldSpace;
|
|
}
|
|
wireFade = HasFeature(keywords, DefineFeature._TOONWIREFADE);
|
|
wireColor = HasFeature(keywords, DefineFeature._WIRESATURATIONBRIGHTNESS) ? WireColorMode.SaturationBrightness : WireColorMode.Color;
|
|
flatTexture = HasFeature(keywords, DefineFeature._TOONFLATTEXTURE) ? EdgeMode.Triangle : EdgeMode.None;
|
|
if (flatTexture != EdgeMode.None && HasFeature(keywords, DefineFeature._TOONFLATTEXTUREQUAD))
|
|
{
|
|
flatTexture = EdgeMode.Quads;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
} |