testss
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("Unity.ShaderGraph.Editor.Tests")]
|
||||
[assembly: InternalsVisibleTo("Unity.RenderPipelines.Universal.Editor")]
|
||||
[assembly: InternalsVisibleTo("Unity.ShaderGraph.GraphicsTests")]
|
||||
[assembly: InternalsVisibleTo("Unity.ShaderGraph.Editor.GraphicsTests")]
|
||||
[assembly: InternalsVisibleTo("Unity.RenderPipelines.HighDefinition.Editor")]
|
||||
[assembly: InternalsVisibleTo("Unity.VisualEffectGraph.Editor")]
|
@@ -0,0 +1,13 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
static class CreateShaderGraph
|
||||
{
|
||||
[MenuItem("Assets/Create/Shader/Blank Shader Graph", false, 208)]
|
||||
public static void CreateBlankShaderGraph()
|
||||
{
|
||||
GraphUtil.CreateNewGraph();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
using System.IO;
|
||||
using UnityEditor.ProjectWindowCallback;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
class CreateShaderSubGraph : EndNameEditAction
|
||||
{
|
||||
[MenuItem("Assets/Create/Shader/Sub Graph", false, 208)]
|
||||
public static void CreateMaterialSubGraph()
|
||||
{
|
||||
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, CreateInstance<CreateShaderSubGraph>(),
|
||||
string.Format("New Shader Sub Graph.{0}", ShaderSubGraphImporter.Extension), null, null);
|
||||
}
|
||||
|
||||
public override void Action(int instanceId, string pathName, string resourceFile)
|
||||
{
|
||||
var graph = new GraphData { isSubGraph = true };
|
||||
var outputNode = new SubGraphOutputNode();
|
||||
graph.AddNode(outputNode);
|
||||
graph.outputNode = outputNode;
|
||||
outputNode.AddSlot(ConcreteSlotValueType.Vector4);
|
||||
graph.path = "Sub Graphs";
|
||||
FileUtilities.WriteShaderGraphToDisk(pathName, graph);
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
#if VFX_GRAPH_10_0_0_OR_NEWER
|
||||
using System;
|
||||
using UnityEditor.ShaderGraph;
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
static class CreateVFXShaderGraph
|
||||
{
|
||||
[MenuItem("Assets/Create/Shader/VFX Shader Graph", false, 208)]
|
||||
public static void CreateVFXGraph()
|
||||
{
|
||||
var target = (VFXTarget)Activator.CreateInstance(typeof(VFXTarget));
|
||||
|
||||
var blockDescriptors = new[]
|
||||
{
|
||||
BlockFields.SurfaceDescription.BaseColor,
|
||||
BlockFields.SurfaceDescription.Alpha,
|
||||
};
|
||||
|
||||
GraphUtil.CreateNewGraphWithOutputs(new[] {target}, blockDescriptors);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Drawing
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
class BuiltinKeywordAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
|
||||
internal abstract class ContextFilterableAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Drawing
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class InspectableAttribute : Attribute
|
||||
{
|
||||
// String value to use in the Property name TextLabel
|
||||
public string labelName { get; private set; }
|
||||
|
||||
// The default value of this property
|
||||
public object defaultValue { get; private set; }
|
||||
|
||||
// String value to supply if you wish to use a custom style when drawing this property
|
||||
public string customStyleName { get; private set; }
|
||||
|
||||
public InspectableAttribute(string labelName, object defaultValue, string customStyleName = "")
|
||||
{
|
||||
this.labelName = labelName;
|
||||
this.defaultValue = defaultValue;
|
||||
this.customStyleName = customStyleName;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||
internal class NeverAllowedByTargetAttribute : ContextFilterableAttribute
|
||||
{
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Drawing
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class SGPropertyDrawerAttribute : Attribute
|
||||
{
|
||||
public Type propertyType { get; private set; }
|
||||
|
||||
public SGPropertyDrawerAttribute(Type propertyType)
|
||||
{
|
||||
this.propertyType = propertyType;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[GenerationAPI]
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||
internal class SRPFilterAttribute : ContextFilterableAttribute
|
||||
{
|
||||
public Type[] srpTypes = null;
|
||||
public SRPFilterAttribute(params Type[] WorksWithSRP)
|
||||
{
|
||||
srpTypes = WorksWithSRP;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEditor.ShaderGraph.Serialization;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
sealed class ContextData
|
||||
{
|
||||
[SerializeField]
|
||||
Vector2 m_Position;
|
||||
|
||||
[SerializeField]
|
||||
List<JsonRef<BlockNode>> m_Blocks = new List<JsonRef<BlockNode>>();
|
||||
|
||||
[NonSerialized]
|
||||
ShaderStage m_ShaderStage;
|
||||
|
||||
public ContextData()
|
||||
{
|
||||
}
|
||||
|
||||
public List<JsonRef<BlockNode>> blocks => m_Blocks;
|
||||
|
||||
public Vector2 position
|
||||
{
|
||||
get => m_Position;
|
||||
set => m_Position = value;
|
||||
}
|
||||
|
||||
public ShaderStage shaderStage
|
||||
{
|
||||
get => m_ShaderStage;
|
||||
set => m_ShaderStage = value;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
enum Precision
|
||||
{
|
||||
Inherit,
|
||||
Single,
|
||||
Half,
|
||||
}
|
||||
|
||||
public enum ConcretePrecision
|
||||
{
|
||||
Single,
|
||||
Half,
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
}
|
@@ -0,0 +1,262 @@
|
||||
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)
|
||||
{
|
||||
return referenceName;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
internal Precision precision
|
||||
{
|
||||
get => m_Precision;
|
||||
set => m_Precision = value;
|
||||
}
|
||||
|
||||
ConcretePrecision m_ConcretePrecision = ConcretePrecision.Single;
|
||||
public ConcretePrecision concretePrecision => m_ConcretePrecision;
|
||||
internal void ValidateConcretePrecision(ConcretePrecision graphPrecision)
|
||||
{
|
||||
m_ConcretePrecision = (precision == Precision.Inherit) ? graphPrecision : precision.ToConcrete();
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
bool m_Hidden = false;
|
||||
public bool hidden
|
||||
{
|
||||
get => m_Hidden;
|
||||
set => m_Hidden = value;
|
||||
}
|
||||
|
||||
internal string hideTagString => hidden ? "[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;
|
||||
}
|
||||
|
||||
// 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()
|
||||
{
|
||||
return GetPropertyAsArgumentString();
|
||||
}
|
||||
|
||||
internal abstract string GetPropertyAsArgumentString();
|
||||
internal abstract AbstractMaterialNode ToConcreteNode();
|
||||
internal abstract PreviewProperty GetPreviewMaterialProperty();
|
||||
|
||||
public virtual string GetPropertyTypeString()
|
||||
{
|
||||
string depString = $" (Deprecated{(ShaderGraphPreferences.allowDeprecatedBehaviors ? " V" + sgVersion : "" )})";
|
||||
return propertyType.ToString() + (sgVersion < latestVersion ? depString : "");
|
||||
}
|
||||
}
|
||||
|
||||
[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;
|
||||
}
|
||||
|
||||
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 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();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class BitangentMaterialSlot : SpaceMaterialSlot, IMayRequireBitangent
|
||||
{
|
||||
public BitangentMaterialSlot() : base()
|
||||
{}
|
||||
|
||||
public BitangentMaterialSlot(int slotId, string displayName, string shaderOutputName, CoordinateSpace space,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All, bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, space, stageCapability, hidden)
|
||||
{}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new LabelSlotControlView(space + " Space");
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.BiTangent));
|
||||
}
|
||||
|
||||
public NeededCoordinateSpace RequiresBitangent(ShaderStageCapability stageCapability)
|
||||
{
|
||||
if (isConnected)
|
||||
return NeededCoordinateSpace.None;
|
||||
return space.ToNeededCoordinateSpace();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,105 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class BooleanMaterialSlot : MaterialSlot, IMaterialSlotHasValue<bool>
|
||||
{
|
||||
[SerializeField]
|
||||
private bool m_Value;
|
||||
|
||||
[SerializeField]
|
||||
private bool m_DefaultValue;
|
||||
|
||||
public BooleanMaterialSlot()
|
||||
{}
|
||||
|
||||
public BooleanMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
bool value,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
m_DefaultValue = value;
|
||||
m_Value = value;
|
||||
}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new BooleanSlotControlView(this);
|
||||
}
|
||||
|
||||
public bool defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public bool value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return (value ? 1 : 0).ToString();
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var property = new BooleanShaderProperty()
|
||||
{
|
||||
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
|
||||
generatePropertyBlock = false,
|
||||
value = value
|
||||
};
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Boolean; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Boolean; } }
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Boolean)
|
||||
{
|
||||
name = name,
|
||||
booleanValue = value
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as BooleanMaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
|
||||
public override void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
base.CopyDefaultValue(other);
|
||||
if (other is IMaterialSlotHasValue<bool> ms)
|
||||
{
|
||||
m_DefaultValue = ms.defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Controls;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
[FormerName("UnityEditor.ShaderGraph.BooleanShaderProperty")]
|
||||
[BlackboardInputInfo(20)]
|
||||
public sealed class BooleanShaderProperty : AbstractShaderProperty<bool>
|
||||
{
|
||||
internal BooleanShaderProperty()
|
||||
{
|
||||
displayName = "Boolean";
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Boolean;
|
||||
|
||||
internal override bool isExposable => true;
|
||||
internal override bool isRenamable => true;
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return $"{concreteShaderValueType.ToShaderString(concretePrecision.ToShaderString())} {referenceName}";
|
||||
}
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
HLSLDeclaration decl = GetDefaultHLSLDeclaration();
|
||||
action(new HLSLProperty(HLSLType._float, referenceName, decl, concretePrecision));
|
||||
}
|
||||
|
||||
internal override string GetPropertyBlockString()
|
||||
{
|
||||
return $"{hideTagString}[ToggleUI]{referenceName}(\"{displayName}\", Float) = {(value == true ? 1 : 0)}";
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return new BooleanNode { value = new ToggleData(value) };
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
booleanValue = value
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new BooleanShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
class ColorRGBAMaterialSlot : Vector4MaterialSlot
|
||||
{
|
||||
public ColorRGBAMaterialSlot() {}
|
||||
|
||||
public ColorRGBAMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
Vector4 value,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, value, stageCapability, hidden: hidden)
|
||||
{
|
||||
}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new ColorRGBASlotControlView(this);
|
||||
}
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return string.Format("IsGammaSpace() ? $precision4({0}, {1}, {2}, {3}) : $precision4 (SRGBToLinear($precision3({0}, {1}, {2})), {3})"
|
||||
, NodeUtils.FloatToShaderValue(value.x)
|
||||
, NodeUtils.FloatToShaderValue(value.y)
|
||||
, NodeUtils.FloatToShaderValue(value.z)
|
||||
, NodeUtils.FloatToShaderValue(value.w));
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var property = new ColorShaderProperty()
|
||||
{
|
||||
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
|
||||
generatePropertyBlock = false,
|
||||
value = value
|
||||
};
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Color)
|
||||
{
|
||||
name = name,
|
||||
colorValue = new Color(value.x, value.y, value.z, value.w),
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
class ColorRGBMaterialSlot : Vector3MaterialSlot
|
||||
{
|
||||
[SerializeField]
|
||||
ColorMode m_ColorMode = ColorMode.Default;
|
||||
|
||||
[SerializeField]
|
||||
private Color m_DefaultColor = Color.grey;
|
||||
|
||||
public ColorRGBMaterialSlot() {}
|
||||
|
||||
public ColorRGBMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
Color value,
|
||||
ColorMode colorMode,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, (Vector4)value, stageCapability, hidden: hidden)
|
||||
{
|
||||
m_ColorMode = colorMode;
|
||||
m_DefaultColor = value;
|
||||
}
|
||||
|
||||
public ColorMode colorMode
|
||||
{
|
||||
get { return m_ColorMode; }
|
||||
set { m_ColorMode = value; }
|
||||
}
|
||||
|
||||
public Color defaultColor => m_DefaultColor;
|
||||
|
||||
public override bool isDefaultValue => value.Equals((Vector4)defaultColor);
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new ColorRGBSlotControlView(this);
|
||||
}
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return string.Format(m_ColorMode == ColorMode.Default ? "IsGammaSpace() ? $precision3({0}, {1}, {2}) : SRGBToLinear($precision3({0}, {1}, {2}))" : "$precision3({0}, {1}, {2})"
|
||||
, NodeUtils.FloatToShaderValue(value.x)
|
||||
, NodeUtils.FloatToShaderValue(value.y)
|
||||
, NodeUtils.FloatToShaderValue(value.z));
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var property = new ColorShaderProperty()
|
||||
{
|
||||
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
|
||||
generatePropertyBlock = false,
|
||||
value = new Color(value.x, value.y, value.z)
|
||||
};
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Color)
|
||||
{
|
||||
name = name,
|
||||
colorValue = new Color(value.x, value.y, value.z, 1),
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,115 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
[FormerName("UnityEditor.ShaderGraph.ColorShaderProperty")]
|
||||
[BlackboardInputInfo(10)]
|
||||
public sealed class ColorShaderProperty : AbstractShaderProperty<Color>
|
||||
{
|
||||
// 0 - original (broken color space)
|
||||
// 1 - fixed color space
|
||||
// 2 - original (broken color space) with HLSLDeclaration override
|
||||
// 3 - fixed color space with HLSLDeclaration override
|
||||
public override int latestVersion => 3;
|
||||
public const int deprecatedVersion = 2;
|
||||
|
||||
internal ColorShaderProperty()
|
||||
{
|
||||
displayName = "Color";
|
||||
}
|
||||
|
||||
internal ColorShaderProperty(int version) : this()
|
||||
{
|
||||
this.sgVersion = version;
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Color;
|
||||
|
||||
internal override bool isExposable => true;
|
||||
internal override bool isRenamable => true;
|
||||
|
||||
internal string hdrTagString => colorMode == ColorMode.HDR ? "[HDR]" : "";
|
||||
|
||||
internal override string GetPropertyBlockString()
|
||||
{
|
||||
return $"{hideTagString}{hdrTagString}{referenceName}(\"{displayName}\", Color) = ({NodeUtils.FloatToShaderValue(value.r)}, {NodeUtils.FloatToShaderValue(value.g)}, {NodeUtils.FloatToShaderValue(value.b)}, {NodeUtils.FloatToShaderValue(value.a)})";
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return $"{concreteShaderValueType.ToShaderString(concretePrecision.ToShaderString())} {referenceName}";
|
||||
}
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
HLSLDeclaration decl = GetDefaultHLSLDeclaration();
|
||||
action(new HLSLProperty(HLSLType._float4, referenceName, decl, concretePrecision));
|
||||
}
|
||||
|
||||
public override string GetOldDefaultReferenceName()
|
||||
{
|
||||
return $"Color_{objectId}";
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
ColorMode m_ColorMode;
|
||||
|
||||
public ColorMode colorMode
|
||||
{
|
||||
get => m_ColorMode;
|
||||
set => m_ColorMode = value;
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return new ColorNode { color = new ColorNode.Color(value, colorMode) };
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
UnityEngine.Color propColor = value;
|
||||
if (colorMode == ColorMode.Default)
|
||||
{
|
||||
if (PlayerSettings.colorSpace == ColorSpace.Linear)
|
||||
propColor = propColor.linear;
|
||||
}
|
||||
else if (colorMode == ColorMode.HDR)
|
||||
{
|
||||
// conversion from linear to active color space is handled in the shader code (see PropertyNode.cs)
|
||||
}
|
||||
|
||||
// we use Vector4 type to avoid all of the automatic color conversions of PropertyType.Color
|
||||
return new PreviewProperty(PropertyType.Vector4)
|
||||
{
|
||||
name = referenceName,
|
||||
vector4Value = propColor
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new ColorShaderProperty()
|
||||
{
|
||||
sgVersion = sgVersion,
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
colorMode = colorMode,
|
||||
};
|
||||
}
|
||||
|
||||
public override void OnAfterDeserialize(string json)
|
||||
{
|
||||
if (sgVersion < 2)
|
||||
{
|
||||
LegacyShaderPropertyData.UpgradeToHLSLDeclarationOverride(json, this);
|
||||
// version 0 upgrades to 2
|
||||
// version 1 upgrades to 3
|
||||
ChangeVersion((sgVersion == 0) ? 2 : 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
[HasDependencies(typeof(MinimalCubemapInputMaterialSlot))]
|
||||
class CubemapInputMaterialSlot : CubemapMaterialSlot
|
||||
{
|
||||
[SerializeField]
|
||||
private SerializableCubemap m_Cubemap = new SerializableCubemap();
|
||||
|
||||
public Cubemap cubemap
|
||||
{
|
||||
get { return m_Cubemap.cubemap; }
|
||||
set { m_Cubemap.cubemap = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => cubemap == null;
|
||||
|
||||
public CubemapInputMaterialSlot()
|
||||
{}
|
||||
|
||||
public CubemapInputMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, SlotType.Input, stageCapability, hidden)
|
||||
{}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new CubemapSlotControlView(this);
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
var nodeOwner = owner as AbstractMaterialNode;
|
||||
if (nodeOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
return $"UnityBuildTextureCubeStruct({nodeOwner.GetVariableNameForSlot(id)})";
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
var nodeOwner = owner as AbstractMaterialNode;
|
||||
if (nodeOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var prop = new CubemapShaderProperty();
|
||||
prop.overrideReferenceName = nodeOwner.GetVariableNameForSlot(id);
|
||||
prop.modifiable = false;
|
||||
prop.generatePropertyBlock = true;
|
||||
prop.value.cubemap = cubemap;
|
||||
properties.AddShaderProperty(prop);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Cubemap)
|
||||
{
|
||||
name = name,
|
||||
cubemapValue = cubemap
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as CubemapInputMaterialSlot;
|
||||
if (slot != null)
|
||||
{
|
||||
m_Cubemap = slot.m_Cubemap;
|
||||
bareResource = slot.bareResource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MinimalCubemapInputMaterialSlot : IHasDependencies
|
||||
{
|
||||
[SerializeField]
|
||||
private SerializableCubemap m_Cubemap = null;
|
||||
|
||||
public void GetSourceAssetDependencies(AssetCollection assetCollection)
|
||||
{
|
||||
var guidString = m_Cubemap.guid;
|
||||
if (!string.IsNullOrEmpty(guidString) && GUID.TryParse(guidString, out var guid))
|
||||
{
|
||||
assetCollection.AddAssetDependency(guid, AssetCollection.Flags.IncludeInExportPackage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class CubemapMaterialSlot : MaterialSlot
|
||||
{
|
||||
public CubemapMaterialSlot()
|
||||
{}
|
||||
|
||||
public CubemapMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{}
|
||||
|
||||
[SerializeField]
|
||||
bool m_BareResource = false;
|
||||
internal override bool bareResource
|
||||
{
|
||||
get { return m_BareResource; }
|
||||
set { m_BareResource = value; }
|
||||
}
|
||||
|
||||
public override void AppendHLSLParameterDeclaration(ShaderStringBuilder sb, string paramName)
|
||||
{
|
||||
if (m_BareResource)
|
||||
{
|
||||
sb.Append("TEXTURECUBE(");
|
||||
sb.Append(paramName);
|
||||
sb.Append(")");
|
||||
}
|
||||
else
|
||||
base.AppendHLSLParameterDeclaration(sb, paramName);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Cubemap; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Cubemap; } }
|
||||
public override bool isDefaultValue => true;
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{}
|
||||
}
|
||||
}
|
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
[FormerName("UnityEditor.ShaderGraph.CubemapShaderProperty")]
|
||||
[BlackboardInputInfo(53)]
|
||||
public sealed class CubemapShaderProperty : AbstractShaderProperty<SerializableCubemap>
|
||||
{
|
||||
internal CubemapShaderProperty()
|
||||
{
|
||||
displayName = "Cubemap";
|
||||
value = new SerializableCubemap();
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Cubemap;
|
||||
|
||||
internal override bool isExposable => true;
|
||||
internal override bool isRenamable => true;
|
||||
|
||||
internal string modifiableTagString => modifiable ? "" : "[NonModifiableTextureData]";
|
||||
|
||||
internal override string GetPropertyBlockString()
|
||||
{
|
||||
return $"{hideTagString}{modifiableTagString}[NoScaleOffset]{referenceName}(\"{displayName}\", CUBE) = \"\" {{}}";
|
||||
}
|
||||
|
||||
internal override bool AllowHLSLDeclaration(HLSLDeclaration decl) => false; // disable UI, nothing to choose
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
action(new HLSLProperty(HLSLType._TextureCube, referenceName, HLSLDeclaration.Global));
|
||||
action(new HLSLProperty(HLSLType._SamplerState, "sampler" + referenceName, HLSLDeclaration.Global));
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return "UnityTextureCube " + referenceName;
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentStringForVFX()
|
||||
{
|
||||
return "TEXTURECUBE(" + referenceName + ")";
|
||||
}
|
||||
|
||||
internal override string GetHLSLVariableName(bool isSubgraphProperty)
|
||||
{
|
||||
if (isSubgraphProperty)
|
||||
return referenceName;
|
||||
else
|
||||
return $"UnityBuildTextureCubeStruct({referenceName})";
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
bool m_Modifiable = true;
|
||||
|
||||
internal bool modifiable
|
||||
{
|
||||
get => m_Modifiable;
|
||||
set => m_Modifiable = value;
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return new CubemapAssetNode { cubemap = value.cubemap };
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
cubemapValue = value.cubemap
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new CubemapShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,129 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class DynamicMatrixMaterialSlot : MaterialSlot, IMaterialSlotHasValue<Matrix4x4>
|
||||
{
|
||||
[SerializeField]
|
||||
private Matrix4x4 m_Value = Matrix4x4.identity;
|
||||
|
||||
[SerializeField]
|
||||
private Matrix4x4 m_DefaultValue = Matrix4x4.identity;
|
||||
|
||||
private ConcreteSlotValueType m_ConcreteValueType = ConcreteSlotValueType.Matrix4;
|
||||
|
||||
public DynamicMatrixMaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public DynamicMatrixMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
m_Value = value;
|
||||
}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new LabelSlotControlView("Identity");
|
||||
}
|
||||
|
||||
public Matrix4x4 defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public Matrix4x4 value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.DynamicMatrix; } }
|
||||
|
||||
public override ConcreteSlotValueType concreteValueType
|
||||
{
|
||||
get { return m_ConcreteValueType; }
|
||||
}
|
||||
|
||||
public void SetConcreteType(ConcreteSlotValueType valueType)
|
||||
{
|
||||
m_ConcreteValueType = valueType;
|
||||
}
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
var channelCount = (int)SlotValueHelper.GetMatrixDimension(concreteValueType);
|
||||
var values = "";
|
||||
bool isFirst = true;
|
||||
for (var r = 0; r < channelCount; r++)
|
||||
{
|
||||
for (var c = 0; c < channelCount; c++)
|
||||
{
|
||||
if (!isFirst)
|
||||
values += ", ";
|
||||
isFirst = false;
|
||||
values += value.GetRow(r)[c];
|
||||
}
|
||||
}
|
||||
return string.Format("$precision{0}x{0}({1})", channelCount, values);
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
AbstractShaderProperty property;
|
||||
switch (concreteValueType)
|
||||
{
|
||||
case ConcreteSlotValueType.Matrix4:
|
||||
property = new Matrix4ShaderProperty();
|
||||
break;
|
||||
case ConcreteSlotValueType.Matrix3:
|
||||
property = new Matrix3ShaderProperty();
|
||||
break;
|
||||
case ConcreteSlotValueType.Matrix2:
|
||||
property = new Matrix2ShaderProperty();
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
property.overrideReferenceName = matOwner.GetVariableNameForSlot(id);
|
||||
property.generatePropertyBlock = false;
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as DynamicMatrixMaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
|
||||
public override void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
base.CopyDefaultValue(other);
|
||||
if (other is IMaterialSlotHasValue<Matrix4x4> ms)
|
||||
{
|
||||
m_DefaultValue = ms.defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,158 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class DynamicValueMaterialSlot : MaterialSlot, IMaterialSlotHasValue<Matrix4x4>
|
||||
{
|
||||
[SerializeField]
|
||||
private Matrix4x4 m_Value;
|
||||
|
||||
[SerializeField]
|
||||
private Matrix4x4 m_DefaultValue = Matrix4x4.identity;
|
||||
|
||||
static readonly string[] k_Labels = {"X", "Y", "Z", "W"};
|
||||
|
||||
private ConcreteSlotValueType m_ConcreteValueType = ConcreteSlotValueType.Vector4;
|
||||
|
||||
public DynamicValueMaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public DynamicValueMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
Matrix4x4 value,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
m_Value = value;
|
||||
}
|
||||
|
||||
public Matrix4x4 defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public Matrix4x4 value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
var labels = k_Labels.Take(concreteValueType.GetChannelCount()).ToArray();
|
||||
return new MultiFloatSlotControlView(owner, labels, () => value.GetRow(0), (newValue) =>
|
||||
value = new Matrix4x4()
|
||||
{
|
||||
m00 = newValue.x, m01 = newValue.y, m02 = newValue.z, m03 = newValue.w,
|
||||
m10 = value.m10, m11 = value.m11, m12 = value.m12, m13 = value.m13,
|
||||
m20 = value.m20, m21 = value.m21, m22 = value.m22, m23 = value.m23,
|
||||
m30 = value.m30, m31 = value.m31, m32 = value.m32, m33 = value.m33,
|
||||
});
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Dynamic; } }
|
||||
|
||||
public override ConcreteSlotValueType concreteValueType
|
||||
{
|
||||
get { return m_ConcreteValueType; }
|
||||
}
|
||||
|
||||
public void SetConcreteType(ConcreteSlotValueType valueType)
|
||||
{
|
||||
m_ConcreteValueType = valueType;
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var propType = concreteValueType.ToPropertyType();
|
||||
var pp = new PreviewProperty(propType) { name = name };
|
||||
if (propType == PropertyType.Float)
|
||||
pp.floatValue = value.m00;
|
||||
else
|
||||
pp.vector4Value = new Vector4(value.m00, value.m01, value.m02, value.m03);
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
var channelCount = SlotValueHelper.GetChannelCount(concreteValueType);
|
||||
string values = NodeUtils.FloatToShaderValue(value.m00);
|
||||
if (channelCount == 1)
|
||||
return values;
|
||||
for (var i = 1; i < channelCount; i++)
|
||||
values += ", " + NodeUtils.FloatToShaderValue(value.GetRow(0)[i]);
|
||||
return string.Format("$precision{0}({1})", channelCount, values);
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
AbstractShaderProperty property;
|
||||
switch (concreteValueType)
|
||||
{
|
||||
case ConcreteSlotValueType.Vector4:
|
||||
property = new Vector4ShaderProperty();
|
||||
break;
|
||||
case ConcreteSlotValueType.Vector3:
|
||||
property = new Vector3ShaderProperty();
|
||||
break;
|
||||
case ConcreteSlotValueType.Vector2:
|
||||
property = new Vector2ShaderProperty();
|
||||
break;
|
||||
case ConcreteSlotValueType.Vector1:
|
||||
property = new Vector1ShaderProperty();
|
||||
break;
|
||||
case ConcreteSlotValueType.Matrix4:
|
||||
property = new Matrix4ShaderProperty();
|
||||
break;
|
||||
case ConcreteSlotValueType.Matrix3:
|
||||
property = new Matrix3ShaderProperty();
|
||||
break;
|
||||
case ConcreteSlotValueType.Matrix2:
|
||||
property = new Matrix2ShaderProperty();
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
property.overrideReferenceName = matOwner.GetVariableNameForSlot(id);
|
||||
property.generatePropertyBlock = false;
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as DynamicValueMaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
|
||||
public override void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
base.CopyDefaultValue(other);
|
||||
if (other is IMaterialSlotHasValue<Matrix4x4> ms)
|
||||
{
|
||||
m_DefaultValue = ms.defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,145 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class DynamicVectorMaterialSlot : MaterialSlot, IMaterialSlotHasValue<Vector4>
|
||||
{
|
||||
[SerializeField]
|
||||
private Vector4 m_Value;
|
||||
|
||||
[SerializeField]
|
||||
private Vector4 m_DefaultValue = Vector4.zero;
|
||||
|
||||
static readonly string[] k_Labels = {"X", "Y", "Z", "W"};
|
||||
|
||||
private ConcreteSlotValueType m_ConcreteValueType = ConcreteSlotValueType.Vector4;
|
||||
|
||||
public DynamicVectorMaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public DynamicVectorMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
Vector4 value,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
m_Value = value;
|
||||
}
|
||||
|
||||
public Vector4 defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public Vector4 value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
var labels = k_Labels.Take(concreteValueType.GetChannelCount()).ToArray();
|
||||
return new MultiFloatSlotControlView(owner, labels, () => value, (newValue) => value = newValue);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.DynamicVector; } }
|
||||
|
||||
public override ConcreteSlotValueType concreteValueType
|
||||
{
|
||||
get { return m_ConcreteValueType; }
|
||||
}
|
||||
|
||||
public void SetConcreteType(ConcreteSlotValueType valueType)
|
||||
{
|
||||
m_ConcreteValueType = valueType;
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var propType = concreteValueType.ToPropertyType();
|
||||
var pp = new PreviewProperty(propType) { name = name };
|
||||
if (propType == PropertyType.Float)
|
||||
pp.floatValue = value.x;
|
||||
else
|
||||
pp.vector4Value = new Vector4(value.x, value.y, value.z, value.w);
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
var channelCount = SlotValueHelper.GetChannelCount(concreteValueType);
|
||||
string values = NodeUtils.FloatToShaderValue(value.x);
|
||||
if (channelCount == 1)
|
||||
return values;
|
||||
for (var i = 1; i < channelCount; i++)
|
||||
values += ", " + NodeUtils.FloatToShaderValue(value[i]);
|
||||
return string.Format("$precision{0}({1})", channelCount, values);
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
AbstractShaderProperty property;
|
||||
switch (concreteValueType)
|
||||
{
|
||||
case ConcreteSlotValueType.Vector4:
|
||||
property = new Vector4ShaderProperty();
|
||||
break;
|
||||
case ConcreteSlotValueType.Vector3:
|
||||
property = new Vector3ShaderProperty();
|
||||
break;
|
||||
case ConcreteSlotValueType.Vector2:
|
||||
property = new Vector2ShaderProperty();
|
||||
break;
|
||||
case ConcreteSlotValueType.Vector1:
|
||||
property = new Vector1ShaderProperty();
|
||||
break;
|
||||
default:
|
||||
// This shouldn't happen due to edge validation. The generated shader will
|
||||
// have errors.
|
||||
Debug.LogError($"Invalid value type {concreteValueType} passed to Vector Slot {displayName}. Value will be ignored, please plug in an edge with a vector type.");
|
||||
return;
|
||||
}
|
||||
|
||||
property.overrideReferenceName = matOwner.GetVariableNameForSlot(id);
|
||||
property.generatePropertyBlock = false;
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as DynamicVectorMaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
|
||||
public override void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
base.CopyDefaultValue(other);
|
||||
if (other is IMaterialSlotHasValue<Vector4> ms)
|
||||
{
|
||||
m_DefaultValue = ms.defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class GradientInputMaterialSlot : GradientMaterialSlot, IMaterialSlotHasValue<Gradient>
|
||||
{
|
||||
[SerializeField]
|
||||
Gradient m_Value = new Gradient();
|
||||
|
||||
[SerializeField]
|
||||
Gradient m_DefaultValue = new Gradient();
|
||||
|
||||
public GradientInputMaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public GradientInputMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, SlotType.Input, stageCapability, hidden)
|
||||
{
|
||||
}
|
||||
|
||||
public Gradient value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public Gradient defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new GradientSlotControlView(this);
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
if (generationMode.IsPreview())
|
||||
return GradientUtil.GetGradientForPreview(matOwner.GetVariableNameForSlot(id));
|
||||
|
||||
return ConcreteSlotValueAsVariable();
|
||||
}
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return GradientUtil.GetGradientValue(value, "");
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
if (generationMode != GenerationMode.Preview)
|
||||
return;
|
||||
|
||||
GradientUtil.GetGradientPropertiesForPreview(properties, matOwner.GetVariableNameForSlot(id), value);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
properties.Add(new PreviewProperty(PropertyType.Gradient)
|
||||
{
|
||||
name = name,
|
||||
gradientValue = value
|
||||
});
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as GradientInputMaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class GradientMaterialSlot : MaterialSlot
|
||||
{
|
||||
public GradientMaterialSlot()
|
||||
{}
|
||||
|
||||
public GradientMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Gradient; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Gradient; } }
|
||||
public override bool isDefaultValue => true;
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{}
|
||||
}
|
||||
}
|
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor.ShaderGraph.Drawing.Controls;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
[BlackboardInputInfo(30)]
|
||||
class GradientShaderProperty : AbstractShaderProperty<Gradient>
|
||||
{
|
||||
public GradientShaderProperty()
|
||||
{
|
||||
displayName = "Gradient";
|
||||
value = new Gradient();
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Gradient;
|
||||
|
||||
internal override bool isExposable => false;
|
||||
internal override bool isRenamable => true;
|
||||
|
||||
internal override bool AllowHLSLDeclaration(HLSLDeclaration decl) => false; // disable UI, nothing to choose
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
Action<ShaderStringBuilder> customDecl = (builder) =>
|
||||
{
|
||||
builder.AppendLine("Gradient {0}_Definition()", referenceName);
|
||||
using (builder.BlockScope())
|
||||
{
|
||||
string[] colors = new string[8];
|
||||
for (int i = 0; i < colors.Length; i++)
|
||||
colors[i] = string.Format("g.colors[{0}] = {1}4(0, 0, 0, 0);", i, concretePrecision.ToShaderString());
|
||||
for (int i = 0; i < value.colorKeys.Length; i++)
|
||||
colors[i] = string.Format("g.colors[{0}] = {1}4({2}, {3}, {4}, {5});"
|
||||
, i
|
||||
, concretePrecision.ToShaderString()
|
||||
, NodeUtils.FloatToShaderValue(value.colorKeys[i].color.r)
|
||||
, NodeUtils.FloatToShaderValue(value.colorKeys[i].color.g)
|
||||
, NodeUtils.FloatToShaderValue(value.colorKeys[i].color.b)
|
||||
, NodeUtils.FloatToShaderValue(value.colorKeys[i].time));
|
||||
|
||||
string[] alphas = new string[8];
|
||||
for (int i = 0; i < alphas.Length; i++)
|
||||
alphas[i] = string.Format("g.alphas[{0}] = {1}2(0, 0);", i, concretePrecision.ToShaderString());
|
||||
for (int i = 0; i < value.alphaKeys.Length; i++)
|
||||
alphas[i] = string.Format("g.alphas[{0}] = {1}2({2}, {3});"
|
||||
, i
|
||||
, concretePrecision.ToShaderString()
|
||||
, NodeUtils.FloatToShaderValue(value.alphaKeys[i].alpha)
|
||||
, NodeUtils.FloatToShaderValue(value.alphaKeys[i].time));
|
||||
|
||||
builder.AppendLine("Gradient g;");
|
||||
builder.AppendLine("g.type = {0};",
|
||||
(int)value.mode);
|
||||
builder.AppendLine("g.colorsLength = {0};",
|
||||
value.colorKeys.Length);
|
||||
builder.AppendLine("g.alphasLength = {0};",
|
||||
value.alphaKeys.Length);
|
||||
|
||||
for (int i = 0; i < colors.Length; i++)
|
||||
builder.AppendLine(colors[i]);
|
||||
|
||||
for (int i = 0; i < alphas.Length; i++)
|
||||
builder.AppendLine(alphas[i]);
|
||||
builder.AppendLine("return g;", true);
|
||||
}
|
||||
builder.AppendIndentation();
|
||||
builder.Append("#define {0} {0}_Definition()", referenceName);
|
||||
};
|
||||
|
||||
action(
|
||||
new HLSLProperty(HLSLType._CUSTOM, referenceName, HLSLDeclaration.Global, concretePrecision)
|
||||
{
|
||||
customDeclaration = customDecl
|
||||
});
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return "Gradient " + referenceName;
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return new GradientNode { gradient = value };
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
gradientValue = value
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new GradientShaderProperty
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
sealed partial class GraphData : ISerializationCallbackReceiver
|
||||
{
|
||||
public static class GraphConcretization
|
||||
{
|
||||
public static void ConcretizeNode(AbstractMaterialNode node)
|
||||
{
|
||||
node.Concretize();
|
||||
}
|
||||
|
||||
public static void ConcretizeProperties(GraphData graph)
|
||||
{
|
||||
var propertyNodes = graph.GetNodes<PropertyNode>().Where(n => !graph.m_Properties.Any(p => p == n.property)).ToArray();
|
||||
foreach (var pNode in propertyNodes)
|
||||
graph.ReplacePropertyNodeWithConcreteNodeNoValidate(pNode);
|
||||
}
|
||||
|
||||
public static void ConcretizeGraph(GraphData graph)
|
||||
{
|
||||
ConcretizeProperties(graph);
|
||||
GraphDataUtils.ApplyActionLeafFirst(graph, ConcretizeNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine.Pool;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
sealed partial class GraphData : ISerializationCallbackReceiver
|
||||
{
|
||||
public static class GraphDataUtils
|
||||
{
|
||||
public static void ApplyActionLeafFirst(GraphData graph, Action<AbstractMaterialNode> action)
|
||||
{
|
||||
var temporaryMarks = PooledHashSet<string>.Get();
|
||||
var permanentMarks = PooledHashSet<string>.Get();
|
||||
var slots = ListPool<MaterialSlot>.Get();
|
||||
|
||||
// Make sure we process a node's children before the node itself.
|
||||
var stack = StackPool<AbstractMaterialNode>.Get();
|
||||
foreach (var node in graph.GetNodes<AbstractMaterialNode>())
|
||||
{
|
||||
stack.Push(node);
|
||||
}
|
||||
while (stack.Count > 0)
|
||||
{
|
||||
var node = stack.Pop();
|
||||
if (permanentMarks.Contains(node.objectId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (temporaryMarks.Contains(node.objectId))
|
||||
{
|
||||
action.Invoke(node);
|
||||
permanentMarks.Add(node.objectId);
|
||||
}
|
||||
else
|
||||
{
|
||||
temporaryMarks.Add(node.objectId);
|
||||
stack.Push(node);
|
||||
node.GetInputSlots(slots);
|
||||
foreach (var inputSlot in slots)
|
||||
{
|
||||
var nodeEdges = graph.GetEdges(inputSlot.slotReference);
|
||||
foreach (var edge in nodeEdges)
|
||||
{
|
||||
var fromSocketRef = edge.outputSlot;
|
||||
var childNode = fromSocketRef.node;
|
||||
if (childNode != null)
|
||||
{
|
||||
stack.Push(childNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
slots.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
StackPool<AbstractMaterialNode>.Release(stack);
|
||||
ListPool<MaterialSlot>.Release(slots);
|
||||
temporaryMarks.Dispose();
|
||||
permanentMarks.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
sealed partial class GraphData : ISerializationCallbackReceiver
|
||||
{
|
||||
public static class GraphSetup
|
||||
{
|
||||
public static void SetupNode(AbstractMaterialNode node)
|
||||
{
|
||||
node.Setup();
|
||||
}
|
||||
|
||||
public static void SetupGraph(GraphData graph)
|
||||
{
|
||||
GraphDataUtils.ApplyActionLeafFirst(graph, SetupNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
sealed partial class GraphData : ISerializationCallbackReceiver
|
||||
{
|
||||
public static class GraphValidation
|
||||
{
|
||||
public static void ValidateNode(AbstractMaterialNode node)
|
||||
{
|
||||
Type t = node.GetType();
|
||||
node.ValidateNode();
|
||||
if (!(node is BlockNode))
|
||||
{
|
||||
bool disallowedByAnyTargets = false;
|
||||
bool disallowedByAllTargets = true;
|
||||
IEnumerable<Target> targets = node.owner.activeTargets;
|
||||
if (node.owner.isSubGraph)
|
||||
{
|
||||
targets = node.owner.allPotentialTargets;
|
||||
}
|
||||
foreach (var target in targets)
|
||||
{
|
||||
//if at least one target doesn't allow a node, it is considered invalid
|
||||
if (!target.IsNodeAllowedByTarget(t))
|
||||
{
|
||||
disallowedByAnyTargets = true;
|
||||
node.isValid = false;
|
||||
node.owner.AddValidationError(node.objectId, $"{node.name} Node is not allowed by {target.displayName} implementation", Rendering.ShaderCompilerMessageSeverity.Warning);
|
||||
node.owner.m_UnsupportedTargets.Add(target);
|
||||
}
|
||||
//at least one target does allow node, not going to be explicitly set inactive
|
||||
else
|
||||
{
|
||||
disallowedByAllTargets = false;
|
||||
}
|
||||
}
|
||||
if (!disallowedByAnyTargets)
|
||||
{
|
||||
node.isValid = true;
|
||||
}
|
||||
|
||||
//Set ActiveState based on if all targets disallow this node
|
||||
if (disallowedByAllTargets)
|
||||
{
|
||||
node.SetOverrideActiveState(AbstractMaterialNode.ActiveState.ExplicitInactive);
|
||||
node.owner.AddValidationError(node.objectId, $"{node.name} Node is not allowed by any active targets, and will not be used in generation", Rendering.ShaderCompilerMessageSeverity.Warning);
|
||||
}
|
||||
else
|
||||
{
|
||||
node.SetOverrideActiveState(AbstractMaterialNode.ActiveState.Implicit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void ValidateGraph(GraphData graph)
|
||||
{
|
||||
graph.m_UnsupportedTargets.Clear();
|
||||
GraphDataUtils.ApplyActionLeafFirst(graph, ValidateNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using UnityEditor.ShaderGraph.Serialization;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
public class GroupData : JsonObject
|
||||
{
|
||||
[SerializeField]
|
||||
string m_Title;
|
||||
|
||||
public string title
|
||||
{
|
||||
get { return m_Title; }
|
||||
set { m_Title = value; }
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
Vector2 m_Position;
|
||||
|
||||
public Vector2 position
|
||||
{
|
||||
get { return m_Position; }
|
||||
set { m_Position = value; }
|
||||
}
|
||||
|
||||
public GroupData() : base() {}
|
||||
|
||||
public GroupData(string title, Vector2 position)
|
||||
{
|
||||
m_Title = title;
|
||||
m_Position = position;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
interface IMaterialSlotHasValue<T>
|
||||
{
|
||||
T defaultValue { get; }
|
||||
T value { get; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
internal static class LightmappingShaderProperties
|
||||
{
|
||||
public class LightmapTextureArrayProperty : Texture2DArrayShaderProperty
|
||||
{
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
// no declaration from ShaderGraph side -- declared by SRP internal include files
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return String.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly LightmapTextureArrayProperty kLightmapsArray = new LightmapTextureArrayProperty()
|
||||
{
|
||||
displayName = "unity_Lightmaps",
|
||||
generatePropertyBlock = true,
|
||||
overrideHLSLDeclaration = false,
|
||||
hlslDeclarationOverride = HLSLDeclaration.DoNotDeclare,
|
||||
hidden = true,
|
||||
modifiable = true,
|
||||
overrideReferenceName = "unity_Lightmaps",
|
||||
precision = Precision.Single
|
||||
};
|
||||
|
||||
public static readonly LightmapTextureArrayProperty kLightmapsIndirectionArray = new LightmapTextureArrayProperty()
|
||||
{
|
||||
displayName = "unity_LightmapsInd",
|
||||
generatePropertyBlock = true,
|
||||
overrideHLSLDeclaration = false,
|
||||
hlslDeclarationOverride = HLSLDeclaration.DoNotDeclare,
|
||||
hidden = true,
|
||||
modifiable = true,
|
||||
overrideReferenceName = "unity_LightmapsInd",
|
||||
precision = Precision.Single
|
||||
};
|
||||
|
||||
public static readonly LightmapTextureArrayProperty kShadowMasksArray = new LightmapTextureArrayProperty()
|
||||
{
|
||||
displayName = "unity_ShadowMasks",
|
||||
generatePropertyBlock = true,
|
||||
overrideHLSLDeclaration = false,
|
||||
hlslDeclarationOverride = HLSLDeclaration.DoNotDeclare,
|
||||
hidden = true,
|
||||
modifiable = true,
|
||||
overrideReferenceName = "unity_ShadowMasks",
|
||||
precision = Precision.Single
|
||||
};
|
||||
}
|
||||
}
|
@@ -0,0 +1,338 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEditor.ShaderGraph.Serialization;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
abstract class MaterialSlot : JsonObject
|
||||
{
|
||||
const string k_NotInit = "Not Initilaized";
|
||||
|
||||
[SerializeField]
|
||||
int m_Id;
|
||||
|
||||
[SerializeField]
|
||||
string m_DisplayName = k_NotInit;
|
||||
|
||||
[SerializeField]
|
||||
SlotType m_SlotType = SlotType.Input;
|
||||
|
||||
[SerializeField]
|
||||
bool m_Hidden;
|
||||
|
||||
[SerializeField]
|
||||
string m_ShaderOutputName;
|
||||
|
||||
[SerializeField]
|
||||
ShaderStageCapability m_StageCapability;
|
||||
|
||||
bool m_HasError;
|
||||
|
||||
protected MaterialSlot() {}
|
||||
|
||||
protected MaterialSlot(int slotId, string displayName, string shaderOutputName, SlotType slotType, ShaderStageCapability stageCapability = ShaderStageCapability.All, bool hidden = false)
|
||||
{
|
||||
m_Id = slotId;
|
||||
m_DisplayName = displayName;
|
||||
m_SlotType = slotType;
|
||||
m_Hidden = hidden;
|
||||
m_ShaderOutputName = shaderOutputName;
|
||||
this.stageCapability = stageCapability;
|
||||
}
|
||||
|
||||
internal void SetInternalData(SlotType slotType, string shaderOutputName)
|
||||
{
|
||||
this.m_SlotType = slotType;
|
||||
this.shaderOutputName = shaderOutputName;
|
||||
}
|
||||
|
||||
public virtual VisualElement InstantiateControl()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
static string ConcreteSlotValueTypeAsString(ConcreteSlotValueType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ConcreteSlotValueType.Vector1:
|
||||
return "(1)";
|
||||
case ConcreteSlotValueType.Vector2:
|
||||
return "(2)";
|
||||
case ConcreteSlotValueType.Vector3:
|
||||
return "(3)";
|
||||
case ConcreteSlotValueType.Vector4:
|
||||
return "(4)";
|
||||
case ConcreteSlotValueType.Boolean:
|
||||
return "(B)";
|
||||
case ConcreteSlotValueType.Matrix2:
|
||||
return "(2x2)";
|
||||
case ConcreteSlotValueType.Matrix3:
|
||||
return "(3x3)";
|
||||
case ConcreteSlotValueType.Matrix4:
|
||||
return "(4x4)";
|
||||
case ConcreteSlotValueType.SamplerState:
|
||||
return "(SS)";
|
||||
case ConcreteSlotValueType.Texture2D:
|
||||
return "(T2)";
|
||||
case ConcreteSlotValueType.Texture2DArray:
|
||||
return "(T2A)";
|
||||
case ConcreteSlotValueType.Texture3D:
|
||||
return "(T3)";
|
||||
case ConcreteSlotValueType.Cubemap:
|
||||
return "(C)";
|
||||
case ConcreteSlotValueType.Gradient:
|
||||
return "(G)";
|
||||
case ConcreteSlotValueType.VirtualTexture:
|
||||
return "(VT)";
|
||||
default:
|
||||
return "(E)";
|
||||
}
|
||||
}
|
||||
|
||||
public virtual string displayName
|
||||
{
|
||||
get { return m_DisplayName + ConcreteSlotValueTypeAsString(concreteValueType); }
|
||||
set { m_DisplayName = value; }
|
||||
}
|
||||
|
||||
public string RawDisplayName()
|
||||
{
|
||||
return m_DisplayName;
|
||||
}
|
||||
|
||||
public static MaterialSlot CreateMaterialSlot(SlotValueType type, int slotId, string displayName, string shaderOutputName, SlotType slotType, Vector4 defaultValue, ShaderStageCapability shaderStageCapability = ShaderStageCapability.All, bool hidden = false)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case SlotValueType.SamplerState:
|
||||
return new SamplerStateMaterialSlot(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden);
|
||||
case SlotValueType.DynamicMatrix:
|
||||
return new DynamicMatrixMaterialSlot(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden);
|
||||
case SlotValueType.Matrix4:
|
||||
return new Matrix4MaterialSlot(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden);
|
||||
case SlotValueType.Matrix3:
|
||||
return new Matrix3MaterialSlot(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden);
|
||||
case SlotValueType.Matrix2:
|
||||
return new Matrix2MaterialSlot(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden);
|
||||
case SlotValueType.Texture2D:
|
||||
return slotType == SlotType.Input
|
||||
? new Texture2DInputMaterialSlot(slotId, displayName, shaderOutputName, shaderStageCapability, hidden)
|
||||
: new Texture2DMaterialSlot(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden);
|
||||
case SlotValueType.Texture2DArray:
|
||||
return slotType == SlotType.Input
|
||||
? new Texture2DArrayInputMaterialSlot(slotId, displayName, shaderOutputName, shaderStageCapability, hidden)
|
||||
: new Texture2DArrayMaterialSlot(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden);
|
||||
case SlotValueType.Texture3D:
|
||||
return slotType == SlotType.Input
|
||||
? new Texture3DInputMaterialSlot(slotId, displayName, shaderOutputName, shaderStageCapability, hidden)
|
||||
: new Texture3DMaterialSlot(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden);
|
||||
case SlotValueType.Cubemap:
|
||||
return slotType == SlotType.Input
|
||||
? new CubemapInputMaterialSlot(slotId, displayName, shaderOutputName, shaderStageCapability, hidden)
|
||||
: new CubemapMaterialSlot(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden);
|
||||
case SlotValueType.VirtualTexture:
|
||||
return slotType == SlotType.Input
|
||||
? new VirtualTextureInputMaterialSlot(slotId, displayName, shaderOutputName, shaderStageCapability, hidden)
|
||||
: new VirtualTextureMaterialSlot(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden);
|
||||
case SlotValueType.Gradient:
|
||||
return slotType == SlotType.Input
|
||||
? new GradientInputMaterialSlot(slotId, displayName, shaderOutputName, shaderStageCapability, hidden)
|
||||
: new GradientMaterialSlot(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden);
|
||||
case SlotValueType.DynamicVector:
|
||||
return new DynamicVectorMaterialSlot(slotId, displayName, shaderOutputName, slotType, defaultValue, shaderStageCapability, hidden);
|
||||
case SlotValueType.Vector4:
|
||||
return new Vector4MaterialSlot(slotId, displayName, shaderOutputName, slotType, defaultValue, shaderStageCapability, hidden: hidden);
|
||||
case SlotValueType.Vector3:
|
||||
return new Vector3MaterialSlot(slotId, displayName, shaderOutputName, slotType, defaultValue, shaderStageCapability, hidden: hidden);
|
||||
case SlotValueType.Vector2:
|
||||
return new Vector2MaterialSlot(slotId, displayName, shaderOutputName, slotType, defaultValue, shaderStageCapability, hidden: hidden);
|
||||
case SlotValueType.Vector1:
|
||||
return new Vector1MaterialSlot(slotId, displayName, shaderOutputName, slotType, defaultValue.x, shaderStageCapability, hidden: hidden);
|
||||
case SlotValueType.Dynamic:
|
||||
return new DynamicValueMaterialSlot(slotId, displayName, shaderOutputName, slotType, new Matrix4x4(defaultValue, Vector4.zero, Vector4.zero, Vector4.zero), shaderStageCapability, hidden);
|
||||
case SlotValueType.Boolean:
|
||||
return new BooleanMaterialSlot(slotId, displayName, shaderOutputName, slotType, false, shaderStageCapability, hidden);
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException("type", type, null);
|
||||
}
|
||||
|
||||
public SlotReference slotReference
|
||||
{
|
||||
get { return new SlotReference(owner, m_Id); }
|
||||
}
|
||||
|
||||
public AbstractMaterialNode owner { get; set; }
|
||||
|
||||
// if hidden, the slot does not create a port in the UI
|
||||
public bool hidden
|
||||
{
|
||||
get { return m_Hidden; }
|
||||
set { m_Hidden = value; }
|
||||
}
|
||||
|
||||
public int id
|
||||
{
|
||||
get { return m_Id; }
|
||||
}
|
||||
|
||||
public bool isInputSlot
|
||||
{
|
||||
get { return m_SlotType == SlotType.Input; }
|
||||
}
|
||||
|
||||
public bool isOutputSlot
|
||||
{
|
||||
get { return m_SlotType == SlotType.Output; }
|
||||
}
|
||||
|
||||
public SlotType slotType
|
||||
{
|
||||
get { return m_SlotType; }
|
||||
}
|
||||
|
||||
public bool isConnected
|
||||
{
|
||||
get
|
||||
{
|
||||
// node and graph respectivly
|
||||
if (owner == null || owner.owner == null)
|
||||
return false;
|
||||
|
||||
var graph = owner.owner;
|
||||
var edges = graph.GetEdges(slotReference);
|
||||
return edges.Any();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract bool isDefaultValue { get; }
|
||||
|
||||
public abstract SlotValueType valueType { get; }
|
||||
|
||||
public abstract ConcreteSlotValueType concreteValueType { get; }
|
||||
|
||||
public string shaderOutputName
|
||||
{
|
||||
get { return m_ShaderOutputName; }
|
||||
private set { m_ShaderOutputName = value; }
|
||||
}
|
||||
|
||||
public ShaderStageCapability stageCapability
|
||||
{
|
||||
get { return m_StageCapability; }
|
||||
set { m_StageCapability = value; }
|
||||
}
|
||||
|
||||
public bool hasError
|
||||
{
|
||||
get { return m_HasError; }
|
||||
set { m_HasError = value; }
|
||||
}
|
||||
|
||||
public bool IsUsingDefaultValue()
|
||||
{
|
||||
if (!isConnected && isDefaultValue)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsCompatibleWith(MaterialSlot otherSlot)
|
||||
{
|
||||
return otherSlot != null
|
||||
&& otherSlot.owner != owner
|
||||
&& otherSlot.isInputSlot != isInputSlot
|
||||
&& ((isInputSlot
|
||||
? SlotValueHelper.AreCompatible(valueType, otherSlot.concreteValueType)
|
||||
: SlotValueHelper.AreCompatible(otherSlot.valueType, concreteValueType)));
|
||||
}
|
||||
|
||||
public bool IsCompatibleStageWith(MaterialSlot otherSlot)
|
||||
{
|
||||
var candidateStage = otherSlot.stageCapability;
|
||||
return stageCapability == ShaderStageCapability.All || candidateStage == stageCapability;
|
||||
}
|
||||
|
||||
public string GetDefaultValue(GenerationMode generationMode, ConcretePrecision concretePrecision)
|
||||
{
|
||||
string defaultValue = GetDefaultValue(generationMode);
|
||||
return defaultValue.Replace(PrecisionUtil.Token, concretePrecision.ToShaderString());
|
||||
}
|
||||
|
||||
public virtual string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
if (generationMode.IsPreview() && matOwner.isActive)
|
||||
return matOwner.GetVariableNameForSlot(id);
|
||||
|
||||
return ConcreteSlotValueAsVariable();
|
||||
}
|
||||
|
||||
protected virtual string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return "error";
|
||||
}
|
||||
|
||||
public abstract void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode);
|
||||
|
||||
public virtual void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
properties.Add(default(PreviewProperty));
|
||||
}
|
||||
|
||||
public virtual void AppendHLSLParameterDeclaration(ShaderStringBuilder sb, string paramName)
|
||||
{
|
||||
sb.Append(concreteValueType.ToShaderString());
|
||||
sb.Append(" ");
|
||||
sb.Append(paramName);
|
||||
}
|
||||
|
||||
public abstract void CopyValuesFrom(MaterialSlot foundSlot);
|
||||
|
||||
public bool Equals(MaterialSlot other)
|
||||
{
|
||||
return m_Id == other.m_Id && owner == other.owner;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != this.GetType()) return false;
|
||||
return Equals((MaterialSlot)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return (m_Id * 397) ^ (owner != null ? owner.GetHashCode() : 0);
|
||||
}
|
||||
}
|
||||
|
||||
// this tracks old CustomFunctionNode slots that are expecting the old bare resource inputs
|
||||
// rather than the new structure-based inputs
|
||||
internal virtual bool bareResource { get { return false; } set {} }
|
||||
|
||||
public virtual void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
m_Id = other.m_Id;
|
||||
m_DisplayName = other.m_DisplayName;
|
||||
m_SlotType = other.m_SlotType;
|
||||
m_Hidden = other.m_Hidden;
|
||||
m_ShaderOutputName = other.m_ShaderOutputName;
|
||||
m_StageCapability = other.m_StageCapability;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class Matrix2MaterialSlot : MaterialSlot, IMaterialSlotHasValue<Matrix4x4>
|
||||
{
|
||||
[SerializeField]
|
||||
private Matrix4x4 m_Value = Matrix4x4.identity;
|
||||
|
||||
[SerializeField]
|
||||
private Matrix4x4 m_DefaultValue = Matrix4x4.identity;
|
||||
|
||||
public Matrix2MaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public Matrix2MaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new LabelSlotControlView("Identity");
|
||||
}
|
||||
|
||||
public Matrix4x4 defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public Matrix4x4 value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return "$precision2x2 (1,0,0,1)";
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var property = new Matrix2ShaderProperty()
|
||||
{
|
||||
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
|
||||
generatePropertyBlock = false,
|
||||
value = value
|
||||
};
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Matrix2)
|
||||
{
|
||||
name = name,
|
||||
matrixValue = value
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Matrix2; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Matrix2; } }
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Matrix2MaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
|
||||
public override void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
base.CopyDefaultValue(other);
|
||||
if (other is IMaterialSlotHasValue<Matrix4x4> ms)
|
||||
{
|
||||
m_DefaultValue = ms.defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
[BlackboardInputInfo(70)]
|
||||
class Matrix2ShaderProperty : MatrixShaderProperty
|
||||
{
|
||||
public Matrix2ShaderProperty()
|
||||
{
|
||||
displayName = "Matrix2x2";
|
||||
value = Matrix4x4.identity;
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Matrix2;
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return $"{concretePrecision.ToShaderString()}2x2 {referenceName}";
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return new Matrix2Node
|
||||
{
|
||||
row0 = new Vector2(value.m00, value.m01),
|
||||
row1 = new Vector2(value.m10, value.m11)
|
||||
};
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
matrixValue = value
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new Matrix2ShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
|
||||
public override int latestVersion => 1;
|
||||
public override void OnAfterDeserialize(string json)
|
||||
{
|
||||
if (sgVersion == 0)
|
||||
{
|
||||
// all old matrices were declared global; yes even if flagged hybrid!
|
||||
// maintain old behavior on versioning, users can always change the override if they wish
|
||||
overrideHLSLDeclaration = true;
|
||||
hlslDeclarationOverride = HLSLDeclaration.Global;
|
||||
ChangeVersion(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class Matrix3MaterialSlot : MaterialSlot, IMaterialSlotHasValue<Matrix4x4>
|
||||
{
|
||||
[SerializeField]
|
||||
private Matrix4x4 m_Value = Matrix4x4.identity;
|
||||
|
||||
[SerializeField]
|
||||
private Matrix4x4 m_DefaultValue = Matrix4x4.identity;
|
||||
|
||||
public Matrix3MaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public Matrix3MaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new LabelSlotControlView("Identity");
|
||||
}
|
||||
|
||||
public Matrix4x4 defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public Matrix4x4 value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return "$precision3x3 (1,0,0,0,1,0,0,0,1)";
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var property = new Matrix3ShaderProperty()
|
||||
{
|
||||
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
|
||||
generatePropertyBlock = false,
|
||||
value = value
|
||||
};
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Matrix3)
|
||||
{
|
||||
name = name,
|
||||
matrixValue = value
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Matrix3; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Matrix3; } }
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Matrix3MaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
|
||||
public override void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
base.CopyDefaultValue(other);
|
||||
if (other is IMaterialSlotHasValue<Matrix4x4> ms)
|
||||
{
|
||||
m_DefaultValue = ms.defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
[BlackboardInputInfo(71)]
|
||||
class Matrix3ShaderProperty : MatrixShaderProperty
|
||||
{
|
||||
public Matrix3ShaderProperty()
|
||||
{
|
||||
displayName = "Matrix3x3";
|
||||
value = Matrix4x4.identity;
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Matrix3;
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return $"{concretePrecision.ToShaderString()}3x3 {referenceName}";
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return new Matrix3Node
|
||||
{
|
||||
row0 = new Vector3(value.m00, value.m01, value.m02),
|
||||
row1 = new Vector3(value.m10, value.m11, value.m12),
|
||||
row2 = new Vector3(value.m20, value.m21, value.m22)
|
||||
};
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
matrixValue = value
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new Matrix3ShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
|
||||
public override int latestVersion => 1;
|
||||
public override void OnAfterDeserialize(string json)
|
||||
{
|
||||
if (sgVersion == 0)
|
||||
{
|
||||
// all old matrices were declared global; yes even if flagged hybrid!
|
||||
// maintain old behavior on versioning, users can always change the override if they wish
|
||||
overrideHLSLDeclaration = true;
|
||||
hlslDeclarationOverride = HLSLDeclaration.Global;
|
||||
ChangeVersion(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class Matrix4MaterialSlot : MaterialSlot, IMaterialSlotHasValue<Matrix4x4>
|
||||
{
|
||||
[SerializeField]
|
||||
private Matrix4x4 m_Value = Matrix4x4.identity;
|
||||
|
||||
[SerializeField]
|
||||
private Matrix4x4 m_DefaultValue = Matrix4x4.identity;
|
||||
|
||||
public Matrix4MaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public Matrix4MaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new LabelSlotControlView("Identity");
|
||||
}
|
||||
|
||||
public Matrix4x4 defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public Matrix4x4 value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return "$precision4x4 (1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)";
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var property = new Matrix4ShaderProperty()
|
||||
{
|
||||
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
|
||||
generatePropertyBlock = false,
|
||||
value = value
|
||||
};
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Matrix4)
|
||||
{
|
||||
name = name,
|
||||
matrixValue = value
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Matrix4; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Matrix4; } }
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Matrix4MaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
|
||||
public override void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
base.CopyDefaultValue(other);
|
||||
if (other is IMaterialSlotHasValue<Matrix4x4> ms)
|
||||
{
|
||||
m_DefaultValue = ms.defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
[BlackboardInputInfo(72)]
|
||||
class Matrix4ShaderProperty : MatrixShaderProperty
|
||||
{
|
||||
public Matrix4ShaderProperty()
|
||||
{
|
||||
displayName = "Matrix4x4";
|
||||
value = Matrix4x4.identity;
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Matrix4;
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return $"{concretePrecision.ToShaderString()}4x4 {referenceName}";
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return new Matrix4Node
|
||||
{
|
||||
row0 = new Vector4(value.m00, value.m01, value.m02, value.m03),
|
||||
row1 = new Vector4(value.m10, value.m11, value.m12, value.m13),
|
||||
row2 = new Vector4(value.m20, value.m21, value.m22, value.m23),
|
||||
row3 = new Vector4(value.m30, value.m31, value.m32, value.m33)
|
||||
};
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
matrixValue = value
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new Matrix4ShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
|
||||
public override int latestVersion => 1;
|
||||
public override void OnAfterDeserialize(string json)
|
||||
{
|
||||
if (sgVersion == 0)
|
||||
{
|
||||
// all old matrices were declared global; yes even if flagged hybrid!
|
||||
// maintain old behavior on versioning, users can always change the override if they wish
|
||||
overrideHLSLDeclaration = true;
|
||||
hlslDeclarationOverride = HLSLDeclaration.Global;
|
||||
ChangeVersion(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
abstract class MatrixShaderProperty : AbstractShaderProperty<Matrix4x4>
|
||||
{
|
||||
internal override bool isExposable => false;
|
||||
internal override bool isRenamable => true;
|
||||
|
||||
internal override HLSLDeclaration GetDefaultHLSLDeclaration()
|
||||
{
|
||||
if (overrideHLSLDeclaration)
|
||||
return hlslDeclarationOverride;
|
||||
|
||||
// Since Matrices cannot be exposed, the default declaration rules would set them to Global.
|
||||
// However, this means new Matrix properties would be different from all other float-based property types
|
||||
// (all others use UnityPerMaterial by default, because they are exposed).
|
||||
// So instead, we override the default rules so that Matrices always default to UnityPerMaterial
|
||||
return HLSLDeclaration.UnityPerMaterial;
|
||||
}
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
HLSLDeclaration decl = GetDefaultHLSLDeclaration();
|
||||
|
||||
// HLSL decl is always 4x4 even if matrix smaller
|
||||
action(new HLSLProperty(HLSLType._matrix4x4, referenceName, decl, concretePrecision));
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Legacy;
|
||||
using UnityEditor.ShaderGraph.Serialization;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
/// <summary>
|
||||
/// Minimal version of <see cref="GraphData"/> used for gathering dependencies. This allows us to not deserialize
|
||||
/// all the nodes, ports, edges, groups etc., which is important as we cannot share data between
|
||||
/// <see cref="ShaderSubGraphImporter.GatherDependenciesFromSourceFile"/> and
|
||||
/// <see cref="ShaderSubGraphImporter.OnImportAsset"/>. The latter must always import fully, but for the former we
|
||||
/// want to avoid the extra GC pressure.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
class MinimalGraphData
|
||||
{
|
||||
static Dictionary<string, Type> s_MinimalTypeMap = CreateMinimalTypeMap();
|
||||
|
||||
static Dictionary<string, Type> CreateMinimalTypeMap()
|
||||
{
|
||||
var types = new Dictionary<string, Type>();
|
||||
foreach (var type in TypeCache.GetTypesWithAttribute<HasDependenciesAttribute>())
|
||||
{
|
||||
var dependencyAttribute = (HasDependenciesAttribute)type.GetCustomAttributes(typeof(HasDependenciesAttribute), false)[0];
|
||||
if (!typeof(IHasDependencies).IsAssignableFrom(dependencyAttribute.minimalType))
|
||||
{
|
||||
Debug.LogError($"{type} must implement {typeof(IHasDependencies)} to be used in {typeof(HasDependenciesAttribute)}");
|
||||
continue;
|
||||
}
|
||||
|
||||
types.Add(type.FullName, dependencyAttribute.minimalType);
|
||||
|
||||
var formerNameAttributes = (FormerNameAttribute[])type.GetCustomAttributes(typeof(FormerNameAttribute), false);
|
||||
foreach (var formerNameAttribute in formerNameAttributes)
|
||||
{
|
||||
types.Add(formerNameAttribute.fullName, dependencyAttribute.minimalType);
|
||||
}
|
||||
}
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
List<SerializationHelper.JSONSerializedElement> m_SerializableNodes = new List<SerializationHelper.JSONSerializedElement>();
|
||||
|
||||
// gather all asset dependencies declared by nodes in the given (shadergraph or shadersubgraph) asset
|
||||
// by reading the source file from disk, and doing a minimal parse
|
||||
// returns true if it successfully gathered the dependencies, false if there was an error
|
||||
public static bool GatherMinimalDependenciesFromFile(string assetPath, AssetCollection assetCollection)
|
||||
{
|
||||
var textGraph = FileUtilities.SafeReadAllText(assetPath);
|
||||
|
||||
// if we can't read the file, no dependencies can be gathered
|
||||
if (string.IsNullOrEmpty(textGraph))
|
||||
return false;
|
||||
|
||||
var entries = MultiJsonInternal.Parse(textGraph);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(entries[0].type))
|
||||
{
|
||||
var minimalGraphData = JsonUtility.FromJson<MinimalGraphData>(textGraph);
|
||||
entries.Clear();
|
||||
foreach (var node in minimalGraphData.m_SerializableNodes)
|
||||
{
|
||||
entries.Add(new MultiJsonEntry(node.typeInfo.fullName, null, node.JSONnodeData));
|
||||
AbstractMaterialNode0 amn = new AbstractMaterialNode0();
|
||||
JsonUtility.FromJsonOverwrite(node.JSONnodeData, amn);
|
||||
foreach (var slot in amn.m_SerializableSlots)
|
||||
{
|
||||
entries.Add(new MultiJsonEntry(slot.typeInfo.fullName, null, slot.JSONnodeData));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
if (s_MinimalTypeMap.TryGetValue(entry.type, out var minimalType))
|
||||
{
|
||||
var instance = (IHasDependencies)Activator.CreateInstance(minimalType);
|
||||
JsonUtility.FromJsonOverwrite(entry.json, instance);
|
||||
instance.GetSourceAssetDependencies(assetCollection);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class NormalMaterialSlot : SpaceMaterialSlot, IMayRequireNormal
|
||||
{
|
||||
public NormalMaterialSlot()
|
||||
{}
|
||||
|
||||
public NormalMaterialSlot(int slotId, string displayName, string shaderOutputName, CoordinateSpace space,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All, bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, space, stageCapability, hidden)
|
||||
{}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new LabelSlotControlView(space + " Space");
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.Normal));
|
||||
}
|
||||
|
||||
public NeededCoordinateSpace RequiresNormal(ShaderStageCapability stageCapability)
|
||||
{
|
||||
if (isConnected)
|
||||
return NeededCoordinateSpace.None;
|
||||
return space.ToNeededCoordinateSpace();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
struct ParentGroupChange
|
||||
{
|
||||
public IGroupItem groupItem;
|
||||
public GroupData oldGroup;
|
||||
public GroupData newGroup;
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class PositionMaterialSlot : SpaceMaterialSlot, IMayRequirePosition
|
||||
{
|
||||
public PositionMaterialSlot()
|
||||
{}
|
||||
|
||||
public PositionMaterialSlot(int slotId, string displayName, string shaderOutputName, CoordinateSpace space,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All, bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, space, stageCapability, hidden)
|
||||
{}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new LabelSlotControlView(space + " Space");
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.Position));
|
||||
}
|
||||
|
||||
public NeededCoordinateSpace RequiresPosition(ShaderStageCapability stageCapability)
|
||||
{
|
||||
if (isConnected)
|
||||
return NeededCoordinateSpace.None;
|
||||
return space.ToNeededCoordinateSpace();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
enum PreviewMode
|
||||
{
|
||||
Inherit, // this usually means: 2D, unless a connected input node is 3D, in which case it is 3D
|
||||
Preview2D,
|
||||
Preview3D
|
||||
}
|
||||
}
|
@@ -0,0 +1,283 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
struct PreviewProperty
|
||||
{
|
||||
public string name { get; set; }
|
||||
public PropertyType propType { get; private set; }
|
||||
|
||||
public PreviewProperty(PropertyType type) : this()
|
||||
{
|
||||
propType = type;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
struct ClassData
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public Texture textureValue;
|
||||
[FieldOffset(0)]
|
||||
public Cubemap cubemapValue;
|
||||
[FieldOffset(0)]
|
||||
public Gradient gradientValue;
|
||||
[FieldOffset(0)]
|
||||
public VirtualTextureShaderProperty vtProperty;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
struct StructData
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public Color colorValue;
|
||||
[FieldOffset(0)]
|
||||
public Vector4 vector4Value;
|
||||
[FieldOffset(0)]
|
||||
public float floatValue;
|
||||
[FieldOffset(0)]
|
||||
public bool booleanValue;
|
||||
[FieldOffset(0)]
|
||||
public Matrix4x4 matrixValue;
|
||||
}
|
||||
|
||||
ClassData m_ClassData;
|
||||
StructData m_StructData;
|
||||
Texture2DShaderProperty.DefaultType m_texture2dDefaultType;
|
||||
|
||||
public Color colorValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (propType != PropertyType.Color)
|
||||
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Color, propType));
|
||||
return m_StructData.colorValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (propType != PropertyType.Color)
|
||||
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Color, propType));
|
||||
m_StructData.colorValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Texture textureValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (propType != PropertyType.Texture2D && propType != PropertyType.Texture2DArray && propType != PropertyType.Texture3D)
|
||||
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Texture2D, propType));
|
||||
return m_ClassData.textureValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (propType != PropertyType.Texture2D && propType != PropertyType.Texture2DArray && propType != PropertyType.Texture3D)
|
||||
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Texture2D, propType));
|
||||
m_ClassData.textureValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Texture2DShaderProperty.DefaultType texture2DDefaultType
|
||||
{
|
||||
get
|
||||
{
|
||||
if (propType != PropertyType.Texture2D)
|
||||
throw new ArgumentException(string.Format(k_GetErrorMessage, "Texture2DShaderProperty.DefaultType", propType));
|
||||
return m_texture2dDefaultType;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (propType != PropertyType.Texture2D)
|
||||
throw new ArgumentException(string.Format(k_GetErrorMessage, "Texture2DShaderProperty.DefaultType", propType));
|
||||
m_texture2dDefaultType = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Cubemap cubemapValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (propType != PropertyType.Cubemap)
|
||||
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Cubemap, propType));
|
||||
return m_ClassData.cubemapValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (propType != PropertyType.Cubemap)
|
||||
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Cubemap, propType));
|
||||
m_ClassData.cubemapValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Gradient gradientValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (propType != PropertyType.Gradient)
|
||||
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Gradient, propType));
|
||||
return m_ClassData.gradientValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (propType != PropertyType.Gradient)
|
||||
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Gradient, propType));
|
||||
m_ClassData.gradientValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
public VirtualTextureShaderProperty vtProperty
|
||||
{
|
||||
get
|
||||
{
|
||||
if (propType != PropertyType.VirtualTexture)
|
||||
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Gradient, propType));
|
||||
return m_ClassData.vtProperty;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (propType != PropertyType.VirtualTexture)
|
||||
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Gradient, propType));
|
||||
m_ClassData.vtProperty = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector4 vector4Value
|
||||
{
|
||||
get
|
||||
{
|
||||
if (propType != PropertyType.Vector2 && propType != PropertyType.Vector3 && propType != PropertyType.Vector4)
|
||||
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Vector4, propType));
|
||||
return m_StructData.vector4Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (propType != PropertyType.Vector2 && propType != PropertyType.Vector3 && propType != PropertyType.Vector4
|
||||
&& propType != PropertyType.Matrix2 && propType != PropertyType.Matrix3 && propType != PropertyType.Matrix4)
|
||||
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Vector4, propType));
|
||||
m_StructData.vector4Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float floatValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (propType != PropertyType.Float)
|
||||
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Float, propType));
|
||||
return m_StructData.floatValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (propType != PropertyType.Float)
|
||||
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Float, propType));
|
||||
m_StructData.floatValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool booleanValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (propType != PropertyType.Boolean)
|
||||
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Boolean, propType));
|
||||
return m_StructData.booleanValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (propType != PropertyType.Boolean)
|
||||
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Boolean, propType));
|
||||
m_StructData.booleanValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Matrix4x4 matrixValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (propType != PropertyType.Matrix2 && propType != PropertyType.Matrix3 && propType != PropertyType.Matrix4)
|
||||
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Boolean, propType));
|
||||
return m_StructData.matrixValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (propType != PropertyType.Matrix2 && propType != PropertyType.Matrix3 && propType != PropertyType.Matrix4)
|
||||
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Boolean, propType));
|
||||
m_StructData.matrixValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
const string k_SetErrorMessage = "Cannot set a {0} property on a PreviewProperty with type {1}.";
|
||||
const string k_GetErrorMessage = "Cannot get a {0} property on a PreviewProperty with type {1}.";
|
||||
|
||||
public void SetValueOnMaterialPropertyBlock(MaterialPropertyBlock mat)
|
||||
{
|
||||
if ((propType == PropertyType.Texture2D || propType == PropertyType.Texture2DArray || propType == PropertyType.Texture3D))
|
||||
{
|
||||
if (m_ClassData.textureValue == null)
|
||||
{
|
||||
// there's no way to set the texture back to NULL
|
||||
// and no way to delete the property either
|
||||
// so instead we set the value to what we know the default will be
|
||||
// (all textures in ShaderGraph default to white)
|
||||
switch (m_texture2dDefaultType)
|
||||
{
|
||||
case Texture2DShaderProperty.DefaultType.White:
|
||||
mat.SetTexture(name, Texture2D.whiteTexture);
|
||||
break;
|
||||
case Texture2DShaderProperty.DefaultType.Black:
|
||||
mat.SetTexture(name, Texture2D.blackTexture);
|
||||
break;
|
||||
case Texture2DShaderProperty.DefaultType.Grey:
|
||||
mat.SetTexture(name, Texture2D.grayTexture);
|
||||
break;
|
||||
case Texture2DShaderProperty.DefaultType.Bump:
|
||||
mat.SetTexture(name, Texture2D.normalTexture);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
mat.SetTexture(name, m_ClassData.textureValue);
|
||||
}
|
||||
else if (propType == PropertyType.Cubemap)
|
||||
{
|
||||
if (m_ClassData.cubemapValue == null)
|
||||
{
|
||||
// there's no way to set the texture back to NULL
|
||||
// and no way to delete the property either
|
||||
// so instead we set the value to what we know the default will be
|
||||
// (all textures in ShaderGraph default to white)
|
||||
// there's no Cubemap.whiteTexture, but this seems to work
|
||||
mat.SetTexture(name, Texture2D.whiteTexture);
|
||||
}
|
||||
else
|
||||
mat.SetTexture(name, m_ClassData.cubemapValue);
|
||||
}
|
||||
else if (propType == PropertyType.Color)
|
||||
mat.SetColor(name, m_StructData.colorValue);
|
||||
else if (propType == PropertyType.Vector2 || propType == PropertyType.Vector3 || propType == PropertyType.Vector4)
|
||||
mat.SetVector(name, m_StructData.vector4Value);
|
||||
else if (propType == PropertyType.Float)
|
||||
mat.SetFloat(name, m_StructData.floatValue);
|
||||
else if (propType == PropertyType.Boolean)
|
||||
mat.SetFloat(name, m_StructData.booleanValue ? 1 : 0);
|
||||
else if (propType == PropertyType.Matrix2 || propType == PropertyType.Matrix3 || propType == PropertyType.Matrix4)
|
||||
mat.SetMatrix(name, m_StructData.matrixValue);
|
||||
else if (propType == PropertyType.Gradient)
|
||||
{
|
||||
mat.SetFloat(string.Format("{0}_Type", name), (int)m_ClassData.gradientValue.mode);
|
||||
mat.SetFloat(string.Format("{0}_ColorsLength", name), m_ClassData.gradientValue.colorKeys.Length);
|
||||
mat.SetFloat(string.Format("{0}_AlphasLength", name), m_ClassData.gradientValue.alphaKeys.Length);
|
||||
for (int i = 0; i < 8; i++)
|
||||
mat.SetVector(string.Format("{0}_ColorKey{1}", name, i), i < m_ClassData.gradientValue.colorKeys.Length ? GradientUtil.ColorKeyToVector(m_ClassData.gradientValue.colorKeys[i]) : Vector4.zero);
|
||||
for (int i = 0; i < 8; i++)
|
||||
mat.SetVector(string.Format("{0}_AlphaKey{1}", name, i), i < m_ClassData.gradientValue.alphaKeys.Length ? GradientUtil.AlphaKeyToVector(m_ClassData.gradientValue.alphaKeys[i]) : Vector2.zero);
|
||||
}
|
||||
else if (propType == PropertyType.VirtualTexture)
|
||||
{
|
||||
// virtual texture assignments are not supported via the material property block, we must assign them to the materials
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class SamplerStateMaterialSlot : MaterialSlot
|
||||
{
|
||||
public SamplerStateMaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public SamplerStateMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
bool m_BareResource = false;
|
||||
internal override bool bareResource
|
||||
{
|
||||
get { return m_BareResource; }
|
||||
set { m_BareResource = value; }
|
||||
}
|
||||
|
||||
public override void AppendHLSLParameterDeclaration(ShaderStringBuilder sb, string paramName)
|
||||
{
|
||||
if (m_BareResource)
|
||||
{
|
||||
// we have to use our modified macro declaration here, to ensure that something is declared for GLES2 platforms
|
||||
// (the standard SAMPLER macro doesn't declare anything, so the commas will be messed up in the parameter list)
|
||||
sb.Append("UNITY_BARE_SAMPLER(");
|
||||
sb.Append(paramName);
|
||||
sb.Append(")");
|
||||
}
|
||||
else
|
||||
base.AppendHLSLParameterDeclaration(sb, paramName);
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
var nodeOwner = owner as AbstractMaterialNode;
|
||||
if (nodeOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
return "UnityBuildSamplerStateStruct(SamplerState_Linear_Repeat)";
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.SamplerState; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.SamplerState; } }
|
||||
public override bool isDefaultValue => true;
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
var nodeOwner = owner as AbstractMaterialNode;
|
||||
if (nodeOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
properties.AddShaderProperty(new SamplerStateShaderProperty()
|
||||
{
|
||||
value = new TextureSamplerState()
|
||||
{
|
||||
filter = TextureSamplerState.FilterMode.Linear,
|
||||
wrap = TextureSamplerState.WrapMode.Repeat
|
||||
},
|
||||
overrideReferenceName = "SamplerState_Linear_Repeat",
|
||||
generatePropertyBlock = false,
|
||||
});
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{}
|
||||
}
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[BlackboardInputInfo(80)]
|
||||
class SamplerStateShaderProperty : AbstractShaderProperty<TextureSamplerState>
|
||||
{
|
||||
public SamplerStateShaderProperty()
|
||||
{
|
||||
displayName = "SamplerState";
|
||||
value = new TextureSamplerState();
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.SamplerState;
|
||||
|
||||
internal override bool isExposable => false;
|
||||
internal override bool isRenamable => false;
|
||||
|
||||
public override TextureSamplerState value
|
||||
{
|
||||
get => base.value;
|
||||
set
|
||||
{
|
||||
overrideReferenceName = $"SamplerState_{value.filter}_{value.wrap}";
|
||||
base.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal override bool AllowHLSLDeclaration(HLSLDeclaration decl) => false; // disable UI, nothing to choose
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
action(new HLSLProperty(HLSLType._SamplerState, referenceName, HLSLDeclaration.Global));
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return $"UnitySamplerState {referenceName}";
|
||||
}
|
||||
|
||||
internal override string GetHLSLVariableName(bool isSubgraphProperty)
|
||||
{
|
||||
if (isSubgraphProperty)
|
||||
return referenceName;
|
||||
else
|
||||
return $"UnityBuildSamplerStateStruct({referenceName})";
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return new SamplerStateNode()
|
||||
{
|
||||
filter = value.filter,
|
||||
wrap = value.wrap
|
||||
};
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return default(PreviewProperty);
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new SamplerStateShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class ScreenPositionMaterialSlot : Vector4MaterialSlot, IMayRequireScreenPosition
|
||||
{
|
||||
[SerializeField]
|
||||
ScreenSpaceType m_ScreenSpaceType;
|
||||
|
||||
public ScreenSpaceType screenSpaceType
|
||||
{
|
||||
get { return m_ScreenSpaceType; }
|
||||
set { m_ScreenSpaceType = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => screenSpaceType == ScreenSpaceType.Default;
|
||||
|
||||
public ScreenPositionMaterialSlot()
|
||||
{}
|
||||
|
||||
public ScreenPositionMaterialSlot(int slotId, string displayName, string shaderOutputName, ScreenSpaceType screenSpaceType,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All, bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, SlotType.Input, Vector3.zero, stageCapability, hidden: hidden)
|
||||
{
|
||||
this.screenSpaceType = screenSpaceType;
|
||||
}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new ScreenPositionSlotControlView(this);
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
return m_ScreenSpaceType.ToValueAsVariable();
|
||||
}
|
||||
|
||||
public bool RequiresScreenPosition(ShaderStageCapability stageCapability)
|
||||
{
|
||||
return !isConnected;
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as ScreenPositionMaterialSlot;
|
||||
if (slot != null)
|
||||
screenSpaceType = slot.screenSpaceType;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
public sealed class SerializableCubemap : ISerializationCallbackReceiver
|
||||
{
|
||||
[SerializeField]
|
||||
string m_SerializedCubemap;
|
||||
|
||||
[SerializeField]
|
||||
string m_Guid;
|
||||
|
||||
[NonSerialized]
|
||||
Cubemap m_Cubemap;
|
||||
|
||||
[Serializable]
|
||||
class CubemapHelper
|
||||
{
|
||||
#pragma warning disable 649
|
||||
public Cubemap cubemap;
|
||||
#pragma warning restore 649
|
||||
}
|
||||
|
||||
// used to get a Cubemap ref guid without loading the cubemap asset itself into memory
|
||||
[Serializable]
|
||||
class MinimalCubemapHelper
|
||||
{
|
||||
// these variables are only ever populated by serialization, disable the C# warning that checks if they are ever assigned
|
||||
#pragma warning disable 0649
|
||||
[Serializable]
|
||||
public struct MinimalTextureRef
|
||||
{
|
||||
public string guid;
|
||||
}
|
||||
public MinimalTextureRef cubemap;
|
||||
#pragma warning restore 0649
|
||||
}
|
||||
|
||||
internal string guid
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(m_SerializedCubemap))
|
||||
{
|
||||
var textureHelper = new MinimalCubemapHelper();
|
||||
EditorJsonUtility.FromJsonOverwrite(m_SerializedCubemap, textureHelper);
|
||||
if (!string.IsNullOrEmpty(textureHelper.cubemap.guid))
|
||||
return textureHelper.cubemap.guid;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(m_Guid))
|
||||
{
|
||||
return m_Guid;
|
||||
}
|
||||
if (m_Cubemap != null)
|
||||
{
|
||||
if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(m_Cubemap, out string guid, out long localId))
|
||||
return guid;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Cubemap cubemap
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(m_SerializedCubemap))
|
||||
{
|
||||
var textureHelper = new CubemapHelper();
|
||||
EditorJsonUtility.FromJsonOverwrite(m_SerializedCubemap, textureHelper);
|
||||
m_SerializedCubemap = null;
|
||||
m_Guid = null;
|
||||
m_Cubemap = textureHelper.cubemap;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(m_Guid) && m_Cubemap == null)
|
||||
{
|
||||
m_Cubemap = AssetDatabase.LoadAssetAtPath<Cubemap>(AssetDatabase.GUIDToAssetPath(m_Guid));
|
||||
m_Guid = null;
|
||||
}
|
||||
|
||||
return m_Cubemap;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Cubemap = value;
|
||||
m_Guid = null;
|
||||
m_SerializedCubemap = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
m_SerializedCubemap = EditorJsonUtility.ToJson(new CubemapHelper { cubemap = cubemap }, false);
|
||||
}
|
||||
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class SerializableGuid : ISerializationCallbackReceiver
|
||||
{
|
||||
public SerializableGuid()
|
||||
{
|
||||
m_Guid = Guid.NewGuid();
|
||||
}
|
||||
|
||||
public SerializableGuid(Guid guid)
|
||||
{
|
||||
m_Guid = guid;
|
||||
}
|
||||
|
||||
[NonSerialized]
|
||||
private Guid m_Guid;
|
||||
|
||||
[SerializeField]
|
||||
private string m_GuidSerialized;
|
||||
|
||||
public Guid guid
|
||||
{
|
||||
get { return m_Guid; }
|
||||
internal set { m_Guid = value; } // allow id to be overwritten when necessary
|
||||
}
|
||||
|
||||
public virtual void OnBeforeSerialize()
|
||||
{
|
||||
m_GuidSerialized = m_Guid.ToString();
|
||||
}
|
||||
|
||||
public virtual void OnAfterDeserialize()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(m_GuidSerialized))
|
||||
m_Guid = new Guid(m_GuidSerialized);
|
||||
else
|
||||
m_Guid = Guid.NewGuid();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class SerializableMesh : ISerializationCallbackReceiver
|
||||
{
|
||||
[SerializeField]
|
||||
string m_SerializedMesh;
|
||||
|
||||
[SerializeField]
|
||||
string m_Guid;
|
||||
|
||||
[NonSerialized]
|
||||
Mesh m_Mesh;
|
||||
|
||||
[Serializable]
|
||||
class MeshHelper
|
||||
{
|
||||
#pragma warning disable 649
|
||||
public Mesh mesh;
|
||||
#pragma warning restore 649
|
||||
}
|
||||
|
||||
public Mesh mesh
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(m_SerializedMesh))
|
||||
{
|
||||
var textureHelper = new MeshHelper();
|
||||
EditorJsonUtility.FromJsonOverwrite(m_SerializedMesh, textureHelper);
|
||||
m_SerializedMesh = null;
|
||||
m_Guid = null;
|
||||
m_Mesh = textureHelper.mesh;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(m_Guid) && m_Mesh == null)
|
||||
{
|
||||
m_Mesh = AssetDatabase.LoadAssetAtPath<Mesh>(AssetDatabase.GUIDToAssetPath(m_Guid));
|
||||
m_Guid = null;
|
||||
}
|
||||
|
||||
return m_Mesh;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Mesh = value;
|
||||
m_Guid = null;
|
||||
m_SerializedMesh = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
m_SerializedMesh = EditorJsonUtility.ToJson(new MeshHelper { mesh = mesh }, false);
|
||||
}
|
||||
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
public sealed class SerializableTexture : ISerializationCallbackReceiver
|
||||
{
|
||||
[SerializeField]
|
||||
string m_SerializedTexture;
|
||||
|
||||
[SerializeField]
|
||||
string m_Guid;
|
||||
|
||||
[NonSerialized]
|
||||
Texture m_Texture;
|
||||
|
||||
[Serializable]
|
||||
class TextureHelper
|
||||
{
|
||||
#pragma warning disable 649
|
||||
public Texture texture;
|
||||
#pragma warning restore 649
|
||||
}
|
||||
|
||||
// used to get a Texture ref guid without loading the texture asset itself into memory
|
||||
[Serializable]
|
||||
class MinimalTextureHelper
|
||||
{
|
||||
// these variables are only ever populated by serialization, disable the C# warning that checks if they are ever assigned
|
||||
#pragma warning disable 0649
|
||||
[Serializable]
|
||||
public struct MinimalTextureRef
|
||||
{
|
||||
public string guid;
|
||||
}
|
||||
public MinimalTextureRef texture;
|
||||
#pragma warning restore 0649
|
||||
}
|
||||
|
||||
internal string guid
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(m_SerializedTexture))
|
||||
{
|
||||
var textureHelper = new MinimalTextureHelper();
|
||||
EditorJsonUtility.FromJsonOverwrite(m_SerializedTexture, textureHelper);
|
||||
if (!string.IsNullOrEmpty(textureHelper.texture.guid))
|
||||
return textureHelper.texture.guid;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(m_Guid))
|
||||
{
|
||||
return m_Guid;
|
||||
}
|
||||
if (m_Texture != null)
|
||||
{
|
||||
if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(m_Texture, out string guid, out long localId))
|
||||
return guid;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Texture texture
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(m_SerializedTexture))
|
||||
{
|
||||
var textureHelper = new TextureHelper();
|
||||
EditorJsonUtility.FromJsonOverwrite(m_SerializedTexture, textureHelper);
|
||||
m_SerializedTexture = null;
|
||||
m_Guid = null;
|
||||
m_Texture = textureHelper.texture;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(m_Guid) && m_Texture == null)
|
||||
{
|
||||
m_Texture = AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath(m_Guid));
|
||||
m_Guid = null;
|
||||
}
|
||||
|
||||
return m_Texture;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Texture = value;
|
||||
m_Guid = null;
|
||||
m_SerializedTexture = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
m_SerializedTexture = EditorJsonUtility.ToJson(new TextureHelper { texture = texture }, false);
|
||||
}
|
||||
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
public sealed class SerializableTextureArray : ISerializationCallbackReceiver
|
||||
{
|
||||
[SerializeField]
|
||||
string m_SerializedTexture;
|
||||
|
||||
[SerializeField]
|
||||
string m_Guid;
|
||||
|
||||
[NonSerialized]
|
||||
Texture2DArray m_TextureArray;
|
||||
|
||||
[Serializable]
|
||||
class TextureHelper
|
||||
{
|
||||
#pragma warning disable 649
|
||||
public Texture2DArray textureArray;
|
||||
#pragma warning restore 649
|
||||
}
|
||||
|
||||
// used to get a Texture2DArray ref guid without loading the Texture2dArray asset itself into memory
|
||||
[Serializable]
|
||||
class MinimalTextureHelper
|
||||
{
|
||||
// these variables are only ever populated by serialization, disable the C# warning that checks if they are ever assigned
|
||||
#pragma warning disable 0649
|
||||
[Serializable]
|
||||
public struct MinimalTextureRef
|
||||
{
|
||||
public string guid;
|
||||
}
|
||||
public MinimalTextureRef textureArray;
|
||||
#pragma warning restore 0649
|
||||
}
|
||||
|
||||
internal string guid
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(m_SerializedTexture))
|
||||
{
|
||||
var textureHelper = new MinimalTextureHelper();
|
||||
EditorJsonUtility.FromJsonOverwrite(m_SerializedTexture, textureHelper);
|
||||
if (!string.IsNullOrEmpty(textureHelper.textureArray.guid))
|
||||
return textureHelper.textureArray.guid;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(m_Guid))
|
||||
{
|
||||
return m_Guid;
|
||||
}
|
||||
if (m_TextureArray != null)
|
||||
{
|
||||
if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(m_TextureArray, out string guid, out long localId))
|
||||
return guid;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Texture2DArray textureArray
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(m_SerializedTexture))
|
||||
{
|
||||
var textureHelper = new TextureHelper();
|
||||
EditorJsonUtility.FromJsonOverwrite(m_SerializedTexture, textureHelper);
|
||||
m_SerializedTexture = null;
|
||||
m_Guid = null;
|
||||
m_TextureArray = textureHelper.textureArray;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(m_Guid) && m_TextureArray == null)
|
||||
{
|
||||
m_TextureArray = AssetDatabase.LoadAssetAtPath<Texture2DArray>(AssetDatabase.GUIDToAssetPath(m_Guid));
|
||||
m_Guid = null;
|
||||
}
|
||||
|
||||
return m_TextureArray;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_TextureArray = value;
|
||||
m_Guid = null;
|
||||
m_SerializedTexture = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
m_SerializedTexture = EditorJsonUtility.ToJson(new TextureHelper { textureArray = textureArray }, false);
|
||||
}
|
||||
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
enum LayerTextureType
|
||||
{
|
||||
Default,
|
||||
NormalTangentSpace,
|
||||
NormalObjectSpace
|
||||
};
|
||||
|
||||
[Serializable]
|
||||
internal class SerializableVirtualTextureLayer
|
||||
{
|
||||
public string layerName;
|
||||
public string layerRefName;
|
||||
public SerializableTexture layerTexture;
|
||||
public LayerTextureType layerTextureType;
|
||||
[SerializeField]
|
||||
private Guid guid;
|
||||
|
||||
public SerializableVirtualTextureLayer(string name, string refName, SerializableTexture texture)
|
||||
{
|
||||
this.layerName = name; this.layerName = name;
|
||||
this.guid = Guid.NewGuid();
|
||||
this.layerRefName = refName; this.layerRefName = refName;
|
||||
this.layerTexture = texture; this.layerTexture = texture;
|
||||
this.layerTextureType = LayerTextureType.Default; this.layerTextureType = LayerTextureType.Default;
|
||||
}
|
||||
|
||||
public SerializableVirtualTextureLayer(string name, SerializableTexture texture)
|
||||
{
|
||||
this.layerName = name;
|
||||
this.guid = Guid.NewGuid();
|
||||
this.layerRefName = $"Layer_{GuidEncoder.Encode(this.guid)}";
|
||||
this.layerTexture = texture;
|
||||
this.layerTextureType = LayerTextureType.Default;
|
||||
}
|
||||
|
||||
public SerializableVirtualTextureLayer(SerializableVirtualTextureLayer other)
|
||||
{
|
||||
this.layerName = other.layerName;
|
||||
this.guid = Guid.NewGuid();
|
||||
this.layerRefName = $"Layer_{GuidEncoder.Encode(this.guid)}";
|
||||
this.layerTexture = other.layerTexture;
|
||||
this.layerTextureType = LayerTextureType.Default;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
internal sealed class SerializableVirtualTexture
|
||||
{
|
||||
[SerializeField]
|
||||
public List<SerializableVirtualTextureLayer> layers = new List<SerializableVirtualTextureLayer>();
|
||||
|
||||
[SerializeField]
|
||||
public bool procedural;
|
||||
}
|
||||
}
|
@@ -0,0 +1,218 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
public struct ShaderGraphRequirements
|
||||
{
|
||||
[SerializeField] NeededCoordinateSpace m_RequiresNormal;
|
||||
[SerializeField] NeededCoordinateSpace m_RequiresBitangent;
|
||||
[SerializeField] NeededCoordinateSpace m_RequiresTangent;
|
||||
[SerializeField] NeededCoordinateSpace m_RequiresViewDir;
|
||||
[SerializeField] NeededCoordinateSpace m_RequiresPosition;
|
||||
[SerializeField] bool m_RequiresScreenPosition;
|
||||
[SerializeField] bool m_RequiresVertexColor;
|
||||
[SerializeField] bool m_RequiresFaceSign;
|
||||
[SerializeField] List<UVChannel> m_RequiresMeshUVs;
|
||||
[SerializeField] bool m_RequiresDepthTexture;
|
||||
[SerializeField] bool m_RequiresCameraOpaqueTexture;
|
||||
[SerializeField] bool m_RequiresTime;
|
||||
[SerializeField] bool m_RequiresVertexSkinning;
|
||||
[SerializeField] bool m_RequiresVertexID;
|
||||
|
||||
internal static ShaderGraphRequirements none
|
||||
{
|
||||
get
|
||||
{
|
||||
return new ShaderGraphRequirements
|
||||
{
|
||||
m_RequiresMeshUVs = new List<UVChannel>()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public NeededCoordinateSpace requiresNormal
|
||||
{
|
||||
get { return m_RequiresNormal; }
|
||||
internal set { m_RequiresNormal = value; }
|
||||
}
|
||||
|
||||
public NeededCoordinateSpace requiresBitangent
|
||||
{
|
||||
get { return m_RequiresBitangent; }
|
||||
internal set { m_RequiresBitangent = value; }
|
||||
}
|
||||
|
||||
public NeededCoordinateSpace requiresTangent
|
||||
{
|
||||
get { return m_RequiresTangent; }
|
||||
internal set { m_RequiresTangent = value; }
|
||||
}
|
||||
|
||||
public NeededCoordinateSpace requiresViewDir
|
||||
{
|
||||
get { return m_RequiresViewDir; }
|
||||
internal set { m_RequiresViewDir = value; }
|
||||
}
|
||||
|
||||
public NeededCoordinateSpace requiresPosition
|
||||
{
|
||||
get { return m_RequiresPosition; }
|
||||
internal set { m_RequiresPosition = value; }
|
||||
}
|
||||
|
||||
public bool requiresScreenPosition
|
||||
{
|
||||
get { return m_RequiresScreenPosition; }
|
||||
internal set { m_RequiresScreenPosition = value; }
|
||||
}
|
||||
|
||||
public bool requiresVertexColor
|
||||
{
|
||||
get { return m_RequiresVertexColor; }
|
||||
internal set { m_RequiresVertexColor = value; }
|
||||
}
|
||||
|
||||
public bool requiresFaceSign
|
||||
{
|
||||
get { return m_RequiresFaceSign; }
|
||||
internal set { m_RequiresFaceSign = value; }
|
||||
}
|
||||
|
||||
public List<UVChannel> requiresMeshUVs
|
||||
{
|
||||
get { return m_RequiresMeshUVs; }
|
||||
internal set { m_RequiresMeshUVs = value; }
|
||||
}
|
||||
|
||||
public bool requiresDepthTexture
|
||||
{
|
||||
get { return m_RequiresDepthTexture; }
|
||||
internal set { m_RequiresDepthTexture = value; }
|
||||
}
|
||||
|
||||
public bool requiresCameraOpaqueTexture
|
||||
{
|
||||
get { return m_RequiresCameraOpaqueTexture; }
|
||||
internal set { m_RequiresCameraOpaqueTexture = value; }
|
||||
}
|
||||
|
||||
public bool requiresTime
|
||||
{
|
||||
get { return m_RequiresTime; }
|
||||
internal set { m_RequiresTime = value; }
|
||||
}
|
||||
|
||||
public bool requiresVertexSkinning
|
||||
{
|
||||
get { return m_RequiresVertexSkinning; }
|
||||
internal set { m_RequiresVertexSkinning = value; }
|
||||
}
|
||||
|
||||
public bool requiresVertexID
|
||||
{
|
||||
get { return m_RequiresVertexID; }
|
||||
internal set { m_RequiresVertexID = value; }
|
||||
}
|
||||
|
||||
internal bool NeedsTangentSpace()
|
||||
{
|
||||
var compoundSpaces = m_RequiresBitangent | m_RequiresNormal | m_RequiresPosition
|
||||
| m_RequiresTangent | m_RequiresViewDir | m_RequiresPosition
|
||||
| m_RequiresNormal;
|
||||
|
||||
return (compoundSpaces & NeededCoordinateSpace.Tangent) > 0;
|
||||
}
|
||||
|
||||
internal ShaderGraphRequirements Union(ShaderGraphRequirements other)
|
||||
{
|
||||
var newReqs = new ShaderGraphRequirements();
|
||||
newReqs.m_RequiresNormal = other.m_RequiresNormal | m_RequiresNormal;
|
||||
newReqs.m_RequiresTangent = other.m_RequiresTangent | m_RequiresTangent;
|
||||
newReqs.m_RequiresBitangent = other.m_RequiresBitangent | m_RequiresBitangent;
|
||||
newReqs.m_RequiresViewDir = other.m_RequiresViewDir | m_RequiresViewDir;
|
||||
newReqs.m_RequiresPosition = other.m_RequiresPosition | m_RequiresPosition;
|
||||
newReqs.m_RequiresScreenPosition = other.m_RequiresScreenPosition | m_RequiresScreenPosition;
|
||||
newReqs.m_RequiresVertexColor = other.m_RequiresVertexColor | m_RequiresVertexColor;
|
||||
newReqs.m_RequiresFaceSign = other.m_RequiresFaceSign | m_RequiresFaceSign;
|
||||
newReqs.m_RequiresDepthTexture = other.m_RequiresDepthTexture | m_RequiresDepthTexture;
|
||||
newReqs.m_RequiresCameraOpaqueTexture = other.m_RequiresCameraOpaqueTexture | m_RequiresCameraOpaqueTexture;
|
||||
newReqs.m_RequiresTime = other.m_RequiresTime | m_RequiresTime;
|
||||
newReqs.m_RequiresVertexSkinning = other.m_RequiresVertexSkinning | m_RequiresVertexSkinning;
|
||||
newReqs.m_RequiresVertexID = other.m_RequiresVertexID | m_RequiresVertexID;
|
||||
|
||||
newReqs.m_RequiresMeshUVs = new List<UVChannel>();
|
||||
if (m_RequiresMeshUVs != null)
|
||||
newReqs.m_RequiresMeshUVs.AddRange(m_RequiresMeshUVs);
|
||||
if (other.m_RequiresMeshUVs != null)
|
||||
newReqs.m_RequiresMeshUVs.AddRange(other.m_RequiresMeshUVs);
|
||||
return newReqs;
|
||||
}
|
||||
|
||||
internal static ShaderGraphRequirements FromNodes<T>(List<T> nodes, ShaderStageCapability stageCapability = ShaderStageCapability.All, bool includeIntermediateSpaces = true)
|
||||
where T : AbstractMaterialNode
|
||||
{
|
||||
NeededCoordinateSpace requiresNormal = nodes.OfType<IMayRequireNormal>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresNormal(stageCapability));
|
||||
NeededCoordinateSpace requiresBitangent = nodes.OfType<IMayRequireBitangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresBitangent(stageCapability));
|
||||
NeededCoordinateSpace requiresTangent = nodes.OfType<IMayRequireTangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresTangent(stageCapability));
|
||||
NeededCoordinateSpace requiresViewDir = nodes.OfType<IMayRequireViewDirection>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresViewDirection(stageCapability));
|
||||
NeededCoordinateSpace requiresPosition = nodes.OfType<IMayRequirePosition>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresPosition(stageCapability));
|
||||
bool requiresScreenPosition = nodes.OfType<IMayRequireScreenPosition>().Any(x => x.RequiresScreenPosition(stageCapability));
|
||||
bool requiresVertexColor = nodes.OfType<IMayRequireVertexColor>().Any(x => x.RequiresVertexColor());
|
||||
bool requiresFaceSign = nodes.OfType<IMayRequireFaceSign>().Any(x => x.RequiresFaceSign());
|
||||
bool requiresDepthTexture = nodes.OfType<IMayRequireDepthTexture>().Any(x => x.RequiresDepthTexture());
|
||||
bool requiresCameraOpaqueTexture = nodes.OfType<IMayRequireCameraOpaqueTexture>().Any(x => x.RequiresCameraOpaqueTexture());
|
||||
bool requiresTime = nodes.Any(x => x.RequiresTime());
|
||||
bool requiresVertexSkinning = nodes.OfType<IMayRequireVertexSkinning>().Any(x => x.RequiresVertexSkinning(stageCapability));
|
||||
bool requiresVertexID = nodes.OfType<IMayRequireVertexID>().Any(x => x.RequiresVertexID(stageCapability));
|
||||
|
||||
var meshUV = new List<UVChannel>();
|
||||
for (int uvIndex = 0; uvIndex < ShaderGeneratorNames.UVCount; ++uvIndex)
|
||||
{
|
||||
var channel = (UVChannel)uvIndex;
|
||||
if (nodes.OfType<IMayRequireMeshUV>().Any(x => x.RequiresMeshUV(channel)))
|
||||
meshUV.Add(channel);
|
||||
}
|
||||
|
||||
// if anything needs tangentspace we have make
|
||||
// sure to have our othonormal basis!
|
||||
if (includeIntermediateSpaces)
|
||||
{
|
||||
var compoundSpaces = requiresBitangent | requiresNormal | requiresPosition
|
||||
| requiresTangent | requiresViewDir | requiresPosition
|
||||
| requiresNormal;
|
||||
|
||||
var needsTangentSpace = (compoundSpaces & NeededCoordinateSpace.Tangent) > 0;
|
||||
if (needsTangentSpace)
|
||||
{
|
||||
requiresBitangent |= NeededCoordinateSpace.World;
|
||||
requiresNormal |= NeededCoordinateSpace.World;
|
||||
requiresTangent |= NeededCoordinateSpace.World;
|
||||
}
|
||||
}
|
||||
|
||||
var reqs = new ShaderGraphRequirements()
|
||||
{
|
||||
m_RequiresNormal = requiresNormal,
|
||||
m_RequiresBitangent = requiresBitangent,
|
||||
m_RequiresTangent = requiresTangent,
|
||||
m_RequiresViewDir = requiresViewDir,
|
||||
m_RequiresPosition = requiresPosition,
|
||||
m_RequiresScreenPosition = requiresScreenPosition,
|
||||
m_RequiresVertexColor = requiresVertexColor,
|
||||
m_RequiresFaceSign = requiresFaceSign,
|
||||
m_RequiresMeshUVs = meshUV,
|
||||
m_RequiresDepthTexture = requiresDepthTexture,
|
||||
m_RequiresCameraOpaqueTexture = requiresCameraOpaqueTexture,
|
||||
m_RequiresTime = requiresTime,
|
||||
m_RequiresVertexSkinning = requiresVertexSkinning,
|
||||
m_RequiresVertexID = requiresVertexID,
|
||||
};
|
||||
|
||||
return reqs;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,226 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Serialization;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
public abstract class ShaderInput : JsonObject
|
||||
{
|
||||
[SerializeField]
|
||||
SerializableGuid m_Guid = new SerializableGuid();
|
||||
|
||||
internal Guid guid => m_Guid.guid;
|
||||
|
||||
internal void OverrideGuid(string namespaceId, string name) { m_Guid.guid = GenerateNamespaceUUID(namespaceId, name); }
|
||||
|
||||
[SerializeField]
|
||||
string m_Name;
|
||||
|
||||
public string displayName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(m_Name))
|
||||
return $"{concreteShaderValueType}_{objectId}";
|
||||
return m_Name;
|
||||
}
|
||||
set
|
||||
{
|
||||
// this is a raw set of the display name
|
||||
// if you want to a fully graph-connected set-and-sanitize-and-update,
|
||||
// call SetDisplayNameAndSanitizeForGraph() instead
|
||||
m_Name = value;
|
||||
}
|
||||
}
|
||||
|
||||
// This delegate and the associated callback can be bound to in order for any one that cares about display name changes to be notified
|
||||
internal delegate void ChangeDisplayNameCallback(string newDisplayName);
|
||||
ChangeDisplayNameCallback m_displayNameUpdateTrigger;
|
||||
internal ChangeDisplayNameCallback displayNameUpdateTrigger
|
||||
{
|
||||
get => m_displayNameUpdateTrigger;
|
||||
set => m_displayNameUpdateTrigger = value;
|
||||
}
|
||||
|
||||
// sanitizes the desired name according to the current graph, and assigns it as the display name
|
||||
// also calls the update trigger to update other bits of the graph UI that use the name
|
||||
internal void SetDisplayNameAndSanitizeForGraph(GraphData graphData, string desiredName = null)
|
||||
{
|
||||
string originalDisplayName = displayName;
|
||||
|
||||
// if no desired name passed in, sanitize the current name
|
||||
if (desiredName == null)
|
||||
desiredName = originalDisplayName;
|
||||
|
||||
var sanitizedName = graphData.SanitizeGraphInputName(this, desiredName);
|
||||
bool changed = (originalDisplayName != sanitizedName);
|
||||
|
||||
// only assign if it was changed
|
||||
if (changed)
|
||||
m_Name = sanitizedName;
|
||||
|
||||
// update the default reference name
|
||||
UpdateDefaultReferenceName(graphData);
|
||||
|
||||
// Updates any views associated with this input so that display names stay up to date
|
||||
// NOTE: we call this even when the name has not changed, because there may be fields
|
||||
// that were user-edited and still have the temporary desired name -- those must update
|
||||
if (m_displayNameUpdateTrigger != null)
|
||||
{
|
||||
m_displayNameUpdateTrigger.Invoke(m_Name);
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetReferenceNameAndSanitizeForGraph(GraphData graphData, string desiredRefName = null)
|
||||
{
|
||||
string originalRefName = referenceName;
|
||||
|
||||
// if no desired ref name, use the current name
|
||||
if (string.IsNullOrEmpty(desiredRefName))
|
||||
desiredRefName = originalRefName;
|
||||
|
||||
// sanitize and deduplicate the desired name
|
||||
var sanitizedRefName = graphData.SanitizeGraphInputReferenceName(this, desiredRefName);
|
||||
|
||||
// check if the final result is different from the current name
|
||||
bool changed = (originalRefName != sanitizedRefName);
|
||||
|
||||
// if changed, then set the new name up as an override
|
||||
if (changed)
|
||||
overrideReferenceName = sanitizedRefName;
|
||||
}
|
||||
|
||||
// resets the reference name to a "default" value (deduplicated against existing reference names)
|
||||
// returns the new default reference name
|
||||
internal string ResetReferenceName(GraphData graphData)
|
||||
{
|
||||
overrideReferenceName = null;
|
||||
|
||||
// because we are clearing an override, we must force a sanitization pass on the default ref name
|
||||
// as there may now be collisions that didn't previously exist
|
||||
UpdateDefaultReferenceName(graphData, true);
|
||||
|
||||
return referenceName;
|
||||
}
|
||||
|
||||
internal void UpdateDefaultReferenceName(GraphData graphData, bool forceSanitize = false)
|
||||
{
|
||||
if (m_DefaultRefNameVersion <= 0)
|
||||
return; // old version is updated in the getter
|
||||
|
||||
var dispName = displayName;
|
||||
if (forceSanitize ||
|
||||
string.IsNullOrEmpty(m_DefaultReferenceName) ||
|
||||
(m_RefNameGeneratedByDisplayName != dispName))
|
||||
{
|
||||
m_DefaultReferenceName = graphData.SanitizeGraphInputReferenceName(this, dispName);
|
||||
m_RefNameGeneratedByDisplayName = dispName;
|
||||
}
|
||||
}
|
||||
|
||||
const int k_LatestDefaultRefNameVersion = 1;
|
||||
|
||||
// this is used to know whether this shader input is using:
|
||||
// 0) the "old" default reference naming scheme (type + GUID)
|
||||
// 1) the new default reference naming scheme (make it similar to the display name)
|
||||
[SerializeField]
|
||||
int m_DefaultRefNameVersion = k_LatestDefaultRefNameVersion;
|
||||
|
||||
[SerializeField]
|
||||
string m_RefNameGeneratedByDisplayName; // used to tell what was the display name used to generate the default reference name
|
||||
|
||||
[SerializeField]
|
||||
string m_DefaultReferenceName; // NOTE: this can be NULL for old graphs, or newly created properties
|
||||
|
||||
public string referenceName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(overrideReferenceName))
|
||||
{
|
||||
if (m_DefaultRefNameVersion == 0)
|
||||
{
|
||||
if (string.IsNullOrEmpty(m_DefaultReferenceName))
|
||||
m_DefaultReferenceName = GetOldDefaultReferenceName();
|
||||
return m_DefaultReferenceName;
|
||||
}
|
||||
else // version 1
|
||||
{
|
||||
// default reference name is updated elsewhere in the new naming scheme
|
||||
return m_DefaultReferenceName;
|
||||
}
|
||||
}
|
||||
return overrideReferenceName;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnBeforeDeserialize()
|
||||
{
|
||||
// if serialization doesn't write to m_DefaultRefNameVersion, then it is an old shader input, and should use the old default naming scheme
|
||||
m_DefaultRefNameVersion = 0;
|
||||
base.OnBeforeDeserialize();
|
||||
}
|
||||
|
||||
// This is required to handle Material data serialized with "_Color_GUID" reference names
|
||||
// m_DefaultReferenceName expects to match the material data and previously used PropertyType
|
||||
// ColorShaderProperty is the only case where PropertyType doesn't match ConcreteSlotValueType
|
||||
public virtual string GetOldDefaultReferenceName()
|
||||
{
|
||||
return $"{concreteShaderValueType.ToString()}_{objectId}";
|
||||
}
|
||||
|
||||
// returns true if this shader input is CURRENTLY using the old default reference name
|
||||
public bool IsUsingOldDefaultRefName()
|
||||
{
|
||||
return string.IsNullOrEmpty(overrideReferenceName) && (m_DefaultRefNameVersion == 0);
|
||||
}
|
||||
|
||||
// returns true if this shader input is CURRENTLY using the new default reference name
|
||||
public bool IsUsingNewDefaultRefName()
|
||||
{
|
||||
return string.IsNullOrEmpty(overrideReferenceName) && (m_DefaultRefNameVersion >= 1);
|
||||
}
|
||||
|
||||
// upgrades the default reference name to use the new naming scheme
|
||||
internal string UpgradeDefaultReferenceName(GraphData graphData)
|
||||
{
|
||||
m_DefaultRefNameVersion = k_LatestDefaultRefNameVersion;
|
||||
m_DefaultReferenceName = null;
|
||||
m_RefNameGeneratedByDisplayName = null;
|
||||
UpdateDefaultReferenceName(graphData, true); // make sure to sanitize the new default
|
||||
return referenceName;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
string m_OverrideReferenceName;
|
||||
|
||||
internal string overrideReferenceName
|
||||
{
|
||||
get => m_OverrideReferenceName;
|
||||
set => m_OverrideReferenceName = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
bool m_GeneratePropertyBlock = true;
|
||||
|
||||
internal bool generatePropertyBlock // this is basically the "exposed" toggle
|
||||
{
|
||||
get => m_GeneratePropertyBlock;
|
||||
set => m_GeneratePropertyBlock = value;
|
||||
}
|
||||
|
||||
internal bool isExposed => isExposable && generatePropertyBlock;
|
||||
|
||||
internal abstract ConcreteSlotValueType concreteShaderValueType { get; }
|
||||
|
||||
internal abstract bool isExposable { get; }
|
||||
internal virtual bool isAlwaysExposed => false;
|
||||
|
||||
// this controls whether the UI allows the user to rename the display and reference names
|
||||
internal abstract bool isRenamable { get; }
|
||||
|
||||
internal abstract ShaderInput Copy();
|
||||
}
|
||||
}
|
@@ -0,0 +1,219 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class ShaderKeyword : ShaderInput
|
||||
{
|
||||
public const string kVariantLimitWarning = "Graph is generating too many variants. Either delete Keywords, reduce Keyword variants or increase the Shader Variant Limit in Preferences > Shader Graph.";
|
||||
|
||||
public ShaderKeyword()
|
||||
{
|
||||
}
|
||||
|
||||
public ShaderKeyword(KeywordType keywordType)
|
||||
{
|
||||
this.displayName = keywordType.ToString();
|
||||
this.keywordType = keywordType;
|
||||
|
||||
// Add sensible default entries for Enum type
|
||||
if (keywordType == KeywordType.Enum)
|
||||
{
|
||||
m_Entries = new List<KeywordEntry>();
|
||||
m_Entries.Add(new KeywordEntry(1, "A", "A"));
|
||||
m_Entries.Add(new KeywordEntry(2, "B", "B"));
|
||||
m_Entries.Add(new KeywordEntry(3, "C", "C"));
|
||||
}
|
||||
}
|
||||
|
||||
public static ShaderKeyword CreateBuiltInKeyword(KeywordDescriptor descriptor)
|
||||
{
|
||||
if (descriptor.entries != null)
|
||||
{
|
||||
for (int i = 0; i < descriptor.entries.Length; i++)
|
||||
{
|
||||
if (descriptor.entries[i].id == -1)
|
||||
descriptor.entries[i].id = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return new ShaderKeyword()
|
||||
{
|
||||
isBuiltIn = true,
|
||||
displayName = descriptor.displayName,
|
||||
overrideReferenceName = descriptor.referenceName,
|
||||
keywordType = descriptor.type,
|
||||
keywordDefinition = descriptor.definition,
|
||||
keywordScope = descriptor.scope,
|
||||
value = descriptor.value,
|
||||
entries = descriptor.entries.ToList(),
|
||||
};
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private KeywordType m_KeywordType = KeywordType.Boolean;
|
||||
|
||||
public KeywordType keywordType
|
||||
{
|
||||
get => m_KeywordType;
|
||||
set => m_KeywordType = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private KeywordDefinition m_KeywordDefinition = KeywordDefinition.ShaderFeature;
|
||||
|
||||
public KeywordDefinition keywordDefinition
|
||||
{
|
||||
get => m_KeywordDefinition;
|
||||
set => m_KeywordDefinition = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private KeywordScope m_KeywordScope = KeywordScope.Local;
|
||||
|
||||
public KeywordScope keywordScope
|
||||
{
|
||||
get => m_KeywordScope;
|
||||
set => m_KeywordScope = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private List<KeywordEntry> m_Entries;
|
||||
|
||||
public List<KeywordEntry> entries
|
||||
{
|
||||
get => m_Entries;
|
||||
set => m_Entries = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private int m_Value;
|
||||
|
||||
public int value
|
||||
{
|
||||
get => m_Value;
|
||||
set => m_Value = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private bool m_IsEditable = true; // this serializes !isBuiltIn
|
||||
|
||||
public bool isBuiltIn
|
||||
{
|
||||
get => !m_IsEditable;
|
||||
set => m_IsEditable = !value;
|
||||
}
|
||||
|
||||
internal override bool isExposable => !isBuiltIn && (keywordDefinition != KeywordDefinition.Predefined);
|
||||
|
||||
internal override bool isRenamable => !isBuiltIn;
|
||||
|
||||
internal override ConcreteSlotValueType concreteShaderValueType => keywordType.ToConcreteSlotValueType();
|
||||
|
||||
public override string GetOldDefaultReferenceName()
|
||||
{
|
||||
// _ON suffix is required for exposing Boolean type to Material
|
||||
var suffix = string.Empty;
|
||||
if (keywordType == KeywordType.Boolean)
|
||||
{
|
||||
suffix = "_ON";
|
||||
}
|
||||
|
||||
return $"{keywordType.ToString()}_{objectId}{suffix}".ToUpper();
|
||||
}
|
||||
|
||||
public void AppendPropertyBlockStrings(ShaderStringBuilder builder)
|
||||
{
|
||||
if (isExposed)
|
||||
{
|
||||
switch (keywordType)
|
||||
{
|
||||
case KeywordType.Enum:
|
||||
string enumTagString = $"[KeywordEnum({string.Join(", ", entries.Select(x => x.displayName))})]";
|
||||
builder.AppendLine($"{enumTagString}{referenceName}(\"{displayName}\", Float) = {value}");
|
||||
break;
|
||||
case KeywordType.Boolean:
|
||||
if (referenceName.EndsWith("_ON"))
|
||||
builder.AppendLine($"[Toggle]{referenceName.Remove(referenceName.Length - 3, 3)}(\"{displayName}\", Float) = {value}");
|
||||
else
|
||||
builder.AppendLine($"[Toggle({referenceName})]{referenceName}(\"{displayName}\", Float) = {value}");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string GetKeywordDeclarationString()
|
||||
{
|
||||
// Predefined keywords do not need to be defined
|
||||
if (keywordDefinition == KeywordDefinition.Predefined)
|
||||
return string.Empty;
|
||||
|
||||
// Get definition type using scope
|
||||
string scopeString = keywordScope == KeywordScope.Local ? "_local" : string.Empty;
|
||||
string definitionString = $"{keywordDefinition.ToDeclarationString()}{scopeString}";
|
||||
|
||||
switch (keywordType)
|
||||
{
|
||||
case KeywordType.Boolean:
|
||||
return $"#pragma {definitionString} _ {referenceName}";
|
||||
case KeywordType.Enum:
|
||||
var enumEntryDefinitions = entries.Select(x => $"{referenceName}_{x.referenceName}");
|
||||
string enumEntriesString = string.Join(" ", enumEntryDefinitions);
|
||||
return $"#pragma {definitionString} {enumEntriesString}";
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public string GetKeywordPreviewDeclarationString()
|
||||
{
|
||||
switch (keywordType)
|
||||
{
|
||||
case KeywordType.Boolean:
|
||||
return value == 1 ? $"#define {referenceName}" : string.Empty;
|
||||
case KeywordType.Enum:
|
||||
return $"#define {referenceName}_{entries[value].referenceName}";
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
// Keywords copy reference name
|
||||
// This is because keywords are copied between graphs
|
||||
// When copying dependent nodes
|
||||
return new ShaderKeyword()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
isBuiltIn = isBuiltIn,
|
||||
keywordType = keywordType,
|
||||
keywordDefinition = keywordDefinition,
|
||||
keywordScope = keywordScope,
|
||||
entries = entries,
|
||||
};
|
||||
}
|
||||
|
||||
public override int latestVersion => 1;
|
||||
public override void OnAfterDeserialize(string json)
|
||||
{
|
||||
if (sgVersion == 0)
|
||||
{
|
||||
// we now allow keywords to control whether they are exposed (for Material control) or not.
|
||||
// old exposable keywords set their exposed state to maintain previous behavior
|
||||
// (where only keywords ending in "_ON" showed up in the material)
|
||||
if (isExposable)
|
||||
generatePropertyBlock = referenceName.EndsWith("_ON");
|
||||
ChangeVersion(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
abstract class SpaceMaterialSlot : Vector3MaterialSlot
|
||||
{
|
||||
[SerializeField]
|
||||
private CoordinateSpace m_Space = CoordinateSpace.World;
|
||||
|
||||
public CoordinateSpace space
|
||||
{
|
||||
get { return m_Space; }
|
||||
set { m_Space = value; }
|
||||
}
|
||||
|
||||
protected SpaceMaterialSlot()
|
||||
{}
|
||||
|
||||
protected SpaceMaterialSlot(int slotId, string displayName, string shaderOutputName, CoordinateSpace space,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All, bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, SlotType.Input, Vector3.zero, stageCapability, hidden: hidden)
|
||||
{
|
||||
this.space = space;
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as SpaceMaterialSlot;
|
||||
if (slot != null)
|
||||
space = slot.space;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using UnityEditor.ShaderGraph.Serialization;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class StickyNoteData : JsonObject, IGroupItem
|
||||
{
|
||||
[SerializeField]
|
||||
string m_Title;
|
||||
|
||||
public string title
|
||||
{
|
||||
get => m_Title;
|
||||
set => m_Title = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
string m_Content;
|
||||
|
||||
public string content
|
||||
{
|
||||
get => m_Content;
|
||||
set => m_Content = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
int m_TextSize;
|
||||
|
||||
public int textSize
|
||||
{
|
||||
get => m_TextSize;
|
||||
set => m_TextSize = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
int m_Theme;
|
||||
|
||||
public int theme
|
||||
{
|
||||
get => m_Theme;
|
||||
set => m_Theme = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
Rect m_Position;
|
||||
|
||||
public Rect position
|
||||
{
|
||||
get => m_Position;
|
||||
set => m_Position = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
JsonRef<GroupData> m_Group = null;
|
||||
|
||||
public GroupData group
|
||||
{
|
||||
get => m_Group;
|
||||
set
|
||||
{
|
||||
if (m_Group == value)
|
||||
return;
|
||||
|
||||
m_Group = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public StickyNoteData() : base() {}
|
||||
public StickyNoteData(string title, string content, Rect position)
|
||||
{
|
||||
m_Title = title;
|
||||
m_Position = position;
|
||||
m_Content = content;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class TangentMaterialSlot : SpaceMaterialSlot, IMayRequireTangent
|
||||
{
|
||||
public TangentMaterialSlot()
|
||||
{}
|
||||
|
||||
public TangentMaterialSlot(int slotId, string displayName, string shaderOutputName, CoordinateSpace space,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All, bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, space, stageCapability, hidden)
|
||||
{}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new LabelSlotControlView(space + " Space");
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.Tangent));
|
||||
}
|
||||
|
||||
public NeededCoordinateSpace RequiresTangent(ShaderStageCapability stageCapability)
|
||||
{
|
||||
if (isConnected)
|
||||
return NeededCoordinateSpace.None;
|
||||
return space.ToNeededCoordinateSpace();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
[HasDependencies(typeof(MinimalTexture2DArrayInputMaterialSlot))]
|
||||
class Texture2DArrayInputMaterialSlot : Texture2DArrayMaterialSlot
|
||||
{
|
||||
[SerializeField]
|
||||
private SerializableTextureArray m_TextureArray = new SerializableTextureArray();
|
||||
|
||||
public Texture2DArray textureArray
|
||||
{
|
||||
get { return m_TextureArray.textureArray; }
|
||||
set { m_TextureArray.textureArray = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => textureArray == null;
|
||||
|
||||
public Texture2DArrayInputMaterialSlot()
|
||||
{}
|
||||
|
||||
public Texture2DArrayInputMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
ShaderStageCapability shaderStageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, SlotType.Input, shaderStageCapability, hidden)
|
||||
{}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new TextureArraySlotControlView(this);
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
var nodeOwner = owner as AbstractMaterialNode;
|
||||
if (nodeOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
return $"UnityBuildTexture2DArrayStruct({nodeOwner.GetVariableNameForSlot(id)})";
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
var nodeOwner = owner as AbstractMaterialNode;
|
||||
if (nodeOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var prop = new Texture2DArrayShaderProperty();
|
||||
prop.overrideReferenceName = nodeOwner.GetVariableNameForSlot(id);
|
||||
prop.modifiable = false;
|
||||
prop.generatePropertyBlock = true;
|
||||
prop.value.textureArray = textureArray;
|
||||
properties.AddShaderProperty(prop);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Texture2DArray)
|
||||
{
|
||||
name = name,
|
||||
textureValue = textureArray,
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Texture2DArrayInputMaterialSlot;
|
||||
if (slot != null)
|
||||
{
|
||||
m_TextureArray = slot.m_TextureArray;
|
||||
bareResource = slot.bareResource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MinimalTexture2DArrayInputMaterialSlot : IHasDependencies
|
||||
{
|
||||
[SerializeField]
|
||||
private SerializableTextureArray m_TextureArray = null;
|
||||
|
||||
public void GetSourceAssetDependencies(AssetCollection assetCollection)
|
||||
{
|
||||
var guidString = m_TextureArray.guid;
|
||||
if (!string.IsNullOrEmpty(guidString) && GUID.TryParse(guidString, out var guid))
|
||||
{
|
||||
assetCollection.AddAssetDependency(guid, AssetCollection.Flags.IncludeInExportPackage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class Texture2DArrayMaterialSlot : MaterialSlot
|
||||
{
|
||||
public Texture2DArrayMaterialSlot()
|
||||
{}
|
||||
|
||||
public Texture2DArrayMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
ShaderStageCapability shaderStageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden)
|
||||
{}
|
||||
|
||||
[SerializeField]
|
||||
bool m_BareResource = false;
|
||||
internal override bool bareResource
|
||||
{
|
||||
get { return m_BareResource; }
|
||||
set { m_BareResource = value; }
|
||||
}
|
||||
|
||||
public override void AppendHLSLParameterDeclaration(ShaderStringBuilder sb, string paramName)
|
||||
{
|
||||
if (m_BareResource)
|
||||
{
|
||||
sb.Append("TEXTURE2D_ARRAY(");
|
||||
sb.Append(paramName);
|
||||
sb.Append(")");
|
||||
}
|
||||
else
|
||||
base.AppendHLSLParameterDeclaration(sb, paramName);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Texture2DArray; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Texture2DArray; } }
|
||||
public override bool isDefaultValue => true;
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Texture2DArrayMaterialSlot;
|
||||
if (slot != null)
|
||||
{
|
||||
m_BareResource = slot.m_BareResource;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
[FormerName("UnityEditor.ShaderGraph.Texture2DArrayShaderProperty")]
|
||||
[BlackboardInputInfo(51)]
|
||||
public class Texture2DArrayShaderProperty : AbstractShaderProperty<SerializableTextureArray>
|
||||
{
|
||||
internal Texture2DArrayShaderProperty()
|
||||
{
|
||||
displayName = "Texture2D Array";
|
||||
value = new SerializableTextureArray();
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Texture2DArray;
|
||||
|
||||
internal override bool isExposable => true;
|
||||
internal override bool isRenamable => true;
|
||||
|
||||
internal string modifiableTagString => modifiable ? "" : "[NonModifiableTextureData]";
|
||||
|
||||
internal override string GetPropertyBlockString()
|
||||
{
|
||||
return $"{hideTagString}{modifiableTagString}[NoScaleOffset]{referenceName}(\"{displayName}\", 2DArray) = \"\" {{}}";
|
||||
}
|
||||
|
||||
internal override bool AllowHLSLDeclaration(HLSLDeclaration decl) => false; // disable UI, nothing to choose
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
action(new HLSLProperty(HLSLType._Texture2DArray, referenceName, HLSLDeclaration.Global));
|
||||
action(new HLSLProperty(HLSLType._SamplerState, "sampler" + referenceName, HLSLDeclaration.Global));
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return "UnityTexture2DArray " + referenceName;
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentStringForVFX()
|
||||
{
|
||||
return "TEXTURE2D_ARRAY(" + referenceName + ")";
|
||||
}
|
||||
|
||||
internal override string GetHLSLVariableName(bool isSubgraphProperty)
|
||||
{
|
||||
if (isSubgraphProperty)
|
||||
return referenceName;
|
||||
else
|
||||
return $"UnityBuildTexture2DArrayStruct({referenceName})";
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
bool m_Modifiable = true;
|
||||
|
||||
internal bool modifiable
|
||||
{
|
||||
get => m_Modifiable;
|
||||
set => m_Modifiable = value;
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return new Texture2DArrayAssetNode { texture = value.textureArray };
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
textureValue = value.textureArray
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new Texture2DArrayShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
[HasDependencies(typeof(MinimalTexture2DInputMaterialSlot))]
|
||||
class Texture2DInputMaterialSlot : Texture2DMaterialSlot
|
||||
{
|
||||
[SerializeField]
|
||||
private SerializableTexture m_Texture = new SerializableTexture();
|
||||
|
||||
[SerializeField]
|
||||
private Texture2DShaderProperty.DefaultType m_DefaultType = Texture2DShaderProperty.DefaultType.White;
|
||||
|
||||
public Texture texture
|
||||
{
|
||||
get { return m_Texture.texture; }
|
||||
set { m_Texture.texture = value; }
|
||||
}
|
||||
|
||||
public Texture2DShaderProperty.DefaultType defaultType
|
||||
{
|
||||
get { return m_DefaultType; }
|
||||
set { m_DefaultType = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => texture == null;
|
||||
|
||||
public Texture2DInputMaterialSlot()
|
||||
{}
|
||||
|
||||
public Texture2DInputMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, SlotType.Input, stageCapability, hidden)
|
||||
{}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new TextureSlotControlView(this);
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
var nodeOwner = owner as AbstractMaterialNode;
|
||||
if (nodeOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
return $"UnityBuildTexture2DStructNoScale({nodeOwner.GetVariableNameForSlot(id)})";
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
var nodeOwner = owner as AbstractMaterialNode;
|
||||
if (nodeOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var prop = new Texture2DShaderProperty();
|
||||
prop.overrideReferenceName = nodeOwner.GetVariableNameForSlot(id);
|
||||
prop.modifiable = false;
|
||||
prop.generatePropertyBlock = true;
|
||||
prop.value.texture = texture;
|
||||
prop.defaultType = defaultType;
|
||||
properties.AddShaderProperty(prop);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Texture2D)
|
||||
{
|
||||
name = name,
|
||||
textureValue = texture,
|
||||
texture2DDefaultType = defaultType
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Texture2DInputMaterialSlot;
|
||||
if (slot != null)
|
||||
{
|
||||
m_Texture = slot.m_Texture;
|
||||
bareResource = slot.bareResource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MinimalTexture2DInputMaterialSlot : IHasDependencies
|
||||
{
|
||||
[SerializeField]
|
||||
private SerializableTexture m_Texture = null;
|
||||
|
||||
public void GetSourceAssetDependencies(AssetCollection assetCollection)
|
||||
{
|
||||
var guidString = m_Texture.guid;
|
||||
if (!string.IsNullOrEmpty(guidString) && GUID.TryParse(guidString, out var guid))
|
||||
{
|
||||
assetCollection.AddAssetDependency(guid, AssetCollection.Flags.IncludeInExportPackage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class Texture2DMaterialSlot : MaterialSlot
|
||||
{
|
||||
public Texture2DMaterialSlot()
|
||||
{}
|
||||
|
||||
public Texture2DMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{}
|
||||
|
||||
[SerializeField]
|
||||
bool m_BareResource = false;
|
||||
internal override bool bareResource
|
||||
{
|
||||
get { return m_BareResource; }
|
||||
set { m_BareResource = value; }
|
||||
}
|
||||
|
||||
public override void AppendHLSLParameterDeclaration(ShaderStringBuilder sb, string paramName)
|
||||
{
|
||||
if (m_BareResource)
|
||||
{
|
||||
sb.Append("TEXTURE2D(");
|
||||
sb.Append(paramName);
|
||||
sb.Append(")");
|
||||
}
|
||||
else
|
||||
base.AppendHLSLParameterDeclaration(sb, paramName);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Texture2D; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Texture2D; } }
|
||||
public override bool isDefaultValue => true;
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Texture2DMaterialSlot;
|
||||
if (slot != null)
|
||||
{
|
||||
m_BareResource = slot.m_BareResource;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
[FormerName("UnityEditor.ShaderGraph.TextureShaderProperty")]
|
||||
[BlackboardInputInfo(50)]
|
||||
public sealed class Texture2DShaderProperty : AbstractShaderProperty<SerializableTexture>
|
||||
{
|
||||
public enum DefaultType { White, Black, Grey, Bump }
|
||||
|
||||
internal Texture2DShaderProperty()
|
||||
{
|
||||
displayName = "Texture2D";
|
||||
value = new SerializableTexture();
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Texture2D;
|
||||
|
||||
internal override bool isExposable => true;
|
||||
internal override bool isRenamable => true;
|
||||
|
||||
internal string modifiableTagString => modifiable ? "" : "[NonModifiableTextureData]";
|
||||
|
||||
internal override string GetPropertyBlockString()
|
||||
{
|
||||
return $"{hideTagString}{modifiableTagString}[NoScaleOffset]{referenceName}(\"{displayName}\", 2D) = \"{defaultType.ToString().ToLower()}\" {{}}";
|
||||
}
|
||||
|
||||
// Texture2D properties cannot be set via Hybrid path at the moment; disallow that choice
|
||||
internal override bool AllowHLSLDeclaration(HLSLDeclaration decl) => (decl != HLSLDeclaration.HybridPerInstance) && (decl != HLSLDeclaration.DoNotDeclare);
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
HLSLDeclaration decl = (generatePropertyBlock ? HLSLDeclaration.UnityPerMaterial : HLSLDeclaration.Global);
|
||||
|
||||
action(new HLSLProperty(HLSLType._Texture2D, referenceName, HLSLDeclaration.Global));
|
||||
action(new HLSLProperty(HLSLType._SamplerState, "sampler" + referenceName, HLSLDeclaration.Global));
|
||||
action(new HLSLProperty(HLSLType._float4, referenceName + "_TexelSize", decl));
|
||||
// action(new HLSLProperty(HLSLType._float4, referenceName + "_ST", decl)); // TODO: allow users to make use of the ST values
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return "UnityTexture2D " + referenceName;
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentStringForVFX()
|
||||
{
|
||||
return "TEXTURE2D(" + referenceName + ")";
|
||||
}
|
||||
|
||||
internal override string GetHLSLVariableName(bool isSubgraphProperty)
|
||||
{
|
||||
if (isSubgraphProperty)
|
||||
return referenceName;
|
||||
else
|
||||
return $"UnityBuildTexture2DStructNoScale({referenceName})";
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
bool m_Modifiable = true;
|
||||
|
||||
internal bool modifiable
|
||||
{
|
||||
get => m_Modifiable;
|
||||
set => m_Modifiable = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
DefaultType m_DefaultType = DefaultType.White;
|
||||
|
||||
public DefaultType defaultType
|
||||
{
|
||||
get { return m_DefaultType; }
|
||||
set { m_DefaultType = value; }
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return new Texture2DAssetNode { texture = value.texture };
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
textureValue = value.texture,
|
||||
texture2DDefaultType = defaultType
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new Texture2DShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
defaultType = defaultType,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
[HasDependencies(typeof(MinimalTexture3DInputMaterialSlot))]
|
||||
class Texture3DInputMaterialSlot : Texture3DMaterialSlot
|
||||
{
|
||||
[SerializeField]
|
||||
private SerializableTexture m_Texture = new SerializableTexture();
|
||||
|
||||
public Texture texture
|
||||
{
|
||||
get { return m_Texture.texture; }
|
||||
set { m_Texture.texture = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => texture == null;
|
||||
|
||||
public Texture3DInputMaterialSlot()
|
||||
{}
|
||||
|
||||
public Texture3DInputMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
ShaderStageCapability shaderStageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, SlotType.Input, shaderStageCapability, hidden)
|
||||
{}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new Texture3DSlotControlView(this);
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
var nodeOwner = owner as AbstractMaterialNode;
|
||||
if (nodeOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
return $"UnityBuildTexture3DStruct({nodeOwner.GetVariableNameForSlot(id)})";
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
var nodeOwner = owner as AbstractMaterialNode;
|
||||
if (nodeOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var prop = new Texture3DShaderProperty();
|
||||
prop.overrideReferenceName = nodeOwner.GetVariableNameForSlot(id);
|
||||
prop.modifiable = false;
|
||||
prop.generatePropertyBlock = true;
|
||||
prop.value.texture = texture;
|
||||
properties.AddShaderProperty(prop);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Texture3D)
|
||||
{
|
||||
name = name,
|
||||
textureValue = texture,
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Texture3DInputMaterialSlot;
|
||||
if (slot != null)
|
||||
{
|
||||
m_Texture = slot.m_Texture;
|
||||
bareResource = slot.bareResource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MinimalTexture3DInputMaterialSlot : IHasDependencies
|
||||
{
|
||||
[SerializeField]
|
||||
private SerializableTexture m_Texture = null;
|
||||
|
||||
public void GetSourceAssetDependencies(AssetCollection assetCollection)
|
||||
{
|
||||
var guidString = m_Texture.guid;
|
||||
if (!string.IsNullOrEmpty(guidString) && GUID.TryParse(guidString, out var guid))
|
||||
{
|
||||
assetCollection.AddAssetDependency(guid, AssetCollection.Flags.IncludeInExportPackage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class Texture3DMaterialSlot : MaterialSlot
|
||||
{
|
||||
public Texture3DMaterialSlot()
|
||||
{}
|
||||
|
||||
public Texture3DMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
ShaderStageCapability shaderStageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, shaderStageCapability, hidden)
|
||||
{}
|
||||
|
||||
[SerializeField]
|
||||
bool m_BareResource = false;
|
||||
internal override bool bareResource
|
||||
{
|
||||
get { return m_BareResource; }
|
||||
set { m_BareResource = value; }
|
||||
}
|
||||
|
||||
public override void AppendHLSLParameterDeclaration(ShaderStringBuilder sb, string paramName)
|
||||
{
|
||||
if (m_BareResource)
|
||||
{
|
||||
sb.Append("TEXTURE3D(");
|
||||
sb.Append(paramName);
|
||||
sb.Append(")");
|
||||
}
|
||||
else
|
||||
base.AppendHLSLParameterDeclaration(sb, paramName);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Texture3D; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Texture3D; } }
|
||||
public override bool isDefaultValue => true;
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Texture3DMaterialSlot;
|
||||
if (slot != null)
|
||||
{
|
||||
m_BareResource = slot.m_BareResource;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
[FormerName("UnityEditor.ShaderGraph.Texture3DShaderProperty")]
|
||||
[BlackboardInputInfo(52)]
|
||||
public sealed class Texture3DShaderProperty : AbstractShaderProperty<SerializableTexture>
|
||||
{
|
||||
internal Texture3DShaderProperty()
|
||||
{
|
||||
displayName = "Texture3D";
|
||||
value = new SerializableTexture();
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Texture3D;
|
||||
|
||||
internal override bool isExposable => true;
|
||||
internal override bool isRenamable => true;
|
||||
|
||||
internal string modifiableTagString => modifiable ? "" : "[NonModifiableTextureData]";
|
||||
|
||||
internal override string GetPropertyBlockString()
|
||||
{
|
||||
return $"{hideTagString}{modifiableTagString}[NoScaleOffset]{referenceName}(\"{displayName}\", 3D) = \"white\" {{}}";
|
||||
}
|
||||
|
||||
internal override bool AllowHLSLDeclaration(HLSLDeclaration decl) => false; // disable UI, nothing to choose
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
action(new HLSLProperty(HLSLType._Texture3D, referenceName, HLSLDeclaration.Global));
|
||||
action(new HLSLProperty(HLSLType._SamplerState, "sampler" + referenceName, HLSLDeclaration.Global));
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return "UnityTexture3D " + referenceName;
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentStringForVFX()
|
||||
{
|
||||
return "TEXTURE3D(" + referenceName + ")";
|
||||
}
|
||||
|
||||
internal override string GetHLSLVariableName(bool isSubgraphProperty)
|
||||
{
|
||||
if (isSubgraphProperty)
|
||||
return referenceName;
|
||||
else
|
||||
return $"UnityBuildTexture3DStruct({referenceName})";
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
bool m_Modifiable = true;
|
||||
|
||||
public bool modifiable
|
||||
{
|
||||
get => m_Modifiable;
|
||||
set => m_Modifiable = value;
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return new Texture3DAssetNode { texture = value.texture as Texture3D };
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
textureValue = value.texture
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new Texture3DShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class TextureSamplerState
|
||||
{
|
||||
public enum FilterMode
|
||||
{
|
||||
Linear,
|
||||
Point,
|
||||
Trilinear
|
||||
}
|
||||
|
||||
public enum WrapMode
|
||||
{
|
||||
Repeat,
|
||||
Clamp,
|
||||
Mirror,
|
||||
MirrorOnce
|
||||
}
|
||||
|
||||
[SerializeField] private FilterMode m_filter = FilterMode.Linear;
|
||||
|
||||
public FilterMode filter
|
||||
{
|
||||
get { return m_filter; }
|
||||
set
|
||||
{
|
||||
if (m_filter == value)
|
||||
return;
|
||||
|
||||
m_filter = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField] private WrapMode m_wrap = WrapMode.Repeat;
|
||||
|
||||
public WrapMode wrap
|
||||
{
|
||||
get { return m_wrap; }
|
||||
set
|
||||
{
|
||||
if (m_wrap == value)
|
||||
return;
|
||||
|
||||
m_wrap = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class UVMaterialSlot : Vector2MaterialSlot, IMayRequireMeshUV
|
||||
{
|
||||
[SerializeField]
|
||||
UVChannel m_Channel = UVChannel.UV0;
|
||||
|
||||
public UVChannel channel
|
||||
{
|
||||
get { return m_Channel; }
|
||||
set { m_Channel = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => channel == UVChannel.UV0;
|
||||
|
||||
public UVMaterialSlot()
|
||||
{}
|
||||
|
||||
public UVMaterialSlot(int slotId, string displayName, string shaderOutputName, UVChannel channel,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All, bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, SlotType.Input, Vector2.zero, stageCapability, hidden: hidden)
|
||||
{
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new UVSlotControlView(this);
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
return string.Format("IN.{0}.xy", channel.GetUVName());
|
||||
}
|
||||
|
||||
public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability)
|
||||
{
|
||||
if (isConnected)
|
||||
return false;
|
||||
|
||||
return m_Channel == channel;
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as UVMaterialSlot;
|
||||
if (slot != null)
|
||||
channel = slot.channel;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,122 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class Vector1MaterialSlot : MaterialSlot, IMaterialSlotHasValue<float>
|
||||
{
|
||||
[SerializeField]
|
||||
float m_Value;
|
||||
|
||||
[SerializeField]
|
||||
float m_DefaultValue;
|
||||
|
||||
[SerializeField]
|
||||
string[] m_Labels; // this can be null, which means fallback to k_LabelDefaults
|
||||
|
||||
static readonly string[] k_LabelDefaults = { "X" };
|
||||
string[] labels
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((m_Labels == null) || (m_Labels.Length != k_LabelDefaults.Length))
|
||||
return k_LabelDefaults;
|
||||
return m_Labels;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector1MaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public Vector1MaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
float value,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
string label1 = null,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
m_DefaultValue = value;
|
||||
m_Value = value;
|
||||
if (label1 != null)
|
||||
m_Labels = new[] { label1 };
|
||||
}
|
||||
|
||||
public float defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public float value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new MultiFloatSlotControlView(owner, labels, () => new Vector4(value, 0f, 0f, 0f), (newValue) => value = newValue.x);
|
||||
}
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return NodeUtils.FloatToShaderValue(value);
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var property = new Vector1ShaderProperty()
|
||||
{
|
||||
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
|
||||
generatePropertyBlock = false,
|
||||
value = value
|
||||
};
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Vector1; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Vector1; } }
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Float)
|
||||
{
|
||||
name = name,
|
||||
floatValue = value,
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Vector1MaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
|
||||
public override void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
base.CopyDefaultValue(other);
|
||||
if (other is IMaterialSlotHasValue<float> ms)
|
||||
{
|
||||
m_DefaultValue = ms.defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,179 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
[FormerName("UnityEditor.ShaderGraph.FloatShaderProperty")]
|
||||
[FormerName("UnityEditor.ShaderGraph.Vector1ShaderProperty")]
|
||||
[BlackboardInputInfo(0, "Float")]
|
||||
public sealed class Vector1ShaderProperty : AbstractShaderProperty<float>
|
||||
{
|
||||
internal Vector1ShaderProperty()
|
||||
{
|
||||
displayName = "Float";
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Float;
|
||||
|
||||
internal override bool isExposable => true;
|
||||
internal override bool isRenamable => true;
|
||||
|
||||
string enumTagString
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (enumType)
|
||||
{
|
||||
case EnumType.CSharpEnum:
|
||||
return $"[Enum({m_CSharpEnumType.ToString()})]";
|
||||
case EnumType.KeywordEnum:
|
||||
return $"[KeywordEnum({string.Join(", ", enumNames)})]";
|
||||
default:
|
||||
string enumValuesString = "";
|
||||
for (int i = 0; i < enumNames.Count; i++)
|
||||
{
|
||||
int value = (i < enumValues.Count) ? enumValues[i] : i;
|
||||
enumValuesString += (enumNames[i] + ", " + value + ((i != enumNames.Count - 1) ? ", " : ""));
|
||||
}
|
||||
return $"[Enum({enumValuesString})]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal override string GetPropertyBlockString()
|
||||
{
|
||||
string valueString = NodeUtils.FloatToShaderValueShaderLabSafe(value);
|
||||
|
||||
switch (floatType)
|
||||
{
|
||||
case FloatType.Slider:
|
||||
return $"{hideTagString}{referenceName}(\"{displayName}\", Range({NodeUtils.FloatToShaderValue(m_RangeValues.x)}, {NodeUtils.FloatToShaderValue(m_RangeValues.y)})) = {valueString}";
|
||||
case FloatType.Integer:
|
||||
return $"{hideTagString}{referenceName}(\"{displayName}\", Int) = {((int)value).ToString(CultureInfo.InvariantCulture)}";
|
||||
case FloatType.Enum:
|
||||
return $"{hideTagString}{enumTagString}{referenceName}(\"{displayName}\", Float) = {valueString}";
|
||||
default:
|
||||
return $"{hideTagString}{referenceName}(\"{displayName}\", Float) = {valueString}";
|
||||
}
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return $"{concreteShaderValueType.ToShaderString(concretePrecision.ToShaderString())} {referenceName}";
|
||||
}
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
HLSLDeclaration decl = GetDefaultHLSLDeclaration();
|
||||
action(new HLSLProperty(HLSLType._float, referenceName, decl, concretePrecision));
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
FloatType m_FloatType = FloatType.Default;
|
||||
|
||||
public FloatType floatType
|
||||
{
|
||||
get => m_FloatType;
|
||||
set => m_FloatType = value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
Vector2 m_RangeValues = new Vector2(0, 1);
|
||||
|
||||
public Vector2 rangeValues
|
||||
{
|
||||
get => m_RangeValues;
|
||||
set => m_RangeValues = value;
|
||||
}
|
||||
|
||||
EnumType m_EnumType = EnumType.Enum;
|
||||
|
||||
public EnumType enumType
|
||||
{
|
||||
get => m_EnumType;
|
||||
set => m_EnumType = value;
|
||||
}
|
||||
|
||||
Type m_CSharpEnumType;
|
||||
|
||||
public Type cSharpEnumType
|
||||
{
|
||||
get => m_CSharpEnumType;
|
||||
set => m_CSharpEnumType = value;
|
||||
}
|
||||
|
||||
List<string> m_EnumNames = new List<string>();
|
||||
|
||||
public List<string> enumNames
|
||||
{
|
||||
get => m_EnumNames;
|
||||
set => m_EnumNames = value;
|
||||
}
|
||||
|
||||
List<int> m_EnumValues = new List<int>();
|
||||
|
||||
public List<int> enumValues
|
||||
{
|
||||
get => m_EnumValues;
|
||||
set => m_EnumValues = value;
|
||||
}
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
switch (m_FloatType)
|
||||
{
|
||||
case FloatType.Slider:
|
||||
return new SliderNode { value = new Vector3(value, m_RangeValues.x, m_RangeValues.y) };
|
||||
case FloatType.Integer:
|
||||
return new IntegerNode { value = (int)value };
|
||||
default:
|
||||
var node = new Vector1Node();
|
||||
node.FindInputSlot<Vector1MaterialSlot>(Vector1Node.InputSlotXId).value = value;
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
floatValue = value
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new Vector1ShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
floatType = floatType,
|
||||
rangeValues = rangeValues,
|
||||
enumType = enumType,
|
||||
enumNames = enumNames,
|
||||
enumValues = enumValues,
|
||||
};
|
||||
}
|
||||
|
||||
public override int latestVersion => 1;
|
||||
public override void OnAfterDeserialize(string json)
|
||||
{
|
||||
if (sgVersion == 0)
|
||||
{
|
||||
LegacyShaderPropertyData.UpgradeToHLSLDeclarationOverride(json, this);
|
||||
ChangeVersion(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum FloatType { Default, Slider, Integer, Enum }
|
||||
|
||||
public enum EnumType { Enum, CSharpEnum, KeywordEnum, }
|
||||
}
|
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class Vector2MaterialSlot : MaterialSlot, IMaterialSlotHasValue<Vector2>
|
||||
{
|
||||
[SerializeField]
|
||||
Vector2 m_Value;
|
||||
|
||||
[SerializeField]
|
||||
Vector2 m_DefaultValue = Vector2.zero;
|
||||
|
||||
[SerializeField]
|
||||
string[] m_Labels; // this can be null, which means fallback to k_LabelDefaults
|
||||
|
||||
static readonly string[] k_LabelDefaults = { "X", "Y" };
|
||||
string[] labels
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((m_Labels == null) || (m_Labels.Length != k_LabelDefaults.Length))
|
||||
return k_LabelDefaults;
|
||||
return m_Labels;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2MaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public Vector2MaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
Vector2 value,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
string label1 = null,
|
||||
string label2 = null,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
m_Value = value;
|
||||
if ((label1 != null) || (label2 != null))
|
||||
{
|
||||
m_Labels = new[]
|
||||
{
|
||||
label1 ?? k_LabelDefaults[0],
|
||||
label2 ?? k_LabelDefaults[1]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public Vector2 value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new MultiFloatSlotControlView(owner, labels, () => value, (newValue) => value = newValue);
|
||||
}
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return string.Format("$precision2 ({0}, {1})"
|
||||
, NodeUtils.FloatToShaderValue(value.x)
|
||||
, NodeUtils.FloatToShaderValue(value.y));
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var property = new Vector2ShaderProperty
|
||||
{
|
||||
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
|
||||
generatePropertyBlock = false,
|
||||
value = value
|
||||
};
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Vector2)
|
||||
{
|
||||
name = name,
|
||||
vector4Value = new Vector4(value.x, value.y, 0, 0),
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Vector2; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Vector2; } }
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Vector2MaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
|
||||
public override void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
base.CopyDefaultValue(other);
|
||||
if (other is IMaterialSlotHasValue<Vector2> ms)
|
||||
{
|
||||
m_DefaultValue = ms.defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
[FormerName("UnityEditor.ShaderGraph.Vector2ShaderProperty")]
|
||||
[BlackboardInputInfo(1)]
|
||||
public sealed class Vector2ShaderProperty : VectorShaderProperty
|
||||
{
|
||||
internal Vector2ShaderProperty()
|
||||
{
|
||||
displayName = "Vector2";
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Vector2;
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
var node = new Vector2Node();
|
||||
node.FindInputSlot<Vector1MaterialSlot>(Vector2Node.InputSlotXId).value = value.x;
|
||||
node.FindInputSlot<Vector1MaterialSlot>(Vector2Node.InputSlotYId).value = value.y;
|
||||
return node;
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
vector4Value = value
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new Vector2ShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
HLSLDeclaration decl = GetDefaultHLSLDeclaration();
|
||||
action(new HLSLProperty(HLSLType._float2, referenceName, decl, concretePrecision));
|
||||
}
|
||||
|
||||
public override int latestVersion => 1;
|
||||
public override void OnAfterDeserialize(string json)
|
||||
{
|
||||
if (sgVersion == 0)
|
||||
{
|
||||
LegacyShaderPropertyData.UpgradeToHLSLDeclarationOverride(json, this);
|
||||
ChangeVersion(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,133 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class Vector3MaterialSlot : MaterialSlot, IMaterialSlotHasValue<Vector3>
|
||||
{
|
||||
[SerializeField]
|
||||
private Vector3 m_Value;
|
||||
|
||||
[SerializeField]
|
||||
private Vector3 m_DefaultValue = Vector3.zero;
|
||||
|
||||
[SerializeField]
|
||||
string[] m_Labels; // this can be null, which means fallback to k_LabelDefaults
|
||||
|
||||
static readonly string[] k_LabelDefaults = { "X", "Y", "Z" };
|
||||
string[] labels
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((m_Labels == null) || (m_Labels.Length != k_LabelDefaults.Length))
|
||||
return k_LabelDefaults;
|
||||
return m_Labels;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3MaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public Vector3MaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
Vector3 value,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
string label1 = null,
|
||||
string label2 = null,
|
||||
string label3 = null,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
m_Value = value;
|
||||
if ((label1 != null) || (label2 != null) || (label3 != null))
|
||||
{
|
||||
m_Labels = new[]
|
||||
{
|
||||
label1 ?? k_LabelDefaults[0],
|
||||
label2 ?? k_LabelDefaults[1],
|
||||
label3 ?? k_LabelDefaults[2]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public Vector3 value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new MultiFloatSlotControlView(owner, labels, () => value, (newValue) => value = newValue);
|
||||
}
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return string.Format("$precision3 ({0}, {1}, {2})"
|
||||
, NodeUtils.FloatToShaderValue(value.x)
|
||||
, NodeUtils.FloatToShaderValue(value.y)
|
||||
, NodeUtils.FloatToShaderValue(value.z));
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var property = new Vector3ShaderProperty()
|
||||
{
|
||||
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
|
||||
generatePropertyBlock = false,
|
||||
value = value
|
||||
};
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Vector3)
|
||||
{
|
||||
name = name,
|
||||
vector4Value = new Vector4(value.x, value.y, value.z, 0)
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Vector3; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Vector3; } }
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Vector3MaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
|
||||
public override void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
base.CopyDefaultValue(other);
|
||||
if (other is IMaterialSlotHasValue<Vector3> ms)
|
||||
{
|
||||
m_DefaultValue = ms.defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
[FormerName("UnityEditor.ShaderGraph.Vector3ShaderProperty")]
|
||||
[BlackboardInputInfo(3)]
|
||||
public sealed class Vector3ShaderProperty : VectorShaderProperty
|
||||
{
|
||||
internal Vector3ShaderProperty()
|
||||
{
|
||||
displayName = "Vector3";
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Vector3;
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
var node = new Vector3Node();
|
||||
node.FindInputSlot<Vector1MaterialSlot>(Vector3Node.InputSlotXId).value = value.x;
|
||||
node.FindInputSlot<Vector1MaterialSlot>(Vector3Node.InputSlotYId).value = value.y;
|
||||
node.FindInputSlot<Vector1MaterialSlot>(Vector3Node.InputSlotZId).value = value.z;
|
||||
return node;
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
vector4Value = value
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new Vector3ShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
HLSLDeclaration decl = GetDefaultHLSLDeclaration();
|
||||
action(new HLSLProperty(HLSLType._float3, referenceName, decl, concretePrecision));
|
||||
}
|
||||
|
||||
public override int latestVersion => 1;
|
||||
public override void OnAfterDeserialize(string json)
|
||||
{
|
||||
if (sgVersion == 0)
|
||||
{
|
||||
LegacyShaderPropertyData.UpgradeToHLSLDeclarationOverride(json, this);
|
||||
ChangeVersion(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,136 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class Vector4MaterialSlot : MaterialSlot, IMaterialSlotHasValue<Vector4>
|
||||
{
|
||||
[SerializeField]
|
||||
private Vector4 m_Value;
|
||||
|
||||
[SerializeField]
|
||||
private Vector4 m_DefaultValue = Vector4.zero;
|
||||
|
||||
[SerializeField]
|
||||
string[] m_Labels; // this can be null, which means fallback to k_LabelDefaults
|
||||
|
||||
static readonly string[] k_LabelDefaults = { "X", "Y", "Z", "W" };
|
||||
string[] labels
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((m_Labels == null) || (m_Labels.Length != k_LabelDefaults.Length))
|
||||
return k_LabelDefaults;
|
||||
return m_Labels;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector4MaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public Vector4MaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
Vector4 value,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
string label1 = null,
|
||||
string label2 = null,
|
||||
string label3 = null,
|
||||
string label4 = null,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{
|
||||
m_Value = value;
|
||||
if ((label1 != null) || (label2 != null) || (label3 != null) || (label4 != null))
|
||||
{
|
||||
m_Labels = new[]
|
||||
{
|
||||
label1 ?? k_LabelDefaults[0],
|
||||
label2 ?? k_LabelDefaults[1],
|
||||
label3 ?? k_LabelDefaults[2],
|
||||
label4 ?? k_LabelDefaults[3]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public Vector4 defaultValue { get { return m_DefaultValue; } }
|
||||
|
||||
public Vector4 value
|
||||
{
|
||||
get { return m_Value; }
|
||||
set { m_Value = value; }
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => value.Equals(defaultValue);
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new MultiFloatSlotControlView(owner, labels, () => value, (newValue) => value = newValue);
|
||||
}
|
||||
|
||||
protected override string ConcreteSlotValueAsVariable()
|
||||
{
|
||||
return string.Format("$precision4 ({0}, {1}, {2}, {3})"
|
||||
, NodeUtils.FloatToShaderValue(value.x)
|
||||
, NodeUtils.FloatToShaderValue(value.y)
|
||||
, NodeUtils.FloatToShaderValue(value.z)
|
||||
, NodeUtils.FloatToShaderValue(value.w));
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
if (!generationMode.IsPreview())
|
||||
return;
|
||||
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
var property = new Vector4ShaderProperty()
|
||||
{
|
||||
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
|
||||
generatePropertyBlock = false,
|
||||
value = value
|
||||
};
|
||||
properties.AddShaderProperty(property);
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
var pp = new PreviewProperty(PropertyType.Vector4)
|
||||
{
|
||||
name = name,
|
||||
vector4Value = new Vector4(value.x, value.y, value.z, value.w),
|
||||
};
|
||||
properties.Add(pp);
|
||||
}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.Vector4; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.Vector4; } }
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
var slot = foundSlot as Vector4MaterialSlot;
|
||||
if (slot != null)
|
||||
value = slot.value;
|
||||
}
|
||||
|
||||
public override void CopyDefaultValue(MaterialSlot other)
|
||||
{
|
||||
base.CopyDefaultValue(other);
|
||||
if (other is IMaterialSlotHasValue<Vector4> ms)
|
||||
{
|
||||
m_DefaultValue = ms.defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
[FormerName("UnityEditor.ShaderGraph.Vector4ShaderProperty")]
|
||||
[BlackboardInputInfo(4)]
|
||||
public sealed class Vector4ShaderProperty : VectorShaderProperty
|
||||
{
|
||||
internal Vector4ShaderProperty()
|
||||
{
|
||||
displayName = "Vector4";
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.Vector4;
|
||||
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
var node = new Vector4Node();
|
||||
node.FindInputSlot<Vector1MaterialSlot>(Vector4Node.InputSlotXId).value = value.x;
|
||||
node.FindInputSlot<Vector1MaterialSlot>(Vector4Node.InputSlotYId).value = value.y;
|
||||
node.FindInputSlot<Vector1MaterialSlot>(Vector4Node.InputSlotZId).value = value.z;
|
||||
node.FindInputSlot<Vector1MaterialSlot>(Vector4Node.InputSlotWId).value = value.w;
|
||||
return node;
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
vector4Value = value
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
return new Vector4ShaderProperty()
|
||||
{
|
||||
displayName = displayName,
|
||||
value = value,
|
||||
};
|
||||
}
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
HLSLDeclaration decl = GetDefaultHLSLDeclaration();
|
||||
action(new HLSLProperty(HLSLType._float4, referenceName, decl, concretePrecision));
|
||||
}
|
||||
|
||||
public override int latestVersion => 1;
|
||||
public override void OnAfterDeserialize(string json)
|
||||
{
|
||||
if (sgVersion == 0)
|
||||
{
|
||||
LegacyShaderPropertyData.UpgradeToHLSLDeclarationOverride(json, this);
|
||||
ChangeVersion(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Internal
|
||||
{
|
||||
[Serializable]
|
||||
public abstract class VectorShaderProperty : AbstractShaderProperty<Vector4>
|
||||
{
|
||||
internal override bool isExposable => true;
|
||||
internal override bool isRenamable => true;
|
||||
|
||||
internal override string GetPropertyBlockString()
|
||||
{
|
||||
return $"{hideTagString}{referenceName}(\"{displayName}\", Vector) = ({NodeUtils.FloatToShaderValueShaderLabSafe(value.x)}, {NodeUtils.FloatToShaderValueShaderLabSafe(value.y)}, {NodeUtils.FloatToShaderValueShaderLabSafe(value.z)}, {NodeUtils.FloatToShaderValueShaderLabSafe(value.w)})";
|
||||
}
|
||||
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return $"{concreteShaderValueType.ToShaderString(concretePrecision.ToShaderString())} {referenceName}";
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class VertexColorMaterialSlot : Vector4MaterialSlot, IMayRequireScreenPosition
|
||||
{
|
||||
public VertexColorMaterialSlot(int slotId, string displayName, string shaderOutputName,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All, bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, SlotType.Input, Vector3.zero, stageCapability, hidden: hidden)
|
||||
{}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new LabelSlotControlView("Vertex Color");
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
return string.Format("IN.{0}", ShaderGeneratorNames.VertexColor);
|
||||
}
|
||||
|
||||
public bool RequiresScreenPosition(ShaderStageCapability stageCapability)
|
||||
{
|
||||
return !isConnected;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class ViewDirectionMaterialSlot : SpaceMaterialSlot, IMayRequireViewDirection
|
||||
{
|
||||
public ViewDirectionMaterialSlot()
|
||||
{}
|
||||
|
||||
public ViewDirectionMaterialSlot(int slotId, string displayName, string shaderOutputName, CoordinateSpace space,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All, bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, space, stageCapability, hidden)
|
||||
{}
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return new LabelSlotControlView(space + " Space");
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.ViewDirection));
|
||||
}
|
||||
|
||||
public NeededCoordinateSpace RequiresViewDirection(ShaderStageCapability stageCapability)
|
||||
{
|
||||
if (isConnected)
|
||||
return NeededCoordinateSpace.None;
|
||||
return space.ToNeededCoordinateSpace();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Drawing.Slots;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class VirtualTextureInputMaterialSlot : VirtualTextureMaterialSlot
|
||||
{
|
||||
public VirtualTextureInputMaterialSlot()
|
||||
{
|
||||
}
|
||||
|
||||
public VirtualTextureInputMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, SlotType.Input, stageCapability, hidden)
|
||||
{
|
||||
}
|
||||
|
||||
public override VisualElement InstantiateControl()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public override string GetDefaultValue(GenerationMode generationMode)
|
||||
{
|
||||
var matOwner = owner as AbstractMaterialNode;
|
||||
if (matOwner == null)
|
||||
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
|
||||
|
||||
return matOwner.GetVariableNameForSlot(id);
|
||||
}
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
}
|
||||
|
||||
public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
|
||||
{
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using UnityEditor.Graphing;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
class VirtualTextureMaterialSlot : MaterialSlot
|
||||
{
|
||||
public VirtualTextureMaterialSlot()
|
||||
{}
|
||||
|
||||
public VirtualTextureMaterialSlot(
|
||||
int slotId,
|
||||
string displayName,
|
||||
string shaderOutputName,
|
||||
SlotType slotType,
|
||||
ShaderStageCapability stageCapability = ShaderStageCapability.All,
|
||||
bool hidden = false)
|
||||
: base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden)
|
||||
{}
|
||||
|
||||
public override SlotValueType valueType { get { return SlotValueType.VirtualTexture; } }
|
||||
public override ConcreteSlotValueType concreteValueType { get { return ConcreteSlotValueType.VirtualTexture; } }
|
||||
|
||||
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
|
||||
{
|
||||
}
|
||||
|
||||
public override void CopyValuesFrom(MaterialSlot foundSlot)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool isDefaultValue => throw new Exception();
|
||||
}
|
||||
}
|
@@ -0,0 +1,208 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor.ShaderGraph.Drawing.Controls;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
[BlackboardInputInfo(60)]
|
||||
class VirtualTextureShaderProperty : AbstractShaderProperty<SerializableVirtualTexture>
|
||||
{
|
||||
public VirtualTextureShaderProperty()
|
||||
{
|
||||
displayName = "VirtualTexture";
|
||||
value = new SerializableVirtualTexture();
|
||||
|
||||
// add at least one layer
|
||||
value.layers = new List<SerializableVirtualTextureLayer>();
|
||||
value.layers.Add(new SerializableVirtualTextureLayer("Layer0", new SerializableTexture()));
|
||||
value.layers.Add(new SerializableVirtualTextureLayer("Layer1", new SerializableTexture()));
|
||||
}
|
||||
|
||||
public override PropertyType propertyType => PropertyType.VirtualTexture;
|
||||
|
||||
internal override bool isExposable => true; // the textures are exposable at least..
|
||||
internal override bool isRenamable => true;
|
||||
|
||||
internal override void GetPropertyReferenceNames(List<string> result)
|
||||
{
|
||||
result.Add(referenceName);
|
||||
for (int layer = 0; layer < value.layers.Count; layer++)
|
||||
{
|
||||
result.Add(value.layers[layer].layerRefName);
|
||||
}
|
||||
}
|
||||
|
||||
internal override void GetPropertyDisplayNames(List<string> result)
|
||||
{
|
||||
result.Add(displayName);
|
||||
for (int layer = 0; layer < value.layers.Count; layer++)
|
||||
{
|
||||
result.Add(value.layers[layer].layerName);
|
||||
}
|
||||
}
|
||||
|
||||
// this is used for properties exposed to the Material in the shaderlab Properties{} block
|
||||
internal override void AppendPropertyBlockStrings(ShaderStringBuilder builder)
|
||||
{
|
||||
if (!value.procedural)
|
||||
{
|
||||
// adds properties in this format so: [TextureStack.MyStack(0)] [NoScaleOffset] Layer0("Layer0", 2D) = "white" {}
|
||||
for (int layer = 0; layer < value.layers.Count; layer++)
|
||||
{
|
||||
string layerName = value.layers[layer].layerName;
|
||||
string layerRefName = value.layers[layer].layerRefName;
|
||||
builder.AppendLine($"{hideTagString}[TextureStack.{referenceName}({layer})][NoScaleOffset]{layerRefName}(\"{layerName}\", 2D) = \"white\" {{}}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal override string GetPropertyBlockString()
|
||||
{
|
||||
// this should not be called, as it is replaced by the Append*PropertyBlockStrings function above
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
internal override bool AllowHLSLDeclaration(HLSLDeclaration decl) => false; // disable UI, nothing to choose
|
||||
|
||||
internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
|
||||
{
|
||||
int numLayers = value.layers.Count;
|
||||
if (numLayers > 0)
|
||||
{
|
||||
action(new HLSLProperty(HLSLType._CUSTOM, referenceName, HLSLDeclaration.UnityPerMaterial, concretePrecision)
|
||||
{
|
||||
customDeclaration = (ssb) =>
|
||||
{
|
||||
ssb.AppendIndentation();
|
||||
ssb.Append("DECLARE_STACK_CB(");
|
||||
ssb.Append(referenceName);
|
||||
ssb.Append(");");
|
||||
ssb.AppendNewLine();
|
||||
}
|
||||
});
|
||||
|
||||
if (!value.procedural)
|
||||
{
|
||||
// declare regular texture properties (for fallback case)
|
||||
for (int i = 0; i < numLayers; i++)
|
||||
{
|
||||
string layerRefName = value.layers[i].layerRefName;
|
||||
action(new HLSLProperty(HLSLType._Texture2D, layerRefName, HLSLDeclaration.Global));
|
||||
action(new HLSLProperty(HLSLType._SamplerState, "sampler" + layerRefName, HLSLDeclaration.Global));
|
||||
}
|
||||
}
|
||||
|
||||
Action<ShaderStringBuilder> customDecl = (builder) =>
|
||||
{
|
||||
// declare texture stack
|
||||
builder.AppendIndentation();
|
||||
builder.Append("DECLARE_STACK");
|
||||
builder.Append((numLayers <= 1) ? "" : numLayers.ToString());
|
||||
builder.Append("(");
|
||||
builder.Append(referenceName);
|
||||
builder.Append(",");
|
||||
for (int i = 0; i < value.layers.Count; i++)
|
||||
{
|
||||
if (i != 0) builder.Append(",");
|
||||
builder.Append(value.layers[i].layerRefName);
|
||||
}
|
||||
builder.Append(");");
|
||||
builder.AppendNewLine();
|
||||
|
||||
// declare the actual virtual texture property "variable" as a macro define to the BuildVTProperties function
|
||||
builder.AppendIndentation();
|
||||
builder.Append("#define ");
|
||||
builder.Append(referenceName);
|
||||
builder.Append(" AddTextureType(BuildVTProperties_");
|
||||
builder.Append(referenceName);
|
||||
builder.Append("()");
|
||||
for (int i = 0; i < value.layers.Count; i++)
|
||||
{
|
||||
builder.Append(",");
|
||||
builder.Append("TEXTURETYPE_");
|
||||
builder.Append(value.layers[i].layerTextureType.ToString().ToUpper());
|
||||
}
|
||||
builder.Append(")");
|
||||
builder.AppendNewLine();
|
||||
};
|
||||
|
||||
action(new HLSLProperty(HLSLType._CUSTOM, referenceName, HLSLDeclaration.Global, concretePrecision)
|
||||
{
|
||||
customDeclaration = customDecl
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// argument string used to pass this property to a subgraph
|
||||
internal override string GetPropertyAsArgumentString()
|
||||
{
|
||||
return "VTPropertyWithTextureType " + referenceName;
|
||||
}
|
||||
|
||||
// if a blackboard property is deleted, or copy/pasted, all node instances of it are replaced with this:
|
||||
internal override AbstractMaterialNode ToConcreteNode()
|
||||
{
|
||||
return null; // return null to indicate there is NO concrete form of a VT property
|
||||
}
|
||||
|
||||
internal override PreviewProperty GetPreviewMaterialProperty()
|
||||
{
|
||||
return new PreviewProperty(propertyType)
|
||||
{
|
||||
name = referenceName,
|
||||
vtProperty = this
|
||||
};
|
||||
}
|
||||
|
||||
internal override ShaderInput Copy()
|
||||
{
|
||||
var vt = new VirtualTextureShaderProperty
|
||||
{
|
||||
displayName = displayName,
|
||||
value = new SerializableVirtualTexture(),
|
||||
};
|
||||
|
||||
// duplicate layer data, but reset reference names (they should be unique)
|
||||
for (int layer = 0; layer < value.layers.Count; layer++)
|
||||
{
|
||||
var guid = Guid.NewGuid();
|
||||
vt.value.layers.Add(new SerializableVirtualTextureLayer(value.layers[layer]));
|
||||
}
|
||||
|
||||
return vt;
|
||||
}
|
||||
|
||||
internal void AddTextureInfo(List<PropertyCollector.TextureInfo> infos)
|
||||
{
|
||||
for (int layer = 0; layer < value.layers.Count; layer++)
|
||||
{
|
||||
string layerRefName = value.layers[layer].layerRefName;
|
||||
var layerTexture = value.layers[layer].layerTexture;
|
||||
var texture = layerTexture != null ? layerTexture.texture : null;
|
||||
|
||||
var textureInfo = new PropertyCollector.TextureInfo
|
||||
{
|
||||
name = layerRefName,
|
||||
textureId = texture != null ? texture.GetInstanceID() : 0,
|
||||
dimension = texture != null ? texture.dimension : UnityEngine.Rendering.TextureDimension.Any,
|
||||
modifiable = true
|
||||
};
|
||||
infos.Add(textureInfo);
|
||||
}
|
||||
}
|
||||
|
||||
internal override bool isAlwaysExposed => true;
|
||||
|
||||
public override void OnAfterDeserialize(string json)
|
||||
{
|
||||
// VT shader properties must always be exposed
|
||||
generatePropertyBlock = true;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.Graphing
|
||||
{
|
||||
[Serializable]
|
||||
class Edge : IEdge, IComparable<Edge>
|
||||
{
|
||||
[SerializeField]
|
||||
private SlotReference m_OutputSlot;
|
||||
[SerializeField]
|
||||
private SlotReference m_InputSlot;
|
||||
|
||||
public Edge()
|
||||
{}
|
||||
|
||||
public Edge(SlotReference outputSlot, SlotReference inputSlot)
|
||||
{
|
||||
m_OutputSlot = outputSlot;
|
||||
m_InputSlot = inputSlot;
|
||||
}
|
||||
|
||||
public SlotReference outputSlot
|
||||
{
|
||||
get { return m_OutputSlot; }
|
||||
}
|
||||
|
||||
public SlotReference inputSlot
|
||||
{
|
||||
get { return m_InputSlot; }
|
||||
}
|
||||
|
||||
protected bool Equals(Edge other)
|
||||
{
|
||||
return Equals(m_OutputSlot, other.m_OutputSlot) && Equals(m_InputSlot, other.m_InputSlot);
|
||||
}
|
||||
|
||||
public bool Equals(IEdge other)
|
||||
{
|
||||
return Equals(other as object);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != this.GetType()) return false;
|
||||
return Equals((Edge)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
// Can't make fields readonly due to Unity serialization
|
||||
return (m_OutputSlot.GetHashCode() * 397) ^ m_InputSlot.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
public int CompareTo(Edge other)
|
||||
{
|
||||
if (ReferenceEquals(this, other)) return 0;
|
||||
if (ReferenceEquals(null, other)) return 1;
|
||||
var outputSlotComparison = m_OutputSlot.CompareTo(other.m_OutputSlot);
|
||||
if (outputSlotComparison != 0) return outputSlotComparison;
|
||||
return m_InputSlot.CompareTo(other.m_InputSlot);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using UnityEditor.ShaderGraph;
|
||||
using UnityEditor.ShaderGraph.Serialization;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.Graphing
|
||||
{
|
||||
class GraphObject : ScriptableObject, ISerializationCallbackReceiver
|
||||
{
|
||||
[SerializeField]
|
||||
SerializationHelper.JSONSerializedElement m_SerializedGraph;
|
||||
|
||||
[SerializeField]
|
||||
int m_SerializedVersion;
|
||||
|
||||
[SerializeField]
|
||||
bool m_IsDirty;
|
||||
|
||||
[SerializeField]
|
||||
bool m_IsSubGraph;
|
||||
|
||||
[SerializeField]
|
||||
string m_AssetGuid;
|
||||
|
||||
[NonSerialized]
|
||||
GraphData m_Graph;
|
||||
|
||||
[NonSerialized]
|
||||
int m_DeserializedVersion;
|
||||
|
||||
public GraphData graph
|
||||
{
|
||||
get { return m_Graph; }
|
||||
set
|
||||
{
|
||||
if (m_Graph != null)
|
||||
m_Graph.owner = null;
|
||||
m_Graph = value;
|
||||
if (m_Graph != null)
|
||||
m_Graph.owner = this;
|
||||
}
|
||||
}
|
||||
|
||||
// this value stores whether an undo operation has been registered (which indicates a change has been made to the graph)
|
||||
// and is used to trigger the MaterialGraphEditWindow to update it's title
|
||||
public bool isDirty
|
||||
{
|
||||
get { return m_IsDirty; }
|
||||
set { m_IsDirty = value; }
|
||||
}
|
||||
|
||||
public virtual void RegisterCompleteObjectUndo(string actionName)
|
||||
{
|
||||
Undo.RegisterCompleteObjectUndo(this, actionName);
|
||||
m_SerializedVersion++;
|
||||
m_DeserializedVersion++;
|
||||
m_IsDirty = true;
|
||||
}
|
||||
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
if (graph != null)
|
||||
{
|
||||
var json = MultiJson.Serialize(graph);
|
||||
m_SerializedGraph = new SerializationHelper.JSONSerializedElement { JSONnodeData = json };
|
||||
m_IsSubGraph = graph.isSubGraph;
|
||||
m_AssetGuid = graph.assetGuid;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
}
|
||||
|
||||
public bool wasUndoRedoPerformed => m_DeserializedVersion != m_SerializedVersion;
|
||||
|
||||
public void HandleUndoRedo()
|
||||
{
|
||||
Debug.Assert(wasUndoRedoPerformed);
|
||||
var deserializedGraph = DeserializeGraph();
|
||||
m_Graph.ReplaceWith(deserializedGraph);
|
||||
}
|
||||
|
||||
GraphData DeserializeGraph()
|
||||
{
|
||||
var json = m_SerializedGraph.JSONnodeData;
|
||||
var deserializedGraph = new GraphData {isSubGraph = m_IsSubGraph, assetGuid = m_AssetGuid};
|
||||
MultiJson.Deserialize(deserializedGraph, json);
|
||||
m_DeserializedVersion = m_SerializedVersion;
|
||||
m_SerializedGraph = default;
|
||||
return deserializedGraph;
|
||||
}
|
||||
|
||||
public void Validate()
|
||||
{
|
||||
if (graph != null)
|
||||
{
|
||||
graph.OnEnable();
|
||||
graph.ValidateGraph();
|
||||
}
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
if (graph == null && m_SerializedGraph.JSONnodeData != null)
|
||||
{
|
||||
graph = DeserializeGraph();
|
||||
}
|
||||
Validate();
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
graph?.OnDisable();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
class HasDependenciesAttribute : Attribute
|
||||
{
|
||||
public HasDependenciesAttribute(Type minimalType)
|
||||
{
|
||||
this.minimalType = minimalType;
|
||||
}
|
||||
|
||||
public Type minimalType { get; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
interface IHasDependencies
|
||||
{
|
||||
void GetSourceAssetDependencies(AssetCollection assetCollection);
|
||||
}
|
||||
}
|
@@ -0,0 +1,998 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEditor.ShaderGraph;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Pool;
|
||||
using UnityEngine.Rendering.ShaderGraph;
|
||||
|
||||
namespace UnityEditor.Graphing
|
||||
{
|
||||
class SlotConfigurationException : Exception
|
||||
{
|
||||
public SlotConfigurationException(string message)
|
||||
: base(message)
|
||||
{}
|
||||
}
|
||||
|
||||
static class NodeUtils
|
||||
{
|
||||
static string NodeDocSuffix = "-Node";
|
||||
|
||||
public static void SlotConfigurationExceptionIfBadConfiguration(AbstractMaterialNode node, IEnumerable<int> expectedInputSlots, IEnumerable<int> expectedOutputSlots)
|
||||
{
|
||||
var missingSlots = new List<int>();
|
||||
|
||||
var inputSlots = expectedInputSlots as IList<int> ?? expectedInputSlots.ToList();
|
||||
missingSlots.AddRange(inputSlots.Except(node.GetInputSlots<MaterialSlot>().Select(x => x.id)));
|
||||
|
||||
var outputSlots = expectedOutputSlots as IList<int> ?? expectedOutputSlots.ToList();
|
||||
missingSlots.AddRange(outputSlots.Except(node.GetOutputSlots<MaterialSlot>().Select(x => x.id)));
|
||||
|
||||
if (missingSlots.Count == 0)
|
||||
return;
|
||||
|
||||
var toPrint = missingSlots.Select(x => x.ToString());
|
||||
|
||||
throw new SlotConfigurationException(string.Format("Missing slots {0} on node {1}", string.Join(", ", toPrint.ToArray()), node));
|
||||
}
|
||||
|
||||
public static IEnumerable<IEdge> GetAllEdges(AbstractMaterialNode node)
|
||||
{
|
||||
var result = new List<IEdge>();
|
||||
var validSlots = ListPool<MaterialSlot>.Get();
|
||||
|
||||
validSlots.AddRange(node.GetInputSlots<MaterialSlot>());
|
||||
for (int index = 0; index < validSlots.Count; index++)
|
||||
{
|
||||
var inputSlot = validSlots[index];
|
||||
result.AddRange(node.owner.GetEdges(inputSlot.slotReference));
|
||||
}
|
||||
|
||||
validSlots.Clear();
|
||||
validSlots.AddRange(node.GetOutputSlots<MaterialSlot>());
|
||||
for (int index = 0; index < validSlots.Count; index++)
|
||||
{
|
||||
var outputSlot = validSlots[index];
|
||||
result.AddRange(node.owner.GetEdges(outputSlot.slotReference));
|
||||
}
|
||||
|
||||
ListPool<MaterialSlot>.Release(validSlots);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static string GetDuplicateSafeNameForSlot(AbstractMaterialNode node, int slotId, string name)
|
||||
{
|
||||
List<MaterialSlot> slots = new List<MaterialSlot>();
|
||||
node.GetSlots(slots);
|
||||
|
||||
name = name.Trim();
|
||||
return GraphUtil.SanitizeName(slots.Where(p => p.id != slotId).Select(p => p.RawDisplayName()), "{0} ({1})", name);
|
||||
}
|
||||
|
||||
// CollectNodesNodeFeedsInto looks at the current node and calculates
|
||||
// which child nodes it depends on for it's calculation.
|
||||
// Results are returned depth first so by processing each node in
|
||||
// order you can generate a valid code block.
|
||||
public enum IncludeSelf
|
||||
{
|
||||
Include,
|
||||
Exclude
|
||||
}
|
||||
|
||||
public static SlotReference DepthFirstCollectRedirectNodeFromNode(RedirectNodeData node)
|
||||
{
|
||||
var inputSlot = node.FindSlot<MaterialSlot>(RedirectNodeData.kInputSlotID);
|
||||
foreach (var edge in node.owner.GetEdges(inputSlot.slotReference))
|
||||
{
|
||||
// get the input details
|
||||
var outputSlotRef = edge.outputSlot;
|
||||
var inputNode = outputSlotRef.node;
|
||||
// If this is a redirect node we continue to look for the top one
|
||||
if (inputNode is RedirectNodeData redirectNode)
|
||||
{
|
||||
return DepthFirstCollectRedirectNodeFromNode(redirectNode);
|
||||
}
|
||||
return outputSlotRef;
|
||||
}
|
||||
// If no edges it is the first redirect node without an edge going into it and we should return the slot ref
|
||||
return node.GetSlotReference(RedirectNodeData.kInputSlotID);
|
||||
}
|
||||
|
||||
public static void DepthFirstCollectNodesFromNode(List<AbstractMaterialNode> nodeList, AbstractMaterialNode node,
|
||||
IncludeSelf includeSelf = IncludeSelf.Include, List<KeyValuePair<ShaderKeyword, int>> keywordPermutation = null, bool ignoreActiveState = false)
|
||||
{
|
||||
// no where to start
|
||||
if (node == null)
|
||||
return;
|
||||
|
||||
// already added this node
|
||||
if (nodeList.Contains(node))
|
||||
return;
|
||||
|
||||
IEnumerable<int> ids;
|
||||
|
||||
// If this node is a keyword node and we have an active keyword permutation
|
||||
// The only valid port id is the port that corresponds to that keywords value in the active permutation
|
||||
if (node is KeywordNode keywordNode && keywordPermutation != null)
|
||||
{
|
||||
var valueInPermutation = keywordPermutation.Where(x => x.Key == keywordNode.keyword).FirstOrDefault();
|
||||
ids = new int[] { keywordNode.GetSlotIdForPermutation(valueInPermutation) };
|
||||
}
|
||||
else
|
||||
{
|
||||
ids = node.GetInputSlots<MaterialSlot>().Select(x => x.id);
|
||||
}
|
||||
|
||||
foreach (var slot in ids)
|
||||
{
|
||||
foreach (var edge in node.owner.GetEdges(node.GetSlotReference(slot)))
|
||||
{
|
||||
var outputNode = edge.outputSlot.node;
|
||||
if (outputNode != null)
|
||||
DepthFirstCollectNodesFromNode(nodeList, outputNode, keywordPermutation: keywordPermutation, ignoreActiveState: ignoreActiveState);
|
||||
}
|
||||
}
|
||||
|
||||
if (includeSelf == IncludeSelf.Include && (node.isActive || ignoreActiveState))
|
||||
nodeList.Add(node);
|
||||
}
|
||||
|
||||
private static List<AbstractMaterialNode> GetParentNodes(AbstractMaterialNode node)
|
||||
{
|
||||
List<AbstractMaterialNode> nodeList = new List<AbstractMaterialNode>();
|
||||
var ids = node.GetInputSlots<MaterialSlot>().Select(x => x.id);
|
||||
foreach (var slot in ids)
|
||||
{
|
||||
if (node.owner == null)
|
||||
break;
|
||||
foreach (var edge in node.owner.GetEdges(node.FindSlot<MaterialSlot>(slot).slotReference))
|
||||
{
|
||||
var outputNode = ((Edge)edge).outputSlot.node;
|
||||
if (outputNode != null)
|
||||
{
|
||||
nodeList.Add(outputNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
return nodeList;
|
||||
}
|
||||
|
||||
private static bool ActiveLeafExists(AbstractMaterialNode node)
|
||||
{
|
||||
//if our active state has been explicitly set to a value use it
|
||||
switch (node.activeState)
|
||||
{
|
||||
case AbstractMaterialNode.ActiveState.Implicit:
|
||||
break;
|
||||
case AbstractMaterialNode.ActiveState.ExplicitInactive:
|
||||
return false;
|
||||
case AbstractMaterialNode.ActiveState.ExplicitActive:
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
List<AbstractMaterialNode> parentNodes = GetParentNodes(node);
|
||||
//at this point we know we are not explicitly set to a state,
|
||||
//so there is no reason to be inactive
|
||||
if (parentNodes.Count == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool output = false;
|
||||
foreach (var parent in parentNodes)
|
||||
{
|
||||
output |= ActiveLeafExists(parent);
|
||||
if (output)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
private static List<AbstractMaterialNode> GetChildNodes(AbstractMaterialNode node)
|
||||
{
|
||||
List<AbstractMaterialNode> nodeList = new List<AbstractMaterialNode>();
|
||||
var ids = node.GetOutputSlots<MaterialSlot>().Select(x => x.id);
|
||||
foreach (var slot in ids)
|
||||
{
|
||||
foreach (var edge in node.owner.GetEdges(node.FindSlot<MaterialSlot>(slot).slotReference))
|
||||
{
|
||||
var inputNode = ((Edge)edge).inputSlot.node;
|
||||
if (inputNode != null)
|
||||
{
|
||||
nodeList.Add(inputNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
return nodeList;
|
||||
}
|
||||
|
||||
private static bool ActiveRootExists(AbstractMaterialNode node)
|
||||
{
|
||||
//if our active state has been explicitly set to a value use it
|
||||
switch (node.activeState)
|
||||
{
|
||||
case AbstractMaterialNode.ActiveState.Implicit:
|
||||
break;
|
||||
case AbstractMaterialNode.ActiveState.ExplicitInactive:
|
||||
return false;
|
||||
case AbstractMaterialNode.ActiveState.ExplicitActive:
|
||||
return true;
|
||||
}
|
||||
|
||||
List<AbstractMaterialNode> childNodes = GetChildNodes(node);
|
||||
//at this point we know we are not explicitly set to a state,
|
||||
//so there is no reason to be inactive
|
||||
if (childNodes.Count == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool output = false;
|
||||
foreach (var child in childNodes)
|
||||
{
|
||||
output |= ActiveRootExists(child);
|
||||
if (output)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
private static void ActiveTreeExists(AbstractMaterialNode node, out bool activeLeaf, out bool activeRoot, out bool activeTree)
|
||||
{
|
||||
activeLeaf = ActiveLeafExists(node);
|
||||
activeRoot = ActiveRootExists(node);
|
||||
activeTree = activeRoot && activeLeaf;
|
||||
}
|
||||
|
||||
//First pass check if node is now active after a change, so just check if there is a valid "tree" : a valid upstream input path,
|
||||
// and a valid downstream output path, or "leaf" and "root". If this changes the node's active state, then anything connected may
|
||||
// change as well, so update the "forrest" or all connectected trees of this nodes leaves.
|
||||
// NOTE: I cannot think if there is any case where the entirety of the connected graph would need to change, but if there are bugs
|
||||
// on certain nodes farther away from the node not updating correctly, a possible solution may be to get the entirety of the connected
|
||||
// graph instead of just what I have declared as the "local" connected graph
|
||||
public static void ReevaluateActivityOfConnectedNodes(AbstractMaterialNode node, PooledHashSet<AbstractMaterialNode> changedNodes = null)
|
||||
{
|
||||
List<AbstractMaterialNode> forest = GetForest(node);
|
||||
ReevaluateActivityOfNodeList(forest, changedNodes);
|
||||
}
|
||||
|
||||
public static void ReevaluateActivityOfNodeList(IEnumerable<AbstractMaterialNode> nodes, PooledHashSet<AbstractMaterialNode> changedNodes = null)
|
||||
{
|
||||
bool getChangedNodes = changedNodes != null;
|
||||
foreach (AbstractMaterialNode n in nodes)
|
||||
{
|
||||
if (n.activeState != AbstractMaterialNode.ActiveState.Implicit)
|
||||
continue;
|
||||
ActiveTreeExists(n, out _, out _, out bool at);
|
||||
if (n.isActive != at && getChangedNodes)
|
||||
{
|
||||
changedNodes.Add(n);
|
||||
}
|
||||
n.SetActive(at, false);
|
||||
}
|
||||
}
|
||||
|
||||
//Go to the leaves of the node, then get all trees with those leaves
|
||||
private static List<AbstractMaterialNode> GetForest(AbstractMaterialNode node)
|
||||
{
|
||||
List<AbstractMaterialNode> leaves = GetLeaves(node);
|
||||
List<AbstractMaterialNode> forrest = new List<AbstractMaterialNode>();
|
||||
foreach (var leaf in leaves)
|
||||
{
|
||||
if (!forrest.Contains(leaf))
|
||||
{
|
||||
forrest.Add(leaf);
|
||||
}
|
||||
foreach (var child in GetChildNodesRecursive(leaf))
|
||||
{
|
||||
if (!forrest.Contains(child))
|
||||
{
|
||||
forrest.Add(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
return forrest;
|
||||
}
|
||||
|
||||
private static List<AbstractMaterialNode> GetChildNodesRecursive(AbstractMaterialNode node)
|
||||
{
|
||||
List<AbstractMaterialNode> output = new List<AbstractMaterialNode>() { node };
|
||||
List<AbstractMaterialNode> children = GetChildNodes(node);
|
||||
foreach (var child in children)
|
||||
{
|
||||
if (!output.Contains(child))
|
||||
{
|
||||
output.Add(child);
|
||||
}
|
||||
foreach (var descendent in GetChildNodesRecursive(child))
|
||||
{
|
||||
if (!output.Contains(descendent))
|
||||
{
|
||||
output.Add(descendent);
|
||||
}
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
private static List<AbstractMaterialNode> GetLeaves(AbstractMaterialNode node)
|
||||
{
|
||||
List<AbstractMaterialNode> parents = GetParentNodes(node);
|
||||
List<AbstractMaterialNode> output = new List<AbstractMaterialNode>();
|
||||
if (parents.Count == 0)
|
||||
{
|
||||
output.Add(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var parent in parents)
|
||||
{
|
||||
foreach (var leaf in GetLeaves(parent))
|
||||
{
|
||||
if (!output.Contains(leaf))
|
||||
{
|
||||
output.Add(leaf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
public static void GetDownsteamNodesForNode(List<AbstractMaterialNode> nodeList, AbstractMaterialNode node)
|
||||
{
|
||||
// no where to start
|
||||
if (node == null)
|
||||
return;
|
||||
|
||||
// Recursively traverse downstream from the original node
|
||||
// Traverse down each edge and continue on any connected downstream nodes
|
||||
// Only nodes with no nodes further downstream are added to node list
|
||||
bool hasDownstream = false;
|
||||
var ids = node.GetOutputSlots<MaterialSlot>().Select(x => x.id);
|
||||
foreach (var slot in ids)
|
||||
{
|
||||
foreach (var edge in node.owner.GetEdges(node.FindSlot<MaterialSlot>(slot).slotReference))
|
||||
{
|
||||
var inputNode = ((Edge)edge).inputSlot.node;
|
||||
if (inputNode != null)
|
||||
{
|
||||
hasDownstream = true;
|
||||
GetDownsteamNodesForNode(nodeList, inputNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No more nodes downstream from here
|
||||
if (!hasDownstream)
|
||||
nodeList.Add(node);
|
||||
}
|
||||
|
||||
public static void CollectNodeSet(HashSet<AbstractMaterialNode> nodeSet, MaterialSlot slot)
|
||||
{
|
||||
var node = slot.owner;
|
||||
var graph = node.owner;
|
||||
foreach (var edge in graph.GetEdges(node.GetSlotReference(slot.id)))
|
||||
{
|
||||
var outputNode = edge.outputSlot.node;
|
||||
if (outputNode != null)
|
||||
{
|
||||
CollectNodeSet(nodeSet, outputNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void CollectNodeSet(HashSet<AbstractMaterialNode> nodeSet, AbstractMaterialNode node)
|
||||
{
|
||||
if (!nodeSet.Add(node))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using (ListPool<MaterialSlot>.Get(out var slots))
|
||||
{
|
||||
node.GetInputSlots(slots);
|
||||
foreach (var slot in slots)
|
||||
{
|
||||
CollectNodeSet(nodeSet, slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void CollectNodesNodeFeedsInto(List<AbstractMaterialNode> nodeList, AbstractMaterialNode node, IncludeSelf includeSelf = IncludeSelf.Include)
|
||||
{
|
||||
if (node == null)
|
||||
return;
|
||||
|
||||
if (nodeList.Contains(node))
|
||||
return;
|
||||
|
||||
foreach (var slot in node.GetOutputSlots<MaterialSlot>())
|
||||
{
|
||||
foreach (var edge in node.owner.GetEdges(slot.slotReference))
|
||||
{
|
||||
var inputNode = edge.inputSlot.node;
|
||||
CollectNodesNodeFeedsInto(nodeList, inputNode);
|
||||
}
|
||||
}
|
||||
if (includeSelf == IncludeSelf.Include)
|
||||
nodeList.Add(node);
|
||||
}
|
||||
|
||||
public static string GetDocumentationString(string pageName)
|
||||
{
|
||||
return Documentation.GetPageLink(pageName.Replace(" ", "-") + NodeDocSuffix);
|
||||
}
|
||||
|
||||
static Stack<MaterialSlot> s_SlotStack = new Stack<MaterialSlot>();
|
||||
|
||||
public static ShaderStage GetEffectiveShaderStage(MaterialSlot initialSlot, bool goingBackwards)
|
||||
{
|
||||
var graph = initialSlot.owner.owner;
|
||||
s_SlotStack.Clear();
|
||||
s_SlotStack.Push(initialSlot);
|
||||
while (s_SlotStack.Any())
|
||||
{
|
||||
var slot = s_SlotStack.Pop();
|
||||
ShaderStage stage;
|
||||
if (slot.stageCapability.TryGetShaderStage(out stage))
|
||||
return stage;
|
||||
|
||||
if (goingBackwards && slot.isInputSlot)
|
||||
{
|
||||
foreach (var edge in graph.GetEdges(slot.slotReference))
|
||||
{
|
||||
var node = edge.outputSlot.node;
|
||||
s_SlotStack.Push(node.FindOutputSlot<MaterialSlot>(edge.outputSlot.slotId));
|
||||
}
|
||||
}
|
||||
else if (!goingBackwards && slot.isOutputSlot)
|
||||
{
|
||||
foreach (var edge in graph.GetEdges(slot.slotReference))
|
||||
{
|
||||
var node = edge.inputSlot.node;
|
||||
s_SlotStack.Push(node.FindInputSlot<MaterialSlot>(edge.inputSlot.slotId));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var ownerSlots = Enumerable.Empty<MaterialSlot>();
|
||||
if (goingBackwards && slot.isOutputSlot)
|
||||
ownerSlots = slot.owner.GetInputSlots<MaterialSlot>();
|
||||
else if (!goingBackwards && slot.isInputSlot)
|
||||
ownerSlots = slot.owner.GetOutputSlots<MaterialSlot>();
|
||||
foreach (var ownerSlot in ownerSlots)
|
||||
s_SlotStack.Push(ownerSlot);
|
||||
}
|
||||
}
|
||||
// We default to fragment shader stage if all connected nodes were compatible with both.
|
||||
return ShaderStage.Fragment;
|
||||
}
|
||||
|
||||
public static ShaderStageCapability GetEffectiveShaderStageCapability(MaterialSlot initialSlot, bool goingBackwards)
|
||||
{
|
||||
var graph = initialSlot.owner.owner;
|
||||
s_SlotStack.Clear();
|
||||
s_SlotStack.Push(initialSlot);
|
||||
while (s_SlotStack.Any())
|
||||
{
|
||||
var slot = s_SlotStack.Pop();
|
||||
ShaderStage stage;
|
||||
if (slot.stageCapability.TryGetShaderStage(out stage))
|
||||
return slot.stageCapability;
|
||||
|
||||
if (goingBackwards && slot.isInputSlot)
|
||||
{
|
||||
foreach (var edge in graph.GetEdges(slot.slotReference))
|
||||
{
|
||||
var node = edge.outputSlot.node;
|
||||
s_SlotStack.Push(node.FindOutputSlot<MaterialSlot>(edge.outputSlot.slotId));
|
||||
}
|
||||
}
|
||||
else if (!goingBackwards && slot.isOutputSlot)
|
||||
{
|
||||
foreach (var edge in graph.GetEdges(slot.slotReference))
|
||||
{
|
||||
var node = edge.inputSlot.node;
|
||||
s_SlotStack.Push(node.FindInputSlot<MaterialSlot>(edge.inputSlot.slotId));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var ownerSlots = Enumerable.Empty<MaterialSlot>();
|
||||
if (goingBackwards && slot.isOutputSlot)
|
||||
ownerSlots = slot.owner.GetInputSlots<MaterialSlot>();
|
||||
else if (!goingBackwards && slot.isInputSlot)
|
||||
ownerSlots = slot.owner.GetOutputSlots<MaterialSlot>();
|
||||
foreach (var ownerSlot in ownerSlots)
|
||||
s_SlotStack.Push(ownerSlot);
|
||||
}
|
||||
}
|
||||
|
||||
return ShaderStageCapability.All;
|
||||
}
|
||||
|
||||
public static string GetSlotDimension(ConcreteSlotValueType slotValue)
|
||||
{
|
||||
switch (slotValue)
|
||||
{
|
||||
case ConcreteSlotValueType.Vector1:
|
||||
return String.Empty;
|
||||
case ConcreteSlotValueType.Vector2:
|
||||
return "2";
|
||||
case ConcreteSlotValueType.Vector3:
|
||||
return "3";
|
||||
case ConcreteSlotValueType.Vector4:
|
||||
return "4";
|
||||
case ConcreteSlotValueType.Matrix2:
|
||||
return "2x2";
|
||||
case ConcreteSlotValueType.Matrix3:
|
||||
return "3x3";
|
||||
case ConcreteSlotValueType.Matrix4:
|
||||
return "4x4";
|
||||
default:
|
||||
return "Error";
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: there are several bugs here.. we should use ConvertToValidHLSLIdentifier() instead
|
||||
public static string GetHLSLSafeName(string input)
|
||||
{
|
||||
char[] arr = input.ToCharArray();
|
||||
arr = Array.FindAll<char>(arr, (c => (Char.IsLetterOrDigit(c))));
|
||||
var safeName = new string(arr);
|
||||
if (safeName.Length > 1 && char.IsDigit(safeName[0]))
|
||||
{
|
||||
safeName = $"var{safeName}";
|
||||
}
|
||||
return safeName;
|
||||
}
|
||||
|
||||
static readonly string[] k_HLSLNumericKeywords =
|
||||
{
|
||||
"float",
|
||||
"half", // not technically in HLSL spec, but prob should be
|
||||
"real", // Unity thing, but included here
|
||||
"int",
|
||||
"uint",
|
||||
"bool",
|
||||
"min10float",
|
||||
"min16float",
|
||||
"min12int",
|
||||
"min16int",
|
||||
"min16uint"
|
||||
};
|
||||
|
||||
static readonly string[] k_HLSLNumericKeywordSuffixes =
|
||||
{
|
||||
"",
|
||||
"1", "2", "3", "4",
|
||||
"1x1", "1x2", "1x3", "1x4",
|
||||
"2x1", "2x2", "2x3", "2x4",
|
||||
"3x1", "3x2", "3x3", "3x4",
|
||||
"4x1", "4x2", "4x3", "4x4"
|
||||
};
|
||||
|
||||
static HashSet<string> m_ShaderLabKeywords = new HashSet<string>()
|
||||
{
|
||||
// these should all be lowercase, as shaderlab keywords are case insensitive
|
||||
"properties",
|
||||
"range",
|
||||
"bind",
|
||||
"bindchannels",
|
||||
"tags",
|
||||
"lod",
|
||||
"shader",
|
||||
"subshader",
|
||||
"category",
|
||||
"fallback",
|
||||
"dependency",
|
||||
"customeditor",
|
||||
"rect",
|
||||
"any",
|
||||
"float",
|
||||
"color",
|
||||
"int",
|
||||
"integer",
|
||||
"vector",
|
||||
"matrix",
|
||||
"2d",
|
||||
"cube",
|
||||
"3d",
|
||||
"2darray",
|
||||
"cubearray",
|
||||
"name",
|
||||
"settexture",
|
||||
"true",
|
||||
"false",
|
||||
"on",
|
||||
"off",
|
||||
"separatespecular",
|
||||
"offset",
|
||||
"zwrite",
|
||||
"zclip",
|
||||
"conservative",
|
||||
"ztest",
|
||||
"alphatest",
|
||||
"fog",
|
||||
"stencil",
|
||||
"colormask",
|
||||
"alphatomask",
|
||||
"cull",
|
||||
"front",
|
||||
"material",
|
||||
"ambient",
|
||||
"diffuse",
|
||||
"specular",
|
||||
"emission",
|
||||
"shininess",
|
||||
"blend",
|
||||
"blendop",
|
||||
"colormaterial",
|
||||
"lighting",
|
||||
"pass",
|
||||
"grabpass",
|
||||
"usepass",
|
||||
"gpuprogramid",
|
||||
"add",
|
||||
"sub",
|
||||
"revsub",
|
||||
"min",
|
||||
"max",
|
||||
"logicalclear",
|
||||
"logicalset",
|
||||
"logicalcopy",
|
||||
"logicalcopyinverted",
|
||||
"logicalnoop",
|
||||
"logicalinvert",
|
||||
"logicaland",
|
||||
"logicalnand",
|
||||
"logicalor",
|
||||
"logicalnor",
|
||||
"logicalxor",
|
||||
"logicalequiv",
|
||||
"logicalandreverse",
|
||||
"logicalandinverted",
|
||||
"logicalorreverse",
|
||||
"logicalorinverted",
|
||||
"multiply",
|
||||
"screen",
|
||||
"overlay",
|
||||
"darken",
|
||||
"lighten",
|
||||
"colordodge",
|
||||
"colorburn",
|
||||
"hardlight",
|
||||
"softlight",
|
||||
"difference",
|
||||
"exclusion",
|
||||
"hslhue",
|
||||
"hslsaturation",
|
||||
"hslcolor",
|
||||
"hslluminosity",
|
||||
"zero",
|
||||
"one",
|
||||
"dstcolor",
|
||||
"srccolor",
|
||||
"oneminusdstcolor",
|
||||
"srcalpha",
|
||||
"oneminussrccolor",
|
||||
"dstalpha",
|
||||
"oneminusdstalpha",
|
||||
"srcalphasaturate",
|
||||
"oneminussrcalpha",
|
||||
"constantcolor",
|
||||
"oneminusconstantcolor",
|
||||
"constantalpha",
|
||||
"oneminusconstantalpha",
|
||||
};
|
||||
|
||||
static HashSet<string> m_HLSLKeywords = new HashSet<string>()
|
||||
{
|
||||
"AppendStructuredBuffer",
|
||||
"asm",
|
||||
"asm_fragment",
|
||||
"auto",
|
||||
"BlendState",
|
||||
"break",
|
||||
"Buffer",
|
||||
"ByteAddressBuffer",
|
||||
"case",
|
||||
"catch",
|
||||
"cbuffer",
|
||||
"centroid",
|
||||
"char",
|
||||
"class",
|
||||
"column_major",
|
||||
"compile",
|
||||
"compile_fragment",
|
||||
"CompileShader",
|
||||
"const",
|
||||
"const_cast",
|
||||
"continue",
|
||||
"ComputeShader",
|
||||
"ConsumeStructuredBuffer",
|
||||
"default",
|
||||
"delete",
|
||||
"DepthStencilState",
|
||||
"DepthStencilView",
|
||||
"discard",
|
||||
"do",
|
||||
"double",
|
||||
"DomainShader",
|
||||
"dynamic_cast",
|
||||
"dword",
|
||||
"else",
|
||||
"enum",
|
||||
"explicit",
|
||||
"export",
|
||||
"extern",
|
||||
"false",
|
||||
"for",
|
||||
"friend",
|
||||
"fxgroup",
|
||||
"GeometryShader",
|
||||
"goto",
|
||||
"groupshared",
|
||||
"half",
|
||||
"Hullshader",
|
||||
"if",
|
||||
"in",
|
||||
"inline",
|
||||
"inout",
|
||||
"InputPatch",
|
||||
"interface",
|
||||
"line",
|
||||
"lineadj",
|
||||
"linear",
|
||||
"LineStream",
|
||||
"long",
|
||||
"matrix",
|
||||
"mutable",
|
||||
"namespace",
|
||||
"new",
|
||||
"nointerpolation",
|
||||
"noperspective",
|
||||
"NULL",
|
||||
"operator",
|
||||
"out",
|
||||
"OutputPatch",
|
||||
"packoffset",
|
||||
"pass",
|
||||
"pixelfragment",
|
||||
"PixelShader",
|
||||
"point",
|
||||
"PointStream",
|
||||
"precise",
|
||||
"private",
|
||||
"protected",
|
||||
"public",
|
||||
"RasterizerState",
|
||||
"reinterpret_cast",
|
||||
"RenderTargetView",
|
||||
"return",
|
||||
"register",
|
||||
"row_major",
|
||||
"RWBuffer",
|
||||
"RWByteAddressBuffer",
|
||||
"RWStructuredBuffer",
|
||||
"RWTexture1D",
|
||||
"RWTexture1DArray",
|
||||
"RWTexture2D",
|
||||
"RWTexture2DArray",
|
||||
"RWTexture3D",
|
||||
"sample",
|
||||
"sampler",
|
||||
"SamplerState",
|
||||
"SamplerComparisonState",
|
||||
"shared",
|
||||
"short",
|
||||
"signed",
|
||||
"sizeof",
|
||||
"snorm",
|
||||
"stateblock",
|
||||
"stateblock_state",
|
||||
"static",
|
||||
"static_cast",
|
||||
"string",
|
||||
"struct",
|
||||
"switch",
|
||||
"StructuredBuffer",
|
||||
"tbuffer",
|
||||
"technique",
|
||||
"technique10",
|
||||
"technique11",
|
||||
"template",
|
||||
"texture",
|
||||
"Texture1D",
|
||||
"Texture1DArray",
|
||||
"Texture2D",
|
||||
"Texture2DArray",
|
||||
"Texture2DMS",
|
||||
"Texture2DMSArray",
|
||||
"Texture3D",
|
||||
"TextureCube",
|
||||
"TextureCubeArray",
|
||||
"this",
|
||||
"throw",
|
||||
"true",
|
||||
"try",
|
||||
"typedef",
|
||||
"typename",
|
||||
"triangle",
|
||||
"triangleadj",
|
||||
"TriangleStream",
|
||||
"uniform",
|
||||
"unorm",
|
||||
"union",
|
||||
"unsigned",
|
||||
"using",
|
||||
"vector",
|
||||
"vertexfragment",
|
||||
"VertexShader",
|
||||
"virtual",
|
||||
"void",
|
||||
"volatile",
|
||||
"while"
|
||||
};
|
||||
|
||||
static bool m_HLSLKeywordDictionaryBuilt = false;
|
||||
|
||||
public static bool IsHLSLKeyword(string id)
|
||||
{
|
||||
if (!m_HLSLKeywordDictionaryBuilt)
|
||||
{
|
||||
foreach (var numericKeyword in k_HLSLNumericKeywords)
|
||||
foreach (var suffix in k_HLSLNumericKeywordSuffixes)
|
||||
m_HLSLKeywords.Add(numericKeyword + suffix);
|
||||
|
||||
m_HLSLKeywordDictionaryBuilt = true;
|
||||
}
|
||||
|
||||
bool isHLSLKeyword = m_HLSLKeywords.Contains(id);
|
||||
|
||||
return isHLSLKeyword;
|
||||
}
|
||||
|
||||
public static bool IsShaderLabKeyWord(string id)
|
||||
{
|
||||
bool isShaderLabKeyword = m_ShaderLabKeywords.Contains(id.ToLower());
|
||||
return isShaderLabKeyword;
|
||||
}
|
||||
|
||||
public static string ConvertToValidHLSLIdentifier(string originalId, Func<string, bool> isDisallowedIdentifier = null)
|
||||
{
|
||||
// Converts " 1 var * q-30 ( 0 ) (1) " to "_1_var_q_30_0_1"
|
||||
if (originalId == null)
|
||||
originalId = "";
|
||||
|
||||
StringBuilder hlslId = new StringBuilder(originalId.Length);
|
||||
bool lastInvalid = false;
|
||||
for (int i = 0; i < originalId.Length; i++)
|
||||
{
|
||||
char c = originalId[i];
|
||||
|
||||
bool isLetter = (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
|
||||
bool isUnderscore = (c == '_');
|
||||
bool isDigit = (c >= '0' && c <= '9');
|
||||
|
||||
bool validChar = isLetter || isUnderscore || isDigit;
|
||||
|
||||
if (!validChar)
|
||||
{
|
||||
// when we see an invalid character, we just record that we saw it and go to the next character
|
||||
// this way we combine multiple invalid characters, and trailing ones just get dropped
|
||||
lastInvalid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// whenever we hit a valid character
|
||||
// if the last character was invalid, append an underscore
|
||||
// unless we're at the beginning of the string
|
||||
if (lastInvalid && (hlslId.Length > 0))
|
||||
hlslId.Append("_");
|
||||
|
||||
// HLSL ids can't start with a digit, prepend an underscore to prevent this
|
||||
if (isDigit && (hlslId.Length == 0))
|
||||
hlslId.Append("_");
|
||||
|
||||
hlslId.Append(c);
|
||||
|
||||
lastInvalid = false;
|
||||
}
|
||||
}
|
||||
|
||||
// empty strings not allowed -- append an underscore if it's empty
|
||||
if (hlslId.Length <= 0)
|
||||
hlslId.Append("_");
|
||||
|
||||
var result = hlslId.ToString();
|
||||
|
||||
while (IsHLSLKeyword(result))
|
||||
result = "_" + result;
|
||||
|
||||
if (isDisallowedIdentifier != null)
|
||||
while (isDisallowedIdentifier(result))
|
||||
result = "_" + result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string GetDisplaySafeName(string input)
|
||||
{
|
||||
//strip valid display characters from slot name
|
||||
//current valid characters are whitespace and ( ) _ separators
|
||||
StringBuilder cleanName = new StringBuilder();
|
||||
foreach (var c in input)
|
||||
{
|
||||
if (c != ' ' && c != '(' && c != ')' && c != '_')
|
||||
cleanName.Append(c);
|
||||
}
|
||||
|
||||
return cleanName.ToString();
|
||||
}
|
||||
|
||||
public static bool ValidateSlotName(string inName, out string errorMessage)
|
||||
{
|
||||
//check for invalid characters between display safe and hlsl safe name
|
||||
if (GetDisplaySafeName(inName) != GetHLSLSafeName(inName))
|
||||
{
|
||||
errorMessage = "Slot name(s) found invalid character(s). Valid characters: A-Z, a-z, 0-9, _ ( ) ";
|
||||
return true;
|
||||
}
|
||||
|
||||
//if clean, return null and false
|
||||
errorMessage = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static string FloatToShaderValue(float value)
|
||||
{
|
||||
if (Single.IsPositiveInfinity(value))
|
||||
{
|
||||
return "1.#INF";
|
||||
}
|
||||
if (Single.IsNegativeInfinity(value))
|
||||
{
|
||||
return "-1.#INF";
|
||||
}
|
||||
if (Single.IsNaN(value))
|
||||
{
|
||||
return "NAN";
|
||||
}
|
||||
|
||||
return value.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
// A number large enough to become Infinity (~FLOAT_MAX_VALUE * 10) + explanatory comment
|
||||
private const string k_ShaderLabInfinityAlternatrive = "3402823500000000000000000000000000000000 /* Infinity */";
|
||||
|
||||
// ShaderLab doesn't support Scientific Notion nor Infinity. To stop from generating a broken shader we do this.
|
||||
public static string FloatToShaderValueShaderLabSafe(float value)
|
||||
{
|
||||
if (Single.IsPositiveInfinity(value))
|
||||
{
|
||||
return k_ShaderLabInfinityAlternatrive;
|
||||
}
|
||||
if (Single.IsNegativeInfinity(value))
|
||||
{
|
||||
return "-" + k_ShaderLabInfinityAlternatrive;
|
||||
}
|
||||
if (Single.IsNaN(value))
|
||||
{
|
||||
return "NAN"; // A real error has occured, in this case we should break the shader.
|
||||
}
|
||||
|
||||
// For single point precision, reserve 54 spaces (e-45 min + ~9 digit precision). See floating-point-numeric-types (Microsoft docs).
|
||||
return value.ToString("0.######################################################", CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
namespace UnityEditor.Graphing
|
||||
{
|
||||
enum SlotType
|
||||
{
|
||||
Input,
|
||||
Output
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
enum GenerationMode
|
||||
{
|
||||
Preview,
|
||||
ForReals
|
||||
}
|
||||
static class GenerationModeExtensions
|
||||
{
|
||||
public static bool IsPreview(this GenerationMode mode) { return mode == GenerationMode.Preview; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.Graphing
|
||||
{
|
||||
[Serializable]
|
||||
struct DrawState
|
||||
{
|
||||
[SerializeField]
|
||||
private bool m_Expanded;
|
||||
|
||||
[SerializeField]
|
||||
private Rect m_Position;
|
||||
|
||||
public bool expanded
|
||||
{
|
||||
get { return m_Expanded; }
|
||||
set { m_Expanded = value; }
|
||||
}
|
||||
|
||||
public Rect position
|
||||
{
|
||||
get { return m_Position; }
|
||||
set { m_Position = value; }
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user