[Add] All in one shader

This commit is contained in:
2026-02-23 22:01:07 +07:00
parent ec0aa86ac2
commit 4f942cd7c0
806 changed files with 401510 additions and 33 deletions
@@ -0,0 +1,470 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace AllIn13DShader
{
[System.Serializable]
public class MaterialOverrideData : ScriptableObject
{
public class MaterialOverride
{
public Material sourceMaterial;
public Material previewMaterial;
public MaterialOverride(Material sourceMaterial)
{
this.sourceMaterial = sourceMaterial;
if(sourceMaterial == null)
{
this.previewMaterial = null;
}
else
{
this.previewMaterial = new Material(sourceMaterial);
this.previewMaterial.name = this.previewMaterial.name + "_PREVIEW";
}
}
public void ApplyPreviewToSource()
{
sourceMaterial.CopyMatchingPropertiesFromMaterial(previewMaterial);
}
public bool ApplySourceToPreview()
{
bool res = true;
if (previewMaterial == null || sourceMaterial == null)
{
res = false;
}
else
{
previewMaterial.CopyMatchingPropertiesFromMaterial(sourceMaterial);
}
return res;
}
}
public class RendererOverride
{
public Renderer renderer;
public MaterialOverride[] materialsOverrides;
public Material[] sourceMaterials;
public Material[] previewMaterials;
public RendererOverride(Renderer renderer)
{
this.renderer = renderer;
this.materialsOverrides = new MaterialOverride[renderer.sharedMaterials.Length];
sourceMaterials = new Material[materialsOverrides.Length];
previewMaterials = new Material[materialsOverrides.Length];
for (int i = 0; i < materialsOverrides.Length; i++)
{
materialsOverrides[i] = new MaterialOverride(renderer.sharedMaterials[i]);
sourceMaterials[i] = materialsOverrides[i].sourceMaterial;
previewMaterials[i] = materialsOverrides[i].previewMaterial;
}
}
public void UsePreviewMaterials()
{
if (renderer != null)
{
renderer.sharedMaterials = previewMaterials;
}
}
public void UseMaterialSource()
{
if (renderer != null)
{
renderer.sharedMaterials = sourceMaterials;
}
}
public void ApplyPreviewMaterial()
{
for (int i = 0; i < materialsOverrides.Length; i++)
{
materialsOverrides[i].ApplyPreviewToSource();
renderer.sharedMaterials[i] = materialsOverrides[i].sourceMaterial;
}
}
public void DiscardChanges()
{
renderer.hideFlags = HideFlags.None;
UseMaterialSource();
}
public Material[] GetPreviewMaterials()
{
return previewMaterials;
}
public void CleanPreviewMaterials()
{
for(int i = 0; i < materialsOverrides.Length; i++)
{
MaterialOverride matOverride = materialsOverrides[i];
matOverride.ApplySourceToPreview();
string[] keywords = new string[matOverride.sourceMaterial.shaderKeywords.Length];
matOverride.sourceMaterial.shaderKeywords.CopyTo(keywords, 0);
matOverride.previewMaterial.shaderKeywords = keywords;
}
}
}
public enum ApplyTarget
{
CURRENT_SCENE,
SELECTED_FOLDERS,
ALL_PROJECT,
}
public List<AbstractEffectOverride> effectOverrides;
public List<PropertyOverride> generalPropertiesOverrides;
public RendererOverride[] rendererOverrides;
public ApplyTarget applyTarget;
[SerializeField] private Object[] folders;
public void Initialize()
{
ResetData();
}
public void ResetData()
{
effectOverrides = new List<AbstractEffectOverride>();
generalPropertiesOverrides = new List<PropertyOverride>();
rendererOverrides = new RendererOverride[0];
applyTarget = ApplyTarget.CURRENT_SCENE;
}
public void CreateRendererOverride()
{
Renderer[] renderers = FindObjectsByType<Renderer>(FindObjectsSortMode.None);
for (int i = 0; i < renderers.Length; i++)
{
if (renderers[i] is ParticleSystemRenderer) { continue; }
if (renderers[i].sharedMaterial == null) { continue; }
renderers[i].hideFlags = HideFlags.NotEditable;
RendererOverride rendererOverride = new RendererOverride(renderers[i]);
ArrayUtility.Add(ref rendererOverrides, rendererOverride);
}
}
public List<Material> CollectAffectedMaterials()
{
List<Material> res = new List<Material>();
switch (applyTarget)
{
case ApplyTarget.SELECTED_FOLDERS:
CollectAffectedMaterialsOnSelectedFolders(res);
break;
case ApplyTarget.CURRENT_SCENE:
CollectAffectedMaterialsOnCurrentScene(res);
break;
case ApplyTarget.ALL_PROJECT:
CollectAffectedMaterialsAllProject(res);
break;
}
return res;
}
public void UsePreviewMaterials()
{
for (int i = 0; i < rendererOverrides.Length; i++)
{
rendererOverrides[i].UsePreviewMaterials();
}
}
public void UseMaterialSource()
{
for (int i = 0; i < rendererOverrides.Length; i++)
{
rendererOverrides[i].UseMaterialSource();
}
}
public void EndOverrideProcess()
{
for (int i = 0; i < rendererOverrides.Length; i++)
{
if (rendererOverrides[i].renderer == null) { continue; }
rendererOverrides[i].DiscardChanges();
}
//for(int i = 0; i < rendererOverrides.Length; i++)
//{
// rendererOverrides[i].renderer.hideFlags = HideFlags.None;
//}
//UseMaterialSource();
effectOverrides = new List<AbstractEffectOverride>();
rendererOverrides = new RendererOverride[0];
}
public void ApplyChangesToMaterials(Material[] materials)
{
for (int i = 0; i < materials.Length; i++)
{
ApplyChangesToMaterial(materials[i]);
}
}
public void ApplyChangesToMaterials(List<Material> materials)
{
for(int i = 0; i < materials.Count; i++)
{
ApplyChangesToMaterial(materials[i]);
}
}
public void ApplyChangesToMaterial(Material mat)
{
for (int i = 0; i < effectOverrides.Count; i++)
{
effectOverrides[i].ApplyChangesToMaterial(mat);
}
for (int i = 0; i < generalPropertiesOverrides.Count; i++)
{
generalPropertiesOverrides[i].ApplyChangesToMaterial(mat);
}
}
private void CollectAffectedMaterialsOnCurrentScene(List<Material> affectedMaterials)
{
for (int i = 0; i < rendererOverrides.Length; i++)
{
affectedMaterials.AddRange(rendererOverrides[i].sourceMaterials);
}
}
private void CollectAffectedMaterialsOnSelectedFolders(List<Material> affectedMaterials)
{
HashSet<string> materialsInFolderGUIDs = new HashSet<string>();
for (int i = 0; i < folders.Length; i++)
{
string folderPath = AssetDatabase.GetAssetPath(folders[i]);
if (AssetDatabase.IsValidFolder(folderPath))
{
string[] assetsPathsInFolder = AssetDatabase.FindAssets("t: Material", new string[] { folderPath });
for (int j = 0; j < assetsPathsInFolder.Length; j++)
{
materialsInFolderGUIDs.Add(assetsPathsInFolder[j]);
}
}
}
foreach (string guid in materialsInFolderGUIDs)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
Material mat = AssetDatabase.LoadAssetAtPath<Material>(path);
if (EditorUtils.IsAllIn13DShader(mat.shader))
{
affectedMaterials.Add(mat);
}
}
}
private void CollectAffectedMaterialsAllProject(List<Material> affectedMaterials)
{
string[] materialsGUIDs = AssetDatabase.FindAssets("t: Material");
foreach (string guid in materialsGUIDs)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
Material mat = AssetDatabase.LoadAssetAtPath<Material>(path);
if (EditorUtils.IsAllIn13DShader(mat.shader))
{
affectedMaterials.Add(mat);
}
}
}
public bool IsApplyEnabled()
{
bool res = false;
switch (applyTarget)
{
case ApplyTarget.SELECTED_FOLDERS:
res = (folders != null) && (folders.Length > 0);
break;
case ApplyTarget.CURRENT_SCENE:
res = true;
break;
case ApplyTarget.ALL_PROJECT:
res = true;
break;
}
return res;
}
public AbstractEffectOverride AddEffectOverride(AllIn13DEffectConfig effectConfig)
{
AbstractEffectOverride res = FindEffectOverride(effectConfig.keywordPropertyName);
if (res == null)
{
switch (effectConfig.effectConfigType)
{
case EffectConfigType.EFFECT_ENUM:
res = new EffectEnumOverride(effectConfig);
break;
case EffectConfigType.EFFECT_TOGGLE:
res = new EffectToggleOverride(effectConfig);
break;
}
effectOverrides.Add(res);
}
return res;
}
public void AddCopmleteEffectOverride(AllIn13DEffectConfig effectConfig, Shader shader)
{
AbstractEffectOverride effectOverride = FindEffectOverride(effectConfig.keywordPropertyName);
if(effectOverride == null)
{
effectOverride = AddEffectOverride(effectConfig);
}
for (int i = 0; i < effectConfig.effectProperties.Count; i++)
{
effectOverride.AddPropertyOverride(effectConfig.effectProperties[i], shader);
}
}
public void AddPropertyOverride(AllIn13DEffectConfig effectConfig, EffectProperty effectProperty, Shader shader)
{
AbstractEffectOverride effectOverride = FindEffectOverride(effectConfig.keywordPropertyName);
effectOverride = AddEffectOverride(effectConfig);
effectOverride.AddPropertyOverride(effectProperty.propertyIndex, shader);
}
public void AddGeneralPropertyOverride(int propertyIndex, Shader shader)
{
PropertyOverride propertyOverride = new PropertyOverride(null, propertyIndex, shader);
if (!generalPropertiesOverrides.Contains(propertyOverride))
{
generalPropertiesOverrides.Add(propertyOverride);
}
}
public void RemoveEffectOverride(AbstractEffectOverride effectOverrideToRemove)
{
effectOverrides.Remove(effectOverrideToRemove);
RebuildPreviewMaterial();
}
public void RemovePropertyOverride(PropertyOverride propertyOverride)
{
bool removeSuccessfully = propertyOverride.Remove();
if (!removeSuccessfully)
{
generalPropertiesOverrides.Remove(propertyOverride);
}
}
public void RebuildPreviewMaterial()
{
for (int i = 0; i < rendererOverrides.Length; i++)
{
rendererOverrides[i].CleanPreviewMaterials();
}
ShowPreviewChanges();
}
public void ShowPreviewChanges()
{
for (int i = 0; i < rendererOverrides.Length; i++)
{
RendererOverride rendererOverride = rendererOverrides[i];
rendererOverride.UsePreviewMaterials();
ApplyChangesToMaterials(rendererOverride.previewMaterials);
}
}
public AbstractEffectOverride FindEffectOverride(string effectPropertyName)
{
AbstractEffectOverride res = null;
for(int i = 0; i < effectOverrides.Count; i++)
{
if (effectOverrides[i].propertyName == effectPropertyName)
{
res = effectOverrides[i];
break;
}
}
return res;
}
public bool IsEmpty()
{
bool res = effectOverrides.Count <= 0 && generalPropertiesOverrides.Count <= 0;
return res;
}
public bool DiscardChanges(Renderer[] renderers)
{
bool changes = false;
for(int i = this.rendererOverrides.Length - 1; i >= 0; i--)
{
for(int j = 0; j < renderers.Length; j++)
{
if (this.rendererOverrides[i].renderer == renderers[j])
{
rendererOverrides[i].DiscardChanges();
ArrayUtility.RemoveAt(ref this.rendererOverrides, i);
changes = true;
break;
}
}
}
return changes;
}
}
}