123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- using System;
- using System.Collections.Generic;
- using UnityEngine;
-
- namespace UnityEditor.ShaderGraph.Internal
- {
- [Serializable]
- public abstract class AbstractShaderProperty : ShaderInput
- {
- public abstract PropertyType propertyType { get; }
-
- internal override ConcreteSlotValueType concreteShaderValueType => propertyType.ToConcreteShaderValueType();
-
- // user selected precision setting
- [SerializeField]
- Precision m_Precision = Precision.Inherit;
-
- [Obsolete("AbstractShaderProperty.gpuInstanced is no longer used")]
- public bool gpuInstanced
- {
- get { return false; }
- set { }
- }
-
- internal virtual string GetHLSLVariableName(bool isSubgraphProperty, GenerationMode mode)
- {
- if (mode == GenerationMode.VFX)
- {
- // Per-element exposed properties are provided by the properties structure filled by VFX.
- if (overrideHLSLDeclaration)
- return $"PROP.{referenceName}";
- // For un-exposed global properties, just read from the cbuffer.
- else
- return referenceName;
- }
-
- return referenceName;
- }
-
- internal string GetConnectionStateHLSLVariableName()
- {
- return GetConnectionStateVariableName(referenceName + "_" + objectId);
- }
-
- // NOTE: this does not tell you the HLSLDeclaration of the entire property...
- // instead, it tells you what the DEFAULT HLSL Declaration would be, IF the property makes use of the default
- // to check ACTUAL HLSL Declaration types, enumerate the HLSL Properties and check their HLSLDeclarations...
- internal virtual HLSLDeclaration GetDefaultHLSLDeclaration()
- {
- if (overrideHLSLDeclaration)
- return hlslDeclarationOverride;
- // default Behavior switches between UnityPerMaterial and Global based on Exposed checkbox
- if (generatePropertyBlock)
- return HLSLDeclaration.UnityPerMaterial;
- else
- return HLSLDeclaration.Global;
- }
-
- // by default we disallow UI from choosing "DoNotDeclare"
- // it needs a bit more UI support to disable property node output slots before we make it public
- internal virtual bool AllowHLSLDeclaration(HLSLDeclaration decl) => (decl != HLSLDeclaration.DoNotDeclare);
-
- [SerializeField]
- internal bool overrideHLSLDeclaration = false;
-
- [SerializeField]
- internal HLSLDeclaration hlslDeclarationOverride;
-
- override internal bool isExposed => base.isExposed && shouldForceExposed;
-
- internal bool shouldForceExposed => (hlslDeclarationOverride == HLSLDeclaration.HybridPerInstance || GetDefaultHLSLDeclaration() == HLSLDeclaration.UnityPerMaterial) && isExposable;
-
- internal Precision precision
- {
- get => m_Precision;
- set => m_Precision = value;
- }
-
- ConcretePrecision m_ConcretePrecision = ConcretePrecision.Single;
- public ConcretePrecision concretePrecision => m_ConcretePrecision;
- internal void SetupConcretePrecision(ConcretePrecision defaultPrecision)
- {
- m_ConcretePrecision = precision.ToConcrete(defaultPrecision, defaultPrecision);
- }
-
- [SerializeField]
- bool m_Hidden = false;
- public bool hidden
- {
- get => m_Hidden;
- set => m_Hidden = value;
- }
-
- internal string hideTagString => hidden || (shouldForceExposed && !isExposed) ? "[HideInInspector]" : "";
-
- // reference names are the HLSL declaration name / property block ref name
- internal virtual void GetPropertyReferenceNames(List<string> result)
- {
- result.Add(referenceName);
- }
-
- // display names are used as the UI name in the property block / show up in the Material Inspector
- internal virtual void GetPropertyDisplayNames(List<string> result)
- {
- result.Add(displayName);
- }
-
- // the simple interface for simple properties
- internal virtual string GetPropertyBlockString()
- {
- return string.Empty;
- }
-
- internal bool shouldGeneratePropertyBlock => (generatePropertyBlock || shouldForceExposed)
- && GetDefaultHLSLDeclaration() != HLSLDeclaration.Global;
-
- // the more complex interface for complex properties (defaulted for simple properties)
- internal virtual void AppendPropertyBlockStrings(ShaderStringBuilder builder)
- {
- builder.AppendLine(GetPropertyBlockString());
- }
-
- internal abstract void ForeachHLSLProperty(Action<HLSLProperty> action);
-
- internal virtual string GetPropertyAsArgumentStringForVFX(string precisionString)
- {
- return GetPropertyAsArgumentString(precisionString);
- }
-
- internal abstract string GetPropertyAsArgumentString(string precisionString);
- internal abstract AbstractMaterialNode ToConcreteNode();
- internal abstract PreviewProperty GetPreviewMaterialProperty();
-
- public virtual string GetPropertyTypeString()
- {
- var typeString = propertyType.ToString();
- if (sgVersion < latestVersion)
- typeString = $"{typeString} (Legacy v{sgVersion})";
- return typeString;
- }
- }
-
- [Serializable]
- public abstract class AbstractShaderProperty<T> : AbstractShaderProperty
- {
- [SerializeField]
- T m_Value;
-
- public virtual T value
- {
- get => m_Value;
- set => m_Value = value;
- }
- }
-
- // class for extracting deprecated data from older versions of AbstractShaderProperty
- class LegacyShaderPropertyData
- {
- // indicates user wishes to support the HYBRID renderer GPU instanced path
- [SerializeField]
- public bool m_GPUInstanced = false;
-
- // converts the old m_GPUInstanced data into the new override HLSLDeclaration system.
- public static void UpgradeToHLSLDeclarationOverride(string json, AbstractShaderProperty property)
- {
- // this maintains the old behavior for versioned properties:
- // old exposed GPUInstanced properties are declared hybrid (becomes override in new system)
- // old unexposed GPUInstanced properties are declared global (becomes override in new system)
- // old exposed properties are declared UnityPerMaterial (default behavior, no override necessary)
- // old unexposed properties are declared Global (default behavior, no override necessary)
- // moving forward, users can use the overrides directly to control what it does
-
- var legacyShaderPropertyData = new LegacyShaderPropertyData();
- JsonUtility.FromJsonOverwrite(json, legacyShaderPropertyData);
- if (legacyShaderPropertyData.m_GPUInstanced)
- {
- property.overrideHLSLDeclaration = true;
- if (property.generatePropertyBlock)
- property.hlslDeclarationOverride = HLSLDeclaration.HybridPerInstance;
- else
- property.hlslDeclarationOverride = HLSLDeclaration.Global;
- }
- }
- }
-
- public enum HLSLType
- {
- // value types
- _float,
- _float2,
- _float3,
- _float4,
- _matrix4x4,
-
- // object types
- FirstObjectType,
- _Texture2D = FirstObjectType,
- _Texture3D,
- _TextureCube,
- _Texture2DArray,
- _SamplerState,
-
- // custom type
- _CUSTOM
- }
-
- // describes the different ways we can generate HLSL declarations
- [Flags]
- internal enum HLSLDeclaration
- {
- DoNotDeclare, // NOT declared in HLSL
- Global, // declared in the global scope, mainly for use with state coming from Shader.SetGlobal*()
- UnityPerMaterial, // declared in the UnityPerMaterial cbuffer, populated by Material or MaterialPropertyBlock
- HybridPerInstance, // declared using HybridRenderer path (v1 or v2) to get DOTS GPU instancing
- }
-
- internal struct HLSLProperty
- {
- public string name;
- public HLSLType type;
- public ConcretePrecision precision;
- public HLSLDeclaration declaration;
- public Action<ShaderStringBuilder> customDeclaration;
-
- public HLSLProperty(HLSLType type, string name, HLSLDeclaration declaration, ConcretePrecision precision = ConcretePrecision.Single)
- {
- this.type = type;
- this.name = name;
- this.declaration = declaration;
- this.precision = precision;
- this.customDeclaration = null;
- }
-
- public bool ValueEquals(HLSLProperty other)
- {
- if ((name != other.name) ||
- (type != other.type) ||
- (precision != other.precision) ||
- (declaration != other.declaration) ||
- ((customDeclaration == null) != (other.customDeclaration == null)))
- {
- return false;
- }
- else if (customDeclaration != null)
- {
- var ssb = new ShaderStringBuilder();
- var ssbother = new ShaderStringBuilder();
- customDeclaration(ssb);
- other.customDeclaration(ssbother);
- if (ssb.ToCodeBlock() != ssbother.ToCodeBlock())
- return false;
- }
- return true;
- }
-
- static string[,] kValueTypeStrings = new string[(int)HLSLType.FirstObjectType, 2]
- {
- {"float", "half"},
- {"float2", "half2"},
- {"float3", "half3"},
- {"float4", "half4"},
- {"float4x4", "half4x4"}
- };
-
- static string[] kObjectTypeStrings = new string[(int)HLSLType._CUSTOM - (int)HLSLType.FirstObjectType]
- {
- "TEXTURE2D",
- "TEXTURE3D",
- "TEXTURECUBE",
- "TEXTURE2D_ARRAY",
- "SAMPLER",
- };
-
- public bool IsObjectType()
- {
- return type == HLSLType._SamplerState ||
- type == HLSLType._Texture2D ||
- type == HLSLType._Texture3D ||
- type == HLSLType._TextureCube ||
- type == HLSLType._Texture2DArray ||
- type == HLSLType._CUSTOM;
- }
-
- public string GetValueTypeString()
- {
- if (type < HLSLType.FirstObjectType)
- return kValueTypeStrings[(int)type, (int)precision];
- return null;
- }
-
- public void AppendTo(ShaderStringBuilder ssb, Func<string, string> nameModifier = null)
- {
- var mName = nameModifier?.Invoke(name) ?? name;
-
- if (type < HLSLType.FirstObjectType)
- {
- ssb.Append(kValueTypeStrings[(int)type, (int)precision]);
- ssb.Append(" ");
- ssb.Append(mName);
- ssb.Append(";");
- }
- else if (type < HLSLType._CUSTOM)
- {
- ssb.Append(kObjectTypeStrings[type - HLSLType.FirstObjectType]);
- ssb.Append("(");
- ssb.Append(mName);
- ssb.Append(");");
- }
- else
- {
- customDeclaration(ssb);
- }
- //ssb.Append(" // ");
- //ssb.Append(declaration.ToString());
- ssb.AppendNewLine();
- }
- }
- }
|