416 lines
13 KiB
C#
416 lines
13 KiB
C#
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
namespace AllIn13DShader
|
|
{
|
|
[CanEditMultipleObjects]
|
|
public class AllIn13DShaderMaterialInspector : ShaderGUI
|
|
{
|
|
private PropertiesConfigCollection propertiesConfigCollection;
|
|
|
|
private PropertiesConfig currentPropertiesConfig;
|
|
|
|
private AllIn13DShaderInspectorReferences inspectorReferences;
|
|
private AbstractEffectDrawer[] drawers;
|
|
private GlobalPropertiesDrawer globalPropertiesDrawer;
|
|
private AdvancedPropertiesDrawer advancedPropertiesDrawer;
|
|
|
|
private MaterialPresetCollection blendingModeCollection;
|
|
|
|
private MaterialProperty matPropertyRenderPreset;
|
|
private MaterialProperty matPropertyBlendSrc;
|
|
private MaterialProperty matPropertyBlendDst;
|
|
private MaterialProperty matPropertyZWrite;
|
|
|
|
private int lastRenderQueue;
|
|
|
|
private static CommonStyles commonStyles;
|
|
|
|
private void RefreshReferences(MaterialEditor materialEditor, MaterialProperty[] properties)
|
|
{
|
|
if (inspectorReferences == null)
|
|
{
|
|
inspectorReferences = new AllIn13DShaderInspectorReferences();
|
|
inspectorReferences.Setup(materialEditor, properties);
|
|
|
|
if (lastRenderQueue > 0)
|
|
{
|
|
for(int i = 0; i < inspectorReferences.targetMatInfos.Length; i++)
|
|
{
|
|
inspectorReferences.targetMatInfos[i].mat.renderQueue = lastRenderQueue;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (propertiesConfigCollection == null)
|
|
{
|
|
string[] guids = AssetDatabase.FindAssets("PropertiesConfigCollection t:PropertiesConfigCollection");
|
|
if(guids.Length == 0)
|
|
{
|
|
Debug.LogWarning("PropertiesConfigCollection not found in the project. Configuring...");
|
|
this.propertiesConfigCollection = PropertiesConfigCreator.CreateConfig();
|
|
Debug.LogWarning("AllIn13DShader configured");
|
|
}
|
|
else
|
|
{
|
|
string path = AssetDatabase.GUIDToAssetPath(guids[0]);
|
|
propertiesConfigCollection = AssetDatabase.LoadAssetAtPath<PropertiesConfigCollection>(path);
|
|
}
|
|
|
|
RefreshPropertiesConfig();
|
|
}
|
|
|
|
if (blendingModeCollection == null)
|
|
{
|
|
blendingModeCollection = (MaterialPresetCollection)EditorUtils.FindAsset<ScriptableObject>("BlendingModeCollection");
|
|
}
|
|
|
|
CreateDrawers();
|
|
|
|
matPropertyRenderPreset = inspectorReferences.matProperties[currentPropertiesConfig.renderPreset];
|
|
matPropertyBlendSrc = inspectorReferences.matProperties[currentPropertiesConfig.blendSrcIdx];
|
|
matPropertyBlendDst = inspectorReferences.matProperties[currentPropertiesConfig.blendDstIdx];
|
|
matPropertyZWrite = inspectorReferences.matProperties[currentPropertiesConfig.zWriteIndex];
|
|
|
|
//We ensure that data is refreshed. Sometimes objects are not null but we need to refresh the references
|
|
inspectorReferences.Setup(materialEditor, properties);
|
|
|
|
if(commonStyles == null)
|
|
{
|
|
commonStyles = new CommonStyles();
|
|
}
|
|
|
|
RefreshDrawers();
|
|
}
|
|
|
|
private void ResetReferences()
|
|
{
|
|
this.propertiesConfigCollection = null;
|
|
this.currentPropertiesConfig = null;
|
|
|
|
inspectorReferences = null;
|
|
drawers = null;
|
|
|
|
globalPropertiesDrawer = null;
|
|
advancedPropertiesDrawer = null;
|
|
}
|
|
|
|
private void CreateDrawers()
|
|
{
|
|
if (propertiesConfigCollection == null ||
|
|
currentPropertiesConfig == null ||
|
|
inspectorReferences == null ||
|
|
drawers == null ||
|
|
globalPropertiesDrawer == null ||
|
|
advancedPropertiesDrawer == null)
|
|
{
|
|
drawers = new AbstractEffectDrawer[0];
|
|
|
|
GeneralEffectDrawer generalEffectDrawer = new GeneralEffectDrawer(inspectorReferences, currentPropertiesConfig);
|
|
|
|
EffectProperty mainNormalMapProperty = currentPropertiesConfig.FindEffectProperty("NORMAL_MAP", "_NormalMap");
|
|
|
|
TriplanarEffectDrawer triplanarEffectDrawer = new TriplanarEffectDrawer(mainNormalMapProperty, inspectorReferences, currentPropertiesConfig);
|
|
ColorRampEffectDrawer colorRampEffectDrawer = new ColorRampEffectDrawer(inspectorReferences, currentPropertiesConfig);
|
|
OutlineEffectDrawer outlineEffectDrawer = new OutlineEffectDrawer(inspectorReferences, currentPropertiesConfig);
|
|
TextureBlendingEffectDrawer vertexColorEffectDrawer = new TextureBlendingEffectDrawer(mainNormalMapProperty, inspectorReferences, currentPropertiesConfig);
|
|
NormalMapEffectDrawer normalMapEffectDrawer = new NormalMapEffectDrawer(inspectorReferences, currentPropertiesConfig);
|
|
|
|
drawers = new AbstractEffectDrawer[]
|
|
{
|
|
generalEffectDrawer,
|
|
triplanarEffectDrawer,
|
|
colorRampEffectDrawer,
|
|
outlineEffectDrawer,
|
|
vertexColorEffectDrawer,
|
|
normalMapEffectDrawer
|
|
};
|
|
|
|
advancedPropertiesDrawer = new AdvancedPropertiesDrawer(currentPropertiesConfig.advancedProperties, currentPropertiesConfig.blendSrcIdx, currentPropertiesConfig.blendDstIdx, inspectorReferences);
|
|
}
|
|
|
|
if (globalPropertiesDrawer == null)
|
|
{
|
|
globalPropertiesDrawer = new GlobalPropertiesDrawer();
|
|
}
|
|
}
|
|
|
|
private void RefreshDrawers()
|
|
{
|
|
for(int i = 0; i < drawers.Length; i++)
|
|
{
|
|
drawers[i].Refresh(inspectorReferences);
|
|
}
|
|
}
|
|
|
|
private AbstractEffectDrawer FindEffectDrawerByID(string drawerID)
|
|
{
|
|
AbstractEffectDrawer res = null;
|
|
|
|
for (int i = 0; i < drawers.Length; i++)
|
|
{
|
|
if (drawers[i].ID == drawerID)
|
|
{
|
|
res = drawers[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader)
|
|
{
|
|
base.AssignNewShaderToMaterial(material, oldShader, newShader);
|
|
}
|
|
|
|
private void RefreshPropertiesConfig()
|
|
{
|
|
Shader shader = inspectorReferences.GetShader();
|
|
currentPropertiesConfig = propertiesConfigCollection.FindPropertiesConfigByShader(shader);
|
|
|
|
inspectorReferences.SetOutlineEffect(currentPropertiesConfig);
|
|
inspectorReferences.SetCastShadowsEffect(currentPropertiesConfig);
|
|
}
|
|
|
|
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
|
|
{
|
|
if (inspectorReferences != null && drawers != null)
|
|
{
|
|
inspectorReferences.Setup(materialEditor, properties);
|
|
}
|
|
|
|
RefreshReferences(materialEditor, properties);
|
|
|
|
commonStyles.InitStyles();
|
|
|
|
#if ALLIN13DSHADER_URP
|
|
bool urpCorrectlyConfigured = URPConfigurator.IsURPCorrectlyConfigured();
|
|
if (!urpCorrectlyConfigured)
|
|
{
|
|
EditorGUILayout.LabelField(CommonMessages.URP_PIPELINE_NOT_ASSIGNED, commonStyles.warningLabel);
|
|
EditorUtils.DrawButtonLink(CommonMessages.URP_PIPELINE_NOT_ASSIGNED_DOC_LINK);
|
|
|
|
GUILayout.Space(50f);
|
|
}
|
|
|
|
EditorGUI.BeginDisabledGroup(!urpCorrectlyConfigured);
|
|
#endif
|
|
|
|
DrawPresetsTabs();
|
|
DrawAdvancedProperties();
|
|
DrawGlobalProperties();
|
|
DrawEffects();
|
|
|
|
#if ALLIN13DSHADER_URP
|
|
EditorGUI.EndDisabledGroup();
|
|
#endif
|
|
|
|
CheckLightmapFlags();
|
|
bool shaderChanged = false;
|
|
for (int i = 0; i < inspectorReferences.targetMatInfos.Length; i++)
|
|
{
|
|
Material targetMat = inspectorReferences.targetMatInfos[i].mat;
|
|
|
|
lastRenderQueue = targetMat.renderQueue;
|
|
|
|
if (!inspectorReferences.targetMatInfos[i].IsShaderVariant())
|
|
{
|
|
shaderChanged = shaderChanged || MaterialUtils.CheckMaterialShader(targetMat);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
EditorGUILayout.Separator();
|
|
EditorUtils.DrawLine(Color.grey, 1, 3);
|
|
|
|
if (inspectorReferences.AreAllMaterialsShaderGeneric())
|
|
{
|
|
if (GUILayout.Button("Bake Shader Keywords"))
|
|
{
|
|
for (int i = 0; i < inspectorReferences.targetMatInfos.Length; i++)
|
|
{
|
|
string variantName = Selection.objects[i].name;
|
|
Shader newShader = ShaderVariantCreator.CreateVariantByMaterialInfo(currentPropertiesConfig, inspectorReferences.targetMatInfos[i], variantName);
|
|
inspectorReferences.targetMatInfos[i].mat.shader = newShader;
|
|
}
|
|
//Shader newShader = ShaderVariantCreator.CreateVariantByMaterialInfo(currentPropertiesConfig, inspectorReferences.targetMatInfos[0], variantName);
|
|
//materialEditor.SetShader(newShader);
|
|
|
|
shaderChanged = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (GUILayout.Button("Revert To Generic Shader"))
|
|
{
|
|
Shader currentShader = inspectorReferences.GetShader();
|
|
GlobalConfiguration.instance.effectsProfileCollection.RemoveEffectsProfileByShader(currentShader);
|
|
|
|
Shader newShader = Shader.Find(Constants.SHADER_FULL_NAME_ALLIN13D);
|
|
materialEditor.SetShader(newShader);
|
|
|
|
shaderChanged = true;
|
|
}
|
|
}
|
|
|
|
if (shaderChanged)
|
|
{
|
|
ResetReferences();
|
|
}
|
|
}
|
|
|
|
//private void CheckPasses(Material targetMat)
|
|
//{
|
|
// if (targetMat.IsKeywordEnabled("_LIGHTMODEL_FASTLIGHTING") || targetMat.IsKeywordEnabled("_LIGHTMODEL_NONE"))
|
|
// {
|
|
// targetMat.SetShaderPassEnabled("ForwardAdd", false);
|
|
// }
|
|
// else
|
|
// {
|
|
// targetMat.SetShaderPassEnabled("ForwardAdd", true);
|
|
// }
|
|
//}
|
|
|
|
private void DrawPresetsTabs()
|
|
{
|
|
EditorGUI.BeginChangeCheck();
|
|
|
|
string[] texts = blendingModeCollection.CreateStringsArray();
|
|
|
|
|
|
int presetIndex = (int)matPropertyRenderPreset.floatValue;
|
|
if (presetIndex >= blendingModeCollection.presets.Length)
|
|
{
|
|
presetIndex = 1;
|
|
matPropertyRenderPreset.floatValue = presetIndex;
|
|
}
|
|
|
|
BlendingMode previousPreset = blendingModeCollection[presetIndex];
|
|
if(previousPreset == null)
|
|
{
|
|
previousPreset = blendingModeCollection[0];
|
|
}
|
|
|
|
int newIndex = (int)matPropertyRenderPreset.floatValue;
|
|
newIndex = GUILayout.SelectionGrid(newIndex, texts, 3, inspectorReferences.tabButtonStyle);
|
|
matPropertyRenderPreset.floatValue = newIndex;
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
BlendingMode selectedPreset = blendingModeCollection[newIndex];
|
|
for(int i = 0; i < inspectorReferences.targetMatInfos.Length; i++)
|
|
{
|
|
Material targetMat = inspectorReferences.targetMatInfos[i].mat;
|
|
ApplyMaterialPreset(targetMat, previousPreset, selectedPreset);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DrawAdvancedProperties()
|
|
{
|
|
//Security check
|
|
if (advancedPropertiesDrawer != null)
|
|
{
|
|
advancedPropertiesDrawer.Draw();
|
|
}
|
|
}
|
|
|
|
private void DrawGlobalProperties()
|
|
{
|
|
globalPropertiesDrawer.Draw(currentPropertiesConfig.singleProperties, inspectorReferences);
|
|
}
|
|
|
|
private void DrawEffects()
|
|
{
|
|
int globalEffectIndex = 0;
|
|
for (int groupIdx = 0; groupIdx < currentPropertiesConfig.effectsGroups.Length; groupIdx++)
|
|
{
|
|
EffectGroup effectGroup = currentPropertiesConfig.effectsGroups[groupIdx];
|
|
if (effectGroup.effects.Length <= 0) { continue; }
|
|
|
|
EditorGUILayout.Separator();
|
|
EditorUtils.DrawLine(Color.grey, 1, 3);
|
|
GUILayout.Label(effectGroup.DisplayName, inspectorReferences.bigLabelStyle);
|
|
|
|
for (int effectIdx = 0; effectIdx < effectGroup.effects.Length; effectIdx++)
|
|
{
|
|
AllIn13DEffectConfig effectConfig = effectGroup.effects[effectIdx];
|
|
|
|
globalEffectIndex++;
|
|
|
|
AbstractEffectDrawer drawer = FindEffectDrawerByID(effectConfig.effectDrawerID);
|
|
drawer.Draw(currentPropertiesConfig, effectConfig, globalEffectIndex);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void CheckLightmapFlags()
|
|
{
|
|
for (int i = 0; i < inspectorReferences.targetMatInfos.Length; i++)
|
|
{
|
|
AbstractMaterialInfo matInfo = inspectorReferences.targetMatInfos[i];
|
|
AllIn13DEffectConfig emissionEffectConfig = propertiesConfigCollection.propertiesConfig.FindEffectConfigByID(Constants.EFFECT_ID_EMISSION);
|
|
bool emissionEnabled = AllIn13DEffectConfig.IsEffectEnabled(emissionEffectConfig, matInfo);
|
|
if (emissionEnabled)
|
|
{
|
|
matInfo.mat.globalIlluminationFlags = MaterialGlobalIlluminationFlags.BakedEmissive;
|
|
}
|
|
else
|
|
{
|
|
matInfo.mat.globalIlluminationFlags = MaterialGlobalIlluminationFlags.EmissiveIsBlack;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ApplyMaterialPreset(Material targetMat, BlendingMode previousPresset, BlendingMode newPreset)
|
|
{
|
|
matPropertyBlendSrc.floatValue = (float)newPreset.blendSrc;
|
|
matPropertyBlendDst.floatValue = (float)newPreset.blendDst;
|
|
matPropertyZWrite.floatValue = newPreset.depthWrite ? 1.0f : 0.0f;
|
|
|
|
|
|
lastRenderQueue = (int)newPreset.renderQueue;
|
|
targetMat.renderQueue = lastRenderQueue;
|
|
|
|
if (previousPresset != newPreset && previousPresset.defaultEnabledEffects != null)
|
|
{
|
|
for (int i = 0; i < previousPresset.defaultEnabledEffects.Length; i++)
|
|
{
|
|
string effectID = previousPresset.defaultEnabledEffects[i];
|
|
AllIn13DEffectConfig effectConfig = currentPropertiesConfig.FindEffectConfigByID(effectID);
|
|
|
|
for(int matIdx = 0; matIdx < inspectorReferences.targetMatInfos.Length; matIdx++)
|
|
{
|
|
AbstractMaterialInfo matInfo = inspectorReferences.targetMatInfos[matIdx];
|
|
AllIn13DEffectConfig.DisableEffectToggle(effectConfig, inspectorReferences, matInfo);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (newPreset.defaultEnabledEffects != null)
|
|
{
|
|
for (int matIdx = 0; matIdx < inspectorReferences.targetMatInfos.Length; matIdx++)
|
|
{
|
|
AbstractMaterialInfo matInfo = inspectorReferences.targetMatInfos[matIdx];
|
|
|
|
if (newPreset.isTransparent)
|
|
{
|
|
matInfo.EnableKeyword(Constants.KEYWORD_ALLIN13D_SURFACE_TRANSPARENT);
|
|
}
|
|
else
|
|
{
|
|
matInfo.DisableKeyword(Constants.KEYWORD_ALLIN13D_SURFACE_TRANSPARENT);
|
|
}
|
|
|
|
for (int i = 0; i < newPreset.defaultEnabledEffects.Length; i++)
|
|
{
|
|
string effectID = newPreset.defaultEnabledEffects[i];
|
|
AllIn13DEffectConfig effectConfig = currentPropertiesConfig.FindEffectConfigByID(effectID);
|
|
AllIn13DEffectConfig.EnableEffectToggle(effectConfig, inspectorReferences, matInfo);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |