using System; using System.Linq; using System.Collections.Generic; using UnityEngine; using UnityEditor.ShaderGraph; using UnityEngine.Rendering; using UnityEditor.UIElements; using UnityEngine.UIElements; using UnityEditor.ShaderGraph.Legacy; namespace UnityEditor.Rendering.Universal.ShaderGraph { sealed class UniversalLitSubTarget : SubTarget, ILegacyTarget { static readonly GUID kSourceCodeGuid = new GUID("d6c78107b64145745805d963de80cc17"); // UniversalLitSubTarget.cs [SerializeField] WorkflowMode m_WorkflowMode = WorkflowMode.Metallic; [SerializeField] NormalDropOffSpace m_NormalDropOffSpace = NormalDropOffSpace.Tangent; [SerializeField] bool m_ClearCoat = false; public UniversalLitSubTarget() { displayName = "Lit"; } public WorkflowMode workflowMode { get => m_WorkflowMode; set => m_WorkflowMode = value; } public NormalDropOffSpace normalDropOffSpace { get => m_NormalDropOffSpace; set => m_NormalDropOffSpace = value; } public bool clearCoat { get => m_ClearCoat; set => m_ClearCoat = value; } private bool complexLit { get { // Rules for switching to ComplexLit with forward only pass return clearCoat; // && } } public override bool IsActive() => true; public override void Setup(ref TargetSetupContext context) { context.AddAssetDependency(kSourceCodeGuid, AssetCollection.Flags.SourceDependency); if (!context.HasCustomEditorForRenderPipeline(typeof(UnityEngine.Rendering.Universal.UniversalRenderPipelineAsset))) context.AddCustomEditorForRenderPipeline("ShaderGraph.PBRMasterGUI", typeof(UnityEngine.Rendering.Universal.UniversalRenderPipelineAsset)); // TODO: This should be owned by URP // Process SubShaders SubShaderDescriptor[] litSubShaders = { SubShaders.LitComputeDOTS, SubShaders.LitGLES }; SubShaderDescriptor[] complexLitSubShaders = { SubShaders.ComplexLitComputeDOTS, SubShaders.LitGLESForwardOnly}; // TODO: In the future: // We could take a copy of subshaders and dynamically modify them here. // For example, toggle "ComplexLit.ForwardOnlyPass.defines.ClearCoat" index/enable/disable to dynamically // remove clear coat code. // Currently ClearCoat is always on for a ComplexLit, but it's only used when ClearCoat is on. // An alternative is to rely on shader branches and reduce variants/unique graph generations. SubShaderDescriptor[] subShaders = complexLit ? complexLitSubShaders : litSubShaders; for (int i = 0; i < subShaders.Length; i++) { // Update Render State subShaders[i].renderType = target.renderType; subShaders[i].renderQueue = target.renderQueue; context.AddSubShader(subShaders[i]); } } public override void GetFields(ref TargetFieldContext context) { var descs = context.blocks.Select(x => x.descriptor); // Surface Type & Blend Mode // These must be set per SubTarget as Sprite SubTargets override them context.AddField(UniversalFields.SurfaceOpaque, target.surfaceType == SurfaceType.Opaque); context.AddField(UniversalFields.SurfaceTransparent, target.surfaceType != SurfaceType.Opaque); context.AddField(UniversalFields.BlendAdd, target.surfaceType != SurfaceType.Opaque && target.alphaMode == AlphaMode.Additive); context.AddField(Fields.BlendAlpha, target.surfaceType != SurfaceType.Opaque && target.alphaMode == AlphaMode.Alpha); context.AddField(UniversalFields.BlendMultiply, target.surfaceType != SurfaceType.Opaque && target.alphaMode == AlphaMode.Multiply); context.AddField(UniversalFields.BlendPremultiply, target.surfaceType != SurfaceType.Opaque && target.alphaMode == AlphaMode.Premultiply); // Lit context.AddField(UniversalFields.NormalDropOffOS, normalDropOffSpace == NormalDropOffSpace.Object); context.AddField(UniversalFields.NormalDropOffTS, normalDropOffSpace == NormalDropOffSpace.Tangent); context.AddField(UniversalFields.NormalDropOffWS, normalDropOffSpace == NormalDropOffSpace.World); context.AddField(UniversalFields.SpecularSetup, workflowMode == WorkflowMode.Specular); context.AddField(UniversalFields.Normal, descs.Contains(BlockFields.SurfaceDescription.NormalOS) || descs.Contains(BlockFields.SurfaceDescription.NormalTS) || descs.Contains(BlockFields.SurfaceDescription.NormalWS)); // Complex Lit // Template Predicates //context.AddField(UniversalFields.PredicateClearCoat, clearCoat); } public override void GetActiveBlocks(ref TargetActiveBlockContext context) { context.AddBlock(BlockFields.SurfaceDescription.Smoothness); context.AddBlock(BlockFields.SurfaceDescription.NormalOS, normalDropOffSpace == NormalDropOffSpace.Object); context.AddBlock(BlockFields.SurfaceDescription.NormalTS, normalDropOffSpace == NormalDropOffSpace.Tangent); context.AddBlock(BlockFields.SurfaceDescription.NormalWS, normalDropOffSpace == NormalDropOffSpace.World); context.AddBlock(BlockFields.SurfaceDescription.Emission); context.AddBlock(BlockFields.SurfaceDescription.Occlusion); context.AddBlock(BlockFields.SurfaceDescription.Specular, workflowMode == WorkflowMode.Specular); context.AddBlock(BlockFields.SurfaceDescription.Metallic, workflowMode == WorkflowMode.Metallic); context.AddBlock(BlockFields.SurfaceDescription.Alpha, target.surfaceType == SurfaceType.Transparent || target.alphaClip); context.AddBlock(BlockFields.SurfaceDescription.AlphaClipThreshold, target.alphaClip); context.AddBlock(BlockFields.SurfaceDescription.CoatMask, clearCoat); context.AddBlock(BlockFields.SurfaceDescription.CoatSmoothness, clearCoat); } public override void GetPropertiesGUI(ref TargetPropertyGUIContext context, Action onChange, Action registerUndo) { context.AddProperty("Workflow", new EnumField(WorkflowMode.Metallic) { value = workflowMode }, (evt) => { if (Equals(workflowMode, evt.newValue)) return; registerUndo("Change Workflow"); workflowMode = (WorkflowMode)evt.newValue; onChange(); }); context.AddProperty("Surface", new EnumField(SurfaceType.Opaque) { value = target.surfaceType }, (evt) => { if (Equals(target.surfaceType, evt.newValue)) return; registerUndo("Change Surface"); target.surfaceType = (SurfaceType)evt.newValue; onChange(); }); context.AddProperty("Blend", new EnumField(AlphaMode.Alpha) { value = target.alphaMode }, target.surfaceType == SurfaceType.Transparent, (evt) => { if (Equals(target.alphaMode, evt.newValue)) return; registerUndo("Change Blend"); target.alphaMode = (AlphaMode)evt.newValue; onChange(); }); context.AddProperty("Alpha Clip", new Toggle() { value = target.alphaClip }, (evt) => { if (Equals(target.alphaClip, evt.newValue)) return; registerUndo("Change Alpha Clip"); target.alphaClip = evt.newValue; onChange(); }); context.AddProperty("Two Sided", new Toggle() { value = target.twoSided }, (evt) => { if (Equals(target.twoSided, evt.newValue)) return; registerUndo("Change Two Sided"); target.twoSided = evt.newValue; onChange(); }); context.AddProperty("Fragment Normal Space", new EnumField(NormalDropOffSpace.Tangent) { value = normalDropOffSpace }, (evt) => { if (Equals(normalDropOffSpace, evt.newValue)) return; registerUndo("Change Fragment Normal Space"); normalDropOffSpace = (NormalDropOffSpace)evt.newValue; onChange(); }); context.AddProperty("Clear Coat", new Toggle() { value = clearCoat }, (evt) => { if (Equals(clearCoat, evt.newValue)) return; registerUndo("Change Clear Coat"); clearCoat = evt.newValue; onChange(); }); } public bool TryUpgradeFromMasterNode(IMasterNode1 masterNode, out Dictionary blockMap) { blockMap = null; if (!(masterNode is PBRMasterNode1 pbrMasterNode)) return false; m_WorkflowMode = (WorkflowMode)pbrMasterNode.m_Model; m_NormalDropOffSpace = (NormalDropOffSpace)pbrMasterNode.m_NormalDropOffSpace; // Handle mapping of Normal block specifically BlockFieldDescriptor normalBlock; switch (m_NormalDropOffSpace) { case NormalDropOffSpace.Object: normalBlock = BlockFields.SurfaceDescription.NormalOS; break; case NormalDropOffSpace.World: normalBlock = BlockFields.SurfaceDescription.NormalWS; break; default: normalBlock = BlockFields.SurfaceDescription.NormalTS; break; } // PBRMasterNode adds/removes Metallic/Specular based on settings BlockFieldDescriptor specularMetallicBlock; int specularMetallicId; if (m_WorkflowMode == WorkflowMode.Specular) { specularMetallicBlock = BlockFields.SurfaceDescription.Specular; specularMetallicId = 3; } else { specularMetallicBlock = BlockFields.SurfaceDescription.Metallic; specularMetallicId = 2; } // Set blockmap blockMap = new Dictionary() { { BlockFields.VertexDescription.Position, 9 }, { BlockFields.VertexDescription.Normal, 10 }, { BlockFields.VertexDescription.Tangent, 11 }, { BlockFields.SurfaceDescription.BaseColor, 0 }, { normalBlock, 1 }, { specularMetallicBlock, specularMetallicId }, { BlockFields.SurfaceDescription.Emission, 4 }, { BlockFields.SurfaceDescription.Smoothness, 5 }, { BlockFields.SurfaceDescription.Occlusion, 6 }, { BlockFields.SurfaceDescription.Alpha, 7 }, { BlockFields.SurfaceDescription.AlphaClipThreshold, 8 }, }; return true; } #region SubShader static class SubShaders { // Overloads to do inline PassDescriptor modifications // NOTE: param order should match PassDescriptor field order for consistency #region PassVariant private static PassDescriptor PassVariant(in PassDescriptor source, PragmaCollection pragmas) { var result = source; result.pragmas = pragmas; return result; } private static PassDescriptor PassVariant(in PassDescriptor source, BlockFieldDescriptor[] vertexBlocks, BlockFieldDescriptor[] pixelBlocks, PragmaCollection pragmas, DefineCollection defines) { var result = source; result.validVertexBlocks = vertexBlocks; result.validPixelBlocks = pixelBlocks; result.pragmas = pragmas; result.defines = defines; return result; } #endregion // SM 4.5, compute with dots instancing public readonly static SubShaderDescriptor LitComputeDOTS = new SubShaderDescriptor() { pipelineTag = UniversalTarget.kPipelineTag, customTags = UniversalTarget.kLitMaterialTypeTag, generatesPreview = true, passes = new PassCollection { { PassVariant(LitPasses.Forward, CorePragmas.DOTSForward) }, { LitPasses.GBuffer }, { PassVariant(CorePasses.ShadowCaster, CorePragmas.DOTSInstanced) }, { PassVariant(CorePasses.DepthOnly, CorePragmas.DOTSInstanced) }, { PassVariant(LitPasses.DepthNormalOnly, CorePragmas.DOTSInstanced) }, { PassVariant(LitPasses.Meta, CorePragmas.DOTSDefault) }, { PassVariant(LitPasses._2D, CorePragmas.DOTSDefault) }, }, }; // Similar to lit, but handles complex material features. // Always ForwardOnly and acts as forward fallback in deferred. // SM 4.5, compute with dots instancing public readonly static SubShaderDescriptor ComplexLitComputeDOTS = new SubShaderDescriptor() { pipelineTag = UniversalTarget.kPipelineTag, customTags = UniversalTarget.kLitMaterialTypeTag, generatesPreview = true, passes = new PassCollection { { PassVariant(LitPasses.ForwardOnly, CoreBlockMasks.Vertex, LitBlockMasks.FragmentComplexLit, CorePragmas.DOTSForward, LitDefines.ComplexLit) }, { PassVariant(CorePasses.ShadowCaster, CorePragmas.DOTSInstanced) }, { PassVariant(CorePasses.DepthOnly, CorePragmas.DOTSInstanced) }, { PassVariant(LitPasses.DepthNormalOnly, CorePragmas.DOTSInstanced) }, { PassVariant(LitPasses.Meta, CorePragmas.DOTSDefault) }, { PassVariant(LitPasses._2D, CorePragmas.DOTSDefault) }, }, }; // SM 2.0, GLES public readonly static SubShaderDescriptor LitGLES = new SubShaderDescriptor() { pipelineTag = UniversalTarget.kPipelineTag, customTags = UniversalTarget.kLitMaterialTypeTag, generatesPreview = true, passes = new PassCollection { { LitPasses.Forward }, { CorePasses.ShadowCaster }, { CorePasses.DepthOnly }, { LitPasses.DepthNormalOnly }, { LitPasses.Meta }, { LitPasses._2D }, }, }; // ForwardOnly pass for SM 2.0, GLES // Used as complex Lit SM 2.0 fallback for GLES. Drops advanced features and renders materials as Lit. public readonly static SubShaderDescriptor LitGLESForwardOnly = new SubShaderDescriptor() { pipelineTag = UniversalTarget.kPipelineTag, customTags = UniversalTarget.kLitMaterialTypeTag, generatesPreview = true, passes = new PassCollection { { LitPasses.ForwardOnly }, { CorePasses.ShadowCaster }, { CorePasses.DepthOnly }, { LitPasses.DepthNormalOnly }, { LitPasses.Meta }, { LitPasses._2D }, }, }; } #endregion #region Passes static class LitPasses { public static PassDescriptor Forward = new PassDescriptor { // Definition displayName = "Universal Forward", referenceName = "SHADERPASS_FORWARD", lightMode = "UniversalForward", useInPreview = true, // Template passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"), sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), // Port Mask validVertexBlocks = CoreBlockMasks.Vertex, validPixelBlocks = LitBlockMasks.FragmentLit, // Fields structs = CoreStructCollections.Default, requiredFields = LitRequiredFields.Forward, fieldDependencies = CoreFieldDependencies.Default, // Conditional State renderStates = CoreRenderStates.Default, pragmas = CorePragmas.Forward, // NOTE: SM 2.0 only GL keywords = LitKeywords.Forward, includes = LitIncludes.Forward, }; public static PassDescriptor ForwardOnly = new PassDescriptor { // Definition displayName = "Universal Forward Only", referenceName = "SHADERPASS_FORWARDONLY", lightMode = "UniversalForwardOnly", useInPreview = true, // Template passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"), sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), // Port Mask validVertexBlocks = CoreBlockMasks.Vertex, validPixelBlocks = LitBlockMasks.FragmentLit, // Fields structs = CoreStructCollections.Default, requiredFields = LitRequiredFields.Forward, fieldDependencies = CoreFieldDependencies.Default, // Conditional State renderStates = CoreRenderStates.Default, pragmas = CorePragmas.Forward, // NOTE: SM 2.0 only GL keywords = LitKeywords.Forward, includes = LitIncludes.Forward, }; // Deferred only in SM4.5, MRT not supported in GLES2 public static PassDescriptor GBuffer = new PassDescriptor { // Definition displayName = "GBuffer", referenceName = "SHADERPASS_GBUFFER", lightMode = "UniversalGBuffer", // Template passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"), sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), // Port Mask validVertexBlocks = CoreBlockMasks.Vertex, validPixelBlocks = LitBlockMasks.FragmentLit, // Fields structs = CoreStructCollections.Default, requiredFields = LitRequiredFields.GBuffer, fieldDependencies = CoreFieldDependencies.Default, // Conditional State renderStates = CoreRenderStates.Default, pragmas = CorePragmas.DOTSGBuffer, keywords = LitKeywords.GBuffer, includes = LitIncludes.GBuffer, }; public static PassDescriptor Meta = new PassDescriptor() { // Definition displayName = "Meta", referenceName = "SHADERPASS_META", lightMode = "Meta", // Template passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"), sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), // Port Mask validVertexBlocks = CoreBlockMasks.Vertex, validPixelBlocks = LitBlockMasks.FragmentMeta, // Fields structs = CoreStructCollections.Default, requiredFields = LitRequiredFields.Meta, fieldDependencies = CoreFieldDependencies.Default, // Conditional State renderStates = CoreRenderStates.Meta, pragmas = CorePragmas.Default, keywords = LitKeywords.Meta, includes = LitIncludes.Meta, }; public static readonly PassDescriptor _2D = new PassDescriptor() { // Definition referenceName = "SHADERPASS_2D", lightMode = "Universal2D", // Template passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"), sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), // Port Mask validVertexBlocks = CoreBlockMasks.Vertex, validPixelBlocks = CoreBlockMasks.FragmentColorAlpha, // Fields structs = CoreStructCollections.Default, fieldDependencies = CoreFieldDependencies.Default, // Conditional State renderStates = CoreRenderStates.Default, pragmas = CorePragmas.Instanced, includes = LitIncludes._2D, }; public static readonly PassDescriptor DepthNormalOnly = new PassDescriptor() { // Definition displayName = "DepthNormals", referenceName = "SHADERPASS_DEPTHNORMALSONLY", lightMode = "DepthNormals", useInPreview = false, // Template passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"), sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), // Port Mask validVertexBlocks = CoreBlockMasks.Vertex, validPixelBlocks = LitBlockMasks.FragmentDepthNormals, // Fields structs = CoreStructCollections.Default, requiredFields = LitRequiredFields.DepthNormals, fieldDependencies = CoreFieldDependencies.Default, // Conditional State renderStates = CoreRenderStates.DepthNormalsOnly, pragmas = CorePragmas.Instanced, includes = CoreIncludes.DepthNormalsOnly, }; } #endregion #region PortMasks static class LitBlockMasks { public static readonly BlockFieldDescriptor[] FragmentLit = new BlockFieldDescriptor[] { BlockFields.SurfaceDescription.BaseColor, BlockFields.SurfaceDescription.NormalOS, BlockFields.SurfaceDescription.NormalTS, BlockFields.SurfaceDescription.NormalWS, BlockFields.SurfaceDescription.Emission, BlockFields.SurfaceDescription.Metallic, BlockFields.SurfaceDescription.Specular, BlockFields.SurfaceDescription.Smoothness, BlockFields.SurfaceDescription.Occlusion, BlockFields.SurfaceDescription.Alpha, BlockFields.SurfaceDescription.AlphaClipThreshold, }; public static readonly BlockFieldDescriptor[] FragmentComplexLit = new BlockFieldDescriptor[] { BlockFields.SurfaceDescription.BaseColor, BlockFields.SurfaceDescription.NormalOS, BlockFields.SurfaceDescription.NormalTS, BlockFields.SurfaceDescription.NormalWS, BlockFields.SurfaceDescription.Emission, BlockFields.SurfaceDescription.Metallic, BlockFields.SurfaceDescription.Specular, BlockFields.SurfaceDescription.Smoothness, BlockFields.SurfaceDescription.Occlusion, BlockFields.SurfaceDescription.Alpha, BlockFields.SurfaceDescription.AlphaClipThreshold, BlockFields.SurfaceDescription.CoatMask, BlockFields.SurfaceDescription.CoatSmoothness, }; public static readonly BlockFieldDescriptor[] FragmentMeta = new BlockFieldDescriptor[] { BlockFields.SurfaceDescription.BaseColor, BlockFields.SurfaceDescription.Emission, BlockFields.SurfaceDescription.Alpha, BlockFields.SurfaceDescription.AlphaClipThreshold, }; public static readonly BlockFieldDescriptor[] FragmentDepthNormals = new BlockFieldDescriptor[] { BlockFields.SurfaceDescription.NormalOS, BlockFields.SurfaceDescription.NormalTS, BlockFields.SurfaceDescription.NormalWS, BlockFields.SurfaceDescription.Alpha, BlockFields.SurfaceDescription.AlphaClipThreshold, }; } #endregion #region RequiredFields static class LitRequiredFields { public static readonly FieldCollection Forward = new FieldCollection() { StructFields.Attributes.uv1, // needed for meta vertex position StructFields.Varyings.positionWS, StructFields.Varyings.normalWS, StructFields.Varyings.tangentWS, // needed for vertex lighting StructFields.Varyings.viewDirectionWS, UniversalStructFields.Varyings.lightmapUV, UniversalStructFields.Varyings.sh, UniversalStructFields.Varyings.fogFactorAndVertexLight, // fog and vertex lighting, vert input is dependency UniversalStructFields.Varyings.shadowCoord, // shadow coord, vert input is dependency }; public static readonly FieldCollection GBuffer = new FieldCollection() { StructFields.Attributes.uv1, // needed for meta vertex position StructFields.Varyings.positionWS, StructFields.Varyings.normalWS, StructFields.Varyings.tangentWS, // needed for vertex lighting StructFields.Varyings.viewDirectionWS, UniversalStructFields.Varyings.lightmapUV, UniversalStructFields.Varyings.sh, UniversalStructFields.Varyings.fogFactorAndVertexLight, // fog and vertex lighting, vert input is dependency UniversalStructFields.Varyings.shadowCoord, // shadow coord, vert input is dependency }; public static readonly FieldCollection DepthNormals = new FieldCollection() { StructFields.Attributes.uv1, // needed for meta vertex position StructFields.Varyings.normalWS, StructFields.Varyings.tangentWS, // needed for vertex lighting }; public static readonly FieldCollection Meta = new FieldCollection() { StructFields.Attributes.uv1, // needed for meta vertex position StructFields.Attributes.uv2, //needed for meta vertex position }; } #endregion #region Defines static class LitDefines { public static readonly KeywordDescriptor ClearCoat = new KeywordDescriptor() { displayName = "Clear Coat", referenceName = "_CLEARCOAT 1", type = KeywordType.Boolean, definition = KeywordDefinition.ShaderFeature, scope = KeywordScope.Local, }; public static readonly DefineCollection ComplexLit = new DefineCollection() { {ClearCoat, 1}, }; } #endregion #region Keywords static class LitKeywords { public static readonly KeywordDescriptor GBufferNormalsOct = new KeywordDescriptor() { displayName = "GBuffer normal octaedron encoding", referenceName = "_GBUFFER_NORMALS_OCT", type = KeywordType.Boolean, definition = KeywordDefinition.MultiCompile, scope = KeywordScope.Global, }; public static readonly KeywordDescriptor ScreenSpaceAmbientOcclusion = new KeywordDescriptor() { displayName = "Screen Space Ambient Occlusion", referenceName = "_SCREEN_SPACE_OCCLUSION", type = KeywordType.Boolean, definition = KeywordDefinition.MultiCompile, scope = KeywordScope.Global, }; public static readonly KeywordCollection Forward = new KeywordCollection { { ScreenSpaceAmbientOcclusion }, { CoreKeywordDescriptors.Lightmap }, { CoreKeywordDescriptors.DirectionalLightmapCombined }, { CoreKeywordDescriptors.MainLightShadows }, { CoreKeywordDescriptors.AdditionalLights }, { CoreKeywordDescriptors.AdditionalLightShadows }, { CoreKeywordDescriptors.ShadowsSoft }, { CoreKeywordDescriptors.LightmapShadowMixing }, { CoreKeywordDescriptors.ShadowsShadowmask }, }; public static readonly KeywordCollection GBuffer = new KeywordCollection { { CoreKeywordDescriptors.Lightmap }, { CoreKeywordDescriptors.DirectionalLightmapCombined }, { CoreKeywordDescriptors.MainLightShadows }, { CoreKeywordDescriptors.ShadowsSoft }, { CoreKeywordDescriptors.MixedLightingSubtractive }, { GBufferNormalsOct }, }; public static readonly KeywordCollection Meta = new KeywordCollection { { CoreKeywordDescriptors.SmoothnessChannel }, }; } #endregion #region Includes static class LitIncludes { const string kShadows = "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"; const string kMetaInput = "Packages/com.unity.render-pipelines.universal/ShaderLibrary/MetaInput.hlsl"; const string kForwardPass = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRForwardPass.hlsl"; const string kGBuffer = "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityGBuffer.hlsl"; const string kPBRGBufferPass = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRGBufferPass.hlsl"; const string kLightingMetaPass = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/LightingMetaPass.hlsl"; const string k2DPass = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBR2DPass.hlsl"; public static readonly IncludeCollection Forward = new IncludeCollection { // Pre-graph { CoreIncludes.CorePregraph }, { kShadows, IncludeLocation.Pregraph }, { CoreIncludes.ShaderGraphPregraph }, // Post-graph { CoreIncludes.CorePostgraph }, { kForwardPass, IncludeLocation.Postgraph }, }; public static readonly IncludeCollection GBuffer = new IncludeCollection { // Pre-graph { CoreIncludes.CorePregraph }, { kShadows, IncludeLocation.Pregraph }, { CoreIncludes.ShaderGraphPregraph }, // Post-graph { CoreIncludes.CorePostgraph }, { kGBuffer, IncludeLocation.Postgraph }, { kPBRGBufferPass, IncludeLocation.Postgraph }, }; public static readonly IncludeCollection Meta = new IncludeCollection { // Pre-graph { CoreIncludes.CorePregraph }, { CoreIncludes.ShaderGraphPregraph }, { kMetaInput, IncludeLocation.Pregraph }, // Post-graph { CoreIncludes.CorePostgraph }, { kLightingMetaPass, IncludeLocation.Postgraph }, }; public static readonly IncludeCollection _2D = new IncludeCollection { // Pre-graph { CoreIncludes.CorePregraph }, { CoreIncludes.ShaderGraphPregraph }, // Post-graph { CoreIncludes.CorePostgraph }, { k2DPass, IncludeLocation.Postgraph }, }; } #endregion } }