Files
beyond/Assets/Plugins/Easy performant outline/Scripts/SerializedPass.cs
2024-11-20 15:21:28 +01:00

396 lines
12 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace EPOOutline
{
public class SerializedPassInfoAttribute : Attribute
{
public readonly string Title;
public readonly string ShadersFolder;
public SerializedPassInfoAttribute(string title, string shadersFolder)
{
Title = title;
ShadersFolder = shadersFolder;
}
}
[System.Serializable]
public class SerializedPass : ISerializationCallbackReceiver
{
public enum PropertyType
{
Color = 0,
Vector = 1,
Float = 2,
Range = 3,
TexEnv = 4
}
[System.Serializable]
private class SerializedPropertyKeyValuePair
{
[SerializeField]
public string PropertyName;
[SerializeField]
public SerializedPassProperty Property;
}
[System.Serializable]
private class SerializedPassProperty
{
#pragma warning disable CS0649
[SerializeField]
public Color ColorValue;
[SerializeField]
public float FloatValue;
[SerializeField]
public Vector4 VectorValue;
[SerializeField]
public PropertyType PropertyType;
#pragma warning restore CS0649
}
[SerializeField]
private Shader shader;
public Shader Shader
{
get
{
return shader;
}
set
{
propertiesIsDirty = true;
shader = value;
}
}
[SerializeField]
private List<SerializedPropertyKeyValuePair> serializedProperties = new List<SerializedPropertyKeyValuePair>();
private Dictionary<int, SerializedPassProperty> propertiesById = new Dictionary<int, SerializedPassProperty>();
private Dictionary<string, SerializedPassProperty> propertiesByName = new Dictionary<string, SerializedPassProperty>();
private Material material;
private bool propertiesIsDirty = false;
public Material Material
{
get
{
if (shader == null)
return null;
if (material == null || material.shader != shader)
{
if (material != null)
GameObject.DestroyImmediate(material);
material = new Material(shader);
}
if (!propertiesIsDirty)
return material;
foreach (var property in propertiesById)
{
switch (property.Value.PropertyType)
{
case PropertyType.Color:
material.SetColor(property.Key, property.Value.ColorValue);
break;
case PropertyType.Vector:
material.SetVector(property.Key, property.Value.VectorValue);
break;
case PropertyType.Float:
material.SetFloat(property.Key, property.Value.FloatValue);
break;
case PropertyType.Range:
material.SetFloat(property.Key, property.Value.FloatValue);
break;
case PropertyType.TexEnv:
break;
}
}
propertiesIsDirty = false;
return material;
}
}
public bool HasProperty(string name)
{
return propertiesByName.ContainsKey(name);
}
public bool HasProperty(int hash)
{
return propertiesById.ContainsKey(hash);
}
public Vector4 GetVector(string name)
{
SerializedPassProperty result = null;
if (!propertiesByName.TryGetValue(name, out result))
{
Debug.LogError("The property " + name + " doesn't exist");
return Vector4.zero;
}
if (result.PropertyType == PropertyType.Vector)
return result.VectorValue;
else
{
Debug.LogError("The property " + name + " is not a vector property");
return Vector4.zero;
}
}
public Vector4 GetVector(int hash)
{
SerializedPassProperty result = null;
if (!propertiesById.TryGetValue(hash, out result))
{
Debug.LogError("The property " + hash + " doesn't exist");
return Vector4.zero;
}
if (result.PropertyType == PropertyType.Vector)
return result.VectorValue;
else
{
Debug.LogError("The property " + hash + " is not a vector property");
return Vector4.zero;
}
}
public void SetVector(string name, Vector4 value)
{
propertiesIsDirty = true;
SerializedPassProperty result = null;
if (!propertiesByName.TryGetValue(name, out result))
{
result = new SerializedPassProperty();
result.PropertyType = PropertyType.Vector;
propertiesByName.Add(name, result);
propertiesById.Add(Shader.PropertyToID(name), result);
}
if (result.PropertyType != PropertyType.Vector)
{
Debug.LogError("The property " + name + " is not a vector property");
return;
}
result.VectorValue = value;
}
public void SetVector(int hash, Vector4 value)
{
propertiesIsDirty = true;
SerializedPassProperty result = null;
if (!propertiesById.TryGetValue(hash, out result))
{
Debug.LogWarning("The property " + hash + " doesn't exist. Use string overload to create one.");
return;
}
if (result.PropertyType != PropertyType.Vector)
{
Debug.LogError("The property " + hash + " is not a vector property");
return;
}
result.VectorValue = value;
}
public float GetFloat(string name)
{
SerializedPassProperty result = null;
if (!propertiesByName.TryGetValue(name, out result))
{
Debug.LogError("The property " + name + " doesn't exist");
return 0.0f;
}
if (result.PropertyType == PropertyType.Float || result.PropertyType == PropertyType.Range)
return result.FloatValue;
else
{
Debug.LogError("The property " + name + " is not a float property");
return 0.0f;
}
}
public float GetFloat(int hash)
{
SerializedPassProperty result = null;
if (!propertiesById.TryGetValue(hash, out result))
{
Debug.LogError("The property " + hash + " is doesn't exist");
return 0.0f;
}
if (result.PropertyType == PropertyType.Float || result.PropertyType == PropertyType.Range)
return result.FloatValue;
else
{
Debug.LogError("The property " + hash + " is not a float property");
return 0.0f;
}
}
public void SetFloat(string name, float value)
{
propertiesIsDirty = true;
SerializedPassProperty result = null;
if (!propertiesByName.TryGetValue(name, out result))
{
result = new SerializedPassProperty();
result.PropertyType = PropertyType.Float;
propertiesByName.Add(name, result);
propertiesById.Add(Shader.PropertyToID(name), result);
}
if (result.PropertyType != PropertyType.Float)
{
Debug.LogError("The property " + name + " is not a float property");
return;
}
result.FloatValue = value;
}
public void SetFloat(int hash, float value)
{
propertiesIsDirty = true;
SerializedPassProperty result = null;
if (!propertiesById.TryGetValue(hash, out result))
{
Debug.LogError("The property " + hash + " doesn't exist. Use string overload to create one.");
return;
}
if (result.PropertyType != PropertyType.Float)
{
Debug.LogError("The property " + hash + " is not a float property");
return;
}
result.FloatValue = value;
}
public Color GetColor(string name)
{
SerializedPassProperty result = null;
if (!propertiesByName.TryGetValue(name, out result))
{
Debug.LogError("The property " + name + " doesn't exist");
return Color.black;
}
if (result.PropertyType == PropertyType.Color)
return result.ColorValue;
else
{
Debug.LogError("The property " + name + " is not a color property");
return Color.black;
}
}
public Color GetColor(int hash)
{
SerializedPassProperty result = null;
if (!propertiesById.TryGetValue(hash, out result))
{
Debug.LogError("The property " + hash + " doesn't exist");
return Color.black;
}
if (result.PropertyType == PropertyType.Color)
return result.ColorValue;
else
return Color.black;
}
public void SetColor(string name, Color value)
{
propertiesIsDirty = true;
SerializedPassProperty result = null;
if (!propertiesByName.TryGetValue(name, out result))
{
result = new SerializedPassProperty();
result.PropertyType = PropertyType.Color;
propertiesByName.Add(name, result);
propertiesById.Add(Shader.PropertyToID(name), result);
}
if (result.PropertyType != PropertyType.Color)
{
Debug.LogError("The property " + name + " is not a color property.");
return;
}
result.ColorValue = value;
}
public void SetColor(int hash, Color value)
{
propertiesIsDirty = true;
SerializedPassProperty result = null;
if (!propertiesById.TryGetValue(hash, out result))
{
Debug.LogError("The property " + hash + " doesn't exist. Use string overload to create one.");
return;
}
if (result.PropertyType != PropertyType.Color)
{
Debug.LogError("The property " + hash + " is not a color property");
return;
}
result.ColorValue = value;
}
public void OnBeforeSerialize()
{
serializedProperties.Clear();
foreach (var property in propertiesByName)
{
var pair = new SerializedPropertyKeyValuePair();
pair.Property = property.Value;
pair.PropertyName = property.Key;
serializedProperties.Add(pair);
}
}
public void OnAfterDeserialize()
{
propertiesIsDirty = true;
propertiesById.Clear();
propertiesByName.Clear();
foreach (var serialized in serializedProperties)
{
if (propertiesByName.ContainsKey(serialized.PropertyName))
continue;
propertiesById.Add(Shader.PropertyToID(serialized.PropertyName), serialized.Property);
propertiesByName.Add(serialized.PropertyName, serialized.Property);
}
}
}
}