[unity] Simplified Sprite shader GUI.

This commit is contained in:
pharan 2016-11-19 09:19:01 +08:00
parent a4ee7e3b4d
commit 5779d0e09a

View File

@ -32,6 +32,8 @@ using System;
using UnityEngine;
using UnityEditor;
using SpineInspectorUtility = Spine.Unity.Editor.SpineInspectorUtility;
public class SpineSpriteShaderGUI : ShaderGUI {
static readonly string kShaderVertexLit = "Spine/Sprite/Vertex Lit";
static readonly string kShaderPixelLit = "Spine/Sprite/Pixel Lit";
@ -93,6 +95,7 @@ public class SpineSpriteShaderGUI : ShaderGUI {
bool _firstTimeApply = true;
eLightMode _lightMode;
static bool showAdvanced = false;
#region ShaderGUI
public override void OnGUI (MaterialEditor materialEditor, MaterialProperty[] properties) {
@ -119,7 +122,7 @@ public class SpineSpriteShaderGUI : ShaderGUI {
#endregion
#region Virtual Interface
protected virtual void FindProperties(MaterialProperty[] props) {
protected virtual void FindProperties (MaterialProperty[] props) {
_mainTexture = FindProperty("_MainTex", props);
_color = FindProperty("_Color", props);
_blendMode = FindProperty("_BlendMode", props);
@ -149,259 +152,204 @@ public class SpineSpriteShaderGUI : ShaderGUI {
_rimColor = FindProperty("_RimColor", props, false);
}
protected virtual void ShaderPropertiesGUI(Material material) {
// Use default labelWidth
EditorGUIUtility.labelWidth = 0f;
protected virtual void ShaderPropertiesGUI (Material material) {
using (new EditorGUILayout.HorizontalScope()) {
GUILayout.FlexibleSpace();
var showAdvancedLabel = new GUIContent("Show Advanced", "Show extra options under all sections. This only affects the inspector. The Material's resulting shader is still compiled/optimized based on what features you actually use and don't use.");
float lw = GUI.skin.toggle.CalcSize(showAdvancedLabel).x;
EditorGUIUtility.labelWidth = lw;
showAdvanced = EditorGUILayout.Toggle(showAdvancedLabel, showAdvanced);
EditorGUIUtility.labelWidth = 0f;
}
EditorGUILayout.Space();
// Detect any changes to the material
EditorGUI.BeginChangeCheck();
{
//GUILayout.Label("Rendering", EditorStyles.boldLabel);
{
RenderModes(material);
}
GUILayout.Label("Main Maps", EditorStyles.boldLabel);
{
RenderTextureProperties(material);
}
GUILayout.Label("Depth", EditorStyles.boldLabel);
{
RenderDepthProperties(material);
}
if (_fixedNormal != null)
{
GUILayout.Label("Normals", EditorStyles.boldLabel);
RenderNormalsProperties(material);
}
GUILayout.Label("Shadows", EditorStyles.boldLabel);
{
RenderShadowsProperties(material);
}
GUILayout.Label("Color Adjustment", EditorStyles.boldLabel);
{
RenderColorProperties(material);
}
if (_emissionMap != null && _emissionColor != null)
{
GUILayout.Label("Emission", EditorStyles.boldLabel);
{
RenderEmissionProperties(material);
}
}
if (_rimColor != null)
{
GUILayout.Label("Rim Lighting", EditorStyles.boldLabel);
RenderRimLightingProperties(material);
}
GUILayout.Label("Fog", EditorStyles.boldLabel);
{
RenderFogProperties(material);
}
}
if (EditorGUI.EndChangeCheck())
{
foreach (var obj in _blendMode.targets)
MaterialChanged((Material)obj);
}
}
protected virtual void RenderModes (Material material) {
LightingModePopup();
BlendModePopup();
if (showAdvanced) {
EditorGUILayout.Space();
EditorGUI.BeginChangeCheck();
int renderQueue = EditorGUILayout.IntSlider("Renderer Queue", (int)_renderQueue.floatValue, 0, 49);
if (EditorGUI.EndChangeCheck())
{
material.SetInt("_RenderQueue", renderQueue);
}
int renderQueue = EditorGUILayout.IntSlider("Renderer Queue Offset", (int)_renderQueue.floatValue, 0, 49);
if (EditorGUI.EndChangeCheck()) material.SetInt("_RenderQueue", renderQueue);
EditorGUI.BeginChangeCheck();
eCulling culling = (eCulling)Mathf.RoundToInt(_culling.floatValue);
culling = (eCulling)EditorGUILayout.EnumPopup("Culling", culling);
if (EditorGUI.EndChangeCheck())
{
material.SetInt("_Cull", (int)culling);
}
}
protected virtual void RenderTextureProperties (Material material) {
_materialEditor.TexturePropertySingleLine(new GUIContent("Albedo"), _mainTexture, _color);
if (_bumpMap != null)
_materialEditor.TexturePropertySingleLine(new GUIContent("Normal Map"), _bumpMap);
if (_diffuseRamp != null)
_materialEditor.TexturePropertySingleLine(new GUIContent("Diffuse Ramp", "A black and white gradient can be used to create a 'Toon Shading' effect."), _diffuseRamp);
if (_blendTexture != null)
{
EditorGUI.BeginChangeCheck();
_materialEditor.TexturePropertySingleLine(new GUIContent("Blend Texture", "When a blend texture is set the albedo will be a mix of the blend texture and main texture based on the blend amount."), _blendTexture, _blendTextureLerp);
if (EditorGUI.EndChangeCheck())
{
SetKeyword(material, "_TEXTURE_BLEND", _blendTexture != null);
}
}
_materialEditor.TextureScaleOffsetProperty(_mainTexture);
}
protected virtual void RenderEmissionProperties (Material material) {
bool emission = material.IsKeywordEnabled("_EMISSION");
if (EditorGUI.EndChangeCheck()) material.SetInt("_Cull", (int)culling);
EditorGUI.BeginChangeCheck();
emission = EditorGUILayout.Toggle("Enable Emission", emission);
if (EditorGUI.EndChangeCheck())
{
SetKeyword(material, "_EMISSION", emission);
bool fog = EditorGUILayout.Toggle("Use fog", material.IsKeywordEnabled("_FOG"));
if (EditorGUI.EndChangeCheck()) SetKeyword(material, "_FOG", fog);
}
if (emission)
{
_materialEditor.TexturePropertyWithHDRColor(new GUIContent("Emission"), _emissionMap, _emissionColor, new ColorPickerHDRConfig(0,1, 0.01010101f, 3), true);
_materialEditor.FloatProperty(_emissionPower, "Emission Power");
}
}
using (new SpineInspectorUtility.BoxScope())
RenderTextureProperties("Main Maps", material);
protected virtual void RenderDepthProperties (Material material) {
if (showAdvanced) {
using (new SpineInspectorUtility.BoxScope()) {
Heading("Depth and Cast Shadow");
EditorGUI.BeginChangeCheck();
bool writeTodepth = EditorGUILayout.Toggle(new GUIContent("Write to Depth", "Write to Depth Buffer by clipping alpha."), _writeToDepth.floatValue != 0.0f);
if (EditorGUI.EndChangeCheck())
{
material.SetInt("_ZWrite", writeTodepth ? 1 : 0);
}
if (writeTodepth)
{
_materialEditor.RangeProperty(_depthAlphaCutoff, "Depth Alpha Cutoff");
}
EditorGUILayout.Space();
_materialEditor.RangeProperty(_shadowAlphaCutoff, "Shadow Alpha Cutoff");
}
protected virtual void RenderNormalsProperties (Material material) {
if (_fixedNormal != null) {
using (new SpineInspectorUtility.BoxScope()) {
Heading("Normals");
bool meshNormals = UseMeshNormalsCheckbox(material);
if (!meshNormals) {
Vector3 normal;
EditorGUI.BeginChangeCheck();
bool fixedNormals = material.IsKeywordEnabled("_FIXED_NORMALS");
bool fixedNormalsBackRendering = material.IsKeywordEnabled("_FIXED_NORMALS_BACK_RENDERING");
bool meshNormals = EditorGUILayout.Toggle(new GUIContent("Use Mesh Normals", "If this is unticked instead of requiring mesh normals a Fixed Normal will be used instead (it's quicker and can result in better looking lighting effects on 2d objects)."),
!fixedNormals && !fixedNormalsBackRendering);
normal = showAdvanced ? EditorGUILayout.Vector3Field(new GUIContent("Fixed Normal", "Defined in Camera Space. Should normally be (0,0,-1)."), _fixedNormal.vectorValue) : (Vector3)_fixedNormal.vectorValue;
if (EditorGUI.EndChangeCheck())
{
SetKeyword(material, "_FIXED_NORMALS", meshNormals ? false : fixedNormalsBackRendering ? false : true);
SetKeyword(material, "_FIXED_NORMALS_BACK_RENDERING", meshNormals ? false : fixedNormalsBackRendering);
}
if (!meshNormals)
{
Vector3 normal = EditorGUILayout.Vector3Field(new GUIContent("Fixed Normal", "Defined in Camera Space. Should normally be (0,0,-1)."), _fixedNormal.vectorValue);
_fixedNormal.vectorValue = new Vector4(normal.x, normal.y, normal.z, 1.0f);
bool backRendering;
EditorGUI.BeginChangeCheck();
bool backRendering = EditorGUILayout.Toggle(new GUIContent("Fixed Normal Back Rendering", "Tick only if you are going to rotate the sprite to face away from the camera, the fixed normal will be flipped to compensate."),
if (showAdvanced) {
backRendering = EditorGUILayout.Toggle(new GUIContent("Fixed Normal Back Rendering", "Tick only if you are going to rotate the sprite to face away from the camera, the fixed normal will be flipped to compensate."),
material.IsKeywordEnabled("_FIXED_NORMALS_BACK_RENDERING"));
if (EditorGUI.EndChangeCheck())
{
} else {
backRendering = material.IsKeywordEnabled("_FIXED_NORMALS_BACK_RENDERING");
}
if (EditorGUI.EndChangeCheck()) {
SetKeyword(material, "_FIXED_NORMALS_BACK_RENDERING", backRendering);
SetKeyword(material, "_FIXED_NORMALS", !backRendering);
}
}
}
protected virtual void RenderShadowsProperties (Material material) {
_materialEditor.FloatProperty(_shadowAlphaCutoff, "Shadow Alpha Cutoff");
}
protected virtual void RenderColorProperties (Material material) {
} else {
using (new SpineInspectorUtility.BoxScope()) {
EditorGUI.BeginChangeCheck();
bool colorAdjust = EditorGUILayout.Toggle("Enable Color Adjustment", material.IsKeywordEnabled("_COLOR_ADJUST"));
bool writeTodepth = EditorGUILayout.Toggle(new GUIContent("Write to Depth", "Write to Depth Buffer by clipping alpha."), _writeToDepth.floatValue != 0.0f);
if (EditorGUI.EndChangeCheck())
{
SetKeyword(material, "_COLOR_ADJUST", colorAdjust);
material.SetInt("_ZWrite", writeTodepth ? 1 : 0);
if (_fixedNormal != null)
UseMeshNormalsCheckbox(material);
}
}
if (colorAdjust) {
using (new SpineInspectorUtility.BoxScope())
RenderColorProperties("Color Adjustment", material);
if (_emissionMap != null && _emissionColor != null && _rimColor != null) {
Heading("Extra Lighting");
if (_emissionMap != null && _emissionColor != null)
using (new SpineInspectorUtility.BoxScope())
RenderEmissionProperties(material);
if (_rimColor != null)
using (new SpineInspectorUtility.BoxScope())
RenderRimLightingProperties(material);
}
}
if (EditorGUI.EndChangeCheck()) {
foreach (var obj in _blendMode.targets)
MaterialChanged((Material)obj);
}
}
protected virtual void RenderTextureProperties (string label, Material material) {
if (showAdvanced)
Heading(label);
_materialEditor.TexturePropertySingleLine(new GUIContent(showAdvanced ? "Albedo" : "Main Texture"), _mainTexture, _color);
if (_bumpMap != null)
_materialEditor.TexturePropertySingleLine(new GUIContent("Normal Map"), _bumpMap);
if (showAdvanced) {
if (_blendTexture != null) {
EditorGUI.BeginChangeCheck();
_materialEditor.TexturePropertySingleLine(new GUIContent("Blend Texture", "When a blend texture is set the albedo will be a mix of the blend texture and main texture based on the blend amount."), _blendTexture, _blendTextureLerp);
if (EditorGUI.EndChangeCheck())
SetKeyword(material, "_TEXTURE_BLEND", _blendTexture != null);
}
}
if (_diffuseRamp != null) {
EditorGUILayout.Space();
_materialEditor.TexturePropertySingleLine(new GUIContent("Diffuse Ramp", "A gradient can be used to create a 'Toon Shading' effect."), _diffuseRamp);
}
// if (showAdvanced)
// _materialEditor.TextureScaleOffsetProperty(_mainTexture);
}
protected virtual void RenderDepthProperties (string label, Material material) {
}
protected virtual void RenderNormalsProperties (string label, Material material) {
}
bool UseMeshNormalsCheckbox (Material material) {
EditorGUI.BeginChangeCheck();
bool fixedNormals = material.IsKeywordEnabled("_FIXED_NORMALS");
bool fixedNormalsBackRendering = material.IsKeywordEnabled("_FIXED_NORMALS_BACK_RENDERING");
bool meshNormals = EditorGUILayout.Toggle(new GUIContent("Use Mesh Normals", "If this is unticked, a Fixed Normal value will be used instead of the vertex normals on the mesh. Using a fixed normal is better for performance and can result in better looking lighting effects on 2d objects."),
!fixedNormals && !fixedNormalsBackRendering);
if (EditorGUI.EndChangeCheck()) {
SetKeyword(material, "_FIXED_NORMALS", meshNormals ? false : fixedNormalsBackRendering ? false : true);
SetKeyword(material, "_FIXED_NORMALS_BACK_RENDERING", meshNormals ? false : fixedNormalsBackRendering);
}
return meshNormals;
}
protected virtual void RenderColorProperties (string label, Material material) {
if (ToggleHeadingKeyword(label, material, "_COLOR_ADJUST")) {
_materialEditor.ColorProperty(_overlayColor, "Overlay Color");
EditorGUILayout.Space();
using (new SpineInspectorUtility.IndentScope()) {
_materialEditor.RangeProperty(_hue, "Hue");
_materialEditor.RangeProperty(_saturation, "Saturation");
_materialEditor.RangeProperty(_brightness, "Brightness");
}
}
}
protected virtual void RenderEmissionProperties (Material material) {
if (ToggleHeadingKeyword("Emission", material, "_EMISSION")) {
_materialEditor.TexturePropertyWithHDRColor(new GUIContent("Emission"), _emissionMap, _emissionColor, new ColorPickerHDRConfig(0,1, 0.01010101f, 3), true);
_materialEditor.FloatProperty(_emissionPower, "Emission Power");
}
}
protected virtual void RenderRimLightingProperties (Material material) {
EditorGUI.BeginChangeCheck();
bool rimLighting = EditorGUILayout.Toggle("Enable Rim Lighting", material.IsKeywordEnabled("_RIM_LIGHTING"));
if (EditorGUI.EndChangeCheck())
{
SetKeyword(material, "_RIM_LIGHTING", rimLighting);
}
if (rimLighting)
{
if (ToggleHeadingKeyword("Rim Lighting", material, "_RIM_LIGHTING")) {
_materialEditor.ColorProperty(_rimColor, "Rim Color");
_materialEditor.FloatProperty(_rimPower, "Rim Power");
}
}
protected virtual void RenderFogProperties (Material material) {
EditorGUI.BeginChangeCheck();
bool fog = EditorGUILayout.Toggle("Enable Fog", material.IsKeywordEnabled("_FOG"));
if (EditorGUI.EndChangeCheck())
{
SetKeyword(material, "_FOG", fog);
}
}
#endregion
void SetLightModeFromShader (Material material) {
if (material.shader.name == kShaderPixelLit)
{
_lightMode = eLightMode.PixelLit;
}
else if (material.shader.name == kShaderUnlit)
{
_lightMode = eLightMode.Unlit;
}
else
{
_lightMode = eLightMode.VertexLit;
}
}
void SetShaderFromLightMode() {
Material material = _materialEditor.target as Material;
switch (_lightMode)
{
case eLightMode.VertexLit:
if (material.shader.name != kShaderVertexLit)
_materialEditor.SetShader(Shader.Find(kShaderVertexLit), false);
break;
case eLightMode.PixelLit:
if (material.shader.name != kShaderPixelLit)
_materialEditor.SetShader(Shader.Find(kShaderPixelLit), false);
break;
case eLightMode.Unlit:
if (material.shader.name != kShaderUnlit)
_materialEditor.SetShader(Shader.Find(kShaderUnlit), false);
break;
}
MaterialChanged(material);
}
static void SetMaterialKeywords(Material material) {
static void SetMaterialKeywords (Material material) {
eBlendMode blendMode = (eBlendMode)material.GetFloat("_BlendMode");
bool normalMap = material.HasProperty("_BumpMap") && material.GetTexture("_BumpMap") != null;
@ -481,24 +429,59 @@ public class SpineSpriteShaderGUI : ShaderGUI {
material.renderQueue = renderQueue + material.GetInt("_RenderQueue");
}
static void Heading (string label) {
GUILayout.Label(label, EditorStyles.boldLabel);
}
static bool ToggleHeadingKeyword (string label, Material material, string keyword) {
int i = EditorGUI.indentLevel;
var o = EditorStyles.label.fontStyle;
EditorGUI.indentLevel = 0;
EditorStyles.label.fontStyle = FontStyle.Bold;
EditorGUI.BeginChangeCheck();
bool r = EditorGUILayout.Toggle(new GUIContent(label, string.Format("This checkbox sets shader keyword: '{0}', which causes the Material to use extra shader features.", keyword)), material.IsKeywordEnabled(keyword));
if (EditorGUI.EndChangeCheck())
SetKeyword(material, keyword, r);
EditorStyles.label.fontStyle = o;
EditorGUI.indentLevel = i;
return r;
}
static void MaterialChanged (Material material) {
SetMaterialKeywords(material);
}
static void SetKeyword (Material m, string keyword, bool state) {
if (state)
m.EnableKeyword (keyword);
m.EnableKeyword(keyword);
else
m.DisableKeyword (keyword);
m.DisableKeyword(keyword);
}
void LightingModePopup ()
{
void LightingModePopup () {
EditorGUI.BeginChangeCheck();
_lightMode = (eLightMode)EditorGUILayout.Popup("Lighting Mode", (int)_lightMode, Enum.GetNames(typeof(eLightMode)));
if (EditorGUI.EndChangeCheck())
{
SetShaderFromLightMode();
if (EditorGUI.EndChangeCheck()) {
var material = _materialEditor.target as Material;
switch (_lightMode) {
case eLightMode.VertexLit:
if (material.shader.name != kShaderVertexLit)
_materialEditor.SetShader(Shader.Find(kShaderVertexLit), false);
break;
case eLightMode.PixelLit:
if (material.shader.name != kShaderPixelLit)
_materialEditor.SetShader(Shader.Find(kShaderPixelLit), false);
break;
case eLightMode.Unlit:
if (material.shader.name != kShaderUnlit)
_materialEditor.SetShader(Shader.Find(kShaderUnlit), false);
break;
}
MaterialChanged(material);
}
}
@ -506,8 +489,7 @@ public class SpineSpriteShaderGUI : ShaderGUI {
eBlendMode mode = (eBlendMode)_blendMode.floatValue;
EditorGUI.BeginChangeCheck();
mode = (eBlendMode)EditorGUILayout.Popup("Blend Mode", (int)mode, Enum.GetNames(typeof(eBlendMode)));
if (EditorGUI.EndChangeCheck())
{
if (EditorGUI.EndChangeCheck()) {
_materialEditor.RegisterPropertyChangeUndo("Blend Mode");
_blendMode.floatValue = (float)mode;
}