451 lines
19 KiB
C#
451 lines
19 KiB
C#
using System;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
using NBShader;
|
|
|
|
namespace NBShaderEditor
|
|
{
|
|
public enum RenderFace
|
|
{
|
|
Front = 2,
|
|
Back = 1,
|
|
Both = 0
|
|
}
|
|
|
|
public enum ForceZWriteMode
|
|
{
|
|
Default = 0,
|
|
ForceOn = 1,
|
|
ForceOff = 2
|
|
}
|
|
|
|
public class BaseOptionBigBlockItem : BigBlockItem
|
|
{
|
|
private readonly NBShaderRootItem _nbRootItem;
|
|
private readonly ShaderGUIFloatItem _baseColorIntensityItem;
|
|
private readonly ShaderGUISliderItem _alphaAllItem;
|
|
private readonly BlockItem _colorAdjustmentBlock;
|
|
private readonly ToggleItem _colorAdjustmentOnlyMainTexItem;
|
|
private readonly PropertyToggleBlockItem _hueShiftBlock;
|
|
private readonly ShaderGUISliderItem _hueShiftSlider;
|
|
private readonly CustomDataSelectItem _hueShiftCustomDataItem;
|
|
private readonly PropertyToggleBlockItem _saturabilityBlock;
|
|
private readonly ShaderGUISliderItem _saturabilitySlider;
|
|
private readonly CustomDataSelectItem _saturabilityCustomDataItem;
|
|
private readonly PropertyToggleBlockItem _contrastBlock;
|
|
private readonly ColorItem _contrastMidColorItem;
|
|
private readonly ShaderGUISliderItem _contrastSlider;
|
|
private readonly CustomDataSelectItem _contrastCustomDataItem;
|
|
private readonly PropertyToggleBlockItem _baseMapColorRefineBlock;
|
|
private readonly VectorComponentItem _baseMapColorRefineA;
|
|
private readonly VectorComponentItem _baseMapColorRefineBPower;
|
|
private readonly VectorComponentItem _baseMapColorRefineBMultiply;
|
|
private readonly VectorComponentItem _baseMapColorRefineLerp;
|
|
private readonly ToggleItem _colorMultiAlphaItem;
|
|
private readonly ZTestItem _zTestItem;
|
|
private readonly CullModeItem _cullItem;
|
|
private readonly ToggleItem _backFirstPassItem;
|
|
private readonly ForceZWriteItem _forceZWriteItem;
|
|
private readonly ToggleItem _affectsShadowsItem;
|
|
private readonly ToggleItem _transparentShadowDitherItem;
|
|
private readonly PropertyToggleBlockItem _baseBackColorBlock;
|
|
private readonly ColorItem _baseBackColorItem;
|
|
private readonly PropertyToggleBlockItem _distanceFadeBlock;
|
|
private readonly Vector2LineItem _fadeRangeItem;
|
|
private readonly PropertyToggleBlockItem _softParticlesBlock;
|
|
private readonly Vector2LineItem _softParticleFadeItem;
|
|
private readonly ToggleItem _stencilWithoutPlayerItem;
|
|
private readonly ToggleItem _ignoreVertexColorItem;
|
|
private readonly ShaderGUISliderItem _fogIntensityItem;
|
|
|
|
public BaseOptionBigBlockItem(NBShaderRootItem rootItem, ShaderGUIItem parentItem) :
|
|
base(
|
|
rootItem,
|
|
parentItem,
|
|
"_BaseOptionBigBlockItemFoldOut",
|
|
() => Content("block.base", "Base Options", "Global controls"))
|
|
{
|
|
_nbRootItem = rootItem;
|
|
|
|
_baseColorIntensityItem = new ShaderGUIFloatItem(rootItem, this)
|
|
{
|
|
PropertyName = "_BaseColorIntensityForTimeline",
|
|
GuiContent = Content("base.colorIntensity", "Base Color Intensity")
|
|
};
|
|
_baseColorIntensityItem.InitTriggerByChild();
|
|
|
|
_alphaAllItem = new ShaderGUISliderItem(rootItem, this)
|
|
{
|
|
PropertyName = "_AlphaAll",
|
|
GuiContent = Content("base.alphaAll", "Overall Alpha"),
|
|
RangePropertyName = "AlphaAllRangeVec"
|
|
};
|
|
_alphaAllItem.InitTriggerByChild();
|
|
|
|
_colorAdjustmentBlock = new BlockItem(
|
|
rootItem,
|
|
this,
|
|
"_BaseColorAdjustmentFoldOut",
|
|
() => Content("base.colorAdjustment", "Color Adjustment"));
|
|
|
|
_colorAdjustmentOnlyMainTexItem = new ToggleItem(
|
|
rootItem,
|
|
_colorAdjustmentBlock,
|
|
"_ColorAdjustmentOnlyAffectMainTex",
|
|
() => Content("base.colorAdjustment.onlyMainTex", "Only Affect Main Texture"),
|
|
enabled => rootItem.SyncService.ApplyToggleFlag(
|
|
NBShaderFlags.FLAG_BIT_PARTICLE_COLOR_ADJUSTMENT_ONLY_AFFECT_MAINTEX,
|
|
enabled));
|
|
|
|
_hueShiftBlock = new PropertyToggleBlockItem(
|
|
rootItem,
|
|
_colorAdjustmentBlock,
|
|
"_HueShiftFoldOut",
|
|
"_HueShift_Toggle",
|
|
() => Content("base.hueShift", "Hue Shift"),
|
|
NBShaderFlags.FLAG_BIT_HUESHIFT_ON);
|
|
_hueShiftSlider = new ShaderGUISliderItem(rootItem, _hueShiftBlock)
|
|
{
|
|
PropertyName = "_HueShift",
|
|
GuiContent = Content("base.hueShift.value", "Hue"),
|
|
Min = 0f,
|
|
Max = 1f
|
|
};
|
|
_hueShiftSlider.InitTriggerByChild();
|
|
_hueShiftCustomDataItem = new CustomDataSelectItem(
|
|
rootItem,
|
|
_hueShiftBlock,
|
|
NBShaderFlags.FLAGBIT_POS_0_CUSTOMDATA_HUESHIFT,
|
|
0,
|
|
() => Content("base.hueShift.customData", "Hue Custom Data"),
|
|
IsParticleMode);
|
|
|
|
_saturabilityBlock = new PropertyToggleBlockItem(
|
|
rootItem,
|
|
_colorAdjustmentBlock,
|
|
"_SaturabilityFoldOut",
|
|
"_ChangeSaturability_Toggle",
|
|
() => Content("base.saturability", "Saturation"),
|
|
NBShaderFlags.FLAG_BIT_SATURABILITY_ON);
|
|
_saturabilitySlider = new ShaderGUISliderItem(rootItem, _saturabilityBlock)
|
|
{
|
|
PropertyName = "_Saturability",
|
|
GuiContent = Content("base.saturability.value", "Saturation"),
|
|
RangePropertyName = "SaturabilityRangeVec"
|
|
};
|
|
_saturabilitySlider.InitTriggerByChild();
|
|
_saturabilityCustomDataItem = new CustomDataSelectItem(
|
|
rootItem,
|
|
_saturabilityBlock,
|
|
NBShaderFlags.FLAGBIT_POS_1_CUSTOMDATA_SATURATE,
|
|
1,
|
|
() => Content("base.saturability.customData", "Saturation Custom Data"),
|
|
IsParticleMode);
|
|
|
|
_contrastBlock = new PropertyToggleBlockItem(
|
|
rootItem,
|
|
_colorAdjustmentBlock,
|
|
"_ContrastFoldOut",
|
|
"_Contrast_Toggle",
|
|
() => Content("base.contrast", "Contrast"),
|
|
NBShaderFlags.FLAG_BIT_PARTICLE_1_MAINTEX_CONTRAST,
|
|
1);
|
|
_contrastMidColorItem = new ColorItem(rootItem, _contrastBlock, "_ContrastMidColor", () => Content("base.contrast.mid", "Contrast Mid Color"));
|
|
_contrastSlider = new ShaderGUISliderItem(rootItem, _contrastBlock)
|
|
{
|
|
PropertyName = "_Contrast",
|
|
GuiContent = Content("base.contrast.value", "Contrast"),
|
|
Min = 0f,
|
|
Max = 5f
|
|
};
|
|
_contrastSlider.InitTriggerByChild();
|
|
_contrastCustomDataItem = new CustomDataSelectItem(
|
|
rootItem,
|
|
_contrastBlock,
|
|
NBShaderFlags.FLAGBIT_POS_2_CUSTOMDATA_MAINTEX_CONTRAST,
|
|
2,
|
|
() => Content("base.contrast.customData", "Contrast Custom Data"),
|
|
IsParticleMode);
|
|
|
|
_baseMapColorRefineBlock = new PropertyToggleBlockItem(
|
|
rootItem,
|
|
_colorAdjustmentBlock,
|
|
"_BaseMapColorRefineFoldOut",
|
|
"_BaseMapColorRefine_Toggle",
|
|
() => Content("base.colorRefine", "Color Refine"),
|
|
NBShaderFlags.FLAG_BIT_PARTICLE_1_MAINTEX_COLOR_REFINE,
|
|
1);
|
|
_baseMapColorRefineA = new VectorComponentItem(rootItem, _baseMapColorRefineBlock, "_BaseMapColorRefine", 0, () => Content("base.colorRefine.a", "A Main Color Multiply"), false);
|
|
_baseMapColorRefineBPower = new VectorComponentItem(rootItem, _baseMapColorRefineBlock, "_BaseMapColorRefine", 1, () => Content("base.colorRefine.bPower", "B Main Color Power"), false);
|
|
_baseMapColorRefineBMultiply = new VectorComponentItem(rootItem, _baseMapColorRefineBlock, "_BaseMapColorRefine", 2, () => Content("base.colorRefine.bMultiply", "B After Power Multiply"), false);
|
|
_baseMapColorRefineLerp = new VectorComponentItem(rootItem, _baseMapColorRefineBlock, "_BaseMapColorRefine", 3, () => Content("base.colorRefine.lerp", "A/B Lerp"), true, 0f, 1f);
|
|
|
|
_colorMultiAlphaItem = new ToggleItem(
|
|
rootItem,
|
|
_colorAdjustmentBlock,
|
|
"_ColorMultiAlpha",
|
|
() => Content("base.colorMultiAlpha", "Color Multiply Alpha"),
|
|
enabled => rootItem.SyncService.ApplyToggleFlag(NBShaderFlags.FLAG_BIT_PARTICLE_COLOR_MULTI_ALPHA, enabled));
|
|
|
|
_zTestItem = new ZTestItem(rootItem, this);
|
|
_cullItem = new CullModeItem(rootItem, this);
|
|
|
|
_backFirstPassItem = new ToggleItem(
|
|
rootItem,
|
|
this,
|
|
"_BackFirstPassToggle",
|
|
() => Content("base.backFirstPass", "Back First Pass"),
|
|
OnBackFirstPassChanged,
|
|
() => Is3DTransparent());
|
|
|
|
_forceZWriteItem = new ForceZWriteItem(rootItem, this);
|
|
_affectsShadowsItem = new ToggleItem(
|
|
rootItem,
|
|
this,
|
|
"_AffectsShadows",
|
|
() => Content("base.affectsShadows", "Affects Shadows"),
|
|
_ => rootItem.SyncService.SyncMaterialState(),
|
|
Is3DMode);
|
|
_transparentShadowDitherItem = new ToggleItem(
|
|
rootItem,
|
|
this,
|
|
"_TransparentShadowDitherToggle",
|
|
() => Content("base.transparentShadowDither", "Transparent Dither Shadows"),
|
|
_ => rootItem.SyncService.SyncMaterialState(),
|
|
ShouldDrawTransparentShadowDither);
|
|
|
|
_baseBackColorBlock = new PropertyToggleBlockItem(
|
|
rootItem,
|
|
this,
|
|
"_BaseBackColorFoldOut",
|
|
"_BaseBackColor_Toggle",
|
|
() => Content("base.backColor", "Back Color"),
|
|
NBShaderFlags.FLAG_BIT_PARTICLE_BACKCOLOR,
|
|
0,
|
|
isVisible: Is3DMode);
|
|
_baseBackColorItem = new ColorItem(rootItem, _baseBackColorBlock, "_BaseBackColor", () => Content("base.backColor.color", "Back Color"));
|
|
|
|
_distanceFadeBlock = new PropertyToggleBlockItem(
|
|
rootItem,
|
|
this,
|
|
"_DistanceFadeFoldOut",
|
|
"_DistanceFade_Toggle",
|
|
() => Content("base.distanceFade", "Distance Fade"),
|
|
keyword: "_DISTANCE_FADE",
|
|
isVisible: Is3DMode);
|
|
_fadeRangeItem = new Vector2LineItem(rootItem, _distanceFadeBlock, "_Fade", true, () => Content("base.distanceFade.range", "Fade Range"));
|
|
|
|
_softParticlesBlock = new PropertyToggleBlockItem(
|
|
rootItem,
|
|
this,
|
|
"_SoftParticlesFoldOut",
|
|
"_SoftParticlesEnabled",
|
|
() => Content("base.softParticles", "Soft Particles"),
|
|
keyword: "_SOFTPARTICLES_ON",
|
|
isVisible: Is3DMode);
|
|
_softParticleFadeItem = new Vector2LineItem(rootItem, _softParticlesBlock, "_SoftParticleFadeParams", true, () => Content("base.softParticles.range", "Near/Far Fade"));
|
|
|
|
_stencilWithoutPlayerItem = new NBShaderKeywordToggleItem(
|
|
rootItem,
|
|
this,
|
|
"_StencilWithoutPlayerToggle",
|
|
"_STENCIL_WITHOUT_PLAYER",
|
|
() => Content("base.stencilWithoutPlayer", "Stencil Without Player"),
|
|
OnStencilWithoutPlayerChanged,
|
|
Is3DMode);
|
|
|
|
_ignoreVertexColorItem = new ToggleItem(
|
|
rootItem,
|
|
this,
|
|
"_IgnoreVetexColor_Toggle",
|
|
() => Content("base.ignoreVertexColor", "Ignore Vertex Color"),
|
|
enabled => rootItem.SyncService.ApplyToggleFlag(NBShaderFlags.FLAG_BIT_PARTICLE_1_IGNORE_VERTEX_COLOR, enabled, 1),
|
|
Is3DMode);
|
|
|
|
_fogIntensityItem = new ShaderGUISliderItem(rootItem, this)
|
|
{
|
|
PropertyName = "_fogintensity",
|
|
GuiContent = Content("base.fogIntensity", "Fog Intensity"),
|
|
Min = 0f,
|
|
Max = 1f
|
|
};
|
|
_fogIntensityItem.InitTriggerByChild();
|
|
|
|
InitTriggerByChild();
|
|
}
|
|
|
|
public override void DrawBlock()
|
|
{
|
|
_baseColorIntensityItem.OnGUI();
|
|
_alphaAllItem.OnGUI();
|
|
_colorAdjustmentBlock.OnGUI();
|
|
_zTestItem.OnGUI();
|
|
_cullItem.OnGUI();
|
|
_backFirstPassItem.OnGUI();
|
|
DrawBackFirstPassWarning();
|
|
_forceZWriteItem.OnGUI();
|
|
_affectsShadowsItem.OnGUI();
|
|
_transparentShadowDitherItem.OnGUI();
|
|
_baseBackColorBlock.OnGUI();
|
|
_distanceFadeBlock.OnGUI();
|
|
_softParticlesBlock.OnGUI();
|
|
_stencilWithoutPlayerItem.OnGUI();
|
|
_ignoreVertexColorItem.OnGUI();
|
|
|
|
if (Is3DMode())
|
|
{
|
|
_fogIntensityItem.OnGUI();
|
|
}
|
|
else if (_nbRootItem.PropertyInfoDic.ContainsKey("_fogintensity"))
|
|
{
|
|
_nbRootItem.PropertyInfoDic["_fogintensity"].Property.floatValue = 0f;
|
|
}
|
|
}
|
|
|
|
private bool Is3DMode()
|
|
{
|
|
return _nbRootItem.Context.UIEffectEnabled == MixedBool.False;
|
|
}
|
|
|
|
private bool Is3DTransparent()
|
|
{
|
|
return Is3DMode() && _nbRootItem.Context.TransparentMode == TransparentMode.Transparent;
|
|
}
|
|
|
|
private bool IsParticleMode()
|
|
{
|
|
return _nbRootItem.Context.ParticleMode == MixedBool.True;
|
|
}
|
|
|
|
private bool ShouldDrawTransparentShadowDither()
|
|
{
|
|
return Is3DTransparent() &&
|
|
_nbRootItem.PropertyInfoDic.TryGetValue("_AffectsShadows", out ShaderPropertyInfo info) &&
|
|
!info.Property.hasMixedValue &&
|
|
info.Property.floatValue > 0.5f;
|
|
}
|
|
|
|
private void DrawBackFirstPassWarning()
|
|
{
|
|
if (!Is3DTransparent() ||
|
|
!_nbRootItem.PropertyInfoDic.ContainsKey("_BackFirstPassToggle") ||
|
|
_nbRootItem.PropertyInfoDic["_BackFirstPassToggle"].Property.hasMixedValue ||
|
|
_nbRootItem.PropertyInfoDic["_BackFirstPassToggle"].Property.floatValue <= 0.5f)
|
|
{
|
|
return;
|
|
}
|
|
|
|
DrawLayoutHelpBox(
|
|
NBShaderInspectorLocalization.GetInspectorText(
|
|
"base.backFirstPass.warning",
|
|
"预渲染反面会导致打断动态合批,请谨慎使用。"),
|
|
MessageType.Warning);
|
|
}
|
|
|
|
private void OnBackFirstPassChanged(bool enabled)
|
|
{
|
|
_nbRootItem.SyncService.ApplyShaderPass("SRPDefaultUnlit", enabled);
|
|
if (enabled && _nbRootItem.PropertyInfoDic.ContainsKey("_Cull"))
|
|
{
|
|
_nbRootItem.PropertyInfoDic["_Cull"].Property.floatValue = (float)RenderFace.Front;
|
|
}
|
|
}
|
|
|
|
private void OnStencilWithoutPlayerChanged(bool enabled)
|
|
{
|
|
_nbRootItem.SyncService.ApplyStencilPreset(enabled ? "ParticleWithoutPlayer" : "ParticleBaseDefault");
|
|
if (_nbRootItem.PropertyInfoDic.ContainsKey("_CustomStencilTest"))
|
|
{
|
|
_nbRootItem.PropertyInfoDic["_CustomStencilTest"].Property.floatValue = enabled ? 1f : 0f;
|
|
}
|
|
}
|
|
|
|
private static GUIContent Content(string key, string fallback, string tip = "")
|
|
{
|
|
return NBShaderInspectorLocalization.MakeInspectorContent(key, fallback, tip);
|
|
}
|
|
}
|
|
|
|
public class ZTestItem : ShaderGUIPopUpItem
|
|
{
|
|
private static readonly string[] Options = Enum.GetNames(typeof(CompareFunction));
|
|
|
|
public ZTestItem(ShaderGUIRootItem rootItem, ShaderGUIItem parentItem) : base(rootItem, parentItem: parentItem)
|
|
{
|
|
PropertyName = "_ZTest";
|
|
GuiContent = NBShaderInspectorLocalization.MakeInspectorContent("base.ztest", "ZTest");
|
|
PopUpNames = NBShaderInspectorLocalization.GetInspectorOptions("base.ztest", Options);
|
|
InitTriggerByChild();
|
|
}
|
|
|
|
public override void OnGUI()
|
|
{
|
|
if (RootItem is NBShaderRootItem nbRootItem)
|
|
{
|
|
if (nbRootItem.Context.UIEffectEnabled == MixedBool.True)
|
|
{
|
|
if (!Mathf.Approximately(PropertyInfo.Property.floatValue, (float)CompareFunction.LessEqual))
|
|
{
|
|
PropertyInfo.Property.floatValue = (float)CompareFunction.LessEqual;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (nbRootItem.Context.UIEffectEnabled == MixedBool.Mixed)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
base.OnGUI();
|
|
}
|
|
}
|
|
|
|
public class CullModeItem : ShaderGUIPopUpItem
|
|
{
|
|
private static readonly string[] Options = { "Both", "Back", "Front" };
|
|
|
|
public CullModeItem(ShaderGUIRootItem rootItem, ShaderGUIItem parentItem) : base(rootItem, parentItem)
|
|
{
|
|
PropertyName = "_Cull";
|
|
GuiContent = NBShaderInspectorLocalization.MakeInspectorContent("base.cull", "Cull");
|
|
PopUpNames = NBShaderInspectorLocalization.GetInspectorOptions("base.cull", Options);
|
|
InitTriggerByChild();
|
|
}
|
|
|
|
public override void OnGUI()
|
|
{
|
|
base.OnGUI();
|
|
}
|
|
}
|
|
|
|
public class ForceZWriteItem : ShaderGUIPopUpItem
|
|
{
|
|
private static readonly string[] Options = { "Default", "Force On", "Force Off" };
|
|
|
|
public ForceZWriteItem(ShaderGUIRootItem rootItem, ShaderGUIItem parentItem) : base(rootItem, parentItem)
|
|
{
|
|
PropertyName = "_ForceZWriteToggle";
|
|
GuiContent = NBShaderInspectorLocalization.MakeInspectorContent("base.forceZWrite", "Force ZWrite");
|
|
PopUpNames = NBShaderInspectorLocalization.GetInspectorOptions("base.forceZWrite", Options);
|
|
InitTriggerByChild();
|
|
}
|
|
|
|
public override void OnGUI()
|
|
{
|
|
base.OnGUI();
|
|
}
|
|
|
|
public override void OnEndChange()
|
|
{
|
|
base.OnEndChange();
|
|
if (RootItem is NBShaderRootItem nbRootItem)
|
|
{
|
|
nbRootItem.SyncService.SyncMaterialState();
|
|
}
|
|
}
|
|
}
|
|
}
|