This commit is contained in:
SoulliesOfficial
2026-07-17 17:46:16 -04:00
parent b00ac27e3a
commit 40fa80cd70
1178 changed files with 51090 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
using NBShader;
namespace NBShaderEditor
{
internal sealed class ChromaticAberrationFeatureItem : FeatureToggleFoldOutItem
{
public ChromaticAberrationFeatureItem(NBShaderRootItem rootItem, ShaderGUIItem parentItem)
: base(
rootItem,
parentItem,
"_ChromaticAberrationFoldOut",
"_Distortion_Choraticaberrat_Toggle",
"色散",
keyword: "_CHROMATIC_ABERRATION")
{
ShaderGUIItem chromaticNoiseAffect = new NoiseAffectItem(rootItem, this);
new ToggleItem(
rootItem,
chromaticNoiseAffect,
"_Distortion_Choraticaberrat_WithNoise_Toggle",
() => Content("色散强度受扭曲强度影响"),
enabled => rootItem.SyncService.ApplyToggleFlag(NBShaderFlags.FLAG_BIT_PARTICLE_NOISE_CHORATICABERRAT_WITH_NOISE, enabled));
new VectorComponentItem(rootItem, this, "_DistortionDirection", 2, () => Content("色散强度"), false);
new CustomDataSelectItem(rootItem, this, NBShaderFlags.FLAGBIT_POS_0_CUSTOMDATA_CHORATICABERRAT_INTENSITY, 0, () => Content("色散强度自定义曲线"));
InitTriggerByChild();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d0e463cf92ee4725b57727544bc58488
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,29 @@
using System;
using NBShader;
using UnityEditor;
using UnityEngine;
namespace NBShaderEditor
{
internal sealed class ColorBlendFeatureItem : FeatureToggleFoldOutItem
{
private static readonly string[] OnOffNames = { "关闭", "开启" };
public ColorBlendFeatureItem(NBShaderRootItem rootItem, ShaderGUIItem parentItem)
: base(rootItem, parentItem, "_ColorBlendBlockFoldOut", "_ColorBlendMap_Toggle", "渐变(颜色相乘)", keyword: "_COLORMAPBLEND")
{
AddTextureWithWrap(rootItem, this, "_ColorBlendMap", "颜色渐变贴图", NBShaderFlags.FLAG_BIT_WRAPMODE_COLORBLENDMAP, "_ColorBlendColor");
new UVModeSelectItem(rootItem, this, "_ColorBlendUVModeFoldOut", NBShaderFlags.FLAG_BIT_UVMODE_POS_0_COLOR_BLEND_MAP, 0, () => Content("颜色渐变贴图UV来源"), "_ColorBlendMap");
new CustomDataSelectItem(rootItem, this, NBShaderFlags.FLAGBIT_POS_3_CUSTOMDATA_COLOR_BLEND_OFFSET_X, 3, () => Content("颜色渐变贴图X轴偏移自定义曲线"));
new CustomDataSelectItem(rootItem, this, NBShaderFlags.FLAGBIT_POS_3_CUSTOMDATA_COLOR_BLEND_OFFSET_Y, 3, () => Content("颜色渐变贴图Y轴偏移自定义曲线"));
new VectorComponentItem(rootItem, this, "_ColorBlendVec", 3, () => Content("颜色渐变贴图旋转"), true, 0f, 360f);
new Vector2LineItem(rootItem, this, "_ColorBlendMapOffset", true, () => Content("颜色渐变贴图偏移速度"));
ShaderGUIItem colorBlendNoiseAffect = new NoiseAffectItem(rootItem, this);
new VectorComponentItem(rootItem, colorBlendNoiseAffect, "_ColorBlendVec", 0, () => Content("颜色渐变扭曲强度"), true);
new FeaturePopupItem(rootItem, this, "_ColorBlendAlphaMultiplyMode", () => Content("颜色渐变图Alpha作用"), OnOffNames,
property => rootItem.SyncService.ApplyToggleFlag(NBShaderFlags.FLAG_BIT_PARTICLE_COLOR_BLEND_ALPHA_MULTIPLY_MODE, property.floatValue > 0.5f));
new VectorComponentItem(rootItem, this, "_ColorBlendVec", 2, () => Content("颜色渐变图Alpha强度"), true);
InitTriggerByChild();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a4e1e4d5240a4b748b50807573e22ab8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,64 @@
using System;
using NBShader;
using UnityEditor;
using UnityEngine;
namespace NBShaderEditor
{
internal sealed class DepthFeatureItem : ShaderGUIItem
{
public DepthFeatureItem(NBShaderRootItem rootItem, ShaderGUIItem parentItem)
: base(rootItem, parentItem)
{
new DepthOutlineFeatureItem(rootItem, this);
new ToggleItem(
rootItem,
this,
"_DepthDecal_Toggle",
() => FeatureToggleFoldOutItem.Content("深度贴花"),
rootItem.SyncService.ApplyDepthDecalEnabled,
FeatureToggleFoldOutItem.TierVisible(
rootItem,
"_DEPTH_DECAL",
() => rootItem.Context.UIEffectEnabled != MixedBool.True));
InitTriggerByChild();
}
public override void OnGUI()
{
for (int i = 0; i < ChildrenItemList.Count; i++)
{
ChildrenItemList[i].OnGUI();
}
}
public override void CheckIsPropertyModified(bool isCallByChild = false)
{
HasModified = false;
for (int i = 0; i < ChildrenItemList.Count; i++)
{
HasModified |= ChildrenItemList[i].HasModified;
}
ParentItem?.CheckIsPropertyModified(true);
}
}
internal sealed class DepthOutlineFeatureItem : FeatureToggleFoldOutItem
{
public DepthOutlineFeatureItem(NBShaderRootItem rootItem, ShaderGUIItem parentItem)
: base(
rootItem,
parentItem,
"_DepthOutlineBlockFoldOut",
"_DepthOutline_Toggle",
"深度描边",
keyword: "_DEPTH_OUTLINE",
isVisible: () => rootItem.Context.UIEffectEnabled != MixedBool.True)
{
new ColorItem(rootItem, this, "_DepthOutline_Color", () => Content("深度描边颜色"));
new Vector2LineItem(rootItem, this, "_DepthOutline_Vec", true, () => Content("深度描边距离"));
InitTriggerByChild();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0482c5f68e7b4438bc494df4ebf47267
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,83 @@
using System;
using NBShader;
using UnityEditor;
using UnityEngine;
namespace NBShaderEditor
{
internal sealed class DissolveFeatureItem : FeatureToggleFoldOutItem
{
private static readonly string[] RampSourceNames = { "渐变", "贴图" };
private static readonly string[] BlendModeNames = { "叠加", "相乘" };
private static readonly string[] DissolveMaskModeNames = { "Process Dissolve", "Dissolve Mask" };
public DissolveFeatureItem(NBShaderRootItem rootItem, ShaderGUIItem parentItem)
: base(rootItem, parentItem, "_DissolveBlockFoldOut", "_Dissolve_Toggle", "溶解", keyword: "_DISSOLVE")
{
new NBShaderKeywordToggleItem(
rootItem,
this,
"_NB_Debug_Dissolve",
"NB_DEBUG_DISSOLVE",
() => Content("溶解度黑白值测试"),
isVisible: null);
TextureRelatedFoldOutItem dissolveMapRelatedFoldOut = AddTextureWithRelatedFoldOut(rootItem, this, "_DissolveMap", "溶解贴图", "_DissolveMapFoldOut", NBShaderFlags.FLAG_BIT_WRAPMODE_DISSOLVE_MAP);
new ColorChannelSelectItem(rootItem, dissolveMapRelatedFoldOut, NBShaderFlags.FLAG_BIT_COLOR_CHANNEL_POS_0_DISSOLVE_MAP, 0, () => Content("溶解贴图通道选择"));
new CustomDataSelectItem(rootItem, dissolveMapRelatedFoldOut, NBShaderFlags.FLAGBIT_POS_1_CUSTOMDATA_DISSOLVE_OFFSET_X, 1, () => Content("溶解贴图X轴偏移自定义曲线"));
new CustomDataSelectItem(rootItem, dissolveMapRelatedFoldOut, NBShaderFlags.FLAGBIT_POS_1_CUSTOMDATA_DISSOLVE_OFFSET_Y, 1, () => Content("溶解贴图Y轴偏移自定义曲线"));
new UVModeSelectItem(rootItem, dissolveMapRelatedFoldOut, "_DissolveUVModeFoldOut", NBShaderFlags.FLAG_BIT_UVMODE_POS_0_DISSOLVE_MAP, 0, () => Content("溶解贴图UV来源"), "_DissolveMap");
new Vector2LineItem(rootItem, dissolveMapRelatedFoldOut, "_DissolveOffsetRotateDistort", true, () => Content("溶解贴图偏移速度"));
new VectorComponentItem(rootItem, dissolveMapRelatedFoldOut, "_DissolveOffsetRotateDistort", 2, () => Content("溶解贴图旋转"), true, 0f, 360f);
new PNoiseBlendModeItem(rootItem, this, NBShaderFlags.FLAG_BIT_PNOISE_BLEND_POS_0_DISSOLVE, "_DissolvePNoiseBlendOpacity", () => Content("溶解程序噪波混合"),
() => rootItem.Context.ProgramNoiseEnabled == MixedBool.True);
new VectorComponentItem(rootItem, this, "_Dissolve", 1, () => Content("溶解值Pow"), true, 0.001f, 10f);
new VectorComponentRangeSliderItem(rootItem, this, "_Dissolve", 0, "DissolveXRangeVec", () => Content("溶解强度"));
new CustomDataSelectItem(rootItem, this, NBShaderFlags.FLAGBIT_POS_0_CUSTOMDATA_DISSOLVE_INTENSITY, 0, () => Content("溶解强度自定义曲线"));
new VectorComponentItem(rootItem, this, "_Dissolve", 3, () => Content("溶解硬软度"), true, 0.001f, 1f);
ShaderGUIItem dissolveNoiseAffect = new NoiseAffectItem(rootItem, this);
new VectorComponentItem(rootItem, dissolveNoiseAffect, "_DissolveOffsetRotateDistort", 3, () => Content("溶解贴图扭曲强度"), false);
PropertyToggleBlockItem lineBlock = ToggleBlock(rootItem, "_DissolveLineFoldOut", "_DissolveLineMaskToggle", "溶解描边",
NBShaderFlags.FLAG_BIT_PARTICLE_1_DISSOLVE_LINE_MASK, 1, parent: this);
new ColorItem(rootItem, lineBlock, "_DissolveLineColor", () => Content("溶解描边颜色"));
new VectorComponentRangeSliderItem(rootItem, lineBlock, "_Dissolve_Vec2", 0, "Dissolve2XRangeVec", () => Content("描边位置"));
new VectorComponentRangeSliderItem(rootItem, lineBlock, "_Dissolve_Vec2", 1, "Dissolve2YRangeVec", () => Content("描边软硬"));
PropertyToggleBlockItem rampBlock = ToggleBlock(rootItem, "_DissolveRampFoldOut", "_Dissolve_useRampMap_Toggle", "溶解Ramp图功能",
parent: this, keyword: "_DISSOLVE_RAMP",
onValueChanged: _ => rootItem.SyncService.SyncMaterialState());
Func<bool> isDissolveRampMapVisible = TierVisible(rootItem, "_DISSOLVE_RAMP_MAP", () => IsPropertyMode(rootItem, "_DissolveRampSourceMode", 1));
new FeaturePopupItem(rootItem, rampBlock, "_DissolveRampSourceMode", () => Content("溶解Ramp模式"), RampSourceNames,
_ => rootItem.SyncService.SyncMaterialState(),
keyword: "_DISSOLVE_RAMP_MAP");
AddTextureWithWrap(rootItem, rampBlock, "_DissolveRampMap", "溶解Ramp图", NBShaderFlags.FLAG_BIT_WRAPMODE_DISSOLVE_RAMPMAP, "_DissolveRampColor",
isDissolveRampMapVisible);
AddGradient(rootItem, rampBlock, "Ramp颜色", "_DissolveRampCount", "_DissolveRampColor", "_DissolveRampAlpha", hdr: true,
isVisible: () => IsPropertyMode(rootItem, "_DissolveRampSourceMode", 0));
new TextureScaleOffsetItem(rootItem, rampBlock, "_DissolveRampMap", false, () => IsPropertyMode(rootItem, "_DissolveRampSourceMode", 0), TillingContent, OffsetContent);
new ColorItem(rootItem, rampBlock, "_DissolveRampColor", () => Content("Ramp颜色叠加"), () => IsPropertyMode(rootItem, "_DissolveRampSourceMode", 0));
new WrapModeItem(rootItem, rampBlock, NBShaderFlags.FLAG_BIT_WRAPMODE_DISSOLVE_RAMPMAP, () => Content("溶解RampUV Wrap"), 2,
() => IsPropertyMode(rootItem, "_DissolveRampSourceMode", 0));
new FeaturePopupItem(rootItem, rampBlock, "_DissolveRampColorBlendMode", () => Content("溶解Ramp混合模式"), BlendModeNames,
property => rootItem.SyncService.ApplyToggleFlag(NBShaderFlags.FLAG_BIT_PARTICLE_1_DISSOLVE_RAMP_MULITPLY, property.floatValue > 0.5f, 1));
PropertyToggleBlockItem maskBlock = ToggleBlock(rootItem, "_DissolveMaskFoldOut", "_DissolveMask_Toggle", "溶解遮罩图(过程溶解)",
parent: this, keyword: "_DISSOLVE_MASK");
new FeaturePopupItem(rootItem, maskBlock, "_DissolveMaskMode", () => Content("溶解遮罩模式"), DissolveMaskModeNames);
AddTextureWithWrap(rootItem, maskBlock, "_DissolveMaskMap", "溶解遮罩图", NBShaderFlags.FLAG_BIT_WRAPMODE_DISSOLVE_MASKMAP);
new UVModeSelectItem(rootItem, maskBlock, "_DissolveMaskUVModeFoldOut", NBShaderFlags.FLAG_BIT_UVMODE_POS_0_DISSOLVE_MASK_MAP, 0, () => Content("溶解遮罩图UV来源"), "_DissolveMaskMap");
new ColorChannelSelectItem(rootItem, maskBlock, NBShaderFlags.FLAG_BIT_COLOR_CHANNEL_POS_0_DISSOLVE_MASK_MAP, 0, () => Content("溶解遮罩图通道选择"));
new VectorComponentItem(rootItem, maskBlock, "_Dissolve", 2, () => Content("溶解遮罩强度"), false, isVisible: () => !IsDissolveMaskStrengthSlider(rootItem));
new VectorComponentItem(rootItem, maskBlock, "_Dissolve", 2, () => Content("溶解遮罩强度"), true, 0f, 2f, () => IsDissolveMaskStrengthSlider(rootItem));
new CustomDataSelectItem(rootItem, maskBlock, NBShaderFlags.FLAGBIT_POS_1_CUSTOMDATA_DISSOLVE_MASK_INTENSITY, 1, () => Content("溶解遮罩图强度自定义曲线"));
InitTriggerByChild();
}
private static bool IsDissolveMaskStrengthSlider(NBShaderRootItem rootItem)
{
return rootItem.PropertyInfoDic.TryGetValue("_DissolveMaskMode", out ShaderPropertyInfo info) &&
!info.Property.hasMixedValue &&
info.Property.floatValue > 0.5f;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 64cae13520d842939c7d27d6ffadd01d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,42 @@
using System;
using NBShader;
using UnityEditor;
using UnityEngine;
namespace NBShaderEditor
{
internal sealed class EmissionFeatureItem : FeatureToggleFoldOutItem
{
public EmissionFeatureItem(NBShaderRootItem rootItem, ShaderGUIItem parentItem)
: base(rootItem, parentItem, "_EmissionBlockFoldOut", "_EmissionEnabled", "流光(颜色相加)", keyword: "_EMISSION")
{
AddTextureWithWrap(rootItem, this, "_EmissionMap", "流光贴图", NBShaderFlags.FLAG_BIT_WRAPMODE_EMISSIONMAP, "_EmissionMapColor");
new UVModeSelectItem(rootItem, this, "_EmissionUVModeFoldOut", NBShaderFlags.FLAG_BIT_UVMODE_POS_0_EMISSION_MAP, 0, () => Content("流光贴图UV来源"), "_EmissionMap");
new CustomDataSelectItem(rootItem, this, NBShaderFlags.FLAGBIT_POS_3_CUSTOMDATA_EMISSION_OFFSET_X, 3, () => Content("流光贴图X轴偏移自定义曲线"));
new CustomDataSelectItem(rootItem, this, NBShaderFlags.FLAGBIT_POS_3_CUSTOMDATA_EMISSION_OFFSET_Y, 3, () => Content("流光贴图Y轴偏移自定义曲线"));
ShaderGUISliderItem emissionMapUVRotationItem = new ShaderGUISliderItem(rootItem, this)
{
PropertyName = "_EmissionMapUVRotation",
GuiContent = Content("流光贴图旋转"),
Min = 0f,
Max = 360f
};
emissionMapUVRotationItem.InitTriggerByChild();
new Vector2LineItem(rootItem, this, "_EmissionMapUVOffset", true, () => Content("流光贴图偏移速度"));
ShaderGUIItem emissionNoiseAffect = new NoiseAffectItem(rootItem, this);
ShaderGUIFloatItem emissionDistortionIntensityItem = new ShaderGUIFloatItem(rootItem, emissionNoiseAffect)
{
PropertyName = "_Emi_Distortion_intensity",
GuiContent = Content("流光贴图扭曲强度")
};
emissionDistortionIntensityItem.InitTriggerByChild();
ShaderGUIFloatItem emissionMapColorIntensityItem = new ShaderGUIFloatItem(rootItem, this)
{
PropertyName = "_EmissionMapColorIntensity",
GuiContent = Content("流光颜色强度")
};
emissionMapColorIntensityItem.InitTriggerByChild();
InitTriggerByChild();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ed7051253ed04c968aa25e96aa0e5d5d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,175 @@
using System;
using NBShader;
using UnityEditor;
using UnityEngine;
namespace NBShaderEditor
{
internal sealed class NoiseAffectItem : ShaderGUIItem
{
private readonly NBShaderRootItem _nbRootItem;
public NoiseAffectItem(NBShaderRootItem rootItem, ShaderGUIItem parentItem)
: base(rootItem, parentItem)
{
_nbRootItem = rootItem;
}
public override void OnGUI()
{
bool previousMixedValue = EditorGUI.showMixedValue;
bool noiseEnabledHasMixedValue = _nbRootItem.Context.NoiseEnabled == MixedBool.Mixed;
using (new InheritedControlDisabledScope(_nbRootItem.Context.NoiseEnabled == MixedBool.False))
{
for (int i = 0; i < ChildrenItemList.Count; i++)
{
EditorGUI.showMixedValue = noiseEnabledHasMixedValue;
ChildrenItemList[i].OnGUI();
}
}
EditorGUI.showMixedValue = previousMixedValue;
}
public override void CheckIsPropertyModified(bool isCallByChild = false)
{
HasModified = false;
for (int i = 0; i < ChildrenItemList.Count; i++)
{
HasModified |= ChildrenItemList[i].HasModified;
}
ParentItem?.CheckIsPropertyModified(true);
}
}
internal sealed class FlipbookFeatureItem : ToggleItem
{
private readonly NBShaderRootItem _nbRootItem;
public FlipbookFeatureItem(NBShaderRootItem rootItem, ShaderGUIItem parentItem)
: base(
rootItem,
parentItem,
"_FlipbookBlending",
() => FeatureToggleFoldOutItem.Content("序列帧融帧(丝滑)"),
rootItem.SyncService.ApplyFlipbookEnabled)
{
_nbRootItem = rootItem;
}
public override void DrawBlock()
{
if (PropertyInfo.Property.hasMixedValue || PropertyInfo.Property.floatValue <= 0.5f)
{
return;
}
if (_nbRootItem.Context.MeshSourceMode == MeshSourceMode.Particle ||
_nbRootItem.Context.MeshSourceMode == MeshSourceMode.UIParticle)
{
if (HasSpecialUVChannel())
{
using (ParentControlDisabledScope())
{
DrawLayoutHelpBox(
FeatureToggleFoldOutItem.Text(
"feature.flipbook.specialUvWarning.message",
"序列帧融帧和特殊UV通道同时开启粒子序列帧应该影响UV0和UV1两个通道特殊通道只能使用UV3原始UV"),
MessageType.Warning);
}
}
else
{
using (ParentControlDisabledScope())
{
DrawLayoutHelpBox(
FeatureToggleFoldOutItem.Text(
"feature.flipbook.particleInfo.message",
"AnimationSheet的AffectUVChannel需要有UV0和UV1"),
MessageType.Info);
}
}
return;
}
if (_nbRootItem.Context.MeshSourceMode == MeshSourceMode.Mesh)
{
using (ParentControlDisabledScope())
{
DrawLayoutHelpBox(
FeatureToggleFoldOutItem.Text(
"feature.flipbook.meshInfo.message",
"需要添加AnimationSheetHelper脚本"),
MessageType.Info);
}
}
}
private bool HasSpecialUVChannel()
{
for (int i = 0; i < _nbRootItem.ShaderFlags.Count; i++)
{
if (_nbRootItem.ShaderFlags[i] is NBShaderFlags flags &&
flags.CheckIsUVModeOn(NBShaderFlags.UVMode.SpecialUVChannel))
{
return true;
}
}
return false;
}
}
internal sealed class VatFrameCustomDataItem : CustomDataSelectItem
{
private readonly Func<bool> _isVisible;
private readonly Func<bool> _anyVatFrameCustomDataVisible;
public VatFrameCustomDataItem(
NBShaderRootItem rootItem,
ShaderGUIItem parentItem,
Func<GUIContent> contentProvider,
Func<bool> isVisible,
Func<bool> anyVatFrameCustomDataVisible)
: base(rootItem, parentItem, NBShaderFlags.FLAGBIT_POS_2_CUSTOMDATA_VAT_FRAME, 2, contentProvider)
{
_isVisible = isVisible;
_anyVatFrameCustomDataVisible = anyVatFrameCustomDataVisible;
}
public override void OnGUI()
{
if (_isVisible != null && !_isVisible())
{
if (_anyVatFrameCustomDataVisible == null || !_anyVatFrameCustomDataVisible())
{
ClearVatFrameCustomData();
}
return;
}
base.OnGUI();
}
private void ClearVatFrameCustomData()
{
for (int i = 0; i < RootItem.ShaderFlags.Count; i++)
{
if (RootItem.ShaderFlags[i] is NBShaderFlags flags && flags.material != null)
{
if (flags.GetCustomDataFlag(NBShaderFlags.FLAGBIT_POS_2_CUSTOMDATA_VAT_FRAME, 2) !=
NBShaderFlags.CutomDataComponent.Off)
{
flags.SetCustomDataFlag(
NBShaderFlags.CutomDataComponent.Off,
NBShaderFlags.FLAGBIT_POS_2_CUSTOMDATA_VAT_FRAME,
2);
}
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2c8170a5849c4a5abf332cdf3832fa02
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,276 @@
using System;
using System.Collections.Generic;
using NBShader;
using UnityEditor;
using UnityEngine;
namespace NBShaderEditor
{
internal abstract class FeatureToggleFoldOutItem : PropertyToggleBlockItem
{
private const string LocalizationTableName = NBShaderInspectorLocalization.TableName;
private static readonly Dictionary<string, GUIContent> ContentCache =
new Dictionary<string, GUIContent>(StringComparer.Ordinal);
private static readonly Dictionary<string, string[]> PopupOptionsCache =
new Dictionary<string, string[]>(StringComparer.Ordinal);
private static string s_CacheLanguage;
protected FeatureToggleFoldOutItem(
NBShaderRootItem rootItem,
ShaderGUIItem parentItem,
string foldOutPropertyName,
string togglePropertyName,
string label,
int flagBits = 0,
int flagIndex = 0,
string keyword = null,
Action<bool> onValueChanged = null,
Func<bool> isVisible = null,
bool bold = true)
: base(
rootItem,
parentItem,
foldOutPropertyName,
togglePropertyName,
() => Content(label),
flagBits,
flagIndex,
keyword,
onValueChanged: onValueChanged,
isVisible: isVisible,
bold: bold)
{
}
protected TextureRelatedFoldOutItem AddTextureWithRelatedFoldOut(
NBShaderRootItem rootItem,
ShaderGUIItem parent,
string texturePropertyName,
string label,
string foldOutPropertyName,
int wrapFlag,
string colorPropertyName = null,
Func<bool> isVisible = null)
{
new TextureItem(
rootItem,
parent,
texturePropertyName,
() => Content(label),
colorPropertyName,
isVisible: isVisible,
tillingContentProvider: TillingContent,
offsetContentProvider: OffsetContent);
TextureRelatedFoldOutItem relatedFoldOut = new TextureRelatedFoldOutItem(
rootItem,
parent,
foldOutPropertyName,
texturePropertyName,
() => Content(label + "相关功能"),
isVisible);
new WrapModeItem(rootItem, relatedFoldOut, wrapFlag, () => Content(label + " Wrap"), 2);
return relatedFoldOut;
}
protected void AddTextureWithWrap(
NBShaderRootItem rootItem,
ShaderGUIItem parent,
string texturePropertyName,
string label,
int wrapFlag,
string colorPropertyName = null,
Func<bool> isVisible = null)
{
new TextureItem(
rootItem,
parent,
texturePropertyName,
() => Content(label),
colorPropertyName,
isVisible: isVisible,
tillingContentProvider: TillingContent,
offsetContentProvider: OffsetContent);
new WrapModeItem(rootItem, parent, wrapFlag, () => Content(label + " Wrap"), 2, isVisible);
}
protected PropertyToggleBlockItem ToggleBlock(
NBShaderRootItem rootItem,
string foldOutPropertyName,
string togglePropertyName,
string label,
int flagBits = 0,
int flagIndex = 0,
ShaderGUIItem parent = null,
string keyword = null,
Action<bool> onValueChanged = null,
Func<bool> isVisible = null,
bool bold = false)
{
return new PropertyToggleBlockItem(
rootItem,
parent ?? this,
foldOutPropertyName,
togglePropertyName,
() => Content(label),
flagBits,
flagIndex,
keyword,
onValueChanged: onValueChanged,
isVisible: isVisible,
bold: bold);
}
protected static void AddGradient(
NBShaderRootItem rootItem,
ShaderGUIItem parent,
string label,
string countPropertyName,
string colorPrefix,
string alphaPrefix,
bool hdr = false,
Func<bool> isVisible = null)
{
new GradientItem(
rootItem,
parent,
countPropertyName,
6,
BuildPropertyNames(colorPrefix, 6),
BuildPropertyNames(alphaPrefix, 3),
() => Content(label),
hdr,
ColorSpace.Gamma,
isVisible);
}
protected static string[] BuildPropertyNames(string prefix, int count)
{
string[] names = new string[count];
for (int i = 0; i < count; i++)
{
names[i] = prefix + i;
}
return names;
}
protected static bool IsPropertyMode(NBShaderRootItem rootItem, string propertyName, int expectedMode)
{
return rootItem.PropertyInfoDic.TryGetValue(propertyName, out ShaderPropertyInfo info) &&
!info.Property.hasMixedValue &&
Mathf.RoundToInt(info.Property.floatValue) == expectedMode;
}
protected static bool IsPropertyMode(NBShaderRootItem rootItem, string propertyName, params int[] expectedModes)
{
if (!rootItem.PropertyInfoDic.TryGetValue(propertyName, out ShaderPropertyInfo info) ||
info.Property.hasMixedValue)
{
return false;
}
int value = Mathf.RoundToInt(info.Property.floatValue);
for (int i = 0; i < expectedModes.Length; i++)
{
if (value == expectedModes[i])
{
return true;
}
}
return false;
}
internal static GUIContent Content(string label)
{
EnsureCacheLanguage();
if (ContentCache.TryGetValue(label, out GUIContent cachedContent))
{
return cachedContent;
}
cachedContent = NBShaderInspectorLocalization.MakeInspectorContent("feature." + label, label);
ContentCache[label] = cachedContent;
return cachedContent;
}
protected static GUIContent TillingContent()
{
return LocalizedInspectorContent(LocalizationTableName, "common.tilling", "Tilling");
}
protected static GUIContent OffsetContent()
{
return LocalizedInspectorContent(LocalizationTableName, "common.offset", "Offset");
}
internal static string Text(string key, string fallback)
{
return LocalizedText(LocalizationTableName, key, fallback);
}
internal static string[] PopupOptions(string propertyName, string[] fallback)
{
EnsureCacheLanguage();
if (PopupOptionsCache.TryGetValue(propertyName, out string[] cachedOptions))
{
return cachedOptions;
}
cachedOptions = NBShaderInspectorLocalization.GetInspectorOptions("feature.popup." + propertyName, fallback);
PopupOptionsCache[propertyName] = cachedOptions;
return cachedOptions;
}
private static void EnsureCacheLanguage()
{
string currentLanguage = NBShaderInspectorLocalization.CurrentLanguage;
if (string.Equals(s_CacheLanguage, currentLanguage, StringComparison.Ordinal))
{
return;
}
s_CacheLanguage = currentLanguage;
ContentCache.Clear();
PopupOptionsCache.Clear();
}
internal static bool IsTierKeywordAllowed(NBShaderRootItem rootItem, string keyword)
{
return string.IsNullOrEmpty(keyword) ||
rootItem == null ||
rootItem.Context == null ||
rootItem.Context.IsKeywordAllowed(keyword);
}
internal static Func<bool> TierVisible(NBShaderRootItem rootItem, string keyword, Func<bool> isVisible = null)
{
return () => IsTierKeywordAllowed(rootItem, keyword) && (isVisible == null || isVisible());
}
}
internal sealed class FeaturePopupItem : ShaderGUIPopUpItem
{
public FeaturePopupItem(
ShaderGUIRootItem rootItem,
ShaderGUIItem parentItem,
string propertyName,
Func<GUIContent> contentProvider,
string[] popupNames,
Action<MaterialProperty> onValueChanged = null,
Func<bool> isVisible = null,
string keyword = null)
: base(
rootItem,
parentItem,
propertyName,
contentProvider,
() => FeatureToggleFoldOutItem.PopupOptions(propertyName, popupNames),
onValueChanged,
string.IsNullOrEmpty(keyword)
? isVisible
: FeatureToggleFoldOutItem.TierVisible(rootItem as NBShaderRootItem, keyword, isVisible))
{
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 355bed04b23c4ea093ad45991f0004a4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,50 @@
using System;
using NBShader;
using UnityEditor;
using UnityEngine;
namespace NBShaderEditor
{
internal sealed class FresnelFeatureItem : FeatureToggleFoldOutItem
{
private static readonly string[] FresnelModeNames = { "颜色", "透明" };
public FresnelFeatureItem(NBShaderRootItem rootItem, ShaderGUIItem parentItem)
: base(rootItem, parentItem, "_FresnelBlockFoldOut", "_fresnelEnabled", "菲涅尔", keyword: "_FRESNEL")
{
new NBShaderKeywordToggleItem(
rootItem,
this,
"_NB_Debug_Fresnel",
"NB_DEBUG_FRESNEL",
() => Content("菲涅尔测试颜色"),
isVisible: null);
new FeaturePopupItem(rootItem, this, "_FresnelMode", () => Content("菲涅尔模式"), FresnelModeNames,
property => rootItem.SyncService.ApplyToggleFlag(NBShaderFlags.FLAG_BIT_PARTICLE_FRESNEL_FADE_ON, property.floatValue > 0.5f));
Func<bool> isFresnelColorMode = () => IsPropertyMode(rootItem, "_FresnelMode", 0);
new ColorItem(rootItem, this, "_FresnelColor", () => Content("菲涅尔颜色"), isFresnelColorMode);
new VectorComponentItem(rootItem, this, "_FresnelUnit", 2, () => Content("菲涅尔强度"), true);
new VectorComponentItem(rootItem, this, "_FresnelUnit", 0, () => Content("菲涅尔位置"), true, -1f, 1f);
new CustomDataSelectItem(rootItem, this, NBShaderFlags.FLAGBIT_POS_0_CUSTOMDATA_FRESNEL_OFFSET, 0, () => Content("菲涅尔位置自定义曲线"));
new VectorComponentItem(rootItem, this, "_FresnelUnit", 1, () => Content("菲涅尔范围Pow"), true, 0f, 10f);
new VectorComponentItem(rootItem, this, "_FresnelUnit", 3, () => Content("菲涅尔硬度"), true);
new ToggleItem(
rootItem,
this,
"_InvertFresnel_Toggle",
() => Content("翻转菲涅尔"),
enabled => rootItem.SyncService.ApplyToggleFlag(NBShaderFlags.FLAG_BIT_PARTICLE_FRESNEL_INVERT_ON, enabled));
new ToggleItem(
rootItem,
this,
"_FresnelColorAffectByAlpha",
() => Content("菲涅尔颜色受Alpha影响"),
enabled => rootItem.SyncService.ApplyToggleFlag(NBShaderFlags.FLAG_BIT_PARTICLE_FRESNEL_COLOR_AFFETCT_BY_ALPHA, enabled),
isFresnelColorMode);
new VectorComponentItem(rootItem, this, "_FresnelRotation", 0, () => Content("菲涅尔方向偏移X"), false);
new VectorComponentItem(rootItem, this, "_FresnelRotation", 1, () => Content("菲涅尔方向偏移Y"), false);
new VectorComponentItem(rootItem, this, "_FresnelRotation", 2, () => Content("菲涅尔方向偏移Z"), false);
InitTriggerByChild();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ee140beb49b74735960d38a89bd528fd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,171 @@
using System;
using NBShader;
using UnityEditor;
using UnityEngine;
namespace NBShaderEditor
{
internal sealed class MaskFeatureItem : FeatureToggleFoldOutItem
{
private static readonly string[] TextureGradientNames = { "贴图", "渐变" };
public MaskFeatureItem(NBShaderRootItem rootItem, ShaderGUIItem parentItem)
: base(rootItem, parentItem, "_MaskBlockFoldOut", "_Mask_Toggle", "遮罩", keyword: "_MASKMAP_ON")
{
new NBShaderKeywordToggleItem(
rootItem,
this,
"_NB_Debug_Mask",
"NB_DEBUG_MASK",
() => Content("测试遮罩颜色"),
isVisible: null);
new VectorComponentItem(rootItem, this, "_MaskMapVec", 0, () => Content("遮罩强度"), true);
PropertyToggleBlockItem refineBlock = ToggleBlock(
rootItem,
"_MaskRefineFoldOut",
"_MaskRefineToggle",
"遮罩整体调整",
NBShaderFlags.FLAG_BIT_PARTICLE_1_MASK_REFINE,
1,
parent: this);
new VectorComponentItem(rootItem, refineBlock, "_MaskRefineVec", 0, () => Content("范围(Pow)"), false);
new VectorComponentItem(rootItem, refineBlock, "_MaskRefineVec", 1, () => Content("相乘"), false);
new VectorComponentItem(rootItem, refineBlock, "_MaskRefineVec", 2, () => Content("偏移(相加)"), false);
new PNoiseBlendModeItem(rootItem, this, NBShaderFlags.FLAG_BIT_PNOISE_BLEND_POS_0_MASK, "_MaskPNoiseBlendOpacity", () => Content("遮罩程序噪波混合"),
() => rootItem.Context.ProgramNoiseEnabled == MixedBool.True);
AddMaskMap(rootItem, this, "_MaskMap", "_MaskMapGradientToggle", "_MaskUVModeFoldOut", "遮罩",
NBShaderFlags.FLAG_BIT_WRAPMODE_MASKMAP,
NBShaderFlags.FLAG_BIT_COLOR_CHANNEL_POS_0_MASKMAP1,
NBShaderFlags.FLAG_BIT_UVMODE_POS_0_MASKMAP,
NBShaderFlags.FLAG_BIT_PARTICLE_1_MASKMAP_GRADIENT,
1,
"_MaskMapFoldOut");
new CustomDataSelectItem(rootItem, this, NBShaderFlags.FLAGBIT_POS_0_CUSTOMDATA_MASK_OFFSET_X, 0, () => Content("Mask图X轴偏移自定义曲线"));
new CustomDataSelectItem(rootItem, this, NBShaderFlags.FLAGBIT_POS_0_CUSTOMDATA_MASK_OFFSET_Y, 0, () => Content("Mask图Y轴偏移自定义曲线"));
new Vector2LineItem(rootItem, this, "_MaskMapOffsetAnition", true, () => Content("遮罩偏移速度"));
ShaderGUISliderItem maskMapUVRotationItem = new ShaderGUISliderItem(rootItem, this)
{
PropertyName = "_MaskMapUVRotation",
GuiContent = Content("遮罩旋转"),
Min = 0f,
Max = 360f
};
maskMapUVRotationItem.InitTriggerByChild();
PropertyToggleBlockItem rotateBlock = ToggleBlock(
rootItem,
"_MaskRotationFoldOut",
"_Mask_RotationToggle",
"遮罩旋转速度",
NBShaderFlags.FLAG_BIT_PARTILCE_MASKMAPROTATIONANIMATION_ON,
parent: this);
ShaderGUIFloatItem maskMapRotationSpeedItem = new ShaderGUIFloatItem(rootItem, rotateBlock)
{
PropertyName = "_MaskMapRotationSpeed",
GuiContent = Content("旋转速度")
};
maskMapRotationSpeedItem.InitTriggerByChild();
ShaderGUIItem maskNoiseAffect = new NoiseAffectItem(rootItem, this);
ShaderGUISliderItem maskDistortionIntensityItem = new ShaderGUISliderItem(rootItem, maskNoiseAffect)
{
PropertyName = "_MaskDistortion_intensity",
GuiContent = Content("遮罩扭曲强度"),
RangePropertyName = "MaskDistortionIntensityRangeVec"
};
maskDistortionIntensityItem.InitTriggerByChild();
PropertyToggleBlockItem mask2Block = ToggleBlock(
rootItem,
"_Mask2BlockFoldOut",
"_Mask2_Toggle",
"遮罩2",
parent: this,
keyword: "_MASKMAP2_ON");
AddMaskMap(rootItem, mask2Block, "_MaskMap2", "_MaskMap2GradientToggle", "_Mask2UVModeFoldOut", "遮罩2",
NBShaderFlags.FLAG_BIT_WRAPMODE_MASKMAP2,
NBShaderFlags.FLAG_BIT_COLOR_CHANNEL_POS_0_MASKMAP2,
NBShaderFlags.FLAG_BIT_UVMODE_POS_0_MASKMAP_2,
NBShaderFlags.FLAG_BIT_PARTICLE_1_MASKMAP_2_GRADIENT,
1);
new VectorComponentItem(rootItem, mask2Block, "_MaskMapVec", 1, () => Content("遮罩2旋转"), false);
new Vector2LineItem(rootItem, mask2Block, "_MaskMapOffsetAnition", false, () => Content("遮罩2偏移速度"));
PropertyToggleBlockItem mask3Block = ToggleBlock(
rootItem,
"_Mask3BlockFoldOut",
"_Mask3_Toggle",
"遮罩3",
parent: this,
keyword: "_MASKMAP3_ON");
AddMaskMap(rootItem, mask3Block, "_MaskMap3", "_MaskMap3GradientToggle", "_Mask3UVModeFoldOut", "遮罩3",
NBShaderFlags.FLAG_BIT_WRAPMODE_MASKMAP3,
NBShaderFlags.FLAG_BIT_COLOR_CHANNEL_POS_0_MASKMAP3,
NBShaderFlags.FLAG_BIT_UVMODE_POS_0_MASKMAP_3,
NBShaderFlags.FLAG_BIT_PARTICLE_1_MASKMAP_3_GRADIENT,
1);
new VectorComponentItem(rootItem, mask3Block, "_MaskMapVec", 2, () => Content("遮罩3旋转"), false);
new Vector2LineItem(rootItem, mask3Block, "_MaskMap3OffsetAnition", true, () => Content("遮罩3偏移速度"));
InitTriggerByChild();
}
private void AddMaskMap(
NBShaderRootItem rootItem,
ShaderGUIItem parent,
string texturePropertyName,
string modePropertyName,
string uvFoldOutPropertyName,
string label,
int wrapFlag,
int colorChannelFlagPos,
int uvModeFlagPos,
int gradientFlag,
int gradientFlagIndex,
string textureFoldOutPropertyName = null)
{
new FeaturePopupItem(rootItem, parent, modePropertyName, () => Content(label + "模式"), TextureGradientNames,
property => rootItem.SyncService.ApplyToggleFlag(gradientFlag, property.floatValue > 0.5f, gradientFlagIndex));
ShaderGUIItem textureParent = parent;
if (string.IsNullOrEmpty(textureFoldOutPropertyName))
{
AddTextureWithWrap(rootItem, parent, texturePropertyName, label + "贴图", wrapFlag,
isVisible: () => IsPropertyMode(rootItem, modePropertyName, 0));
}
else
{
textureParent = AddTextureWithRelatedFoldOut(rootItem, parent, texturePropertyName, label + "贴图", textureFoldOutPropertyName, wrapFlag,
isVisible: () => IsPropertyMode(rootItem, modePropertyName, 0));
}
new ColorChannelSelectItem(rootItem, textureParent, colorChannelFlagPos, 0, () => Content(label + "通道选择"),
() => IsPropertyMode(rootItem, modePropertyName, 0));
AddAlphaGradient(rootItem, parent, label + "渐变", texturePropertyName + "GradientCount", texturePropertyName + "GradientFloat",
() => IsPropertyMode(rootItem, modePropertyName, 1));
new TextureScaleOffsetItem(rootItem, parent, texturePropertyName, false, () => IsPropertyMode(rootItem, modePropertyName, 1), TillingContent, OffsetContent);
new WrapModeItem(rootItem, parent, wrapFlag, () => Content(label + "UV Wrap"), 2,
() => IsPropertyMode(rootItem, modePropertyName, 1));
new UVModeSelectItem(rootItem, parent, uvFoldOutPropertyName, uvModeFlagPos, 0, () => Content(label + "UV来源"), texturePropertyName, forceEnable: true);
}
private static void AddAlphaGradient(
NBShaderRootItem rootItem,
ShaderGUIItem parent,
string label,
string countPropertyName,
string alphaPrefix,
Func<bool> isVisible = null)
{
new GradientItem(
rootItem,
parent,
countPropertyName,
6,
Array.Empty<string>(),
BuildPropertyNames(alphaPrefix, 3),
() => Content(label),
false,
ColorSpace.Gamma,
isVisible);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c5fe236301944650a35adc509015737c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,519 @@
using System;
using System.Reflection;
using NBShader;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
namespace NBShaderEditor
{
internal sealed class NoiseAndDistortFeatureItem : FeatureToggleFoldOutItem
{
private static readonly string[] DistortModeNames = { "FlowMap/RG贴图", "折射率" };
private static readonly string[] ScreenDistortModeNames = { "No Screen Distort", "Deferred Distort", "Camera Opaque Distort" };
private const int ScreenDistortModeDeferred = 1;
private const int ScreenDistortModeCameraOpaque = 2;
private const string ScreenDistortKeyword = "_SCREEN_DISTORT_MODE";
private const string ScreenDistortModePropertyName = "_ScreenDistortModeToggle";
private const string RendererDataListPropertyName = "m_RendererDataList";
private const string LegacyRendererDataPropertyName = "m_RendererData";
private const string RendererFeaturesPropertyName = "m_RendererFeatures";
private const string OpaqueTexturePropertyName = "supportsCameraOpaqueTexture";
private const string OpaqueTextureSerializedPropertyName = "m_RequireOpaqueTexture";
private const string RendererFeatureActivePropertyName = "isActive";
private const string RendererFeatureActiveSerializedPropertyName = "m_Active";
private const string NBPostProcessTypeFullName = "NBShader.NBPostProcess";
private const string NBPostProcessTypeName = "NBPostProcess";
public NoiseAndDistortFeatureItem(NBShaderRootItem rootItem, ShaderGUIItem parentItem)
: base(rootItem, parentItem, "_NoiseBlockFoldOut", "_noisemapEnabled", "扭曲", keyword: "_NOISEMAP")
{
new NBShaderKeywordToggleItem(
rootItem,
this,
"_NB_Debug_Distort",
"NB_DEBUG_DISTORT",
() => Content("扭曲强度值测试"),
isVisible: null);
ShaderGUISliderItem noiseIntensityItem = new ShaderGUISliderItem(rootItem, this)
{
PropertyName = "_NoiseIntensity",
GuiContent = Content("整体扭曲强度"),
RangePropertyName = "_NoiseIntensityRangeVec"
};
noiseIntensityItem.InitTriggerByChild();
new CustomDataSelectItem(rootItem, this, NBShaderFlags.FLAGBIT_POS_1_CUSTOMDATA_NOISE_INTENSITY, 1, () => Content("扭曲强度自定义曲线"));
new FeaturePopupItem(rootItem, this, "_ScreenDistortModeToggle", () => Content("屏幕扰动模式"), ScreenDistortModeNames,
property => rootItem.SyncService.ApplyScreenDistortMode(Mathf.RoundToInt(property.floatValue)),
() => rootItem.Context.UIEffectEnabled != MixedBool.True,
ScreenDistortKeyword);
Func<bool> isDeferredDistortVisible = TierVisible(
rootItem,
ScreenDistortKeyword,
() => IsScreenDistortMode(rootItem, ScreenDistortModeDeferred));
Func<bool> isCameraOpaqueDistortVisible = TierVisible(
rootItem,
ScreenDistortKeyword,
() => IsScreenDistortMode(rootItem, ScreenDistortModeCameraOpaque));
Func<bool> isScreenDistortModeNeedsNBPostProcessVisible = () => isDeferredDistortVisible() || isCameraOpaqueDistortVisible();
Func<bool> isMissingNBPostProcessVisible = () => isScreenDistortModeNeedsNBPostProcessVisible() && !HasActiveNBPostProcessRendererFeature();
Func<bool> isMissingOpaqueTextureVisible = () => isCameraOpaqueDistortVisible() && !HasCameraOpaqueTextureCopyEnabled();
new PingableHelpBoxItem(
rootItem,
this,
() => Text(
"feature.screenDistort.missingNbPostProcess.message",
"Screen Distort requires an active NB Post Process Feature on at least one RendererData in the current URP Pipeline Asset."),
MessageType.Warning,
() => ButtonContent("feature.screenDistort.pingRendererData", "Ping Renderer"),
GetRendererDataForNBPostProcessPing,
isMissingNBPostProcessVisible);
new PingableHelpBoxItem(
rootItem,
this,
() => Text(
"feature.screenDistort.missingOpaqueTextureCopy.message",
"Camera Opaque Distort requires Opaque Texture to be enabled on the current URP Pipeline Asset."),
MessageType.Warning,
() => ButtonContent("feature.screenDistort.pingPipelineAsset", "Ping URP Asset"),
GetCurrentRenderPipelineAsset,
isMissingOpaqueTextureVisible);
ShaderGUISliderItem screenDistortIntensityItem = new ShaderGUISliderItem(
rootItem,
this,
TierVisible(
rootItem,
ScreenDistortKeyword,
() => rootItem.Context.UIEffectEnabled != MixedBool.True && IsPropertyGreater(rootItem, "_ScreenDistortModeToggle", 0.5f)))
{
PropertyName = "_ScreenDistortIntensity",
GuiContent = Content("屏幕扭曲强度"),
RangePropertyName = "_ScreenDistortIntensityRangeVec"
};
screenDistortIntensityItem.InitTriggerByChild();
new ToggleItem(
rootItem,
this,
"_DisableMainPassToggle",
() => Content("关闭主材质Pass"),
enabled =>
{
rootItem.SyncService.ApplyScreenDistortMode(GetIntProperty(rootItem, "_ScreenDistortModeToggle"));
},
TierVisible(
rootItem,
ScreenDistortKeyword,
() => rootItem.Context.UIEffectEnabled != MixedBool.True && IsPropertyGreater(rootItem, "_ScreenDistortModeToggle", 0.5f)));
PropertyToggleBlockItem screenAlphaBlock = ToggleBlock(
rootItem,
"_ScreenDistortAlphaFoldOut",
"_ScreenDistortAlphaRefineToggle",
"屏幕扭曲Alpha整体调整",
NBShaderFlags.FLAG_BIT_PARTICLE_1_SCREEN_DISTORT_ALPHA_REFINE,
1,
parent: this,
isVisible: TierVisible(
rootItem,
ScreenDistortKeyword,
() => rootItem.Context.UIEffectEnabled != MixedBool.True && IsPropertyGreater(rootItem, "_ScreenDistortModeToggle", 0.5f)));
ShaderGUIFloatItem screenDistortAlphaPowItem = new ShaderGUIFloatItem(rootItem, screenAlphaBlock)
{
PropertyName = "_ScreenDistortAlphaPow",
GuiContent = Content("范围(Pow)")
};
screenDistortAlphaPowItem.InitTriggerByChild();
ShaderGUIFloatItem screenDistortAlphaMultiItem = new ShaderGUIFloatItem(rootItem, screenAlphaBlock)
{
PropertyName = "_ScreenDistortAlphaMulti",
GuiContent = Content("相乘")
};
screenDistortAlphaMultiItem.InitTriggerByChild();
ShaderGUIFloatItem screenDistortAlphaAddItem = new ShaderGUIFloatItem(rootItem, screenAlphaBlock)
{
PropertyName = "_ScreenDistortAlphaAdd",
GuiContent = Content("偏移(相加)")
};
screenDistortAlphaAddItem.InitTriggerByChild();
new FeaturePopupItem(rootItem, this, "_DistortMode", () => Content("扭曲模式"), DistortModeNames,
property => rootItem.SyncService.ApplyToggleKeyword("_DISTORT_REFRACTION", property.floatValue > 0.5f),
keyword: "_DISTORT_REFRACTION");
TextureRelatedFoldOutItem noiseMapRelatedFoldOut = AddTextureWithRelatedFoldOut(rootItem, this, "_NoiseMap", "扭曲贴图", "_NoiseMapFoldOut", NBShaderFlags.FLAG_BIT_WRAPMODE_NOISEMAP,
isVisible: () => IsPropertyMode(rootItem, "_DistortMode", 0));
new UVModeSelectItem(rootItem, noiseMapRelatedFoldOut, "_NoiseUVModeFoldOut", NBShaderFlags.FLAG_BIT_UVMODE_POS_0_NOISE_MAP, 0, () => Content("扭曲贴图UV来源"), "_NoiseMap",
isVisible: () => IsPropertyMode(rootItem, "_DistortMode", 0));
new Vector2LineItem(rootItem, noiseMapRelatedFoldOut, "_DistortionDirection", true, () => Content("扭曲方向强度"), () => IsPropertyMode(rootItem, "_DistortMode", 0));
new CustomDataSelectItem(rootItem, noiseMapRelatedFoldOut, NBShaderFlags.FLAGBIT_POS_2_CUSTOMDATA_NOISE_DIRECTION_X, 2, () => Content("扭曲方向强度X自定义曲线"), () => IsPropertyMode(rootItem, "_DistortMode", 0));
new CustomDataSelectItem(rootItem, noiseMapRelatedFoldOut, NBShaderFlags.FLAGBIT_POS_2_CUSTOMDATA_NOISE_DIRECTION_Y, 2, () => Content("扭曲方向强度Y自定义曲线"), () => IsPropertyMode(rootItem, "_DistortMode", 0));
ShaderGUISliderItem noiseMapUVRotationItem = new ShaderGUISliderItem(rootItem, noiseMapRelatedFoldOut, () => IsPropertyMode(rootItem, "_DistortMode", 0))
{
PropertyName = "_NoiseMapUVRotation",
GuiContent = Content("扭曲旋转"),
Min = 0f,
Max = 360f
};
noiseMapUVRotationItem.InitTriggerByChild();
new Vector2LineItem(rootItem, noiseMapRelatedFoldOut, "_NoiseOffset", true, () => Content("扭曲偏移速度"), () => IsPropertyMode(rootItem, "_DistortMode", 0));
new ToggleItem(
rootItem,
noiseMapRelatedFoldOut,
"_DistortionBothDirection_Toggle",
() => Content("0.5为中值,双向扭曲"),
enabled => rootItem.SyncService.ApplyToggleFlag(NBShaderFlags.FLAG_BIT_PARTICLE_NOISEMAP_NORMALIZEED_ON, enabled),
() => IsPropertyMode(rootItem, "_DistortMode", 0));
ShaderGUISliderItem refractionIorItem = new ShaderGUISliderItem(
rootItem,
this,
TierVisible(rootItem, "_DISTORT_REFRACTION", () => IsPropertyMode(rootItem, "_DistortMode", 1)))
{
PropertyName = "_RefractionIOR",
GuiContent = Content("折射率"),
Min = 0f,
Max = 5f
};
refractionIorItem.InitTriggerByChild();
new PNoiseBlendModeItem(rootItem, this, NBShaderFlags.FLAG_BIT_PNOISE_BLEND_POS_0_DISTORT, "_DistortPNoiseBlendOpacity", () => Content("扭曲程序噪波混合"),
() => rootItem.Context.ProgramNoiseEnabled == MixedBool.True);
PropertyToggleBlockItem noiseMaskBlock = ToggleBlock(
rootItem,
"_NoiseMaskBlockFoldOut",
"_noiseMaskMap_Toggle",
"扭曲遮罩",
parent: this,
keyword: "_NOISE_MASKMAP");
AddTextureWithWrap(rootItem, noiseMaskBlock, "_NoiseMaskMap", "扭曲遮罩贴图", NBShaderFlags.FLAG_BIT_WRAPMODE_NOISE_MASKMAP);
new ColorChannelSelectItem(rootItem, noiseMaskBlock, NBShaderFlags.FLAG_BIT_COLOR_CHANNEL_POS_0_NOISE_MASK, 0, () => Content("扭曲遮罩图通道选择"));
new UVModeSelectItem(rootItem, noiseMaskBlock, "_NoiseMaskUVModeFoldOut", NBShaderFlags.FLAG_BIT_UVMODE_POS_0_NOISE_MASK_MAP, 0, () => Content("扭曲遮罩贴图UV来源"), "_NoiseMaskMap");
InitTriggerByChild();
}
private static int GetIntProperty(NBShaderRootItem rootItem, string propertyName)
{
return rootItem.PropertyInfoDic.TryGetValue(propertyName, out ShaderPropertyInfo info) && !info.Property.hasMixedValue
? Mathf.RoundToInt(info.Property.floatValue)
: 0;
}
private static bool IsPropertyGreater(NBShaderRootItem rootItem, string propertyName, float threshold)
{
return rootItem.PropertyInfoDic.TryGetValue(propertyName, out ShaderPropertyInfo info) &&
!info.Property.hasMixedValue &&
info.Property.floatValue > threshold;
}
private static bool IsScreenDistortMode(NBShaderRootItem rootItem, int mode)
{
return rootItem.Context.UIEffectEnabled != MixedBool.True &&
IsPropertyMode(rootItem, ScreenDistortModePropertyName, mode);
}
private static bool HasActiveNBPostProcessRendererFeature()
{
try
{
RenderPipelineAsset pipelineAsset = GetCurrentRenderPipelineAsset();
if (pipelineAsset == null)
{
return false;
}
SerializedObject pipelineObject = new SerializedObject(pipelineAsset);
SerializedProperty rendererDataList = pipelineObject.FindProperty(RendererDataListPropertyName);
if (rendererDataList != null && rendererDataList.isArray)
{
for (int i = 0; i < rendererDataList.arraySize; i++)
{
UnityEngine.Object rendererData = rendererDataList.GetArrayElementAtIndex(i).objectReferenceValue;
if (RendererDataHasNBPostProcess(rendererData, requireActive: true))
{
return true;
}
}
return false;
}
SerializedProperty legacyRendererData = pipelineObject.FindProperty(LegacyRendererDataPropertyName);
return legacyRendererData != null && RendererDataHasNBPostProcess(legacyRendererData.objectReferenceValue, requireActive: true);
}
catch (Exception)
{
return false;
}
}
private static bool RendererDataHasNBPostProcess(UnityEngine.Object rendererData, bool requireActive)
{
if (rendererData == null)
{
return false;
}
SerializedObject rendererDataObject = new SerializedObject(rendererData);
SerializedProperty rendererFeatures = rendererDataObject.FindProperty(RendererFeaturesPropertyName);
if (rendererFeatures == null || !rendererFeatures.isArray)
{
return false;
}
for (int i = 0; i < rendererFeatures.arraySize; i++)
{
UnityEngine.Object rendererFeature = rendererFeatures.GetArrayElementAtIndex(i).objectReferenceValue;
if (IsNBPostProcessFeature(rendererFeature) &&
(!requireActive || IsRendererFeatureActive(rendererFeature)))
{
return true;
}
}
return false;
}
private static bool IsNBPostProcessFeature(UnityEngine.Object rendererFeature)
{
if (rendererFeature == null)
{
return false;
}
for (Type type = rendererFeature.GetType(); type != null; type = type.BaseType)
{
if (string.Equals(type.FullName, NBPostProcessTypeFullName, StringComparison.Ordinal) ||
string.Equals(type.Name, NBPostProcessTypeName, StringComparison.Ordinal))
{
return true;
}
}
return false;
}
private static bool IsRendererFeatureActive(UnityEngine.Object rendererFeature)
{
if (rendererFeature == null)
{
return false;
}
if (TryGetBoolProperty(rendererFeature, RendererFeatureActivePropertyName, out bool isActive))
{
return isActive;
}
try
{
SerializedObject rendererFeatureObject = new SerializedObject(rendererFeature);
SerializedProperty activeProperty = rendererFeatureObject.FindProperty(RendererFeatureActiveSerializedPropertyName);
return activeProperty != null &&
activeProperty.propertyType == SerializedPropertyType.Boolean &&
activeProperty.boolValue;
}
catch (Exception)
{
return false;
}
}
private static bool HasCameraOpaqueTextureCopyEnabled()
{
try
{
RenderPipelineAsset pipelineAsset = GetCurrentRenderPipelineAsset();
if (pipelineAsset == null)
{
return false;
}
if (TryGetBoolProperty(pipelineAsset, OpaqueTexturePropertyName, out bool supportsCameraOpaqueTexture))
{
return supportsCameraOpaqueTexture;
}
SerializedObject pipelineObject = new SerializedObject(pipelineAsset);
SerializedProperty opaqueTextureProperty = pipelineObject.FindProperty(OpaqueTextureSerializedPropertyName);
return opaqueTextureProperty != null &&
opaqueTextureProperty.propertyType == SerializedPropertyType.Boolean &&
opaqueTextureProperty.boolValue;
}
catch (Exception)
{
return false;
}
}
private static UnityEngine.Object GetRendererDataForNBPostProcessPing()
{
try
{
RenderPipelineAsset pipelineAsset = GetCurrentRenderPipelineAsset();
if (pipelineAsset == null)
{
return null;
}
SerializedObject pipelineObject = new SerializedObject(pipelineAsset);
SerializedProperty rendererDataList = pipelineObject.FindProperty(RendererDataListPropertyName);
if (rendererDataList != null && rendererDataList.isArray)
{
return GetRendererDataForNBPostProcessPing(rendererDataList);
}
SerializedProperty legacyRendererData = pipelineObject.FindProperty(LegacyRendererDataPropertyName);
return legacyRendererData != null ? legacyRendererData.objectReferenceValue : null;
}
catch (Exception)
{
return null;
}
}
private static UnityEngine.Object GetRendererDataForNBPostProcessPing(SerializedProperty rendererDataList)
{
UnityEngine.Object firstRendererData = null;
UnityEngine.Object rendererDataWithInactiveFeature = null;
for (int i = 0; i < rendererDataList.arraySize; i++)
{
UnityEngine.Object rendererData = rendererDataList.GetArrayElementAtIndex(i).objectReferenceValue;
if (rendererData == null)
{
continue;
}
if (firstRendererData == null)
{
firstRendererData = rendererData;
}
if (RendererDataHasNBPostProcess(rendererData, requireActive: true))
{
return rendererData;
}
if (rendererDataWithInactiveFeature == null &&
RendererDataHasNBPostProcess(rendererData, requireActive: false))
{
rendererDataWithInactiveFeature = rendererData;
}
}
return rendererDataWithInactiveFeature != null ? rendererDataWithInactiveFeature : firstRendererData;
}
private static RenderPipelineAsset GetCurrentRenderPipelineAsset()
{
return QualitySettings.renderPipeline != null
? QualitySettings.renderPipeline
: GraphicsSettings.currentRenderPipeline;
}
private static bool TryGetBoolProperty(UnityEngine.Object target, string propertyName, out bool value)
{
value = false;
if (target == null)
{
return false;
}
try
{
PropertyInfo propertyInfo = target.GetType().GetProperty(
propertyName,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (propertyInfo == null || propertyInfo.PropertyType != typeof(bool))
{
return false;
}
value = (bool)propertyInfo.GetValue(target, null);
return true;
}
catch (Exception)
{
return false;
}
}
private static GUIContent ButtonContent(string key, string fallback)
{
return NBShaderInspectorLocalization.MakeContent("inspector." + key + ".button", fallback);
}
private sealed class PingableHelpBoxItem : ShaderGUIItem
{
private const float HelpBoxPadding = 6f;
private const float HelpBoxButtonGap = 4f;
private const float MaxButtonWidth = 160f;
private static readonly GUIContent TempHelpContent = new GUIContent();
private readonly Func<string> _messageProvider;
private readonly MessageType _messageType;
private readonly Func<GUIContent> _buttonContentProvider;
private readonly Func<UnityEngine.Object> _targetProvider;
private readonly Func<bool> _isVisible;
public PingableHelpBoxItem(
ShaderGUIRootItem rootItem,
ShaderGUIItem parentItem,
Func<string> messageProvider,
MessageType messageType,
Func<GUIContent> buttonContentProvider,
Func<UnityEngine.Object> targetProvider,
Func<bool> isVisible) : base(rootItem, parentItem)
{
_messageProvider = messageProvider ?? (() => string.Empty);
_messageType = messageType;
_buttonContentProvider = buttonContentProvider ?? (() => GUIContent.none);
_targetProvider = targetProvider ?? (() => null);
_isVisible = isVisible;
}
public override void OnGUI()
{
if (_isVisible != null && !_isVisible())
{
return;
}
using (ParentControlDisabledScope())
{
string message = _messageProvider();
GUIContent buttonContent = _buttonContentProvider();
TempHelpContent.text = message;
float width = Mathf.Max(1f, EditorGUIUtility.currentViewWidth + GlobalRectWidthExpansion + GlobalRectXOffset);
float messageHeight = Mathf.Max(
EditorGUIUtility.singleLineHeight * 2f,
EditorStyles.helpBox.CalcHeight(TempHelpContent, width));
float buttonHeight = EditorGUIUtility.singleLineHeight;
float height = messageHeight + HelpBoxButtonGap + buttonHeight + HelpBoxPadding;
Rect rect = ApplyGlobalRectCompensation(LayoutRect(height));
EditorGUI.HelpBox(rect, message, _messageType);
float buttonWidth = Mathf.Min(
MaxButtonWidth,
Mathf.Max(90f, EditorStyles.miniButton.CalcSize(buttonContent).x + 18f));
buttonWidth = Mathf.Min(buttonWidth, Mathf.Max(0f, rect.width - HelpBoxPadding * 2f));
Rect buttonRect = new Rect(
rect.xMax - HelpBoxPadding - buttonWidth,
rect.yMax - HelpBoxPadding - buttonHeight,
buttonWidth,
buttonHeight);
UnityEngine.Object target = _targetProvider();
using (new EditorGUI.DisabledScope(target == null))
{
if (GUI.Button(buttonRect, buttonContent, EditorStyles.miniButton))
{
Selection.activeObject = target;
EditorGUIUtility.PingObject(target);
}
}
TempHelpContent.text = string.Empty;
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e4f64374c74c47478edfdd0ddb6e8355
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,35 @@
using System;
using NBShader;
using UnityEditor;
using UnityEngine;
namespace NBShaderEditor
{
internal sealed class ParallaxFeatureItem : FeatureToggleFoldOutItem
{
public ParallaxFeatureItem(NBShaderRootItem rootItem, ShaderGUIItem parentItem)
: base(rootItem, parentItem, "_ParallaxBlockFoldOut", "_ParallaxMapping_Toggle", "遮蔽视差", keyword: "_PARALLAX_MAPPING", isVisible: () => rootItem.Context.UIEffectEnabled != MixedBool.True)
{
AddTextureWithWrap(rootItem, this, "_ParallaxMapping_Map", "视差贴图", NBShaderFlags.FLAG_BIT_WRAPMODE_PARALLAXMAPPINGMAP);
ShaderGUISliderItem parallaxMappingIntensityItem = new ShaderGUISliderItem(rootItem, this)
{
PropertyName = "_ParallaxMapping_Intensity",
GuiContent = Content("视差"),
RangePropertyName = "_ParallaxMapping_IntensityRangeVec"
};
parallaxMappingIntensityItem.InitTriggerByChild();
new VectorComponentItem(rootItem, this, "_ParallaxMapping_Vec", 0, () => Content("遮蔽视差最小层数"), true, 0f, 100f);
new VectorComponentItem(rootItem, this, "_ParallaxMapping_Vec", 1, () => Content("遮蔽视差最大层数"), true, 0f, 100f);
new HelpBoxItem(rootItem, this, () => Text("feature.parallax.layerWarning.message", "遮蔽视差层数过高将影响性能"), MessageType.Warning,
() => IsParallaxMaxLayerHigh(rootItem));
InitTriggerByChild();
}
private static bool IsParallaxMaxLayerHigh(NBShaderRootItem rootItem)
{
return rootItem.PropertyInfoDic.TryGetValue("_ParallaxMapping_Vec", out ShaderPropertyInfo info) &&
!info.Property.hasMixedValue &&
info.Property.vectorValue.y >= 20f;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d5bf38ca73454cc1916d18f40182d5ad
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,17 @@
using System;
using NBShader;
using UnityEditor;
using UnityEngine;
namespace NBShaderEditor
{
internal sealed class PortalFeatureItem : FeatureToggleFoldOutItem
{
public PortalFeatureItem(NBShaderRootItem rootItem, ShaderGUIItem parentItem)
: base(rootItem, parentItem, "_PortalBlockFoldOut", "_Portal_Toggle", "模板视差", onValueChanged: _ => rootItem.SyncService.ApplyPortalState(), isVisible: () => rootItem.Context.UIEffectEnabled != MixedBool.True)
{
new ToggleItem(rootItem, this, "_Portal_MaskToggle", () => Content("模板视差蒙版"), _ => rootItem.SyncService.ApplyPortalState());
InitTriggerByChild();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 67c4fd7f472848dfbefe5703bb834b60
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,58 @@
using System;
using NBShader;
using UnityEditor;
using UnityEngine;
namespace NBShaderEditor
{
internal sealed class ProgramNoiseFeatureItem : FeatureToggleFoldOutItem
{
public ProgramNoiseFeatureItem(NBShaderRootItem rootItem, ShaderGUIItem parentItem)
: base(rootItem, parentItem, "_ProgramNoiseBlockFoldOut", "_ProgramNoise_Toggle", "程序化噪波", keyword: "_PROGRAM_NOISE")
{
new NBShaderKeywordToggleItem(
rootItem,
this,
"_NB_Debug_PNoise",
"NB_DEBUG_PNOISE",
() => Content("程序化噪波测试颜色"),
isVisible: null);
new UVModeSelectItem(rootItem, this, "_ProgramNoiseUVModeFoldOut", NBShaderFlags.FLAG_BIT_UVMODE_POS_0_PROGRAM_NOISE, 0, () => Content("程序噪波UV来源"), forceEnable: true);
ShaderGUIFloatItem programNoiseRotateItem = new ShaderGUIFloatItem(rootItem, this)
{
PropertyName = "_ProgramNoise_Rotate",
GuiContent = Content("程序化噪波旋转")
};
programNoiseRotateItem.InitTriggerByChild();
PropertyToggleBlockItem simpleBlock = ToggleBlock(rootItem, "_ProgramNoiseSimpleFoldOut", "_ProgramNoise_Simple_Toggle", "Perlin噪波",
parent: this, keyword: "_PROGRAM_NOISE_SIMPLE");
new Vector2LineItem(rootItem, simpleBlock, "_DissolveVoronoi_Vec", true, () => Content("噪波1缩放"));
new VectorComponentItem(rootItem, simpleBlock, "_DissolveVoronoi_Vec2", 2, () => Content("噪波1速度"), false);
new Vector2LineItem(rootItem, simpleBlock, "_DissolveVoronoi_Vec4", true, () => Content("噪波1偏移"));
new Vector2LineItem(rootItem, simpleBlock, "_DissolveVoronoi_Vec3", true, () => Content("噪波1偏移速度"));
new CustomDataSelectItem(rootItem, simpleBlock, NBShaderFlags.FLAGBIT_POS_2_CUSTOMDATA_DISSOLVE_NOISE1_OFFSET_X, 2, () => Content("噪波1偏移速度X自定义曲线"));
new CustomDataSelectItem(rootItem, simpleBlock, NBShaderFlags.FLAGBIT_POS_2_CUSTOMDATA_DISSOLVE_NOISE1_OFFSET_Y, 2, () => Content("噪波1偏移速度Y自定义曲线"));
PropertyToggleBlockItem voronoiBlock = ToggleBlock(rootItem, "_ProgramNoiseVoronoiFoldOut", "_ProgramNoise_Voronoi_Toggle", "Voronoi噪波",
parent: this, keyword: "_PROGRAM_NOISE_VORONOI");
new Vector2LineItem(rootItem, voronoiBlock, "_DissolveVoronoi_Vec", false, () => Content("噪波2缩放"));
new VectorComponentItem(rootItem, voronoiBlock, "_DissolveVoronoi_Vec2", 3, () => Content("噪波2速度"), false);
new Vector2LineItem(rootItem, voronoiBlock, "_DissolveVoronoi_Vec4", false, () => Content("噪波2偏移"));
new Vector2LineItem(rootItem, voronoiBlock, "_DissolveVoronoi_Vec3", false, () => Content("噪波2偏移速度"));
new CustomDataSelectItem(rootItem, voronoiBlock, NBShaderFlags.FLAGBIT_POS_2_CUSTOMDATA_DISSOLVE_NOISE2_OFFSET_X, 2, () => Content("噪波2偏移速度X自定义曲线"));
new CustomDataSelectItem(rootItem, voronoiBlock, NBShaderFlags.FLAGBIT_POS_2_CUSTOMDATA_DISSOLVE_NOISE2_OFFSET_Y, 2, () => Content("噪波2偏移速度Y自定义曲线"));
new VectorComponentItem(rootItem, this, "_DissolveVoronoi_Vec2", 0, () => Content("噪波1和噪波2混合系数"), true);
new PNoiseBlendModeItem(
rootItem,
this,
NBShaderFlags.FLAG_BIT_PNOISE_BLEND_POS_0_BASE_BLEND,
"_ProgramNoiseBaseBlendOpacity",
() => Content("两种程序噪波混合"),
() => rootItem.Context.ProgramNoiseEnabled == MixedBool.True &&
rootItem.Context.IsToggleOn("_ProgramNoise_Simple_Toggle") &&
rootItem.Context.IsToggleOn("_ProgramNoise_Voronoi_Toggle"));
InitTriggerByChild();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c6a446a2f0364fb0844cb9d36bd39a27
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,37 @@
using System;
using NBShader;
using UnityEditor;
using UnityEngine;
namespace NBShaderEditor
{
internal sealed class RampColorFeatureItem : FeatureToggleFoldOutItem
{
private static readonly string[] RampSourceNames = { "渐变", "贴图" };
private static readonly string[] BlendModeNames = { "叠加", "相乘" };
public RampColorFeatureItem(NBShaderRootItem rootItem, ShaderGUIItem parentItem)
: base(rootItem, parentItem, "_RampColorBlockFoldOut", "_RampColorToggle", "颜色映射(Ramp)", keyword: "_COLOR_RAMP")
{
Func<bool> isRampMapVisible = TierVisible(rootItem, "_COLOR_RAMP_MAP", () => IsPropertyMode(rootItem, "_RampColorSourceMode", 1));
new FeaturePopupItem(rootItem, this, "_RampColorSourceMode", () => Content("Ramp来源模式"), RampSourceNames,
_ => rootItem.SyncService.SyncMaterialState(),
keyword: "_COLOR_RAMP_MAP");
AddTextureWithWrap(rootItem, this, "_RampColorMap", "颜色映射黑白图", NBShaderFlags.FLAG_BIT_WRAPMODE_RAMP_COLOR_MAP,
isVisible: isRampMapVisible);
new TextureScaleOffsetItem(rootItem, this, "_RampColorMap", false, () => IsPropertyMode(rootItem, "_RampColorSourceMode", 0), TillingContent, OffsetContent);
new WrapModeItem(rootItem, this, NBShaderFlags.FLAG_BIT_WRAPMODE_RAMP_COLOR_MAP, () => Content("颜色映射UV Wrap"), 2,
() => IsPropertyMode(rootItem, "_RampColorSourceMode", 0));
new ColorChannelSelectItem(rootItem, this, NBShaderFlags.FLAG_BIT_COLOR_CHANNEL_POS_0_RAMP_COLOR_MAP, 0, () => Content("颜色映射黑白图通道选择"),
isRampMapVisible);
new UVModeSelectItem(rootItem, this, "_RampColorUVModeFoldOut", NBShaderFlags.FLAG_BIT_UVMODE_POS_0_RAMP_COLOR_MAP, 0, () => Content("颜色映射黑白图UV来源"), "_RampColorMap", true);
new Vector2LineItem(rootItem, this, "_RampColorMapOffset", true, () => Content("颜色映射贴图偏移速度"));
new VectorComponentItem(rootItem, this, "_RampColorMapOffset", 3, () => Content("颜色映射贴图旋转"), true, 0f, 360f);
AddGradient(rootItem, this, "映射颜色", "_RampColorCount", "_RampColor", "_RampColorAlpha", hdr: true);
new FeaturePopupItem(rootItem, this, "_RampColorBlendMode", () => Content("Ramp颜色混合模式"), BlendModeNames,
property => rootItem.SyncService.ApplyToggleFlag(NBShaderFlags.FLAG_BIT_PARTICLE_RAMP_COLOR_BLEND_ADD, property.floatValue > 0.5f));
new ColorItem(rootItem, this, "_RampColorBlendColor", () => Content("颜色映射叠加颜色"));
InitTriggerByChild();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 45dcb7c7a750440a99a8d5017d41fa22
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,24 @@
using System;
using NBShader;
using UnityEditor;
using UnityEngine;
namespace NBShaderEditor
{
internal sealed class SharedUVFeatureItem : FeatureToggleFoldOutItem
{
public SharedUVFeatureItem(NBShaderRootItem rootItem, ShaderGUIItem parentItem)
: base(rootItem, parentItem, "_SharedUVBlockFoldOut", "_SharedUVToggle", "公共UV", keyword: "_SHARED_UV")
{
new UVModeSelectItem(rootItem, this, "_SharedUVModeFoldOut", NBShaderFlags.FLAG_BIT_UVMODE_POS_0_SHAREDUV, 0, () => Content("公共UV来源"), forceEnable: true);
new Vector2LineItem(rootItem, this, "_SharedUV_ST", true, () => Content("公共UV Tiling"));
new Vector2LineItem(rootItem, this, "_SharedUV_ST", false, () => Content("公共UV Offset"));
new Vector2LineItem(rootItem, this, "_SharedUV_Vec", true, () => Content("公共UV偏移速度"));
new VectorComponentItem(rootItem, this, "_SharedUV_Vec", 2, () => Content("旋转"), false);
new VectorComponentItem(rootItem, this, "_SharedUV_Vec", 3, () => Content("旋转速度"), false);
new CustomDataSelectItem(rootItem, this, NBShaderFlags.FLAGBIT_POS_3_CUSTOMDATA_SHARED_UV_OFFSET_X, 3, () => Content("公共UV X轴偏移自定义曲线"));
new CustomDataSelectItem(rootItem, this, NBShaderFlags.FLAGBIT_POS_3_CUSTOMDATA_SHARED_UV_OFFSET_Y, 3, () => Content("公共UV Y轴偏移自定义曲线"));
InitTriggerByChild();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dece160aaa274dd79c1e771fed834249
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,428 @@
using System;
using NBShader;
using UnityEditor;
using UnityEngine;
namespace NBShaderEditor
{
internal sealed class VatFeatureItem : FeatureToggleFoldOutItem
{
private static readonly string[] VatModeNames = { "Houdini", "TyFlow" };
private static readonly string[] HoudiniVatSubModeNames =
{
"SoftBody (Deformation)",
"RigidBody (Pieces)",
"Dynamic Remeshing (Lookup)",
"Particle Sprites (Billboard)"
};
private static readonly string[] TyFlowVatSubModeNames =
{
"Absolute positions",
"Relative offsets",
"Skin (R)",
"Skin (PR)",
"Skin (PRSAVE)",
"Skin (PRSXYZ)"
};
public VatFeatureItem(NBShaderRootItem rootItem, ShaderGUIItem parentItem)
: base(rootItem, parentItem, "_VATBlockFoldOut", "_VAT_Toggle", "VAT顶点动画图", keyword: "_VAT", onValueChanged: rootItem.SyncService.ApplyVatEnabled)
{
new FeaturePopupItem(rootItem, this, "_VATMode", () => Content("VAT模式"), VatModeNames, _ => rootItem.SyncService.SyncMaterialState());
Func<bool> isHoudini = () => IsPropertyMode(rootItem, "_VATMode", (int)VATMode.Houdini);
Func<bool> isTyflow = () => IsPropertyMode(rootItem, "_VATMode", (int)VATMode.Tyflow);
Func<bool> hasVatFrameCustomData = () => IsVatFrameCustomDataVisible(rootItem);
ShaderGUIFloatItem floatItem;
new FeaturePopupItem(rootItem, this, "_HoudiniVATSubMode", () => Content("Houdini VAT Sub Mode"), HoudiniVatSubModeNames,
_ => rootItem.SyncService.SyncMaterialState(), isHoudini);
new HelpBoxItem(rootItem, this, () => Text("feature.vat.houdiniUnsupportedParticle.message", "该 Houdini VAT 类型需要 Mesh 多 UV 数据,不支持 ParticleSystem VertexStream 模式。"), MessageType.Warning,
() => isHoudini() && HasUnsupportedHoudiniParticleMode(rootItem));
new SectionLabelItem(rootItem, this, () => Content("Playback"), isHoudini);
new ToggleItem(rootItem, this, "_B_autoPlayback", () => Content("Auto Playback"), isVisible: isHoudini);
floatItem = new ShaderGUIFloatItem(rootItem, this, () => isHoudini() && ShouldDrawWhenFloatOff(rootItem, "_B_autoPlayback"))
{
PropertyName = "_displayFrame",
GuiContent = Content("Display Frame")
};
floatItem.InitTriggerByChild();
new VatFrameCustomDataItem(rootItem, this, () => Content("VAT Frame CustomData"), () => isHoudini() && hasVatFrameCustomData(), hasVatFrameCustomData);
floatItem = new ShaderGUIFloatItem(rootItem, this, isHoudini)
{
PropertyName = "_gameTimeAtFirstFrame",
GuiContent = Content("Game Time at First Frame")
};
floatItem.InitTriggerByChild();
floatItem = new ShaderGUIFloatItem(rootItem, this, isHoudini)
{
PropertyName = "_playbackSpeed",
GuiContent = Content("Playback Speed")
};
floatItem.InitTriggerByChild();
floatItem = new ShaderGUIFloatItem(rootItem, this, isHoudini)
{
PropertyName = "_houdiniFPS",
GuiContent = Content("Houdini FPS")
};
floatItem.InitTriggerByChild();
new ToggleItem(rootItem, this, "_B_interpolate", () => Content("Interframe Interpolation"), isVisible: isHoudini);
new ToggleItem(rootItem, this, "_animateFirstFrame", () => Content("Animate First Frame"), isVisible: () => isHoudini() && IsPropertyMode(rootItem, "_HoudiniVATSubMode", 1));
floatItem = new ShaderGUIFloatItem(rootItem, this, isHoudini)
{
PropertyName = "_frameCount",
GuiContent = Content("Frame Count")
};
floatItem.InitTriggerByChild();
new SectionLabelItem(rootItem, this, () => Content("Bounds Metadata"), isHoudini);
floatItem = new ShaderGUIFloatItem(rootItem, this, isHoudini)
{
PropertyName = "_boundMinX",
GuiContent = Content("Bound Min X")
};
floatItem.InitTriggerByChild();
floatItem = new ShaderGUIFloatItem(rootItem, this, isHoudini)
{
PropertyName = "_boundMinY",
GuiContent = Content("Bound Min Y")
};
floatItem.InitTriggerByChild();
floatItem = new ShaderGUIFloatItem(rootItem, this, isHoudini)
{
PropertyName = "_boundMinZ",
GuiContent = Content("Bound Min Z")
};
floatItem.InitTriggerByChild();
floatItem = new ShaderGUIFloatItem(rootItem, this, isHoudini)
{
PropertyName = "_boundMaxX",
GuiContent = Content("Bound Max X")
};
floatItem.InitTriggerByChild();
floatItem = new ShaderGUIFloatItem(rootItem, this, isHoudini)
{
PropertyName = "_boundMaxY",
GuiContent = Content("Bound Max Y")
};
floatItem.InitTriggerByChild();
floatItem = new ShaderGUIFloatItem(rootItem, this, isHoudini)
{
PropertyName = "_boundMaxZ",
GuiContent = Content("Bound Max Z")
};
floatItem.InitTriggerByChild();
new SectionLabelItem(rootItem, this, () => Content("Textures"), isHoudini);
new TextureItem(rootItem, this, "_posTexture", () => Content("Position Texture"), drawScaleOffset: false, isVisible: isHoudini);
new TextureItem(rootItem, this, "_posTexture2", () => Content("Position Texture 2"), drawScaleOffset: false,
isVisible: () => isHoudini() && ShouldDrawWhenFloatOn(rootItem, "_B_LOAD_POS_TWO_TEX"));
new TextureItem(rootItem, this, "_rotTexture", () => Content("Rotation Texture"), drawScaleOffset: false,
isVisible: () => isHoudini() && ShouldDrawHoudiniRotationTexture(rootItem));
new TextureItem(rootItem, this, "_colTexture", () => Content("Color Texture"), drawScaleOffset: false,
isVisible: () => isHoudini() && ShouldDrawWhenFloatOn(rootItem, "_B_LOAD_COL_TEX"));
new TextureItem(rootItem, this, "_lookupTable", () => Content("Lookup Table"), drawScaleOffset: false,
isVisible: () => isHoudini() && (IsPropertyMode(rootItem, "_HoudiniVATSubMode", 2) || ShouldDrawWhenFloatOn(rootItem, "_B_LOAD_LOOKUP_TABLE")));
new SectionLabelItem(rootItem, this, () => Content("Scale"), () => isHoudini() && IsPropertyMode(rootItem, "_HoudiniVATSubMode", 1, 3));
floatItem = new ShaderGUIFloatItem(rootItem, this, () => isHoudini() && IsPropertyMode(rootItem, "_HoudiniVATSubMode", 1, 3))
{
PropertyName = "_globalPscaleMul",
GuiContent = Content("Global Piece Scale Multiplier")
};
floatItem.InitTriggerByChild();
new ToggleItem(rootItem, this, "_B_pscaleAreInPosA", () => Content("Piece Scales in Position Alpha"), isVisible: () => isHoudini() && IsPropertyMode(rootItem, "_HoudiniVATSubMode", 1, 3));
new SectionLabelItem(rootItem, this, () => Content("Particle Sprite"), () => isHoudini() && IsPropertyMode(rootItem, "_HoudiniVATSubMode", 3));
floatItem = new ShaderGUIFloatItem(rootItem, this, () => isHoudini() && IsPropertyMode(rootItem, "_HoudiniVATSubMode", 3))
{
PropertyName = "_widthBaseScale",
GuiContent = Content("Width Base Scale")
};
floatItem.InitTriggerByChild();
floatItem = new ShaderGUIFloatItem(rootItem, this, () => isHoudini() && IsPropertyMode(rootItem, "_HoudiniVATSubMode", 3))
{
PropertyName = "_heightBaseScale",
GuiContent = Content("Height Base Scale")
};
floatItem.InitTriggerByChild();
new ToggleItem(rootItem, this, "_B_hideOverlappingOrigin", () => Content("Hide Overlapping Origin"), isVisible: () => isHoudini() && IsPropertyMode(rootItem, "_HoudiniVATSubMode", 3));
floatItem = new ShaderGUIFloatItem(rootItem, this, () => isHoudini() && IsPropertyMode(rootItem, "_HoudiniVATSubMode", 3) && ShouldDrawWhenFloatOn(rootItem, "_B_hideOverlappingOrigin"))
{
PropertyName = "_originRadius",
GuiContent = Content("Origin Effective Radius")
};
floatItem.InitTriggerByChild();
new ToggleItem(rootItem, this, "_B_CAN_SPIN", () => Content("Particles Can Spin"), isVisible: () => isHoudini() && IsPropertyMode(rootItem, "_HoudiniVATSubMode", 3));
new ToggleItem(rootItem, this, "_B_spinFromHeading", () => Content("Compute Spin from Heading"), isVisible: () => isHoudini() && IsPropertyMode(rootItem, "_HoudiniVATSubMode", 3) && ShouldDrawWhenFloatOn(rootItem, "_B_CAN_SPIN"));
floatItem = new ShaderGUIFloatItem(rootItem, this, () => isHoudini() && IsPropertyMode(rootItem, "_HoudiniVATSubMode", 3) && ShouldDrawWhenFloatOn(rootItem, "_B_CAN_SPIN") && ShouldDrawWhenFloatOff(rootItem, "_B_spinFromHeading"))
{
PropertyName = "_spinPhase",
GuiContent = Content("Particle Spin Phase")
};
floatItem.InitTriggerByChild();
floatItem = new ShaderGUIFloatItem(rootItem, this, () => isHoudini() && IsPropertyMode(rootItem, "_HoudiniVATSubMode", 3) && ShouldDrawWhenFloatOn(rootItem, "_B_CAN_SPIN"))
{
PropertyName = "_scaleByVelAmount",
GuiContent = Content("Scale by Velocity Amount")
};
floatItem.InitTriggerByChild();
floatItem = new ShaderGUIFloatItem(rootItem, this, () => isHoudini() && IsPropertyMode(rootItem, "_HoudiniVATSubMode", 3))
{
PropertyName = "_particleTexUScale",
GuiContent = Content("Particle Texture U Scale")
};
floatItem.InitTriggerByChild();
floatItem = new ShaderGUIFloatItem(rootItem, this, () => isHoudini() && IsPropertyMode(rootItem, "_HoudiniVATSubMode", 3))
{
PropertyName = "_particleTexVScale",
GuiContent = Content("Particle Texture V Scale")
};
floatItem.InitTriggerByChild();
new SectionLabelItem(rootItem, this, () => Content("Flags"), isHoudini);
new ToggleItem(rootItem, this, "_B_LOAD_POS_TWO_TEX", () => Content("Positions Require Two Textures"), isVisible: isHoudini);
new ToggleItem(rootItem, this, "_B_UNLOAD_ROT_TEX", () => Content("Use Compressed Normals (no rotTex)"), isVisible: () => isHoudini() && ShouldDrawCompressedNormalsToggle(rootItem));
new ToggleItem(rootItem, this, "_B_LOAD_COL_TEX", () => Content("Load Color Texture"), isVisible: isHoudini);
new ToggleItem(rootItem, this, "_B_LOAD_LOOKUP_TABLE", () => Content("Load Lookup Table"), isVisible: () => isHoudini() && IsPropertyMode(rootItem, "_HoudiniVATSubMode", 2));
new TextureItem(rootItem, this, "_VATTex", () => Content("VAT texture"), drawScaleOffset: false, isVisible: isTyflow);
floatItem = new ShaderGUIFloatItem(rootItem, this, isTyflow)
{
PropertyName = "_ImportScale",
GuiContent = Content("ImportScale")
};
floatItem.InitTriggerByChild();
new FeaturePopupItem(rootItem, this, "_TyFlowVATSubMode", () => Content("TyFlow VAT Sub Mode"), TyFlowVatSubModeNames,
_ => rootItem.SyncService.SyncMaterialState(), isTyflow);
new HelpBoxItem(rootItem, this, () => Text("feature.vat.tyflowUnsupportedParticle.message", "该 TyFlow VAT 类型需要 Mesh 多 UV 数据,不支持 ParticleSystem VertexStream 模式。"), MessageType.Warning,
() => isTyflow() && HasUnsupportedTyflowParticleMode(rootItem));
new HelpBoxItem(rootItem, this, () => Text("feature.vat.tyflowUv2Conflict.message", "TyFlow VAT uses UV2 (TEXCOORD0.zw) as vertexIndex / vertexCount in ParticleSystem mode. Flipbook blending or Special UV (UV2) conflicts with it; VAT takes priority."), MessageType.Warning,
() => isTyflow() && !HasUnsupportedTyflowParticleMode(rootItem) && HasTyflowParticleUV2Conflict(rootItem));
new ToggleItem(rootItem, this, "_DeformingSkin", () => Content("Deforming skin"), isVisible: isTyflow);
floatItem = new ShaderGUIFloatItem(rootItem, this, isTyflow)
{
PropertyName = "_SkinBoneCount",
GuiContent = Content("Skin bone count")
};
floatItem.InitTriggerByChild();
new ToggleItem(rootItem, this, "_RGBAEncoded", () => Content("RGBA encoded"), isVisible: isTyflow);
new ToggleItem(rootItem, this, "_RGBAHalf", () => Content("RGBA half"), isVisible: isTyflow);
new ToggleItem(rootItem, this, "_LinearToGamma", () => Content("Gamma correction"), isVisible: isTyflow);
new ToggleItem(rootItem, this, "_VATIncludesNormals", () => Content("VAT includes normals"), isVisible: isTyflow);
floatItem = new ShaderGUIFloatItem(rootItem, this, isTyflow)
{
PropertyName = "_Frame",
GuiContent = Content("Frame")
};
floatItem.InitTriggerByChild();
new VatFrameCustomDataItem(rootItem, this, () => Content("VAT Frame CustomData"), () => isTyflow() && hasVatFrameCustomData(), hasVatFrameCustomData);
floatItem = new ShaderGUIFloatItem(rootItem, this, isTyflow)
{
PropertyName = "_Frames",
GuiContent = Content("Frames")
};
floatItem.InitTriggerByChild();
new ToggleItem(rootItem, this, "_FrameInterpolation", () => Content("Frame interpolation"), isVisible: isTyflow);
new ToggleItem(rootItem, this, "_Loop", () => Content("Loop"), isVisible: isTyflow);
new ToggleItem(rootItem, this, "_InterpolateLoop", () => Content("Interpolate loop"), isVisible: isTyflow);
new ToggleItem(rootItem, this, "_Autoplay", () => Content("Autoplay"), isVisible: isTyflow);
floatItem = new ShaderGUIFloatItem(rootItem, this, isTyflow)
{
PropertyName = "_AutoplaySpeed",
GuiContent = Content("AutoplaySpeed")
};
floatItem.InitTriggerByChild();
InitTriggerByChild();
}
private static bool ShouldDrawWhenFloatOn(NBShaderRootItem rootItem, string propertyName)
{
if (!rootItem.PropertyInfoDic.TryGetValue(propertyName, out ShaderPropertyInfo info))
{
return false;
}
return info.Property.hasMixedValue || info.Property.floatValue > 0.5f;
}
private static bool ShouldDrawWhenFloatOff(NBShaderRootItem rootItem, string propertyName)
{
if (!rootItem.PropertyInfoDic.TryGetValue(propertyName, out ShaderPropertyInfo info))
{
return false;
}
return info.Property.hasMixedValue || info.Property.floatValue <= 0.5f;
}
private static bool TryGetPropertyMode(NBShaderRootItem rootItem, string propertyName, out int mode)
{
mode = 0;
if (!rootItem.PropertyInfoDic.TryGetValue(propertyName, out ShaderPropertyInfo info) ||
info.Property.hasMixedValue)
{
return false;
}
mode = Mathf.RoundToInt(info.Property.floatValue);
return true;
}
private static bool ShouldDrawHoudiniRotationTexture(NBShaderRootItem rootItem)
{
return TryGetPropertyMode(rootItem, "_HoudiniVATSubMode", out int subMode) &&
subMode != 3 &&
ShouldDrawWhenFloatOff(rootItem, "_B_UNLOAD_ROT_TEX");
}
private static bool ShouldDrawCompressedNormalsToggle(NBShaderRootItem rootItem)
{
return TryGetPropertyMode(rootItem, "_HoudiniVATSubMode", out int subMode) && subMode != 3;
}
private static bool IsVatFrameCustomDataVisible(NBShaderRootItem rootItem)
{
return IsAnyHoudiniParticleModeEnabled(rootItem) || IsAnyTyflowParticleModeEnabled(rootItem);
}
private static bool HasTyflowParticleUV2Conflict(NBShaderRootItem rootItem)
{
if (rootItem.Mats == null || rootItem.ShaderFlags == null)
{
return false;
}
int count = Mathf.Min(rootItem.Mats.Count, rootItem.ShaderFlags.Count);
for (int i = 0; i < count; i++)
{
Material mat = rootItem.Mats[i];
if (!IsTyflowParticleModeEnabled(mat) ||
!(rootItem.ShaderFlags[i] is NBShaderFlags flags))
{
continue;
}
bool flipbook = mat.IsKeywordEnabled("_FLIPBOOKBLENDING_ON");
bool specialUVUsesUV2 = flags.CheckIsUVModeOn(NBShaderFlags.UVMode.SpecialUVChannel) &&
!flags.CheckFlagBits(NBShaderFlags.FLAG_BIT_PARTICLE_1_USE_TEXCOORD2, index: 1);
if (flipbook || specialUVUsesUV2)
{
return true;
}
}
return false;
}
private static bool IsAnyHoudiniParticleModeEnabled(NBShaderRootItem rootItem)
{
if (rootItem.Mats == null)
{
return false;
}
for (int i = 0; i < rootItem.Mats.Count; i++)
{
if (IsHoudiniParticleModeEnabled(rootItem.Mats[i]))
{
return true;
}
}
return false;
}
private static bool IsAnyTyflowParticleModeEnabled(NBShaderRootItem rootItem)
{
if (rootItem.Mats == null)
{
return false;
}
for (int i = 0; i < rootItem.Mats.Count; i++)
{
if (IsTyflowParticleModeEnabled(rootItem.Mats[i]))
{
return true;
}
}
return false;
}
private static bool HasUnsupportedHoudiniParticleMode(NBShaderRootItem rootItem)
{
if (rootItem.Mats == null)
{
return false;
}
for (int i = 0; i < rootItem.Mats.Count; i++)
{
Material mat = rootItem.Mats[i];
if (IsHoudiniParticleModeEnabled(mat) &&
GetMaterialInt(mat, "_HoudiniVATSubMode", 0) == 1)
{
return true;
}
}
return false;
}
private static bool HasUnsupportedTyflowParticleMode(NBShaderRootItem rootItem)
{
if (rootItem.Mats == null)
{
return false;
}
for (int i = 0; i < rootItem.Mats.Count; i++)
{
Material mat = rootItem.Mats[i];
if (IsVatParticleMode(mat, (int)VATMode.Tyflow) &&
GetMaterialInt(mat, "_TyFlowVATSubMode", 0) >= 2)
{
return true;
}
}
return false;
}
private static bool IsHoudiniParticleModeEnabled(Material mat)
{
return IsVatParticleMode(mat, (int)VATMode.Houdini);
}
private static bool IsTyflowParticleModeEnabled(Material mat)
{
return IsVatParticleMode(mat, (int)VATMode.Tyflow) &&
(!mat.HasProperty("_TyFlowVATSubMode") || Mathf.RoundToInt(mat.GetFloat("_TyFlowVATSubMode")) <= 1);
}
private static bool IsVatParticleMode(Material mat, int vatMode)
{
if (mat == null ||
!mat.HasProperty("_VAT_Toggle") ||
!mat.HasProperty("_VATMode") ||
!mat.HasProperty("_MeshSourceMode") ||
mat.GetFloat("_VAT_Toggle") <= 0.5f ||
Mathf.RoundToInt(mat.GetFloat("_VATMode")) != vatMode)
{
return false;
}
MeshSourceMode meshSourceMode = (MeshSourceMode)Mathf.RoundToInt(mat.GetFloat("_MeshSourceMode"));
return meshSourceMode == MeshSourceMode.Particle ||
meshSourceMode == MeshSourceMode.UIParticle;
}
private static int GetMaterialInt(Material mat, string propertyName, int defaultValue)
{
return mat != null && mat.HasProperty(propertyName)
? Mathf.RoundToInt(mat.GetFloat(propertyName))
: defaultValue;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 744c08c430cd42fda37db42e777c3c84
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,62 @@
using System;
using NBShader;
using UnityEditor;
using UnityEngine;
namespace NBShaderEditor
{
internal sealed class VertexOffsetFeatureItem : FeatureToggleFoldOutItem
{
public VertexOffsetFeatureItem(NBShaderRootItem rootItem, ShaderGUIItem parentItem)
: base(rootItem, parentItem, "_VertexOffsetBlockFoldOut", "_VertexOffset_Toggle", "顶点偏移", keyword: "_VERTEX_OFFSET")
{
new NBShaderKeywordToggleItem(
rootItem,
this,
"_NB_Debug_VertexOffset",
"NB_DEBUG_VERTEX_OFFSET",
() => Content("顶点偏移方向测试"),
isVisible: null);
AddTextureWithWrap(rootItem, this, "_VertexOffset_Map", "顶点偏移贴图", NBShaderFlags.FLAG_BIT_WRAPMODE_VERTEXOFFSETMAP);
new UVModeSelectItem(rootItem, this, "_VertexOffsetUVModeFoldOut", NBShaderFlags.FLAG_BIT_UVMODE_POS_0_VERTEX_OFFSET_MAP, 0, () => Content("顶点偏移贴图UV来源"), "_VertexOffset_Map");
new CustomDataSelectItem(rootItem, this, NBShaderFlags.FLAGBIT_POS_1_CUSTOMDATA_VERTEX_OFFSET_X, 1, () => Content("顶点扰动X轴偏移自定义曲线"));
new CustomDataSelectItem(rootItem, this, NBShaderFlags.FLAGBIT_POS_1_CUSTOMDATA_VERTEX_OFFSET_Y, 1, () => Content("顶点扰动Y轴偏移自定义曲线"));
new Vector2LineItem(rootItem, this, "_VertexOffset_Vec", true, () => Content("顶点偏移动画"));
new VectorComponentItem(rootItem, this, "_VertexOffset_Vec", 2, () => Content("顶点偏移强度"), false);
new CustomDataSelectItem(rootItem, this, NBShaderFlags.FLAGBIT_POS_1_CUSTOMDATA_VERTEXOFFSET_INTENSITY, 1, () => Content("顶点扰动强度自定义曲线"));
new ToggleItem(
rootItem,
this,
"_VertexOffset_StartFromZero",
() => Content("顶点偏移从零开始"),
enabled => rootItem.SyncService.ApplyToggleFlag(NBShaderFlags.FLAG_BIT_PARTICLE_1_VERTEXOFFSET_START_FROM_ZERO, enabled, 1));
new ToggleItem(
rootItem,
this,
"_VertexOffset_NormalDir_Toggle",
() => Content("顶点偏移使用法线方向"),
enabled => rootItem.SyncService.ApplyToggleFlag(NBShaderFlags.FLAG_BIT_PARTICLE_VERTEX_OFFSET_NORMAL_DIR, enabled));
Func<bool> showCustomDirection = () => IsPropertyOff(rootItem, "_VertexOffset_NormalDir_Toggle");
new VectorComponentItem(rootItem, this, "_VertexOffset_CustomDir", 0, () => Content("顶点偏移本地方向X"), false, isVisible: showCustomDirection);
new VectorComponentItem(rootItem, this, "_VertexOffset_CustomDir", 1, () => Content("顶点偏移本地方向Y"), false, isVisible: showCustomDirection);
new VectorComponentItem(rootItem, this, "_VertexOffset_CustomDir", 2, () => Content("顶点偏移本地方向Z"), false, isVisible: showCustomDirection);
PropertyToggleBlockItem maskBlock = ToggleBlock(rootItem, "_VertexOffsetMaskBlockFoldOut", "_VertexOffset_Mask_Toggle", "顶点偏移遮罩",
parent: this, keyword: "_VERTEX_OFFSET_MASKMAP");
AddTextureWithWrap(rootItem, maskBlock, "_VertexOffset_MaskMap", "顶点偏移遮罩图", NBShaderFlags.FLAG_BIT_WRAPMODE_VERTEXOFFSET_MASKMAP);
new UVModeSelectItem(rootItem, maskBlock, "_VertexOffsetMaskUVModeFoldOut", NBShaderFlags.FLAG_BIT_UVMODE_POS_0_VERTEX_OFFSET_MASKMAP, 0, () => Content("顶点偏移遮罩图UV来源"), "_VertexOffset_MaskMap");
new CustomDataSelectItem(rootItem, maskBlock, NBShaderFlags.FLAGBIT_POS_3_CUSTOMDATA_VERTEX_OFFSET_MASK_X, 3, () => Content("顶点扰动遮罩X轴偏移自定义曲线"));
new CustomDataSelectItem(rootItem, maskBlock, NBShaderFlags.FLAGBIT_POS_3_CUSTOMDATA_VERTEX_OFFSET_MASK_Y, 3, () => Content("顶点扰动遮罩Y轴偏移自定义曲线"));
new Vector2LineItem(rootItem, maskBlock, "_VertexOffset_MaskMap_Vec", true, () => Content("顶点偏移遮罩动画"));
new VectorComponentItem(rootItem, maskBlock, "_VertexOffset_MaskMap_Vec", 2, () => Content("顶点偏移遮罩强度"), true);
InitTriggerByChild();
}
private static bool IsPropertyOff(NBShaderRootItem rootItem, string propertyName)
{
return rootItem.PropertyInfoDic.TryGetValue(propertyName, out ShaderPropertyInfo info) &&
!info.Property.hasMixedValue &&
info.Property.floatValue <= 0.5f;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5507463f5ee64c358b78250126100a8d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: