UnityGame/Library/PackageCache/com.unity.shadergraph/Editor/Generation/Targets/Canvas/CanvasSubTarget.cs
2024-10-27 10:53:47 +03:00

449 lines
16 KiB
C#

using UnityEditor.ShaderGraph;
using UnityEngine;
using System;
using UnityEngine.UIElements;
using UnityEditor.Rendering.BuiltIn.ShaderGraph;
namespace UnityEditor.Rendering.Canvas.ShaderGraph
{
#region CanvasUniforms
internal static class CanvasUniforms
{
// Uniforms
public static readonly string Lighting = "Off";
public static string ColorMask = "ColorMask [_ColorMask]";
public static string ZTest = "[unity_GUIZTestMode]";
//stencil Props
public static string Ref = "[_Stencil]";
public static string Comp = "[_StencilComp]";
public static string Pass = "[_StencilOp]";
public static string ReadMask = "[_StencilReadMask]";
public static string WriteMask = "[_StencilWriteMask]";
}
#endregion
internal abstract class CanvasSubTarget<T> : SubTarget<T>, IRequiresData<CanvasData>, IHasMetadata where T : Target
{
const string kAssetGuid = "3ab5e3f315cd4041b2aa8600df09dd3e"; // CanvasSubTarget.cs
#region Includes
static readonly string[] kSharedTemplateDirectories = GetCanvasTemplateDirectories();
private static string[] GetCanvasTemplateDirectories()
{
var shared = GenerationUtils.GetDefaultSharedTemplateDirectories();
var canvasTemplateDirectories = new string[shared.Length + 1];
canvasTemplateDirectories[shared.Length] = "Packages/com.unity.shadergraph/Editor/Generation/Targets/Canvas/Templates";
for(int i = 0; i < shared.Length; ++i)
{
canvasTemplateDirectories[i] = shared[i];
}
return canvasTemplateDirectories;
}
//HLSL Includes
protected static readonly string kTemplatePath = "Packages/com.unity.shadergraph/Editor/Generation/Targets/Canvas/Templates/PassUI.template";
protected static readonly string kCommon = "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl";
protected static readonly string kColor = "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl";
protected static readonly string kTexture = "Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl";
protected static readonly string kInstancing = "Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl";
protected static readonly string kPacking = "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl";
protected static readonly string kSpaceTransforms = "Packages/com.unity.render-pipelines.core/ShaderLibrary/SpaceTransforms.hlsl";
protected static readonly string kFunctions = "Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl";
protected static readonly string kTextureStack = "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl";
#endregion
CanvasData m_CanvasData;
CanvasData IRequiresData<CanvasData>.data
{
get => m_CanvasData;
set => m_CanvasData = value;
}
public CanvasData canvasData
{
get => m_CanvasData;
set => m_CanvasData = value;
}
protected bool TargetsVFX() => false;
protected virtual IncludeCollection pregraphIncludes => new IncludeCollection();
protected virtual IncludeCollection postgraphIncludes => new IncludeCollection();
protected virtual KeywordCollection GetAdditionalKeywords() => new KeywordCollection();
protected abstract string pipelineTag { get; }
protected virtual Type GetDefaultShaderGUI() => typeof(CanvasShaderGUI);
public virtual string identifier => GetType().Name;
public virtual ScriptableObject GetMetadataObject(GraphDataReadOnly graph)
{
var canvasMetadata = ScriptableObject.CreateInstance<CanvasMetaData>();
return canvasMetadata;
}
public override bool IsActive() => true;
public override void Setup(ref TargetSetupContext context)
{
context.AddAssetDependency(new GUID(kAssetGuid), AssetCollection.Flags.SourceDependency);
context.AddSubShader(GenerateDefaultSubshader());
}
public override void GetActiveBlocks(ref TargetActiveBlockContext context)
{
//Core Fragment Blocks
context.AddBlock(BlockFields.SurfaceDescription.BaseColor);
context.AddBlock(BlockFields.SurfaceDescription.Emission);
context.AddBlock(BlockFields.SurfaceDescription.Alpha);
}
public override void CollectShaderProperties(PropertyCollector collector, GenerationMode generationMode)
{
base.CollectShaderProperties(collector, generationMode);
CollectRenderStateShaderProperties(collector, generationMode);
}
public void CollectRenderStateShaderProperties(PropertyCollector collector, GenerationMode generationMode)
{
base.CollectShaderProperties(collector, generationMode);
collector.AddShaderProperty(CanvasProperties.MainTex);
collector.AddShaderProperty(CanvasProperties.StencilComp);
collector.AddShaderProperty(CanvasProperties.Stencil);
collector.AddShaderProperty(CanvasProperties.StencilOp);
collector.AddShaderProperty(CanvasProperties.StencilWriteMask);
collector.AddShaderProperty(CanvasProperties.StencilReadMask);
collector.AddShaderProperty(CanvasProperties.ColorMask);
collector.AddShaderProperty(CanvasProperties.ClipRect);
collector.AddShaderProperty(CanvasProperties.UIMaskSoftnessX);
collector.AddShaderProperty(CanvasProperties.UIMaskSoftnessY);
}
public override void GetFields(ref TargetFieldContext context)
{
context.AddField(UnityEditor.ShaderGraph.Fields.GraphPixel);
}
protected virtual DefineCollection GetAdditionalDefines()
{
var result = new DefineCollection();
if (canvasData.disableTint)
result.Add(CanvasKeywords.DisableTint, 1);
return result;
}
public override void GetPropertiesGUI(ref TargetPropertyGUIContext context, Action onChange, Action<string> registerUndo)
{
context.AddProperty("Alpha Clipping", new Toggle() { value = canvasData.alphaClip }, (evt) =>
{
if (Equals(canvasData.alphaClip, evt.newValue))
return;
registerUndo("Alpha Clip");
canvasData.alphaClip = evt.newValue;
onChange();
});
context.AddProperty("Disable Color Tint", new Toggle() { value = canvasData.disableTint }, (evt) =>
{
if (Equals(canvasData.disableTint, evt.newValue))
return;
registerUndo("Disable Tint");
canvasData.disableTint = evt.newValue;
onChange();
});
}
public virtual SubShaderDescriptor GenerateDefaultSubshader(bool isSRP = true )
{
var result = new SubShaderDescriptor()
{
pipelineTag = pipelineTag,
renderQueue = "Transparent",
IgnoreProjector = "True",
renderType = "Transparent",
PreviewType = "Plane",
CanUseSpriteAtlas = "True",
generatesPreview = true,
passes = new PassCollection(),
};
result.passes.Add(GenerateUIPassDescriptor(isSRP));
return result;
}
public IncludeCollection AdditionalIncludesOnly()
{
return new IncludeCollection
{
{ pregraphIncludes },
{ postgraphIncludes },
};
}
public IncludeCollection SRPCoreIncludes()
{
return new IncludeCollection
{
// Pre-graph
SRPPreGraphIncludes(),
// Post-graph
SRPPostGraphIncludes(),
};
}
public virtual IncludeCollection SRPPreGraphIncludes()
{
return new IncludeCollection
{
{kCommon, IncludeLocation.Pregraph},
{kColor, IncludeLocation.Pregraph},
{kTexture, IncludeLocation.Pregraph},
{kTextureStack, IncludeLocation.Pregraph},
{ pregraphIncludes },
{kSpaceTransforms, IncludeLocation.Pregraph},
{kFunctions, IncludeLocation.Pregraph},
};
}
public virtual IncludeCollection SRPPostGraphIncludes()
{
return new IncludeCollection
{
{ postgraphIncludes },
};
}
protected virtual DefineCollection GetPassDefines()
=> new DefineCollection();
protected virtual KeywordCollection GetPassKeywords()
=> new KeywordCollection();
public virtual PassDescriptor GenerateUIPassDescriptor(bool isSRP)
{
var DefaultCanvasPass = new PassDescriptor()
{
// Definition
displayName = "Default",
referenceName = "SHADERPASS_CUSTOM_UI",
useInPreview = true,
// Templates
passTemplatePath = kTemplatePath,
sharedTemplateDirectories = kSharedTemplateDirectories,
// Port Mask
validVertexBlocks = CanvasBlockMasks.Vertex,
validPixelBlocks = CanvasBlockMasks.Fragment,
// Collections
// Fields
structs = CanvasStructCollections.Default,
requiredFields = CanvasRequiredFields.Default,
fieldDependencies = FieldDependencies.Default,
//Conditional State
renderStates = CanvasRenderStates.GenerateRenderStateDeclaration(),
pragmas = CanvasPragmas.Default,
includes = isSRP ? SRPCoreIncludes() : AdditionalIncludesOnly(),
//definitions
defines = GetPassDefines(),
keywords = CanvasKeywords.GenerateCoreKeywords(),
};
DefaultCanvasPass.defines.Add(GetAdditionalDefines());
DefaultCanvasPass.keywords.Add(GetAdditionalKeywords());
return DefaultCanvasPass;
}
// We don't need the save context / update materials for now
public override object saveContext => null;
public CanvasSubTarget()
{
displayName = "Canvas";
}
public override bool IsNodeAllowedBySubTarget(Type nodeType)
{
var interfaces = nodeType.GetInterfaces();
int numInterfaces = interfaces.Length;
// Subgraph nodes inherits all the interfaces including vertex ones.
if (nodeType == typeof(BitangentVectorNode))
return false;
if (nodeType == typeof(TangentVectorNode))
return false;
if (nodeType == typeof(SubGraphNode))
return true;
if (nodeType == typeof(BakedGINode))
return false;
if (nodeType == typeof(ParallaxMappingNode))
return false;
if (nodeType == typeof(ParallaxOcclusionMappingNode))
return false;
if (nodeType == typeof(TriplanarNode))
return false;
if (nodeType == typeof(IsFrontFaceNode))
return false;
for (int i = 0; i < numInterfaces; i++)
{
if (interfaces[i] == typeof(IMayRequireVertexSkinning)) return false;
}
return true;
}
#region KeywordDescriptors
internal static class CanvasKeywords
{
public static KeywordCollection GenerateCoreKeywords()
{
return new KeywordCollection()
{
UIAlphaClipKeyword,
UIClipRectKeyword,
};
}
static KeywordDescriptor UIClipRectKeyword = new KeywordDescriptor()
{
displayName = "UIClipRect",
referenceName = "UNITY_UI_CLIP_RECT",
type = KeywordType.Boolean,
definition = KeywordDefinition.MultiCompile,
scope = KeywordScope.Local,
};
static KeywordDescriptor UIAlphaClipKeyword = new KeywordDescriptor()
{
displayName = "UIAlphaClip",
referenceName = "UNITY_UI_ALPHACLIP",
type = KeywordType.Boolean,
definition = KeywordDefinition.MultiCompile,
scope = KeywordScope.Local,
};
public static readonly KeywordDescriptor DisableTint = new KeywordDescriptor()
{
displayName = "Disable Tint",
referenceName = "_DISABLE_COLOR_TINT",
type = KeywordType.Boolean,
definition = KeywordDefinition.ShaderFeature,
scope = KeywordScope.Local,
stages = KeywordShaderStage.All,
};
}
#endregion
}
#region PortMasks
class CanvasBlockMasks
{
// Port Mask
public static BlockFieldDescriptor[] Vertex = null;
public static BlockFieldDescriptor[] Fragment = new BlockFieldDescriptor[]
{
BlockFields.SurfaceDescription.BaseColor,
BlockFields.SurfaceDescription.Alpha,
BlockFields.SurfaceDescription.Emission,
BlockFields.SurfaceDescription.AlphaClipThreshold
};
}
#endregion
#region StructCollections
static class CanvasStructCollections
{
public static StructCollection Default = new StructCollection()
{
CanvasStructs.Attributes,
Structs.SurfaceDescriptionInputs,
CanvasStructs.Varyings,
Structs.VertexDescriptionInputs,
};
}
#endregion
#region RequiredFields
static class CanvasRequiredFields
{
public static FieldCollection Default = new FieldCollection()
{
StructFields.Varyings.positionCS,
StructFields.Varyings.normalWS,
StructFields.Varyings.positionWS,
StructFields.Varyings.color,
StructFields.Varyings.texCoord0,
StructFields.Varyings.texCoord1,
StructFields.Attributes.color,
StructFields.Attributes.uv0, // Always need texCoord0, for UI image
StructFields.Attributes.uv1, // Always need texCoord1 for UI Clip Mask
StructFields.Attributes.positionOS,
StructFields.Attributes.normalOS,
StructFields.Attributes.instanceID,
StructFields.Attributes.vertexID,
};
}
#endregion
#region RenderStates
static class CanvasRenderStates
{
public static RenderStateCollection GenerateRenderStateDeclaration()
{
return new RenderStateCollection
{
{RenderState.Cull(Cull.Off)},
{RenderState.ZWrite(ZWrite.Off)},
{RenderState.ZTest(CanvasUniforms.ZTest)},
{RenderState.Blend(Blend.One, Blend.OneMinusSrcAlpha)},
{RenderState.ColorMask(CanvasUniforms.ColorMask)},
{RenderState.Stencil(new StencilDescriptor()
{
Ref = CanvasUniforms.Ref,
Comp = CanvasUniforms.Comp,
Pass = CanvasUniforms.Pass,
ReadMask = CanvasUniforms.ReadMask,
WriteMask = CanvasUniforms.WriteMask,
})
}
};
}
}
#endregion
#region Pragmas
static class CanvasPragmas
{
public static PragmaCollection Default = new PragmaCollection
{
{Pragma.Target(ShaderModel.Target20)},
{Pragma.Vertex("vert")},
{Pragma.Fragment("frag")},
};
public static PragmaCollection DefaulDebugt = new PragmaCollection
{
{Pragma.Target(ShaderModel.Target20)},
{Pragma.Vertex("vert")},
{Pragma.Fragment("frag")},
{Pragma.DebugSymbols},
};
}
#endregion
}