using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEditor.Rendering
{
public partial class MaterialUpgrader
{
///
/// The priority of the upgrader.
///
public virtual int priority => 0;
///
/// Material Upgrader finalizer delegate.
///
/// Material
public delegate void MaterialFinalizer(Material mat);
string m_OldShader;
string m_NewShader;
///
/// Retrieves path to new shader.
///
public string NewShaderPath => m_NewShader;
///
/// Retrieves path to old shader.
///
public string OldShaderPath => m_OldShader;
MaterialFinalizer m_Finalizer;
Dictionary m_TextureRename = new Dictionary();
Dictionary m_FloatRename = new Dictionary();
Dictionary m_ColorRename = new Dictionary();
Dictionary m_FloatPropertiesToSet = new Dictionary();
Dictionary m_ColorPropertiesToSet = new Dictionary();
List m_TexturesToRemove = new List();
Dictionary m_TexturesToSet = new Dictionary();
class KeywordFloatRename
{
public string keyword;
public string property;
public float setVal, unsetVal;
}
List m_KeywordFloatRename = new List();
Dictionary)> m_ConditionalFloatRename;
///
/// Type of property to rename.
///
public enum MaterialPropertyType
{
/// Texture reference property.
Texture,
/// Float property.
Float,
/// Color property.
Color
}
///
/// Retrieves a collection of renamed parameters of a specific MaterialPropertyType.
///
/// Material Property Type
/// Dictionary of property names to their renamed values.
/// type is not valid.
public IReadOnlyDictionary GetPropertyRenameMap(MaterialPropertyType type)
{
switch (type)
{
case MaterialPropertyType.Texture: return m_TextureRename;
case MaterialPropertyType.Float: return m_FloatRename;
case MaterialPropertyType.Color: return m_ColorRename;
default: throw new ArgumentException(nameof(type));
}
}
///
/// Upgrade Flags
///
[Flags]
public enum UpgradeFlags
{
/// None.
None = 0,
/// LogErrorOnNonExistingProperty.
LogErrorOnNonExistingProperty = 1,
/// CleanupNonUpgradedProperties.
CleanupNonUpgradedProperties = 2,
/// LogMessageWhenNoUpgraderFound.
LogMessageWhenNoUpgraderFound = 4
}
///
/// Upgrade method.
///
/// Material to upgrade.
/// Upgrade flag
public void Upgrade(Material material, UpgradeFlags flags)
{
Material newMaterial;
if ((flags & UpgradeFlags.CleanupNonUpgradedProperties) != 0)
{
newMaterial = new Material(Shader.Find(m_NewShader));
}
else
{
newMaterial = UnityEngine.Object.Instantiate(material) as Material;
newMaterial.shader = Shader.Find(m_NewShader);
}
Convert(material, newMaterial);
material.shader = Shader.Find(m_NewShader);
material.CopyPropertiesFromMaterial(newMaterial);
UnityEngine.Object.DestroyImmediate(newMaterial);
if (m_Finalizer != null)
m_Finalizer(material);
}
// Overridable function to implement custom material upgrading functionality
///
/// Custom material conversion method.
///
/// Source material.
/// Destination material.
public virtual void Convert(Material srcMaterial, Material dstMaterial)
{
foreach (var t in m_TextureRename)
{
if (!srcMaterial.HasProperty(t.Key) || !dstMaterial.HasProperty(t.Value))
continue;
dstMaterial.SetTextureScale(t.Value, srcMaterial.GetTextureScale(t.Key));
dstMaterial.SetTextureOffset(t.Value, srcMaterial.GetTextureOffset(t.Key));
dstMaterial.SetTexture(t.Value, srcMaterial.GetTexture(t.Key));
}
foreach (var t in m_FloatRename)
{
if (!srcMaterial.HasProperty(t.Key) || !dstMaterial.HasProperty(t.Value))
continue;
dstMaterial.SetFloat(t.Value, srcMaterial.GetFloat(t.Key));
}
foreach (var t in m_ColorRename)
{
if (!srcMaterial.HasProperty(t.Key) || !dstMaterial.HasProperty(t.Value))
continue;
dstMaterial.SetColor(t.Value, srcMaterial.GetColor(t.Key));
}
foreach (var prop in m_TexturesToRemove)
{
if (!dstMaterial.HasProperty(prop))
continue;
dstMaterial.SetTexture(prop, null);
}
foreach (var prop in m_TexturesToSet)
{
if (!dstMaterial.HasProperty(prop.Key))
continue;
dstMaterial.SetTexture(prop.Key, prop.Value);
}
foreach (var prop in m_FloatPropertiesToSet)
{
if (!dstMaterial.HasProperty(prop.Key))
continue;
dstMaterial.SetFloat(prop.Key, prop.Value);
}
foreach (var prop in m_ColorPropertiesToSet)
{
if (!dstMaterial.HasProperty(prop.Key))
continue;
dstMaterial.SetColor(prop.Key, prop.Value);
}
foreach (var t in m_KeywordFloatRename)
{
if (!dstMaterial.HasProperty(t.property))
continue;
dstMaterial.SetFloat(t.property, srcMaterial.IsKeywordEnabled(t.keyword) ? t.setVal : t.unsetVal);
}
// Handle conditional float renaming
if (m_ConditionalFloatRename != null)
{
foreach (var (oldName, (newName, condition)) in m_ConditionalFloatRename)
{
if (srcMaterial.HasProperty(oldName) &&
condition(srcMaterial.GetFloat(oldName)) &&
dstMaterial.HasProperty(newName))
{
dstMaterial.SetFloat(newName, 1.0f);
}
}
}
}
///
/// Rename shader.
///
/// Old name.
/// New name.
/// Finalizer delegate.
public void RenameShader(string oldName, string newName, MaterialFinalizer finalizer = null)
{
m_OldShader = oldName;
m_NewShader = newName;
m_Finalizer = finalizer;
}
///
/// Rename Texture Parameter.
///
/// Old name.
/// New name.
public void RenameTexture(string oldName, string newName)
{
m_TextureRename[oldName] = newName;
}
///
/// Rename Float Parameter.
///
/// Old name.
/// New name.
public void RenameFloat(string oldName, string newName)
{
m_FloatRename[oldName] = newName;
}
///
/// Rename Color Parameter.
///
/// Old name.
/// New name.
public void RenameColor(string oldName, string newName)
{
m_ColorRename[oldName] = newName;
}
///
/// Remove Texture Parameter.
///
/// Parameter name.
public void RemoveTexture(string name)
{
m_TexturesToRemove.Add(name);
}
///
/// Set float property.
///
/// Property name.
/// Property value.
public void SetFloat(string propertyName, float value)
{
m_FloatPropertiesToSet[propertyName] = value;
}
///
/// Set color property.
///
/// Property name.
/// Property value.
public void SetColor(string propertyName, Color value)
{
m_ColorPropertiesToSet[propertyName] = value;
}
///
/// Set texture property.
///
/// Property name.
/// Property value.
public void SetTexture(string propertyName, Texture value)
{
m_TexturesToSet[propertyName] = value;
}
///
/// Rename a keyword to float.
///
/// Old name.
/// New name.
/// Value when set.
/// Value when unset.
public void RenameKeywordToFloat(string oldName, string newName, float setVal, float unsetVal)
{
m_KeywordFloatRename.Add(new KeywordFloatRename { keyword = oldName, property = newName, setVal = setVal, unsetVal = unsetVal });
}
///
/// Rename a float property conditionally based on its value
///
/// Old property name
/// New property name
/// Condition function that takes the float value and returns true if renaming should occur
protected void RenameFloat(string oldName, string newName, System.Func condition)
{
(m_ConditionalFloatRename ??= new Dictionary)>())[oldName] = (newName, condition);
}
}
}