NB_FX
This commit is contained in:
106
Packages/NB_FX/NBShaders2/Runtime/NBShaderFeatureCatalog.cs
Normal file
106
Packages/NB_FX/NBShaders2/Runtime/NBShaderFeatureCatalog.cs
Normal file
@@ -0,0 +1,106 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NBShader
|
||||
{
|
||||
/// <summary>
|
||||
/// Hard-coded catalog of raw shader feature keywords managed by the NBShader runtime tier system.
|
||||
/// Keywords not listed here are never changed by <see cref="NBShaderFeatureRuntime"/>.
|
||||
/// </summary>
|
||||
public static class NBShaderFeatureCatalog
|
||||
{
|
||||
/// <summary>
|
||||
/// Shader name used by NBShader materials.
|
||||
/// </summary>
|
||||
public const string ShaderName = "Effects/NBShader";
|
||||
|
||||
/// <summary>
|
||||
/// Default file name for optional NBShader runtime settings assets.
|
||||
/// User projects decide how those assets are loaded at runtime.
|
||||
/// </summary>
|
||||
public const string RuntimeSettingsAssetName = "NBShaderFeatureRuntimeSettings";
|
||||
|
||||
/// <summary>
|
||||
/// Raw shader_feature keywords currently managed by NBShader tiering. The '_' placeholder and
|
||||
/// multi_compile keywords are intentionally excluded.
|
||||
/// </summary>
|
||||
public static readonly string[] RawKeywords =
|
||||
{
|
||||
"NB_DEBUG_DISSOLVE",
|
||||
"NB_DEBUG_DISTORT",
|
||||
"NB_DEBUG_FRESNEL",
|
||||
"NB_DEBUG_MASK",
|
||||
"NB_DEBUG_PNOISE",
|
||||
"NB_DEBUG_VERTEX_OFFSET",
|
||||
"VFX_SIX_WAY_ABSORPTION",
|
||||
"_ALPHAMODULATE_ON",
|
||||
"_ALPHAPREMULTIPLY_ON",
|
||||
"_ALPHATEST_ON",
|
||||
"_CHROMATIC_ABERRATION",
|
||||
"_COLORMAPBLEND",
|
||||
"_COLOR_RAMP",
|
||||
"_COLOR_RAMP_MAP",
|
||||
"_DEPTH_DECAL",
|
||||
"_DEPTH_OUTLINE",
|
||||
"_DISSOLVE",
|
||||
"_DISSOLVE_MASK",
|
||||
"_DISSOLVE_RAMP",
|
||||
"_DISSOLVE_RAMP_MAP",
|
||||
"_DISTANCE_FADE",
|
||||
"_DISTORT_REFRACTION",
|
||||
"_EMISSION",
|
||||
"_FLIPBOOKBLENDING_ON",
|
||||
"_FRESNEL",
|
||||
"_FX_LIGHT_MODE_BLINN_PHONG",
|
||||
"_FX_LIGHT_MODE_HALF_LAMBERT",
|
||||
"_FX_LIGHT_MODE_PBR",
|
||||
"_FX_LIGHT_MODE_SIX_WAY",
|
||||
"_FX_LIGHT_MODE_UNLIT",
|
||||
"_HOUDINI_VAT_DYNAMIC_REMESH",
|
||||
"_HOUDINI_VAT_PARTICLE_SPRITE",
|
||||
"_HOUDINI_VAT_RIGIDBODY",
|
||||
"_HOUDINI_VAT_SOFTBODY",
|
||||
"_MASKMAP_ON",
|
||||
"_MASKMAP2_ON",
|
||||
"_MASKMAP3_ON",
|
||||
"_MATCAP",
|
||||
"_NOISEMAP",
|
||||
"_NOISE_MASKMAP",
|
||||
"_NORMALMAP",
|
||||
"_OVERRIDE_Z",
|
||||
"_PARALLAX_MAPPING",
|
||||
"_PARCUSTOMDATA_ON",
|
||||
"_PROGRAM_NOISE",
|
||||
"_PROGRAM_NOISE_SIMPLE",
|
||||
"_PROGRAM_NOISE_VORONOI",
|
||||
"_SCREEN_DISTORT_MODE",
|
||||
"_SCRIPTABLETIME",
|
||||
"_SHARED_UV",
|
||||
"_SOFTPARTICLES_ON",
|
||||
"_SPECULAR_COLOR",
|
||||
"_STENCIL_WITHOUT_PLAYER",
|
||||
"_TYFLOW_VAT_ABSOLUTE",
|
||||
"_TYFLOW_VAT_RELATIVE",
|
||||
"_TYFLOW_VAT_SKIN_PR",
|
||||
"_TYFLOW_VAT_SKIN_PRSAVE",
|
||||
"_TYFLOW_VAT_SKIN_PRSXYZ",
|
||||
"_TYFLOW_VAT_SKIN_R",
|
||||
"_UNSCALETIME",
|
||||
"_VAT",
|
||||
"_VAT_HOUDINI",
|
||||
"_VAT_TYFLOW",
|
||||
"_VERTEX_OFFSET",
|
||||
"_VERTEX_OFFSET_MASKMAP"
|
||||
};
|
||||
|
||||
internal static readonly HashSet<string> RawKeywordSet = new HashSet<string>(RawKeywords);
|
||||
|
||||
/// <summary>
|
||||
/// Returns true when the keyword is explicitly managed by the NBShader feature tier system.
|
||||
/// Catalog-external keywords must be ignored by tier application and build stripping.
|
||||
/// </summary>
|
||||
public static bool IsManagedKeyword(string keyword)
|
||||
{
|
||||
return !string.IsNullOrEmpty(keyword) && RawKeywordSet.Contains(keyword);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: faf1ed0560444790b66010208bd2934f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
183
Packages/NB_FX/NBShaders2/Runtime/NBShaderFeatureRuntime.cs
Normal file
183
Packages/NB_FX/NBShaders2/Runtime/NBShaderFeatureRuntime.cs
Normal file
@@ -0,0 +1,183 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBShader
|
||||
{
|
||||
/// <summary>
|
||||
/// Runtime API for applying NBShader feature tiers to materials.
|
||||
/// </summary>
|
||||
public static class NBShaderFeatureRuntime
|
||||
{
|
||||
/// <summary>
|
||||
/// Applies an NBShader feature tier to one material in place. Only materials whose shader name is
|
||||
/// "Effects/NBShader" are processed. Managed Catalog keywords and shader passes are derived from
|
||||
/// serialized material intent, then filtered by the target tier.
|
||||
/// </summary>
|
||||
/// <param name="material">Material to process. Null materials are ignored.</param>
|
||||
/// <param name="tier">
|
||||
/// Target tier. When null, Ultra is used. This overload does not load runtime settings, so it keeps all
|
||||
/// managed Catalog keywords and pass features available.
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
/// If lower-tier shader variants have been stripped from the build, call this API before the material is
|
||||
/// used for rendering. Otherwise Unity can request a missing variant and select a similar available variant.
|
||||
/// </remarks>
|
||||
public static void ApplyTier(Material material, NBShaderFeatureTier? tier = null)
|
||||
{
|
||||
ApplyTierInternal(material, null, tier);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies an NBShader feature tier using a user-loaded runtime settings asset.
|
||||
/// Pass null for <paramref name="tier"/> to resolve the tier from the settings quality mapping.
|
||||
/// </summary>
|
||||
public static void ApplyTier(Material material, NBShaderFeatureRuntimeSettings settings, NBShaderFeatureTier? tier)
|
||||
{
|
||||
ApplyTierInternal(material, settings, tier);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies an NBShader feature tier to multiple materials in place. Only materials whose shader name is
|
||||
/// "Effects/NBShader" are processed. Catalog-external keywords are left unchanged unless they are
|
||||
/// explicitly tied to a managed NBShader feature.
|
||||
/// </summary>
|
||||
/// <param name="materials">Materials to process. Null collections and null entries are ignored.</param>
|
||||
/// <param name="tier">
|
||||
/// Target tier. When null, Ultra is used. This overload does not load runtime settings, so it keeps all
|
||||
/// managed Catalog keywords and pass features available.
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
/// If lower-tier shader variants have been stripped from the build, call this API before the materials are
|
||||
/// used for rendering. Otherwise Unity can request a missing variant and select a similar available variant.
|
||||
/// </remarks>
|
||||
public static void ApplyTier(IEnumerable<Material> materials, NBShaderFeatureTier? tier = null)
|
||||
{
|
||||
ApplyTierInternal(materials, null, tier);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies an NBShader feature tier to multiple materials using a user-loaded runtime settings asset.
|
||||
/// Pass null for <paramref name="tier"/> to resolve the tier from the settings quality mapping.
|
||||
/// </summary>
|
||||
public static void ApplyTier(IEnumerable<Material> materials, NBShaderFeatureRuntimeSettings settings, NBShaderFeatureTier? tier)
|
||||
{
|
||||
ApplyTierInternal(materials, settings, tier);
|
||||
}
|
||||
|
||||
private static void ApplyTierInternal(IEnumerable<Material> materials, NBShaderFeatureRuntimeSettings settings, NBShaderFeatureTier? tier)
|
||||
{
|
||||
if (materials == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (Material material in materials)
|
||||
{
|
||||
ApplyTierInternal(material, settings, tier);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ApplyTierInternal(Material material, NBShaderFeatureRuntimeSettings settings, NBShaderFeatureTier? tier)
|
||||
{
|
||||
if (!IsNBShaderMaterial(material))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NBShaderFeatureTier resolvedTier = tier.HasValue ? tier.Value : ResolveTierFromQuality(settings);
|
||||
HashSet<string> allowed = settings != null
|
||||
? settings.BuildAllowedSet(resolvedTier)
|
||||
: BuildAllowAllCatalogKeywordSet();
|
||||
HashSet<string> allowedPassFeatures = settings != null
|
||||
? settings.BuildAllowedPassFeatureSet(resolvedTier)
|
||||
: null;
|
||||
NBShaderMaterialIntentResult result = NBShaderMaterialIntentResolver.Resolve(material, resolvedTier, allowed, allowedPassFeatures);
|
||||
ApplyResolvedIntent(material, result);
|
||||
}
|
||||
|
||||
private static bool IsNBShaderMaterial(Material material)
|
||||
{
|
||||
return material != null
|
||||
&& material.shader != null
|
||||
&& material.shader.name == NBShaderFeatureCatalog.ShaderName;
|
||||
}
|
||||
|
||||
private static void ApplyResolvedIntent(Material material, NBShaderMaterialIntentResult result)
|
||||
{
|
||||
if (material == null || result == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var effectiveKeywords = new HashSet<string>(result.effectiveKeywords);
|
||||
for (int i = 0; i < NBShaderFeatureCatalog.RawKeywords.Length; i++)
|
||||
{
|
||||
string keyword = NBShaderFeatureCatalog.RawKeywords[i];
|
||||
bool shouldEnable = effectiveKeywords.Contains(keyword);
|
||||
if (material.IsKeywordEnabled(keyword) != shouldEnable)
|
||||
{
|
||||
if (shouldEnable)
|
||||
{
|
||||
material.EnableKeyword(keyword);
|
||||
}
|
||||
else
|
||||
{
|
||||
material.DisableKeyword(keyword);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool evaluateShVertex = effectiveKeywords.Contains("_FX_LIGHT_MODE_SIX_WAY");
|
||||
if (material.IsKeywordEnabled("EVALUATE_SH_VERTEX") != evaluateShVertex)
|
||||
{
|
||||
if (evaluateShVertex)
|
||||
{
|
||||
material.EnableKeyword("EVALUATE_SH_VERTEX");
|
||||
}
|
||||
else
|
||||
{
|
||||
material.DisableKeyword("EVALUATE_SH_VERTEX");
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < result.passes.Length; i++)
|
||||
{
|
||||
NBShaderPassIntent pass = result.passes[i];
|
||||
if (!string.IsNullOrEmpty(pass.passName) &&
|
||||
material.GetShaderPassEnabled(pass.passName) != pass.included)
|
||||
{
|
||||
material.SetShaderPassEnabled(pass.passName, pass.included);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static NBShaderFeatureTier ResolveTierFromQuality(NBShaderFeatureRuntimeSettings settings)
|
||||
{
|
||||
if (settings == null)
|
||||
{
|
||||
return NBShaderFeatureTier.Ultra;
|
||||
}
|
||||
|
||||
string qualityName = GetCurrentQualityName();
|
||||
NBShaderFeatureTier tier;
|
||||
return settings.TryGetTierForQualityName(qualityName, out tier) ? tier : NBShaderFeatureTier.Ultra;
|
||||
}
|
||||
|
||||
private static string GetCurrentQualityName()
|
||||
{
|
||||
string[] names = QualitySettings.names;
|
||||
int index = QualitySettings.GetQualityLevel();
|
||||
if (names != null && index >= 0 && index < names.Length)
|
||||
{
|
||||
return names[index];
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private static HashSet<string> BuildAllowAllCatalogKeywordSet()
|
||||
{
|
||||
return new HashSet<string>(NBShaderFeatureCatalog.RawKeywords);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b6115ddf8278414a953d467dc43f637c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,129 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBShader
|
||||
{
|
||||
/// <summary>
|
||||
/// Optional runtime settings for NBShader feature tiering. User projects own asset creation and
|
||||
/// runtime loading; pass the loaded asset to <see cref="NBShaderFeatureRuntime"/> when tier gating is required.
|
||||
/// </summary>
|
||||
[CreateAssetMenu(fileName = NBShaderFeatureCatalog.RuntimeSettingsAssetName, menuName = "NBShader/Feature Runtime Settings")]
|
||||
public sealed class NBShaderFeatureRuntimeSettings : ScriptableObject
|
||||
{
|
||||
[Serializable]
|
||||
public sealed class QualityTierMapping
|
||||
{
|
||||
public string qualityName;
|
||||
public NBShaderFeatureTier tier = NBShaderFeatureTier.Ultra;
|
||||
}
|
||||
|
||||
[Header("Allowed Raw Shader Feature Keywords")]
|
||||
public string[] lowAllowedKeywords = CloneCatalogKeywords();
|
||||
public string[] mediumAllowedKeywords = CloneCatalogKeywords();
|
||||
public string[] highAllowedKeywords = CloneCatalogKeywords();
|
||||
public string[] ultraAllowedKeywords = CloneCatalogKeywords();
|
||||
|
||||
[Header("Allowed Shader Pass Features")]
|
||||
public string[] lowAllowedPassFeatures = CloneCatalogPassFeatures();
|
||||
public string[] mediumAllowedPassFeatures = CloneCatalogPassFeatures();
|
||||
public string[] highAllowedPassFeatures = CloneCatalogPassFeatures();
|
||||
public string[] ultraAllowedPassFeatures = CloneCatalogPassFeatures();
|
||||
|
||||
[Header("QualitySettings Name To Tier")]
|
||||
public QualityTierMapping[] qualityTierMappings = new QualityTierMapping[0];
|
||||
|
||||
public string[] GetAllowedKeywords(NBShaderFeatureTier tier)
|
||||
{
|
||||
switch (tier)
|
||||
{
|
||||
case NBShaderFeatureTier.Low:
|
||||
return lowAllowedKeywords ?? NBShaderFeatureCatalog.RawKeywords;
|
||||
case NBShaderFeatureTier.Medium:
|
||||
return mediumAllowedKeywords ?? NBShaderFeatureCatalog.RawKeywords;
|
||||
case NBShaderFeatureTier.High:
|
||||
return highAllowedKeywords ?? NBShaderFeatureCatalog.RawKeywords;
|
||||
default:
|
||||
return ultraAllowedKeywords ?? NBShaderFeatureCatalog.RawKeywords;
|
||||
}
|
||||
}
|
||||
|
||||
public string[] GetAllowedPassFeatures(NBShaderFeatureTier tier)
|
||||
{
|
||||
switch (tier)
|
||||
{
|
||||
case NBShaderFeatureTier.Low:
|
||||
return lowAllowedPassFeatures ?? NBShaderPassFeatureCatalog.RawPassFeatureIds;
|
||||
case NBShaderFeatureTier.Medium:
|
||||
return mediumAllowedPassFeatures ?? NBShaderPassFeatureCatalog.RawPassFeatureIds;
|
||||
case NBShaderFeatureTier.High:
|
||||
return highAllowedPassFeatures ?? NBShaderPassFeatureCatalog.RawPassFeatureIds;
|
||||
default:
|
||||
return ultraAllowedPassFeatures ?? NBShaderPassFeatureCatalog.RawPassFeatureIds;
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetTierForQualityName(string qualityName, out NBShaderFeatureTier tier)
|
||||
{
|
||||
tier = NBShaderFeatureTier.Ultra;
|
||||
if (string.IsNullOrEmpty(qualityName) || qualityTierMappings == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < qualityTierMappings.Length; i++)
|
||||
{
|
||||
QualityTierMapping mapping = qualityTierMappings[i];
|
||||
if (mapping != null && string.Equals(mapping.qualityName, qualityName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
tier = mapping.tier;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
internal HashSet<string> BuildAllowedSet(NBShaderFeatureTier tier)
|
||||
{
|
||||
string[] keywords = GetAllowedKeywords(tier);
|
||||
HashSet<string> allowed = new HashSet<string>();
|
||||
for (int i = 0; i < keywords.Length; i++)
|
||||
{
|
||||
string keyword = keywords[i];
|
||||
if (NBShaderFeatureCatalog.IsManagedKeyword(keyword))
|
||||
{
|
||||
allowed.Add(keyword);
|
||||
}
|
||||
}
|
||||
|
||||
return allowed;
|
||||
}
|
||||
|
||||
internal HashSet<string> BuildAllowedPassFeatureSet(NBShaderFeatureTier tier)
|
||||
{
|
||||
string[] passFeatures = GetAllowedPassFeatures(tier);
|
||||
HashSet<string> allowed = new HashSet<string>();
|
||||
for (int i = 0; i < passFeatures.Length; i++)
|
||||
{
|
||||
string passFeature = passFeatures[i];
|
||||
if (NBShaderPassFeatureCatalog.IsManagedPassFeature(passFeature))
|
||||
{
|
||||
allowed.Add(passFeature);
|
||||
}
|
||||
}
|
||||
|
||||
return allowed;
|
||||
}
|
||||
|
||||
private static string[] CloneCatalogKeywords()
|
||||
{
|
||||
return (string[])NBShaderFeatureCatalog.RawKeywords.Clone();
|
||||
}
|
||||
|
||||
private static string[] CloneCatalogPassFeatures()
|
||||
{
|
||||
return (string[])NBShaderPassFeatureCatalog.RawPassFeatureIds.Clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c77ae8665b4443efa5ab2f470a2939b6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
13
Packages/NB_FX/NBShaders2/Runtime/NBShaderFeatureTier.cs
Normal file
13
Packages/NB_FX/NBShaders2/Runtime/NBShaderFeatureTier.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace NBShader
|
||||
{
|
||||
/// <summary>
|
||||
/// Runtime NBShader feature tiers, ordered from the smallest keyword budget to the full feature set.
|
||||
/// </summary>
|
||||
public enum NBShaderFeatureTier
|
||||
{
|
||||
Low = 0,
|
||||
Medium = 1,
|
||||
High = 2,
|
||||
Ultra = 3
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ad18474c2a04675834e005ab993b7c6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
773
Packages/NB_FX/NBShaders2/Runtime/NBShaderFlags.cs
Normal file
773
Packages/NB_FX/NBShaders2/Runtime/NBShaderFlags.cs
Normal file
@@ -0,0 +1,773 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBShader
|
||||
{
|
||||
public class NBShaderFlags : ShaderFlagsBase
|
||||
{
|
||||
public const string FlagsName = "_W9ParticleShaderFlags";
|
||||
public static int FlagsId = Shader.PropertyToID(FlagsName);
|
||||
|
||||
|
||||
public const string Flags1Name = "_W9ParticleShaderFlags1";
|
||||
public static int Flags1Id = Shader.PropertyToID(Flags1Name);
|
||||
|
||||
public const string WrapFlagsName = "_W9ParticleShaderWrapFlags";
|
||||
public static int WrapFlagsId = Shader.PropertyToID(WrapFlagsName);
|
||||
|
||||
public const string foldOutFlagName = "_NBShaderGUIFoldToggle";
|
||||
public static int foldOutFlagId = Shader.PropertyToID(foldOutFlagName);
|
||||
|
||||
public const string foldOutFlagName1 = "_NBShaderGUIFoldToggle1";
|
||||
public static int foldOutFlagId1 = Shader.PropertyToID(foldOutFlagName1);
|
||||
|
||||
public const string foldOutFlagName2 = "_NBShaderGUIFoldToggle2";
|
||||
public static int foldOutFlagId2 = Shader.PropertyToID(foldOutFlagName2);
|
||||
|
||||
public const string colorChannelFlagName = "_W9ParticleShaderColorChannelFlag";
|
||||
public static int colorChannelFlagId = Shader.PropertyToID(colorChannelFlagName);
|
||||
|
||||
public const string pNoiseBlendFlagName = "_W9ParticleShaderPNoiseBlendFlag";
|
||||
public static int pNoiseBlendFlagId = Shader.PropertyToID(pNoiseBlendFlagName);
|
||||
|
||||
// public const string WrapFlags2Name = "_W9ParticleShaderWrapFlags2";
|
||||
// public static int WrapFlags2Id = Shader.PropertyToID(WrapFlags2Name);
|
||||
|
||||
public override int GetShaderFlagsId(int index = 0)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return FlagsId;
|
||||
|
||||
case 1:
|
||||
return Flags1Id;
|
||||
|
||||
case 2:
|
||||
return WrapFlagsId;
|
||||
|
||||
//FoldOut必须要紧挨着,因为按照Index去拿AnimBool
|
||||
case 3:
|
||||
return foldOutFlagId;
|
||||
|
||||
case 4:
|
||||
return foldOutFlagId1;
|
||||
|
||||
case 5:
|
||||
return foldOutFlagId2;
|
||||
|
||||
case 6:
|
||||
return colorChannelFlagId;
|
||||
|
||||
case 7:
|
||||
return pNoiseBlendFlagId;
|
||||
// case 8:
|
||||
// return WrapFlags2Id;
|
||||
|
||||
default:
|
||||
return FlagsId;
|
||||
}
|
||||
}
|
||||
|
||||
protected override string GetShaderFlagsName(int index = 0)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return FlagsName;
|
||||
|
||||
case 1:
|
||||
return Flags1Name;
|
||||
|
||||
case 2:
|
||||
return WrapFlagsName;
|
||||
|
||||
case 3:
|
||||
return foldOutFlagName;
|
||||
|
||||
case 4:
|
||||
return foldOutFlagName1;
|
||||
|
||||
case 5:
|
||||
return colorChannelFlagName;
|
||||
|
||||
default:
|
||||
return FlagsName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public NBShaderFlags(Material material = null) : base(material)
|
||||
{
|
||||
}
|
||||
|
||||
public const int FLAG_BIT_SATURABILITY_ON = 1 << 0;
|
||||
public const int FLAG_BIT_PARTICLE_NOISE_CHORATICABERRAT_WITH_NOISE = 1 << 1;
|
||||
public const int FLAG_BIT_PARTICLE_FRESNEL_FADE_ON = 1 << 2;
|
||||
public const int FLAG_BIT_PARTICLE_FRESNEL_COLOR_ON = 1 << 3;
|
||||
public const int FLAG_BIT_PARTICLE_USETEXCOORD2 = 1 << 4;
|
||||
// public const int FLAG_BIT_PARTICLE_DISTANCEFADE_ON = 1 << 5; // Obsolete/reserved: keyword-driven (_DISTANCE_FADE).
|
||||
// public const int FLAG_BIT_PARTICLE_CHORATICABERRAT = 1 << 6; // Obsolete/reserved: keyword-driven (_CHROMATIC_ABERRATION).
|
||||
public const int FLAG_BIT_PARTILCE_MASKMAPROTATIONANIMATION_ON = 1 << 7;
|
||||
public const int FLAG_BIT_PARTICLE_POLARCOORDINATES_ON = 1 << 8;
|
||||
public const int FLAG_BIT_PARTICLE_UTWIRL_ON = 1 << 9;
|
||||
public const int FLAG_BIT_PARTICLE_LINEARTOGAMMA_ON = 1 << 10;
|
||||
// public const int FLAG_BIT_PARTICLE_FRESNEL_ON = 1 << 11; // Obsolete/reserved: keyword-driven (_FRESNEL).
|
||||
public const int FLAG_BIT_PARTICLE_NOISEMAP_NORMALIZEED_ON = 1 << 12;
|
||||
public const int FLAG_BIT_PARTICLE_FRESNEL_COLOR_AFFETCT_BY_ALPHA = 1 << 13;
|
||||
public const int FLAG_BIT_PARTICLE_UIEFFECT_ON = 1 << 14;
|
||||
public const int FLAG_BIT_PARTICLE_UNSCALETIME_ON = 1 << 15;
|
||||
public const int FLAG_BIT_PARTICLE_SCRIPTABLETIME_ON = 1 << 16;
|
||||
public const int FLAG_BIT_PARTICLE_CUSTOMDATA1_ON = 1 << 17;
|
||||
public const int FLAG_BIT_PARTICLE_FRESNEL_INVERT_ON = 1 << 18;
|
||||
public const int FLAG_BIT_HUESHIFT_ON = 1 << 19;
|
||||
public const int FLAG_BIT_PARTICLE_CUSTOMDATA2_ON = 1 << 20;
|
||||
public const int FLAG_BIT_PARTICLE_NORMALMAP_MASK_MODE = 1 << 21;
|
||||
public const int FLAG_BIT_PARTICLE_COLOR_ADJUSTMENT_ONLY_AFFECT_MAINTEX = 1 << 22;
|
||||
// public const int FLAG_BIT_PARTICLE_RAMP_COLOR_MAP_MODE_ON = 1 << 23; // Obsolete/reserved: keyword-driven (_COLOR_RAMP_MAP).
|
||||
public const int FLAG_BIT_PARTICLE_RAMP_COLOR_BLEND_ADD = 1 << 24;
|
||||
public const int FLAG_BIT_PARTICLE_COLOR_BLEND_ALPHA_MULTIPLY_MODE = 1 << 25;
|
||||
// public const int FLAG_BIT_PARTICLE_DISSOLVE_RAMP_MAP = 1 << 26; // Obsolete/reserved: keyword-driven (_DISSOLVE_RAMP_MAP).
|
||||
// public const int FLAG_BIT_PARTICLE_DISSOLVE_MASK = 1 << 27; // Obsolete/reserved: keyword-driven (_DISSOLVE_MASK).
|
||||
public const int FLAG_BIT_PARTICLE_BACKCOLOR = 1 << 28;
|
||||
public const int FLAG_BIT_PARTICLE_COLOR_MULTI_ALPHA = 1 << 29;
|
||||
// public const int FLAG_BIT_PARTICLE_VERTEX_OFFSET_ON = 1 << 30; // Obsolete/reserved: keyword-driven (_VERTEX_OFFSET).
|
||||
public const int FLAG_BIT_PARTICLE_VERTEX_OFFSET_NORMAL_DIR = 1 << 31;
|
||||
|
||||
public const int FLAG_BIT_PARTICLE_1_TRANSPARENT_MODE = 1 << 0;
|
||||
public const int FLAG_BIT_PARTICLE_1_TRANSPARENT_SHADOW_DITHER = 1 << 1;
|
||||
public const int FLAG_BIT_PARTICLE_1_MASKMAP_GRADIENT = 1 << 2;
|
||||
public const int FLAG_BIT_PARTICLE_1_MASKMAP_2_GRADIENT = 1 << 3;
|
||||
public const int FLAG_BIT_PARTICLE_1_MASKMAP_3_GRADIENT = 1 << 4;
|
||||
public const int FLAG_BIT_PARTICLE_1_DISSOLVE_LINE_MASK = 1 << 5;
|
||||
public const int FLAG_BIT_PARTICLE_1_DISSOLVE_RAMP_MULITPLY = 1 << 6;
|
||||
public const int FLAG_BIT_PARTICLE_1_MASK_REFINE = 1 << 7;
|
||||
public const int FLAG_BIT_PARTICLE_1_SCREEN_DISTORT_ALPHA_REFINE = 1 << 8;
|
||||
public const int FLAG_BIT_PARTICLE_1_IGNORE_VERTEX_COLOR = 1 << 9;
|
||||
// public const int FLAG_BIT_PARTICLE_1_PROGRAM_NOISE_SIMPLE = 1 << 10; // Obsolete/reserved: keyword-driven (_PROGRAM_NOISE_SIMPLE).
|
||||
// public const int FLAG_BIT_PARTICLE_1_DISSOVLE_USE_RAMP = 1 << 11; // Obsolete/reserved: keyword-driven (_DISSOLVE_RAMP).
|
||||
// public const int FLAG_BIT_PARTICLE_1_MASK_MAP2 = 1 << 12; // Obsolete/reserved: keyword-driven (_MASKMAP2_ON).
|
||||
// public const int FLAG_BIT_PARTICLE_1_MASK_MAP3 = 1 << 13; // Obsolete/reserved: keyword-driven (_MASKMAP3_ON).
|
||||
// public const int FLAG_BIT_PARTICLE_1_NOISE_MASKMAP = 1 << 14; // Obsolete/reserved: keyword-driven (_NOISE_MASKMAP).
|
||||
public const int FLAG_BIT_PARTICLE_1_ANIMATION_SHEET_HELPER = 1 << 15;
|
||||
// public const int FLAG_BIT_PARTICLE_1_PROGRAM_NOISE_VORONOI = 1 << 16; // Obsolete/reserved: keyword-driven (_PROGRAM_NOISE_VORONOI).
|
||||
public const int FLAG_BIT_PARTICLE_1_UIEFFECT_SPRITE_MODE = 1 << 17;
|
||||
public const int FLAG_BIT_PARTICLE_1_USE_TEXCOORD1 = 1 << 18;
|
||||
public const int FLAG_BIT_PARTICLE_1_USE_TEXCOORD2 = 1 << 19;
|
||||
public const int FLAG_BIT_PARTICLE_1_CYLINDER_CORDINATE = 1 << 20;
|
||||
public const int FLAG_BIT_PARTICLE_1_UV_FROM_MESH = 1 << 21; //3D条件下,如果不是来源于Mesh,就默认来源于粒子。
|
||||
public const int FLAG_BIT_PARTICLE_1_UIEFFECT_BASEMAP_MODE = 1 << 22; //3D条件下,如果不是来源于Mesh,就默认来源于粒子。
|
||||
public const int FLAG_BIT_PARTICLE_1_IS_PARTICLE_SYSTEM = 1 << 23; //3D条件下,如果不是来源于Mesh,就默认来源于粒子。
|
||||
public const int FLAG_BIT_PARTICLE_1_MAINTEX_CONTRAST = 1 << 24;
|
||||
public const int FLAG_BIT_PARTICLE_1_VERTEXOFFSET_START_FROM_ZERO = 1 << 25;
|
||||
// public const int FLAG_BIT_PARTICLE_1_VERTEXOFFSET_MASKMAP = 1 << 26; // Obsolete/reserved: keyword-driven (_VERTEX_OFFSET_MASKMAP).
|
||||
public const int FLAG_BIT_PARTICLE_1_MAINTEX_COLOR_REFINE = 1 << 27;
|
||||
public const int FLAG_BIT_PARTICLE_1_BUMP_TEX_UV_FOLLOW_MAINTEX = 1 << 28;
|
||||
public const int FLAG_BIT_PARTICLE_1_SIXWAY_RAMPMAP = 1 << 29;
|
||||
public const int FLAG_BIT_PARTICLE_1_MATCAP_MULTY_MODE = 1 << 30;
|
||||
|
||||
|
||||
public const int FLAG_BIT_WRAPMODE_BASEMAP = 1 << 0;
|
||||
public const int FLAG_BIT_WRAPMODE_MASKMAP = 1 << 1;
|
||||
public const int FLAG_BIT_WRAPMODE_MASKMAP2 = 1 << 2;
|
||||
public const int FLAG_BIT_WRAPMODE_NOISEMAP = 1 << 3;
|
||||
public const int FLAG_BIT_WRAPMODE_EMISSIONMAP = 1 << 4;
|
||||
public const int FLAG_BIT_WRAPMODE_DISSOLVE_MAP = 1 << 5;
|
||||
public const int FLAG_BIT_WRAPMODE_DISSOLVE_MASKMAP = 1 << 6;
|
||||
public const int FLAG_BIT_WRAPMODE_DISSOLVE_RAMPMAP = 1 << 7;
|
||||
public const int FLAG_BIT_WRAPMODE_COLORBLENDMAP = 1 << 8;
|
||||
public const int FLAG_BIT_WRAPMODE_VERTEXOFFSETMAP = 1 << 9;
|
||||
public const int FLAG_BIT_WRAPMODE_PARALLAXMAPPINGMAP = 1 << 10;
|
||||
public const int FLAG_BIT_WRAPMODE_MASKMAP3 = 1 << 11;
|
||||
public const int FLAG_BIT_WRAPMODE_NOISE_MASKMAP = 1 << 12;
|
||||
public const int FLAG_BIT_WRAPMODE_VERTEXOFFSET_MASKMAP = 1 << 13;
|
||||
public const int FLAG_BIT_WRAPMODE_BUMPTEX = 1 << 14;
|
||||
public const int FLAG_BIT_WRAPMODE_RAMP_COLOR_MAP = 1 << 15;
|
||||
|
||||
// public const int FLAG_BIT_WRAPMODE2_SHAREDUV = 1 << 0;
|
||||
|
||||
public const int foldOutBitMeshOption = 1 << 0;
|
||||
public const int foldOutBitMainTexOption = 1 << 1;
|
||||
public const int foldOutBitBaseOption = 1 << 2;
|
||||
public const int foldOutBitFeatureOption = 1 << 3;
|
||||
public const int foldOutBitBaseMap = 1 << 4;
|
||||
public const int foldOutBitMask = 1 << 5;
|
||||
public const int foldOutBitMaskMap = 1 << 6;
|
||||
public const int foldOutBitMask2 = 1 << 7;
|
||||
public const int foldOutBitMask3 = 1 << 8;
|
||||
public const int foldOutBitTwril = 1 << 9;
|
||||
public const int foldOutBitPolar = 1 << 10;
|
||||
public const int foldOutBitHueShift = 1 << 11;
|
||||
public const int foldOutBitSaturability = 1 << 12;
|
||||
public const int foldOutBitDistanceFade = 1 << 13;
|
||||
public const int foldOutBitSoftParticles = 1 << 14;
|
||||
public const int foldOutBitMaskRotate = 1 << 15;
|
||||
public const int foldOutBitNoise = 1 << 16;
|
||||
public const int foldOutBitNoiseMap = 1 << 17;
|
||||
public const int foldOutBitNoiseMaskToggle = 1 << 18;
|
||||
public const int foldOutBitEmission = 1 << 19;
|
||||
public const int foldOutBitDistortionChoraticaberrat = 1 << 20;
|
||||
public const int foldOutDissolve = 1 << 21;
|
||||
public const int foldOutDissolveMap = 1 << 22;
|
||||
public const int foldOutProgramNoise = 1 << 23;
|
||||
public const int foldOutDissolveRampMap = 1 << 24;
|
||||
public const int foldOutDissolveMask = 1 << 25;
|
||||
public const int foldOutColorBlend = 1 << 26;
|
||||
public const int foldOutFresnel = 1 << 27;
|
||||
public const int foldOutDepthOutline = 1 << 28;
|
||||
public const int foldOutVertexOffset = 1 << 29;
|
||||
public const int foldOutParallexMapping = 1 << 30;
|
||||
// public const int foldOutBit1Portal= 1 << 31;
|
||||
|
||||
|
||||
|
||||
|
||||
public const int foldOutBit1UVModeMainTex = 1 << 0;
|
||||
public const int foldOutBit1UVModeMaskMap = 1 << 1;
|
||||
public const int foldOutBit1UVModeMaskMap2 = 1 << 2;
|
||||
public const int foldOutBit1UVModeMaskMap3 = 1 << 3;
|
||||
public const int foldOutBit1UVModeNoiseMap = 1 << 4;
|
||||
public const int foldOutBit1UVModeNoiseMaskMap = 1 << 5;
|
||||
public const int foldOutBit1UVModeEmissionMap = 1 << 6;
|
||||
public const int foldOutBit1UVModeDissolveMap = 1 << 7;
|
||||
public const int foldOutBit1UVModeDissolveMaskMap = 1 << 8;
|
||||
public const int foldOutBit1UVModeColorBlendMap = 1 << 9;
|
||||
public const int foldOutBit1UVModeVertexOffsetMap = 1 << 10;
|
||||
public const int foldOutBit1UVModeVertexOffsetMaskMap = 1 << 11;
|
||||
public const int foldOutBit1UVModeBumpTex = 1 << 12;
|
||||
public const int foldOutBit1UVModeRampColorMap = 1 << 13;
|
||||
public const int foldOutBit1UVModeProgramNoise = 1 << 14;
|
||||
|
||||
//留一些位置给以后可能会增加的贴图。
|
||||
public const int foldOutBit1Portal = 1 << 20;
|
||||
public const int foldOutBit1ZOffset = 1 << 21;
|
||||
public const int foldOutBit1CustomStencilTest = 1 << 22;
|
||||
public const int foldOutBit1TaOption = 1 << 23;
|
||||
public const int foldOutBit1MianTexContrast = 1 << 24;
|
||||
public const int foldOutBit1VertexOffsetMask = 1 << 25;
|
||||
public const int foldOutBit1MainTexColorRefine = 1 << 26;
|
||||
public const int foldOutBit1LightOption = 1 << 27;
|
||||
public const int foldOutBit1ShaderKeyword = 1 << 28;
|
||||
public const int foldOutBit1BumpTex = 1 << 29;
|
||||
|
||||
public const int foldOutBit2BumpTexToggle = 1 << 0;
|
||||
public const int foldOutBit2MatCapToggle = 1 << 1;
|
||||
public const int foldOutBit2RampColor = 1 << 2;
|
||||
public const int foldOutBit2DissolveLine = 1 << 3;
|
||||
public const int foldOutBit2BaseBackColor = 1 << 4;
|
||||
public const int foldOutBit2MaskRefine = 1 << 5;
|
||||
public const int foldOutBit2ScreenDistortAlphaRefine = 1 << 6;
|
||||
public const int foldOutBit2ProgramNoiseSimple = 1 << 7;
|
||||
public const int foldOutBit2ProgramNoiseVoronoi = 1 << 8;
|
||||
public const int foldOutBit2ColorAdjustment = 1 << 9;
|
||||
public const int foldOutBit2SharedUV = 1 << 10;
|
||||
public const int foldOutBit2SharedUVMode = 1 << 11;
|
||||
public const int foldOutBit2VAT = 1 << 12;
|
||||
|
||||
|
||||
#region CustomDataCodes
|
||||
|
||||
public const string CustomDataFlag0Name = "_W9ParticleCustomDataFlag0";
|
||||
public const string CustomDataFlag1Name = "_W9ParticleCustomDataFlag1";
|
||||
public const string CustomDataFlag2Name = "_W9ParticleCustomDataFlag2";
|
||||
public const string CustomDataFlag3Name = "_W9ParticleCustomDataFlag3";
|
||||
public static int CustomDataFlag0Id = Shader.PropertyToID(CustomDataFlag0Name);
|
||||
public static int CustomDataFlag1Id = Shader.PropertyToID(CustomDataFlag1Name);
|
||||
public static int CustomDataFlag2Id = Shader.PropertyToID(CustomDataFlag2Name);
|
||||
public static int CustomDataFlag3Id = Shader.PropertyToID(CustomDataFlag3Name);
|
||||
|
||||
public enum CutomDataComponent
|
||||
{
|
||||
Off,
|
||||
CustomData1X,
|
||||
CustomData1Y,
|
||||
CustomData1Z,
|
||||
CustomData1W,
|
||||
CustomData2X,
|
||||
CustomData2Y,
|
||||
CustomData2Z,
|
||||
CustomData2W,
|
||||
UnKnownOrMixed = -1
|
||||
}
|
||||
|
||||
public const int FLAGBIT_POS_0_CUSTOMDATA_MAINTEX_OFFSET_X = 0 * 4;
|
||||
public const int FLAGBIT_POS_0_CUSTOMDATA_MAINTEX_OFFSET_Y = 1 * 4;
|
||||
public const int FLAGBIT_POS_0_CUSTOMDATA_DISSOLVE_INTENSITY = 2 * 4;
|
||||
public const int FLAGBIT_POS_0_CUSTOMDATA_HUESHIFT = 3 * 4;
|
||||
public const int FLAGBIT_POS_0_CUSTOMDATA_MASK_OFFSET_X = 4 * 4;
|
||||
public const int FLAGBIT_POS_0_CUSTOMDATA_MASK_OFFSET_Y = 5 * 4;
|
||||
public const int FLAGBIT_POS_0_CUSTOMDATA_FRESNEL_OFFSET = 6 * 4;
|
||||
public const int FLAGBIT_POS_0_CUSTOMDATA_CHORATICABERRAT_INTENSITY = 7 * 4;
|
||||
|
||||
public const int FLAGBIT_POS_1_CUSTOMDATA_DISSOLVE_OFFSET_X = 0 * 4;
|
||||
public const int FLAGBIT_POS_1_CUSTOMDATA_DISSOLVE_OFFSET_Y = 1 * 4;
|
||||
public const int FLAGBIT_POS_1_CUSTOMDATA_NOISE_INTENSITY = 2 * 4;
|
||||
public const int FLAGBIT_POS_1_CUSTOMDATA_SATURATE = 3 * 4;
|
||||
public const int FLAGBIT_POS_1_CUSTOMDATA_VERTEX_OFFSET_X = 4 * 4;
|
||||
public const int FLAGBIT_POS_1_CUSTOMDATA_VERTEX_OFFSET_Y = 5 * 4;
|
||||
public const int FLAGBIT_POS_1_CUSTOMDATA_VERTEXOFFSET_INTENSITY = 6 * 4;
|
||||
public const int FLAGBIT_POS_1_CUSTOMDATA_DISSOLVE_MASK_INTENSITY = 7 * 4;
|
||||
|
||||
public const int FLAGBIT_POS_2_CUSTOMDATA_DISSOLVE_NOISE1_OFFSET_X = 0 * 4;
|
||||
public const int FLAGBIT_POS_2_CUSTOMDATA_DISSOLVE_NOISE1_OFFSET_Y = 1 * 4;
|
||||
public const int FLAGBIT_POS_2_CUSTOMDATA_DISSOLVE_NOISE2_OFFSET_X = 2 * 4;
|
||||
public const int FLAGBIT_POS_2_CUSTOMDATA_DISSOLVE_NOISE2_OFFSET_Y = 3 * 4;
|
||||
public const int FLAGBIT_POS_2_CUSTOMDATA_NOISE_DIRECTION_X = 4 * 4;
|
||||
public const int FLAGBIT_POS_2_CUSTOMDATA_NOISE_DIRECTION_Y = 5 * 4;
|
||||
public const int FLAGBIT_POS_2_CUSTOMDATA_MAINTEX_CONTRAST = 6 * 4;
|
||||
public const int FLAGBIT_POS_2_CUSTOMDATA_VAT_FRAME = 7 * 4;
|
||||
|
||||
public const int FLAGBIT_POS_3_CUSTOMDATA_VERTEX_OFFSET_MASK_X = 0 * 4;
|
||||
public const int FLAGBIT_POS_3_CUSTOMDATA_VERTEX_OFFSET_MASK_Y = 1 * 4;
|
||||
public const int FLAGBIT_POS_3_CUSTOMDATA_SHARED_UV_OFFSET_X = 2 * 4;
|
||||
public const int FLAGBIT_POS_3_CUSTOMDATA_SHARED_UV_OFFSET_Y = 3 * 4;
|
||||
public const int FLAGBIT_POS_3_CUSTOMDATA_EMISSION_OFFSET_X = 4 * 4;
|
||||
public const int FLAGBIT_POS_3_CUSTOMDATA_EMISSION_OFFSET_Y = 5 * 4;
|
||||
public const int FLAGBIT_POS_3_CUSTOMDATA_COLOR_BLEND_OFFSET_X = 6 * 4;
|
||||
public const int FLAGBIT_POS_3_CUSTOMDATA_COLOR_BLEND_OFFSET_Y = 7 * 4;
|
||||
|
||||
|
||||
public const int isCustomDataBit = 1 << 3;
|
||||
public const int Data12Bit = 1 << 2; //true CustomData1 / false CustomData2
|
||||
public const int DataXYorZWBit = 1 << 1; //true xy / false zw
|
||||
public const int DataXZorYWBit = 1 << 0; //true xz / false yw
|
||||
public const int CustomData1XBit = isCustomDataBit | Data12Bit | DataXYorZWBit | DataXZorYWBit;
|
||||
public const int CustomData1YBit = isCustomDataBit | Data12Bit | DataXYorZWBit;
|
||||
public const int CustomData1ZBit = isCustomDataBit | Data12Bit | DataXZorYWBit;
|
||||
public const int CustomData1WBit = isCustomDataBit | Data12Bit;
|
||||
public const int CustomData2XBit = isCustomDataBit | DataXYorZWBit | DataXZorYWBit;
|
||||
public const int CustomData2YBit = isCustomDataBit | DataXYorZWBit;
|
||||
public const int CustomData2ZBit = isCustomDataBit | DataXZorYWBit;
|
||||
public const int CustomData2WBit = isCustomDataBit;
|
||||
|
||||
private int GetCustomDataFlagID(int dataIndex)
|
||||
{
|
||||
switch (dataIndex)
|
||||
{
|
||||
case 0:
|
||||
return CustomDataFlag0Id;
|
||||
|
||||
case 1:
|
||||
return CustomDataFlag1Id;
|
||||
|
||||
case 2:
|
||||
return CustomDataFlag2Id;
|
||||
case 3:
|
||||
return CustomDataFlag3Id;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public string GetCustomDataFlagPropertyName(int dataIndex)
|
||||
{
|
||||
switch (dataIndex)
|
||||
{
|
||||
case 0:
|
||||
return CustomDataFlag0Name;
|
||||
|
||||
case 1:
|
||||
return CustomDataFlag1Name;
|
||||
|
||||
case 2:
|
||||
return CustomDataFlag2Name;
|
||||
|
||||
case 3:
|
||||
return CustomDataFlag3Name;
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public CutomDataComponent GetCustomDataFlag(int dataBitPos, int dataIndex)
|
||||
{
|
||||
int bit = material.GetInteger(GetCustomDataFlagID(dataIndex));
|
||||
|
||||
bit = bit >> dataBitPos;
|
||||
bit &= 15; // binary 1111
|
||||
|
||||
if ((bit & isCustomDataBit) == 0)
|
||||
{
|
||||
return CutomDataComponent.Off;
|
||||
}
|
||||
else if (bit == CustomData1XBit)
|
||||
{
|
||||
return CutomDataComponent.CustomData1X;
|
||||
}
|
||||
else if (bit == CustomData1YBit)
|
||||
{
|
||||
return CutomDataComponent.CustomData1Y;
|
||||
}
|
||||
else if (bit == CustomData1ZBit)
|
||||
{
|
||||
return CutomDataComponent.CustomData1Z;
|
||||
}
|
||||
else if (bit == CustomData1WBit)
|
||||
{
|
||||
return CutomDataComponent.CustomData1W;
|
||||
}
|
||||
else if (bit == CustomData2XBit)
|
||||
{
|
||||
return CutomDataComponent.CustomData2X;
|
||||
}
|
||||
else if (bit == CustomData2YBit)
|
||||
{
|
||||
return CutomDataComponent.CustomData2Y;
|
||||
}
|
||||
else if (bit == CustomData2ZBit)
|
||||
{
|
||||
return CutomDataComponent.CustomData2Z;
|
||||
}
|
||||
else if (bit == CustomData2WBit)
|
||||
{
|
||||
return CutomDataComponent.CustomData2W;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
Debug.Log("不可能存在的情况");
|
||||
return CutomDataComponent.Off;
|
||||
|
||||
}
|
||||
|
||||
public void SetCustomDataFlag(CutomDataComponent cutomDataComponent, int dataBitPos, int dataIndex)
|
||||
{
|
||||
int bit = 0;
|
||||
switch (cutomDataComponent)
|
||||
{
|
||||
case CutomDataComponent.Off:
|
||||
bit = 0;
|
||||
break;
|
||||
case CutomDataComponent.CustomData1X:
|
||||
bit = CustomData1XBit;
|
||||
break;
|
||||
case CutomDataComponent.CustomData1Y:
|
||||
bit = CustomData1YBit;
|
||||
break;
|
||||
case CutomDataComponent.CustomData1Z:
|
||||
bit = CustomData1ZBit;
|
||||
break;
|
||||
case CutomDataComponent.CustomData1W:
|
||||
bit = CustomData1WBit;
|
||||
break;
|
||||
case CutomDataComponent.CustomData2X:
|
||||
bit = CustomData2XBit;
|
||||
break;
|
||||
case CutomDataComponent.CustomData2Y:
|
||||
bit = CustomData2YBit;
|
||||
break;
|
||||
case CutomDataComponent.CustomData2Z:
|
||||
bit = CustomData2ZBit;
|
||||
break;
|
||||
case CutomDataComponent.CustomData2W:
|
||||
bit = CustomData2WBit;
|
||||
break;
|
||||
}
|
||||
|
||||
bit = bit << dataBitPos;
|
||||
int clearBit = ~(15 << dataBitPos); //~ (1111 << dataBitPos)
|
||||
|
||||
int materialBit = material.GetInteger(GetCustomDataFlagID(dataIndex));
|
||||
materialBit = materialBit & clearBit;
|
||||
materialBit = materialBit | bit;
|
||||
material.SetInteger(GetCustomDataFlagID(dataIndex), materialBit);
|
||||
}
|
||||
|
||||
public bool IsCustomDataOn()
|
||||
{
|
||||
int prop0Flag = material.GetInteger(CustomDataFlag0Id);
|
||||
int prop1Flag = material.GetInteger(CustomDataFlag1Id);
|
||||
int prop2Flag = material.GetInteger(CustomDataFlag2Id);
|
||||
int prop3Flag = material.GetInteger(CustomDataFlag3Id);
|
||||
uint dataOnBit = 0b_1000_1000_1000_1000_1000_1000_1000_1000; //10001000100010001000100010001000;
|
||||
|
||||
return ((prop0Flag & dataOnBit) > 0) || ((prop1Flag & dataOnBit) > 0) || ((prop2Flag & dataOnBit) > 0) ||
|
||||
((prop3Flag & dataOnBit) > 0);
|
||||
}
|
||||
|
||||
bool CheckCustomData(int dataIndex, int flagIndex)
|
||||
{
|
||||
int flagID = 0;
|
||||
switch (flagIndex)
|
||||
{
|
||||
case 0:
|
||||
flagID = CustomDataFlag0Id;
|
||||
break;
|
||||
case 1:
|
||||
flagID = CustomDataFlag1Id;
|
||||
break;
|
||||
case 2:
|
||||
flagID = CustomDataFlag2Id;
|
||||
break;
|
||||
case 3:
|
||||
flagID = CustomDataFlag3Id;
|
||||
break;
|
||||
}
|
||||
|
||||
int flag = material.GetInteger(flagID);
|
||||
int i = 0;
|
||||
while (i < 8)
|
||||
{
|
||||
int bit = flag >> (4 * i);
|
||||
if (dataIndex == 1)
|
||||
{
|
||||
if ((bit & 0b_1000) > 0 && (bit & 0b_0100) > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (dataIndex == 2)
|
||||
{
|
||||
if ((bit & 0b_1000) > 0 && (bit & 0b_0100) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
i += 1;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsCustomData1On()
|
||||
{
|
||||
if (!IsCustomDataOn())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isCustomData1On = false;
|
||||
isCustomData1On |= CheckCustomData(1, 0);
|
||||
isCustomData1On |= CheckCustomData(1, 1);
|
||||
isCustomData1On |= CheckCustomData(1, 2);
|
||||
isCustomData1On |= CheckCustomData(1, 3);
|
||||
return isCustomData1On;
|
||||
}
|
||||
|
||||
public bool IsCustomData2On()
|
||||
{
|
||||
if (!IsCustomDataOn())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isCustomData1On = false;
|
||||
isCustomData1On |= CheckCustomData(2, 0);
|
||||
isCustomData1On |= CheckCustomData(2, 1);
|
||||
isCustomData1On |= CheckCustomData(2, 2);
|
||||
isCustomData1On |= CheckCustomData(2, 3);
|
||||
return isCustomData1On;
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public const string UVModeFlag0Name = "_UVModeFlag0";
|
||||
public const string UVModeFlagType0Name = "_UVModeFlagType0";
|
||||
public static int UVModeFlag0PropID = Shader.PropertyToID(UVModeFlag0Name);
|
||||
public static int UVModeFlagType0PropID = Shader.PropertyToID(UVModeFlagType0Name);
|
||||
|
||||
public string GetUVModePropName(int dataIndex)
|
||||
{
|
||||
switch (dataIndex)
|
||||
{
|
||||
case 0:
|
||||
return UVModeFlag0Name;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public enum UVMode
|
||||
{
|
||||
DefaultUVChannel, //0 0b_00 modeIndex 00
|
||||
SpecialUVChannel, //1 0b_01 modeIndex 00
|
||||
PolarOrTwirl, //2 0b_10 modeIndex 00
|
||||
Cylinder, //3 0b_11 modeIndex 00
|
||||
MainTex, //0 0b_00 modeIndex 01
|
||||
ScreenUV, //1 0b_01 modeIndex 01
|
||||
WorldPos, //2 0b_10 modeIndex 01
|
||||
ObjectPos, //3 0b_11 modeIndex 01
|
||||
CommonUV, //0 0b_00 modeIndex 10
|
||||
UnknownOrMixed = -1
|
||||
}
|
||||
|
||||
public const int FLAG_BIT_UVMODE_POS_0_MAINTEX = 0 * 2;
|
||||
public const int FLAG_BIT_UVMODE_POS_0_MASKMAP = 1 * 2;
|
||||
public const int FLAG_BIT_UVMODE_POS_0_MASKMAP_2 = 2 * 2;
|
||||
public const int FLAG_BIT_UVMODE_POS_0_MASKMAP_3 = 3 * 2;
|
||||
public const int FLAG_BIT_UVMODE_POS_0_NOISE_MAP = 4 * 2;
|
||||
public const int FLAG_BIT_UVMODE_POS_0_NOISE_MASK_MAP = 5 * 2;
|
||||
public const int FLAG_BIT_UVMODE_POS_0_EMISSION_MAP = 6 * 2;
|
||||
public const int FLAG_BIT_UVMODE_POS_0_DISSOLVE_MAP = 7 * 2;
|
||||
public const int FLAG_BIT_UVMODE_POS_0_DISSOLVE_MASK_MAP = 8 * 2;
|
||||
public const int FLAG_BIT_UVMODE_POS_0_COLOR_BLEND_MAP = 9 * 2;
|
||||
public const int FLAG_BIT_UVMODE_POS_0_VERTEX_OFFSET_MAP = 10 * 2;
|
||||
public const int FLAG_BIT_UVMODE_POS_0_VERTEX_OFFSET_MASKMAP = 11 * 2;
|
||||
public const int FLAG_BIT_UVMODE_POS_0_BUMPMAP = 12 * 2;
|
||||
public const int FLAG_BIT_UVMODE_POS_0_RAMP_COLOR_MAP = 13 * 2;
|
||||
public const int FLAG_BIT_UVMODE_POS_0_PROGRAM_NOISE = 14 * 2;
|
||||
public const int FLAG_BIT_UVMODE_POS_0_SHAREDUV = 15 * 2;
|
||||
|
||||
public void GetUVModeFlagPropID(int flagIndex, out int flagID, out int flagTypeID)
|
||||
{
|
||||
switch (flagIndex)
|
||||
{
|
||||
case 0:
|
||||
flagID = UVModeFlag0PropID;
|
||||
flagTypeID = UVModeFlagType0PropID;
|
||||
return;
|
||||
}
|
||||
|
||||
flagID = 0;
|
||||
flagTypeID = 0;
|
||||
|
||||
}
|
||||
|
||||
public void SetUVMode(UVMode mode, int uvModePos, int flagIndex = 0)
|
||||
{
|
||||
GetUVModeFlagPropID(flagIndex, out int uvModeFlagPropId, out int uvModeFlagTypePropId);
|
||||
int uvModeFlag = material.GetInteger(uvModeFlagPropId);
|
||||
int uvModeFlagType = material.GetInteger(uvModeFlagTypePropId);
|
||||
|
||||
|
||||
int clearFlag = 0b_11 << uvModePos;
|
||||
clearFlag = ~ clearFlag;
|
||||
|
||||
uvModeFlag &= clearFlag;
|
||||
int modeBit = (int)mode % 4 << uvModePos;
|
||||
uvModeFlag |= modeBit;
|
||||
uvModeFlagType &= clearFlag;
|
||||
int typeBit = (int)mode / 4 << uvModePos;
|
||||
uvModeFlagType |= typeBit;
|
||||
|
||||
material.SetInteger(uvModeFlagPropId, uvModeFlag);
|
||||
material.SetInteger(uvModeFlagTypePropId, uvModeFlagType);
|
||||
}
|
||||
|
||||
public UVMode GetUVMode(int uvModePos, int flagIndex = 0)
|
||||
{
|
||||
GetUVModeFlagPropID(flagIndex, out int uvModeFlagPropId, out int uvModeFlagTypePropId);
|
||||
int uvModeFlag = material.GetInteger(uvModeFlagPropId);
|
||||
uvModeFlag = uvModeFlag >> uvModePos;
|
||||
uvModeFlag &= 0b_11;
|
||||
int uvModeFlagType = material.GetInteger(uvModeFlagTypePropId);
|
||||
uvModeFlagType = uvModeFlagType >> uvModePos;
|
||||
uvModeFlagType &= 0b_11;
|
||||
return (UVMode)(uvModeFlag + 4 * uvModeFlagType);
|
||||
}
|
||||
|
||||
public bool CheckIsUVModeOn(UVMode mode)
|
||||
{
|
||||
uint uvModeFlag0 = (uint)material.GetInteger(UVModeFlag0PropID);
|
||||
uint uvModeFlagType0 = (uint)material.GetInteger(UVModeFlagType0PropID);
|
||||
|
||||
uint uvModeflagBit = (uint)mode % 4;
|
||||
uint uvModeflagTypeBit = (uint)mode / 4;
|
||||
|
||||
bool isUvMode = false;
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
uint checkflagBit = uvModeFlag0 >> (i * 2);
|
||||
checkflagBit = checkflagBit & 0b_11;
|
||||
uint checkflagTypeBit = uvModeflagTypeBit >> (i * 2);
|
||||
checkflagTypeBit = checkflagTypeBit & 0b_11;
|
||||
if (checkflagBit == uvModeflagBit && checkflagTypeBit == uvModeflagTypeBit)
|
||||
{
|
||||
isUvMode = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return isUvMode;
|
||||
}
|
||||
|
||||
public const int FLAG_BIT_COLOR_CHANNEL_POS_0_MAINTEX_ALPHA = 0 * 2;
|
||||
public const int FLAG_BIT_COLOR_CHANNEL_POS_0_MASKMAP1 = 1 * 2;
|
||||
public const int FLAG_BIT_COLOR_CHANNEL_POS_0_MASKMAP2 = 2 * 2;
|
||||
public const int FLAG_BIT_COLOR_CHANNEL_POS_0_MASKMAP3 = 3 * 2;
|
||||
public const int FLAG_BIT_COLOR_CHANNEL_POS_0_NOISE_MASK = 4 * 2;
|
||||
public const int FLAG_BIT_COLOR_CHANNEL_POS_0_DISSOLVE_MAP = 5 * 2;
|
||||
public const int FLAG_BIT_COLOR_CHANNEL_POS_0_DISSOLVE_MASK_MAP = 6 * 2;
|
||||
public const int FLAG_BIT_COLOR_CHANNEL_POS_0_RAMP_COLOR_MAP = 7 * 2;
|
||||
|
||||
|
||||
public enum ColorChannel
|
||||
{
|
||||
X,
|
||||
Y,
|
||||
Z,
|
||||
W,
|
||||
UnKnownOrMixedValue
|
||||
}
|
||||
|
||||
public void SetColorChanel(ColorChannel channel, int colorChannelFlagPos)
|
||||
{
|
||||
int colorChannelFlag = material.GetInteger(colorChannelFlagId);
|
||||
|
||||
int clearFlag = 0b_11 << colorChannelFlagPos;
|
||||
clearFlag = ~ clearFlag;
|
||||
|
||||
colorChannelFlag &= clearFlag;
|
||||
int channelBit = (int)channel << colorChannelFlagPos;
|
||||
colorChannelFlag |= channelBit;
|
||||
|
||||
material.SetInteger(colorChannelFlagId, colorChannelFlag);
|
||||
}
|
||||
|
||||
public ColorChannel GetColorChanel(int colorChannelFlagPos)
|
||||
{
|
||||
int colorChannelFlag = material.GetInteger(colorChannelFlagId);
|
||||
colorChannelFlag = colorChannelFlag >> colorChannelFlagPos;
|
||||
colorChannelFlag &= 0b_11;
|
||||
return (ColorChannel)colorChannelFlag;
|
||||
}
|
||||
|
||||
public const int FLAG_BIT_PNOISE_BLEND_POS_0_BASE_BLEND = 0 * 3;
|
||||
public const int FLAG_BIT_PNOISE_BLEND_POS_0_MASK = 1 * 3;
|
||||
public const int FLAG_BIT_PNOISE_BLEND_POS_0_DISSOLVE = 2 * 3;
|
||||
public const int FLAG_BIT_PNOISE_BLEND_POS_0_DISTORT = 3 * 3;
|
||||
public const int FLAG_BIT_PNOISE_BLEND_POS_0_MAINTEX = 4 * 3;
|
||||
|
||||
public enum PNoiseBlendMode
|
||||
{
|
||||
NotUse = 0,
|
||||
Multiply = 1,
|
||||
Min = 2,
|
||||
HardLight = 3,
|
||||
UnKnownOrMixedValue = -1
|
||||
|
||||
//后续看看要不要更多吧
|
||||
}
|
||||
|
||||
public void SetPNoiseBlendMode(PNoiseBlendMode mode, int pNoiseBlendModeFlagPos)
|
||||
{
|
||||
int pNoiseBlendFlag = material.GetInteger(pNoiseBlendFlagId);
|
||||
int blendMode = (int)mode;
|
||||
if (blendMode < 0) return;
|
||||
int clearFlag = 0b_111 << pNoiseBlendModeFlagPos;
|
||||
clearFlag = ~clearFlag;
|
||||
pNoiseBlendFlag &= clearFlag;
|
||||
int pNoiseBlendBit = blendMode << pNoiseBlendModeFlagPos;
|
||||
//先不考虑超过4个选项(2bit)的情况
|
||||
pNoiseBlendFlag |= pNoiseBlendBit;
|
||||
material.SetInteger(pNoiseBlendFlagId, pNoiseBlendFlag);
|
||||
}
|
||||
|
||||
public PNoiseBlendMode GetPNoiseBlendMode(int pNoiseBlendModeFlagPos)
|
||||
{
|
||||
int pNoiseBlendFlag = material.GetInteger(pNoiseBlendFlagId);
|
||||
pNoiseBlendFlag = pNoiseBlendFlag >> pNoiseBlendModeFlagPos;
|
||||
pNoiseBlendFlag &= 0b_111;
|
||||
//先不考虑超过4个选项(2bit)的情况
|
||||
return (PNoiseBlendMode)pNoiseBlendFlag;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
11
Packages/NB_FX/NBShaders2/Runtime/NBShaderFlags.cs.meta
Normal file
11
Packages/NB_FX/NBShaders2/Runtime/NBShaderFlags.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2b35030d15614953b769ad23d9fe5dfe
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,36 @@
|
||||
namespace NBShader
|
||||
{
|
||||
/// <summary>
|
||||
/// Serialized material mode values used by NBShader intent resolution.
|
||||
/// These values mirror shader properties and must remain compatible with existing materials.
|
||||
/// </summary>
|
||||
internal static class NBShaderMaterialIntentProtocol
|
||||
{
|
||||
public const int MeshSourceParticle = 0;
|
||||
public const int MeshSourceUIEffectRawImage = 2;
|
||||
public const int MeshSourceUIEffectSprite = 3;
|
||||
public const int MeshSourceUIEffectBaseMap = 4;
|
||||
public const int MeshSourceUIParticle = 5;
|
||||
|
||||
public const int TransparentOpaque = 0;
|
||||
public const int TransparentTransparent = 1;
|
||||
public const int TransparentCutOff = 2;
|
||||
|
||||
public const int FxLightUnlit = 0;
|
||||
public const int FxLightBlinnPhong = 1;
|
||||
public const int FxLightHalfLambert = 2;
|
||||
public const int FxLightPbr = 3;
|
||||
public const int FxLightSixWay = 4;
|
||||
|
||||
public const int BlendAlpha = 0;
|
||||
public const int BlendPremultiply = 1;
|
||||
public const int BlendAdditive = 2;
|
||||
public const int BlendMultiply = 3;
|
||||
public const int BlendOpaque = 4;
|
||||
|
||||
public const int TimeUnscaled = 1;
|
||||
public const int TimeScriptable = 2;
|
||||
|
||||
public const int VatTyflow = 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c88a6a4a7ec940c4aa97cfdcf4a8349e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,574 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBShader
|
||||
{
|
||||
/// <summary>
|
||||
/// Resolves the serialized material feature intent into tier-filtered keywords and pass requirements.
|
||||
/// This class is read-only: it never changes material properties, keywords, or shader pass state.
|
||||
/// </summary>
|
||||
internal static class NBShaderMaterialIntentResolver
|
||||
{
|
||||
private static readonly KeywordToggleBinding[] ToggleKeywordBindings =
|
||||
{
|
||||
new KeywordToggleBinding("_SoftParticlesEnabled", "_SOFTPARTICLES_ON"),
|
||||
new KeywordToggleBinding("_DistanceFade_Toggle", "_DISTANCE_FADE"),
|
||||
new KeywordToggleBinding("_StencilWithoutPlayerToggle", "_STENCIL_WITHOUT_PLAYER"),
|
||||
new KeywordToggleBinding("_Mask_Toggle", "_MASKMAP_ON"),
|
||||
new KeywordToggleBinding("_noisemapEnabled", "_NOISEMAP"),
|
||||
new KeywordToggleBinding("_EmissionEnabled", "_EMISSION"),
|
||||
new KeywordToggleBinding("_ColorBlendMap_Toggle", "_COLORMAPBLEND"),
|
||||
new KeywordToggleBinding("_RampColorToggle", "_COLOR_RAMP"),
|
||||
new KeywordToggleBinding("_Dissolve_Toggle", "_DISSOLVE"),
|
||||
new KeywordToggleBinding("_ProgramNoise_Toggle", "_PROGRAM_NOISE"),
|
||||
new KeywordToggleBinding("_SharedUVToggle", "_SHARED_UV"),
|
||||
new KeywordToggleBinding("_fresnelEnabled", "_FRESNEL"),
|
||||
new KeywordToggleBinding("_ParallaxMapping_Toggle", "_PARALLAX_MAPPING"),
|
||||
new KeywordToggleBinding("_VertexOffset_Toggle", "_VERTEX_OFFSET"),
|
||||
new KeywordToggleBinding("_FlipbookBlending", "_FLIPBOOKBLENDING_ON"),
|
||||
new KeywordToggleBinding("_BumpMapToggle", "_NORMALMAP"),
|
||||
new KeywordToggleBinding("_MatCapToggle", "_MATCAP"),
|
||||
new KeywordToggleBinding("_BlinnPhongSpecularToggle", "_SPECULAR_COLOR"),
|
||||
new KeywordToggleBinding("_SixWayColorAbsorptionToggle", "VFX_SIX_WAY_ABSORPTION"),
|
||||
new KeywordToggleBinding("_DepthDecal_Toggle", "_DEPTH_DECAL"),
|
||||
new KeywordToggleBinding("_DepthOutline_Toggle", "_DEPTH_OUTLINE"),
|
||||
new KeywordToggleBinding("_OverrideZ_Toggle", "_OVERRIDE_Z"),
|
||||
new KeywordToggleBinding("_Mask2_Toggle", "_MASKMAP2_ON"),
|
||||
new KeywordToggleBinding("_Mask3_Toggle", "_MASKMAP3_ON"),
|
||||
new KeywordToggleBinding("_noiseMaskMap_Toggle", "_NOISE_MASKMAP"),
|
||||
new KeywordToggleBinding("_Distortion_Choraticaberrat_Toggle", "_CHROMATIC_ABERRATION"),
|
||||
new KeywordToggleBinding("_DissolveMask_Toggle", "_DISSOLVE_MASK"),
|
||||
new KeywordToggleBinding("_Dissolve_useRampMap_Toggle", "_DISSOLVE_RAMP"),
|
||||
new KeywordToggleBinding("_ProgramNoise_Simple_Toggle", "_PROGRAM_NOISE_SIMPLE"),
|
||||
new KeywordToggleBinding("_ProgramNoise_Voronoi_Toggle", "_PROGRAM_NOISE_VORONOI"),
|
||||
new KeywordToggleBinding("_VertexOffset_Mask_Toggle", "_VERTEX_OFFSET_MASKMAP"),
|
||||
new KeywordToggleBinding("_NB_Debug_Dissolve", "NB_DEBUG_DISSOLVE"),
|
||||
new KeywordToggleBinding("_NB_Debug_Distort", "NB_DEBUG_DISTORT"),
|
||||
new KeywordToggleBinding("_NB_Debug_Fresnel", "NB_DEBUG_FRESNEL"),
|
||||
new KeywordToggleBinding("_NB_Debug_Mask", "NB_DEBUG_MASK"),
|
||||
new KeywordToggleBinding("_NB_Debug_PNoise", "NB_DEBUG_PNOISE"),
|
||||
new KeywordToggleBinding("_NB_Debug_VertexOffset", "NB_DEBUG_VERTEX_OFFSET")
|
||||
};
|
||||
|
||||
private static readonly string[] HoudiniVatKeywords =
|
||||
{
|
||||
"_HOUDINI_VAT_SOFTBODY",
|
||||
"_HOUDINI_VAT_RIGIDBODY",
|
||||
"_HOUDINI_VAT_DYNAMIC_REMESH",
|
||||
"_HOUDINI_VAT_PARTICLE_SPRITE"
|
||||
};
|
||||
|
||||
private static readonly string[] TyflowVatKeywords =
|
||||
{
|
||||
"_TYFLOW_VAT_ABSOLUTE",
|
||||
"_TYFLOW_VAT_RELATIVE",
|
||||
"_TYFLOW_VAT_SKIN_R",
|
||||
"_TYFLOW_VAT_SKIN_PR",
|
||||
"_TYFLOW_VAT_SKIN_PRSAVE",
|
||||
"_TYFLOW_VAT_SKIN_PRSXYZ"
|
||||
};
|
||||
|
||||
public static bool IsNBShaderMaterial(Material material)
|
||||
{
|
||||
return material != null &&
|
||||
material.shader != null &&
|
||||
material.shader.name == NBShaderFeatureCatalog.ShaderName;
|
||||
}
|
||||
|
||||
public static NBShaderMaterialIntentResult Resolve(Material material, NBShaderFeatureTier tier)
|
||||
{
|
||||
return Resolve(
|
||||
material,
|
||||
tier,
|
||||
NBShaderFeatureCatalog.RawKeywords,
|
||||
NBShaderPassFeatureCatalog.GetDefaultAllowedPassFeatures(tier));
|
||||
}
|
||||
|
||||
public static NBShaderMaterialIntentResult Resolve(
|
||||
Material material,
|
||||
NBShaderFeatureTier tier,
|
||||
IEnumerable<string> allowedManagedKeywords,
|
||||
IEnumerable<string> allowedPassFeatureIds)
|
||||
{
|
||||
var allowedKeywords = BuildAllowedKeywordSet(allowedManagedKeywords);
|
||||
var allowedPassFeatures = BuildAllowedPassFeatureSet(allowedPassFeatureIds);
|
||||
var intendedKeywords = ResolveIntendedManagedKeywords(material);
|
||||
var effectiveKeywords = FilterAllowedKeywords(intendedKeywords, allowedKeywords);
|
||||
ApplyKeywordDependencies(effectiveKeywords);
|
||||
var strippedKeywords = BuildDifference(intendedKeywords, effectiveKeywords);
|
||||
var passIntents = ResolvePassIntents(material, effectiveKeywords, allowedPassFeatures);
|
||||
|
||||
return new NBShaderMaterialIntentResult(
|
||||
material,
|
||||
tier,
|
||||
ToCatalogOrderedArray(intendedKeywords),
|
||||
ToCatalogOrderedArray(effectiveKeywords),
|
||||
ToCatalogOrderedArray(strippedKeywords),
|
||||
passIntents);
|
||||
}
|
||||
|
||||
private static HashSet<string> ResolveIntendedManagedKeywords(Material material)
|
||||
{
|
||||
var keywords = new HashSet<string>(StringComparer.Ordinal);
|
||||
if (!IsNBShaderMaterial(material))
|
||||
return keywords;
|
||||
|
||||
for (var i = 0; i < ToggleKeywordBindings.Length; i++)
|
||||
{
|
||||
var binding = ToggleKeywordBindings[i];
|
||||
if (GetFloat(material, binding.propertyName, 0f) > 0.5f)
|
||||
AddManagedKeyword(keywords, binding.keyword);
|
||||
}
|
||||
|
||||
int meshMode = GetInt(material, "_MeshSourceMode", 0);
|
||||
int transparentMode = GetInt(material, "_TransparentMode", NBShaderMaterialIntentProtocol.TransparentTransparent);
|
||||
if (transparentMode == NBShaderMaterialIntentProtocol.TransparentCutOff)
|
||||
AddManagedKeyword(keywords, "_ALPHATEST_ON");
|
||||
|
||||
int blendMode = ResolveBlendMode(material, transparentMode);
|
||||
switch (blendMode)
|
||||
{
|
||||
case NBShaderMaterialIntentProtocol.BlendPremultiply:
|
||||
case NBShaderMaterialIntentProtocol.BlendAdditive:
|
||||
AddManagedKeyword(keywords, "_ALPHAPREMULTIPLY_ON");
|
||||
break;
|
||||
case NBShaderMaterialIntentProtocol.BlendMultiply:
|
||||
AddManagedKeyword(keywords, "_ALPHAMODULATE_ON");
|
||||
break;
|
||||
}
|
||||
|
||||
if (IsParticleMeshSource(meshMode))
|
||||
AddManagedKeyword(keywords, "_PARCUSTOMDATA_ON");
|
||||
|
||||
switch (GetInt(material, "_TimeMode", 0))
|
||||
{
|
||||
case NBShaderMaterialIntentProtocol.TimeUnscaled:
|
||||
AddManagedKeyword(keywords, "_UNSCALETIME");
|
||||
break;
|
||||
case NBShaderMaterialIntentProtocol.TimeScriptable:
|
||||
AddManagedKeyword(keywords, "_SCRIPTABLETIME");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (GetInt(material, "_FxLightMode", NBShaderMaterialIntentProtocol.FxLightUnlit))
|
||||
{
|
||||
case NBShaderMaterialIntentProtocol.FxLightUnlit:
|
||||
AddManagedKeyword(keywords, "_FX_LIGHT_MODE_UNLIT");
|
||||
break;
|
||||
case NBShaderMaterialIntentProtocol.FxLightBlinnPhong:
|
||||
AddManagedKeyword(keywords, "_FX_LIGHT_MODE_BLINN_PHONG");
|
||||
break;
|
||||
case NBShaderMaterialIntentProtocol.FxLightHalfLambert:
|
||||
AddManagedKeyword(keywords, "_FX_LIGHT_MODE_HALF_LAMBERT");
|
||||
break;
|
||||
case NBShaderMaterialIntentProtocol.FxLightPbr:
|
||||
AddManagedKeyword(keywords, "_FX_LIGHT_MODE_PBR");
|
||||
break;
|
||||
case NBShaderMaterialIntentProtocol.FxLightSixWay:
|
||||
AddManagedKeyword(keywords, "_FX_LIGHT_MODE_SIX_WAY");
|
||||
break;
|
||||
}
|
||||
|
||||
if (GetInt(material, "_DistortMode", 0) == 1)
|
||||
AddManagedKeyword(keywords, "_DISTORT_REFRACTION");
|
||||
|
||||
if (GetInt(material, "_RampColorSourceMode", 0) == 1)
|
||||
AddManagedKeyword(keywords, "_COLOR_RAMP_MAP");
|
||||
|
||||
if (GetInt(material, "_DissolveRampSourceMode", 0) == 1 &&
|
||||
GetFloat(material, "_Dissolve_useRampMap_Toggle", 0f) > 0.5f)
|
||||
{
|
||||
AddManagedKeyword(keywords, "_DISSOLVE_RAMP_MAP");
|
||||
}
|
||||
|
||||
if (!IsUIEffectMeshSource(meshMode) && GetInt(material, "_ScreenDistortModeToggle", 0) != 0)
|
||||
AddManagedKeyword(keywords, "_SCREEN_DISTORT_MODE");
|
||||
|
||||
ResolveVatKeywords(material, keywords);
|
||||
|
||||
return keywords;
|
||||
}
|
||||
|
||||
private static void ResolveVatKeywords(Material material, HashSet<string> keywords)
|
||||
{
|
||||
if (GetFloat(material, "_VAT_Toggle", 0f) <= 0.5f)
|
||||
return;
|
||||
|
||||
keywords.Remove("_FLIPBOOKBLENDING_ON");
|
||||
AddManagedKeyword(keywords, "_VAT");
|
||||
|
||||
if (GetInt(material, "_VATMode", 0) == NBShaderMaterialIntentProtocol.VatTyflow)
|
||||
{
|
||||
AddManagedKeyword(keywords, "_VAT_TYFLOW");
|
||||
AddIndexedKeyword(keywords, TyflowVatKeywords, GetInt(material, "_TyFlowVATSubMode", 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddManagedKeyword(keywords, "_VAT_HOUDINI");
|
||||
AddIndexedKeyword(keywords, HoudiniVatKeywords, GetInt(material, "_HoudiniVATSubMode", 0));
|
||||
}
|
||||
}
|
||||
|
||||
private static NBShaderPassIntent[] ResolvePassIntents(
|
||||
Material material,
|
||||
HashSet<string> effectiveKeywords,
|
||||
HashSet<string> allowedPassFeatures)
|
||||
{
|
||||
var result = new List<NBShaderPassIntent>(7);
|
||||
bool isNBShaderMaterial = IsNBShaderMaterial(material);
|
||||
int meshMode = GetInt(material, "_MeshSourceMode", 0);
|
||||
int transparentMode = GetInt(material, "_TransparentMode", NBShaderMaterialIntentProtocol.TransparentTransparent);
|
||||
bool uiEffect = IsUIEffectMeshSource(meshMode);
|
||||
int screenDistortMode = isNBShaderMaterial ? GetInt(material, "_ScreenDistortModeToggle", 0) : 0;
|
||||
bool screenDistortKeywordEnabled = effectiveKeywords.Contains("_SCREEN_DISTORT_MODE");
|
||||
bool screenDistortEnabled = !uiEffect && screenDistortMode != 0 && screenDistortKeywordEnabled;
|
||||
bool disableMainPass = GetFloat(material, "_DisableMainPassToggle", 0f) > 0.5f;
|
||||
bool mainPassEnabled = isNBShaderMaterial && (!screenDistortEnabled || !disableMainPass);
|
||||
|
||||
result.Add(NBShaderPassIntent.CreateCore(
|
||||
NBShaderPassFeatureCatalog.MainForwardPassName,
|
||||
mainPassEnabled,
|
||||
mainPassEnabled ? "main pass" : "disabled by screen distort material intent"));
|
||||
|
||||
AddManagedPass(
|
||||
result,
|
||||
NBShaderPassFeatureCatalog.BackFirstPassId,
|
||||
!uiEffect &&
|
||||
transparentMode == NBShaderMaterialIntentProtocol.TransparentTransparent &&
|
||||
GetFloat(material, "_BackFirstPassToggle", 0f) > 0.5f,
|
||||
allowedPassFeatures,
|
||||
"back first material toggle");
|
||||
|
||||
AddManagedPass(
|
||||
result,
|
||||
NBShaderPassFeatureCatalog.CameraOpaqueDistortPassId,
|
||||
screenDistortEnabled && screenDistortMode == 2,
|
||||
allowedPassFeatures,
|
||||
"camera opaque screen distort material mode");
|
||||
|
||||
AddManagedPass(
|
||||
result,
|
||||
NBShaderPassFeatureCatalog.DeferredDistortPassId,
|
||||
screenDistortEnabled && screenDistortMode == 1,
|
||||
allowedPassFeatures,
|
||||
"deferred screen distort material mode");
|
||||
|
||||
AddManagedPass(
|
||||
result,
|
||||
NBShaderPassFeatureCatalog.DepthOnlyPassId,
|
||||
!uiEffect && ResolveZWrite(material, transparentMode),
|
||||
allowedPassFeatures,
|
||||
"depth write material state");
|
||||
|
||||
AddManagedPass(
|
||||
result,
|
||||
NBShaderPassFeatureCatalog.ShadowCasterPassId,
|
||||
!uiEffect &&
|
||||
GetFloat(material, "_AffectsShadows", 0f) > 0.5f &&
|
||||
IsKnownTransparentMode(GetInt(material, "_TransparentMode", NBShaderMaterialIntentProtocol.TransparentTransparent)),
|
||||
allowedPassFeatures,
|
||||
"shadow material state");
|
||||
|
||||
AddManagedPass(
|
||||
result,
|
||||
NBShaderPassFeatureCatalog.Universal2DPassId,
|
||||
isNBShaderMaterial,
|
||||
allowedPassFeatures,
|
||||
"URP 2D renderer pass");
|
||||
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
private static void AddManagedPass(
|
||||
List<NBShaderPassIntent> result,
|
||||
string featureId,
|
||||
bool enabledByMaterial,
|
||||
HashSet<string> allowedPassFeatures,
|
||||
string reason)
|
||||
{
|
||||
NBShaderPassFeatureInfo feature;
|
||||
if (!NBShaderPassFeatureCatalog.TryGetPassFeature(featureId, out feature))
|
||||
return;
|
||||
|
||||
bool allowedByTier = allowedPassFeatures == null || allowedPassFeatures.Contains(featureId);
|
||||
result.Add(new NBShaderPassIntent(
|
||||
featureId,
|
||||
feature.passName,
|
||||
enabledByMaterial,
|
||||
allowedByTier,
|
||||
enabledByMaterial && allowedByTier,
|
||||
reason));
|
||||
}
|
||||
|
||||
private static HashSet<string> BuildAllowedKeywordSet(IEnumerable<string> allowedManagedKeywords)
|
||||
{
|
||||
var result = new HashSet<string>(StringComparer.Ordinal);
|
||||
if (allowedManagedKeywords == null)
|
||||
{
|
||||
for (var i = 0; i < NBShaderFeatureCatalog.RawKeywords.Length; i++)
|
||||
result.Add(NBShaderFeatureCatalog.RawKeywords[i]);
|
||||
return result;
|
||||
}
|
||||
|
||||
foreach (var keyword in allowedManagedKeywords)
|
||||
{
|
||||
if (NBShaderFeatureCatalog.IsManagedKeyword(keyword))
|
||||
result.Add(keyword);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static HashSet<string> BuildAllowedPassFeatureSet(IEnumerable<string> allowedPassFeatureIds)
|
||||
{
|
||||
if (allowedPassFeatureIds == null)
|
||||
return null;
|
||||
|
||||
var result = new HashSet<string>(StringComparer.Ordinal);
|
||||
foreach (var featureId in allowedPassFeatureIds)
|
||||
{
|
||||
if (NBShaderPassFeatureCatalog.IsManagedPassFeature(featureId))
|
||||
result.Add(featureId);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static HashSet<string> FilterAllowedKeywords(HashSet<string> source, HashSet<string> allowed)
|
||||
{
|
||||
var result = new HashSet<string>(StringComparer.Ordinal);
|
||||
foreach (var keyword in source)
|
||||
{
|
||||
if (allowed.Contains(keyword))
|
||||
result.Add(keyword);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void ApplyKeywordDependencies(HashSet<string> keywords)
|
||||
{
|
||||
RemoveIfParentMissing(keywords, "_MASKMAP_ON", "_MASKMAP2_ON", "_MASKMAP3_ON", "NB_DEBUG_MASK");
|
||||
RemoveIfParentMissing(keywords, "_NOISEMAP", "_NOISE_MASKMAP", "NB_DEBUG_DISTORT", "_SCREEN_DISTORT_MODE", "_DISTORT_REFRACTION");
|
||||
RemoveIfParentMissing(keywords, "_COLOR_RAMP", "_COLOR_RAMP_MAP");
|
||||
RemoveIfParentMissing(keywords, "_DISSOLVE", "_DISSOLVE_MASK", "_DISSOLVE_RAMP", "NB_DEBUG_DISSOLVE");
|
||||
RemoveIfParentMissing(keywords, "_DISSOLVE_RAMP", "_DISSOLVE_RAMP_MAP");
|
||||
RemoveIfParentMissing(keywords, "_PROGRAM_NOISE", "_PROGRAM_NOISE_SIMPLE", "_PROGRAM_NOISE_VORONOI", "NB_DEBUG_PNOISE");
|
||||
RemoveIfParentMissing(keywords, "_FRESNEL", "NB_DEBUG_FRESNEL");
|
||||
RemoveIfParentMissing(keywords, "_VERTEX_OFFSET", "_VERTEX_OFFSET_MASKMAP", "NB_DEBUG_VERTEX_OFFSET");
|
||||
RemoveIfParentMissing(keywords, "_VAT", "_VAT_HOUDINI", "_VAT_TYFLOW");
|
||||
RemoveIfParentMissing(keywords, "_VAT_HOUDINI", HoudiniVatKeywords);
|
||||
RemoveIfParentMissing(keywords, "_VAT_TYFLOW", TyflowVatKeywords);
|
||||
RemoveIfParentMissing(keywords, "_FX_LIGHT_MODE_SIX_WAY", "VFX_SIX_WAY_ABSORPTION");
|
||||
}
|
||||
|
||||
private static void RemoveIfParentMissing(HashSet<string> keywords, string parentKeyword, params string[] dependentKeywords)
|
||||
{
|
||||
if (keywords.Contains(parentKeyword) || dependentKeywords == null)
|
||||
return;
|
||||
|
||||
for (var i = 0; i < dependentKeywords.Length; i++)
|
||||
keywords.Remove(dependentKeywords[i]);
|
||||
}
|
||||
|
||||
private static HashSet<string> BuildDifference(HashSet<string> source, HashSet<string> retained)
|
||||
{
|
||||
var result = new HashSet<string>(StringComparer.Ordinal);
|
||||
foreach (var keyword in source)
|
||||
{
|
||||
if (!retained.Contains(keyword))
|
||||
result.Add(keyword);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void AddManagedKeyword(HashSet<string> keywords, string keyword)
|
||||
{
|
||||
if (NBShaderFeatureCatalog.IsManagedKeyword(keyword))
|
||||
keywords.Add(keyword);
|
||||
}
|
||||
|
||||
private static void AddIndexedKeyword(HashSet<string> keywords, string[] source, int index)
|
||||
{
|
||||
if (source == null || index < 0 || index >= source.Length)
|
||||
return;
|
||||
|
||||
AddManagedKeyword(keywords, source[index]);
|
||||
}
|
||||
|
||||
private static string[] ToCatalogOrderedArray(HashSet<string> keywords)
|
||||
{
|
||||
if (keywords == null || keywords.Count == 0)
|
||||
return new string[0];
|
||||
|
||||
var result = new List<string>();
|
||||
for (var i = 0; i < NBShaderFeatureCatalog.RawKeywords.Length; i++)
|
||||
{
|
||||
var keyword = NBShaderFeatureCatalog.RawKeywords[i];
|
||||
if (keywords.Contains(keyword))
|
||||
result.Add(keyword);
|
||||
}
|
||||
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
private static bool IsParticleMeshSource(int mode)
|
||||
{
|
||||
return mode == NBShaderMaterialIntentProtocol.MeshSourceParticle ||
|
||||
mode == NBShaderMaterialIntentProtocol.MeshSourceUIParticle;
|
||||
}
|
||||
|
||||
private static bool IsUIEffectMeshSource(int mode)
|
||||
{
|
||||
return mode == NBShaderMaterialIntentProtocol.MeshSourceUIEffectRawImage ||
|
||||
mode == NBShaderMaterialIntentProtocol.MeshSourceUIEffectSprite ||
|
||||
mode == NBShaderMaterialIntentProtocol.MeshSourceUIEffectBaseMap ||
|
||||
mode == NBShaderMaterialIntentProtocol.MeshSourceUIParticle;
|
||||
}
|
||||
|
||||
private static bool IsKnownTransparentMode(int mode)
|
||||
{
|
||||
return mode == NBShaderMaterialIntentProtocol.TransparentOpaque ||
|
||||
mode == NBShaderMaterialIntentProtocol.TransparentTransparent ||
|
||||
mode == NBShaderMaterialIntentProtocol.TransparentCutOff;
|
||||
}
|
||||
|
||||
private static int ResolveBlendMode(Material material, int transparentMode)
|
||||
{
|
||||
if (!IsKnownTransparentMode(transparentMode))
|
||||
return GetInt(material, "_Blend", 0);
|
||||
|
||||
if (transparentMode == NBShaderMaterialIntentProtocol.TransparentOpaque ||
|
||||
transparentMode == NBShaderMaterialIntentProtocol.TransparentCutOff)
|
||||
return NBShaderMaterialIntentProtocol.BlendOpaque;
|
||||
|
||||
int blendMode = GetInt(material, "_Blend", 0);
|
||||
return blendMode == NBShaderMaterialIntentProtocol.BlendOpaque
|
||||
? NBShaderMaterialIntentProtocol.BlendAlpha
|
||||
: blendMode;
|
||||
}
|
||||
|
||||
private static bool ResolveZWrite(Material material, int transparentMode)
|
||||
{
|
||||
bool zWrite;
|
||||
if (transparentMode == NBShaderMaterialIntentProtocol.TransparentOpaque ||
|
||||
transparentMode == NBShaderMaterialIntentProtocol.TransparentCutOff)
|
||||
{
|
||||
zWrite = true;
|
||||
}
|
||||
else if (transparentMode == NBShaderMaterialIntentProtocol.TransparentTransparent)
|
||||
{
|
||||
zWrite = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
zWrite = GetInt(material, "_ZWrite", 0) == 1;
|
||||
}
|
||||
|
||||
float forceZWrite = GetFloat(material, "_ForceZWriteToggle", 0f);
|
||||
if (forceZWrite > 0.5f && forceZWrite < 1.5f)
|
||||
return true;
|
||||
if (forceZWrite > 1.5f)
|
||||
return false;
|
||||
return zWrite;
|
||||
}
|
||||
|
||||
private static float GetFloat(Material material, string propertyName, float fallback)
|
||||
{
|
||||
return material != null && material.HasProperty(propertyName) ? material.GetFloat(propertyName) : fallback;
|
||||
}
|
||||
|
||||
private static int GetInt(Material material, string propertyName, int fallback)
|
||||
{
|
||||
return Mathf.RoundToInt(GetFloat(material, propertyName, fallback));
|
||||
}
|
||||
|
||||
private struct KeywordToggleBinding
|
||||
{
|
||||
public readonly string propertyName;
|
||||
public readonly string keyword;
|
||||
|
||||
public KeywordToggleBinding(string propertyName, string keyword)
|
||||
{
|
||||
this.propertyName = propertyName;
|
||||
this.keyword = keyword;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class NBShaderMaterialIntentResult
|
||||
{
|
||||
public readonly Material material;
|
||||
public readonly NBShaderFeatureTier tier;
|
||||
public readonly string[] intendedManagedKeywords;
|
||||
public readonly string[] effectiveKeywords;
|
||||
public readonly string[] strippedManagedKeywords;
|
||||
public readonly NBShaderPassIntent[] passes;
|
||||
public readonly string[] includedPassNames;
|
||||
public readonly string[] strippedPassNames;
|
||||
|
||||
public NBShaderMaterialIntentResult(
|
||||
Material material,
|
||||
NBShaderFeatureTier tier,
|
||||
string[] intendedManagedKeywords,
|
||||
string[] effectiveKeywords,
|
||||
string[] strippedManagedKeywords,
|
||||
NBShaderPassIntent[] passes)
|
||||
{
|
||||
this.material = material;
|
||||
this.tier = tier;
|
||||
this.intendedManagedKeywords = intendedManagedKeywords ?? new string[0];
|
||||
this.effectiveKeywords = effectiveKeywords ?? new string[0];
|
||||
this.strippedManagedKeywords = strippedManagedKeywords ?? new string[0];
|
||||
this.passes = passes ?? new NBShaderPassIntent[0];
|
||||
includedPassNames = BuildPassNameArray(this.passes, true);
|
||||
strippedPassNames = BuildPassNameArray(this.passes, false);
|
||||
}
|
||||
|
||||
private static string[] BuildPassNameArray(NBShaderPassIntent[] passes, bool included)
|
||||
{
|
||||
var result = new List<string>();
|
||||
for (var i = 0; i < passes.Length; i++)
|
||||
{
|
||||
var pass = passes[i];
|
||||
if (pass.included == included && !string.IsNullOrEmpty(pass.passName))
|
||||
result.Add(pass.passName);
|
||||
}
|
||||
|
||||
return result.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class NBShaderPassIntent
|
||||
{
|
||||
public readonly string featureId;
|
||||
public readonly string passName;
|
||||
public readonly bool enabledByMaterial;
|
||||
public readonly bool allowedByTier;
|
||||
public readonly bool included;
|
||||
public readonly string reason;
|
||||
|
||||
public NBShaderPassIntent(
|
||||
string featureId,
|
||||
string passName,
|
||||
bool enabledByMaterial,
|
||||
bool allowedByTier,
|
||||
bool included,
|
||||
string reason)
|
||||
{
|
||||
this.featureId = featureId;
|
||||
this.passName = passName;
|
||||
this.enabledByMaterial = enabledByMaterial;
|
||||
this.allowedByTier = allowedByTier;
|
||||
this.included = included;
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
public static NBShaderPassIntent CreateCore(string passName, bool included, string reason)
|
||||
{
|
||||
return new NBShaderPassIntent(null, passName, included, true, included, reason);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b6fbac1987464c5f9bf46b3b121d4c21
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
106
Packages/NB_FX/NBShaders2/Runtime/NBShaderPassFeatureCatalog.cs
Normal file
106
Packages/NB_FX/NBShaders2/Runtime/NBShaderPassFeatureCatalog.cs
Normal file
@@ -0,0 +1,106 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NBShader
|
||||
{
|
||||
/// <summary>
|
||||
/// Catalog of NBShader passes that can be controlled by feature tiering.
|
||||
/// UniversalForward is the primary pass and is intentionally not listed as a tier feature.
|
||||
/// </summary>
|
||||
internal static class NBShaderPassFeatureCatalog
|
||||
{
|
||||
public const string MainForwardPassName = "UniversalForward";
|
||||
|
||||
public const string BackFirstPassId = "pass.backFirst";
|
||||
public const string CameraOpaqueDistortPassId = "pass.screenDistort.cameraOpaque";
|
||||
public const string DeferredDistortPassId = "pass.screenDistort.deferred";
|
||||
public const string DepthOnlyPassId = "pass.depthOnly";
|
||||
public const string ShadowCasterPassId = "pass.shadowCaster";
|
||||
public const string Universal2DPassId = "pass.universal2D";
|
||||
|
||||
public static readonly NBShaderPassFeatureInfo[] RawPassFeatures =
|
||||
{
|
||||
new NBShaderPassFeatureInfo(BackFirstPassId, "SRPDefaultUnlit", "Back First Pass"),
|
||||
new NBShaderPassFeatureInfo(CameraOpaqueDistortPassId, "NBCameraOpaqueDistortPass", "Camera Opaque Distort Pass"),
|
||||
new NBShaderPassFeatureInfo(DeferredDistortPassId, "NBDeferredDistortPass", "Deferred Distort Pass"),
|
||||
new NBShaderPassFeatureInfo(DepthOnlyPassId, "DepthOnly", "Depth Only Pass"),
|
||||
new NBShaderPassFeatureInfo(ShadowCasterPassId, "ShadowCaster", "Shadow Caster Pass"),
|
||||
new NBShaderPassFeatureInfo(Universal2DPassId, "Universal2D", "Universal 2D Pass")
|
||||
};
|
||||
|
||||
public static readonly string[] RawPassFeatureIds = BuildRawPassFeatureIds();
|
||||
|
||||
private static readonly HashSet<string> RawPassFeatureIdSet = new HashSet<string>(RawPassFeatureIds);
|
||||
private static readonly Dictionary<string, NBShaderPassFeatureInfo> PassFeaturesById = BuildPassFeaturesById();
|
||||
private static readonly Dictionary<string, NBShaderPassFeatureInfo> PassFeaturesByPassName = BuildPassFeaturesByPassName();
|
||||
|
||||
public static bool IsManagedPassFeature(string featureId)
|
||||
{
|
||||
return !string.IsNullOrEmpty(featureId) && RawPassFeatureIdSet.Contains(featureId);
|
||||
}
|
||||
|
||||
public static bool TryGetPassFeature(string featureId, out NBShaderPassFeatureInfo feature)
|
||||
{
|
||||
if (string.IsNullOrEmpty(featureId))
|
||||
{
|
||||
feature = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
return PassFeaturesById.TryGetValue(featureId, out feature);
|
||||
}
|
||||
|
||||
public static bool TryGetPassFeatureByPassName(string passName, out NBShaderPassFeatureInfo feature)
|
||||
{
|
||||
if (string.IsNullOrEmpty(passName))
|
||||
{
|
||||
feature = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
return PassFeaturesByPassName.TryGetValue(passName, out feature);
|
||||
}
|
||||
|
||||
public static string[] GetDefaultAllowedPassFeatures(NBShaderFeatureTier tier)
|
||||
{
|
||||
return (string[])RawPassFeatureIds.Clone();
|
||||
}
|
||||
|
||||
private static string[] BuildRawPassFeatureIds()
|
||||
{
|
||||
var result = new string[RawPassFeatures.Length];
|
||||
for (var i = 0; i < RawPassFeatures.Length; i++)
|
||||
result[i] = RawPassFeatures[i].id;
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Dictionary<string, NBShaderPassFeatureInfo> BuildPassFeaturesById()
|
||||
{
|
||||
var result = new Dictionary<string, NBShaderPassFeatureInfo>();
|
||||
for (var i = 0; i < RawPassFeatures.Length; i++)
|
||||
result[RawPassFeatures[i].id] = RawPassFeatures[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Dictionary<string, NBShaderPassFeatureInfo> BuildPassFeaturesByPassName()
|
||||
{
|
||||
var result = new Dictionary<string, NBShaderPassFeatureInfo>();
|
||||
for (var i = 0; i < RawPassFeatures.Length; i++)
|
||||
result[RawPassFeatures[i].passName] = RawPassFeatures[i];
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class NBShaderPassFeatureInfo
|
||||
{
|
||||
public readonly string id;
|
||||
public readonly string passName;
|
||||
public readonly string displayName;
|
||||
|
||||
public NBShaderPassFeatureInfo(string id, string passName, string displayName)
|
||||
{
|
||||
this.id = id;
|
||||
this.passName = passName;
|
||||
this.displayName = displayName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3238bc94e7aff1147a510c286ad0a673
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Packages/NB_FX/NBShaders2/Runtime/Properties.meta
Normal file
8
Packages/NB_FX/NBShaders2/Runtime/Properties.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a81bdbda432342429bd339932aee1d15
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,3 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("com.xuanxuan.nb.shaders2.Editor")]
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f4991907da0943fe9b83896151ba7d2b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "com.xuanxuan.nb.shaders2",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:8f9e4d586616f13449cfeb86c5f704c2"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aed681b6b9e69ff4dbd8d55e012b87ff
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user