527 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			527 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|  | using System; | |||
|  | using UnityEngine; | |||
|  | using UnityEditor.ShaderGraph; | |||
|  | using UnityEngine.UIElements; | |||
|  | using UnityEngine.Assertions; | |||
|  | using UnityEngine.Rendering; | |||
|  | using static UnityEditor.Rendering.Universal.ShaderGraph.SubShaderUtils; | |||
|  | using UnityEngine.Rendering.Universal; | |||
|  | using static Unity.Rendering.Universal.ShaderUtils; | |||
|  | 
 | |||
|  | namespace UnityEditor.Rendering.Universal.ShaderGraph | |||
|  | { | |||
|  |     sealed class UniversalSixWaySubTarget : UniversalSubTarget | |||
|  |     { | |||
|  |         static readonly GUID kSourceCodeGuid = new GUID("d6c78107b64145745805d963de80cc17"); // UniversalLitSubTarget.cs | |||
|  | 
 | |||
|  |         public override int latestVersion => 2; | |||
|  | 
 | |||
|  |         public UniversalSixWaySubTarget() | |||
|  |         { | |||
|  |             displayName = "Six-way Smoke Lit"; | |||
|  |         } | |||
|  | 
 | |||
|  |         protected override ShaderID shaderID => ShaderID.SG_SixWaySmokeLit; | |||
|  | 
 | |||
|  |         public override bool IsActive() => true; | |||
|  | 
 | |||
|  |         [SerializeField] | |||
|  |         bool m_UseColorAbsorption = true; | |||
|  | 
 | |||
|  |         bool useColorAbsorption | |||
|  |         { | |||
|  |             get => m_UseColorAbsorption; | |||
|  |             set => m_UseColorAbsorption = value; | |||
|  |         } | |||
|  | 
 | |||
|  |         public override void Setup(ref TargetSetupContext context) | |||
|  |         { | |||
|  |             context.AddAssetDependency(kSourceCodeGuid, AssetCollection.Flags.SourceDependency); | |||
|  |             base.Setup(ref context); | |||
|  | 
 | |||
|  |             var universalRPType = typeof(UnityEngine.Rendering.Universal.UniversalRenderPipelineAsset); | |||
|  |             if (!context.HasCustomEditorForRenderPipeline(universalRPType)) | |||
|  |             { | |||
|  |                 var gui = typeof(SixWayGUI); | |||
|  | #if HAS_VFX_GRAPH | |||
|  |                 if (TargetsVFX()) | |||
|  |                     gui = typeof(VFXSixWayGUI); | |||
|  | #endif | |||
|  |                 context.AddCustomEditorForRenderPipeline(gui.FullName, universalRPType); | |||
|  |             } | |||
|  | 
 | |||
|  |             // Process SubShaders | |||
|  |             context.AddSubShader(PostProcessSubShader(SubShaders.SixWaySubShader(target,  target.renderType, target.renderQueue, target.disableBatching, useColorAbsorption))); | |||
|  |         } | |||
|  | 
 | |||
|  |         public override void ProcessPreviewMaterial(Material material) | |||
|  |         { | |||
|  |             if (target.allowMaterialOverride) | |||
|  |             { | |||
|  |                 // copy our target's default settings into the material | |||
|  |                 // (technically not necessary since we are always recreating the material from the shader each time, | |||
|  |                 // which will pull over the defaults from the shader definition) | |||
|  |                 // but if that ever changes, this will ensure the defaults are set | |||
|  | 
 | |||
|  |                 material.SetFloat(Property.CastShadows, target.castShadows ? 1.0f : 0.0f); | |||
|  |                 material.SetFloat(Property.ReceiveShadows, target.receiveShadows ? 1.0f : 0.0f); | |||
|  |                 material.SetFloat(Property.SurfaceType, (float)target.surfaceType); | |||
|  |                 material.SetFloat(Property.BlendMode, (float)target.alphaMode); | |||
|  |                 material.SetFloat(Property.AlphaClip, target.alphaClip ? 1.0f : 0.0f); | |||
|  |                 material.SetFloat(Property.CullMode, (int)target.renderFace); | |||
|  |                 material.SetFloat(Property.ZWriteControl, (float)target.zWriteControl); | |||
|  |                 material.SetFloat(Property.ZTest, (float)target.zTestMode); | |||
|  |                 material.SetFloat(SixWayProperties.UseColorAbsorption, useColorAbsorption ? 1.0f : 0.0f ); | |||
|  |             } | |||
|  | 
 | |||
|  |             // We always need these properties regardless of whether the material is allowed to override | |||
|  |             // Queue control & offset enable correct automatic render queue behavior | |||
|  |             // Control == 0 is automatic, 1 is user-specified render queue | |||
|  |             material.SetFloat(Property.QueueOffset, 0.0f); | |||
|  |             material.SetFloat(Property.QueueControl, (float)BaseShaderGUI.QueueControl.Auto); | |||
|  | 
 | |||
|  |             // call the full unlit material setup function | |||
|  |             ShaderGraphLitGUI.UpdateMaterial(material, MaterialUpdateType.CreatedNewMaterial); | |||
|  |             bool useColorAbsorptionValue = false; | |||
|  |             if (material.HasProperty(SixWayProperties.UseColorAbsorption)) | |||
|  |                 useColorAbsorptionValue = material.GetFloat(SixWayProperties.UseColorAbsorption) > 0.0f; | |||
|  |             CoreUtils.SetKeyword(material, "_SIX_WAY_COLOR_ABSORPTION", useColorAbsorptionValue); | |||
|  |         } | |||
|  | 
 | |||
|  |         public override void GetFields(ref TargetFieldContext context) | |||
|  |         { | |||
|  |             base.GetFields(ref context); | |||
|  | 
 | |||
|  |             bool containsNormalDescriptor = false; | |||
|  |             foreach (var block in context.blocks) | |||
|  |             { | |||
|  |                 if (Equals(block.descriptor, BlockFields.SurfaceDescription.NormalOS) || | |||
|  |                     Equals(block.descriptor, BlockFields.SurfaceDescription.NormalTS) || | |||
|  |                     Equals(block.descriptor, BlockFields.SurfaceDescription.NormalWS)) | |||
|  |                 { | |||
|  |                     containsNormalDescriptor = true; | |||
|  |                     break; | |||
|  |                 } | |||
|  |             } | |||
|  |             context.AddField(UniversalFields.Normal, containsNormalDescriptor); | |||
|  | 
 | |||
|  |         } | |||
|  | 
 | |||
|  |         public struct Varyings | |||
|  |         { | |||
|  |             public static string name = "Varyings"; | |||
|  | 
 | |||
|  |             public static FieldDescriptor diffuseGIData0 = new FieldDescriptor(Varyings.name, "diffuseGIData0", | |||
|  |                 "VARYINGS_NEED_SIX_WAY_DIFFUSE_GI_DATA", ShaderValueType.Float4 ,subscriptOptions: StructFieldOptions.Optional); | |||
|  | 
 | |||
|  |             public static FieldDescriptor diffuseGIData1 = new FieldDescriptor(Varyings.name, "diffuseGIData1", | |||
|  |                 "VARYINGS_NEED_SIX_WAY_DIFFUSE_GI_DATA", ShaderValueType.Float4 ,subscriptOptions: StructFieldOptions.Optional); | |||
|  | 
 | |||
|  |             public static FieldDescriptor diffuseGIData2 = new FieldDescriptor(Varyings.name, "diffuseGIData2", | |||
|  |                 "VARYINGS_NEED_SIX_WAY_DIFFUSE_GI_DATA", ShaderValueType.Float4, subscriptOptions: StructFieldOptions.Optional); | |||
|  |         } | |||
|  | 
 | |||
|  | 
 | |||
|  |         public override void GetActiveBlocks(ref TargetActiveBlockContext context) | |||
|  |         { | |||
|  |             context.AddBlock(BlockFields.SurfaceDescription.Emission); | |||
|  |             context.AddBlock(BlockFields.SurfaceDescription.Occlusion); | |||
|  |             context.AddBlock(BlockFields.SurfaceDescription.MapRightTopBack); | |||
|  |             context.AddBlock(BlockFields.SurfaceDescription.MapLeftBottomFront); | |||
|  |             context.AddBlock(BlockFields.SurfaceDescription.AbsorptionStrength, useColorAbsorption || target.allowMaterialOverride); | |||
|  | 
 | |||
|  |             // when the surface options are material controlled, we must show all of these blocks | |||
|  |             // when target controlled, we can cull the unnecessary blocks | |||
|  |             context.AddBlock(BlockFields.SurfaceDescription.Alpha, (target.surfaceType == SurfaceType.Transparent || target.alphaClip) || target.allowMaterialOverride); | |||
|  |             context.AddBlock(BlockFields.SurfaceDescription.AlphaClipThreshold, (target.alphaClip) || target.allowMaterialOverride); | |||
|  | 
 | |||
|  |         } | |||
|  | 
 | |||
|  |         public override void CollectShaderProperties(PropertyCollector collector, GenerationMode generationMode) | |||
|  |         { | |||
|  |             // if using material control, add the material property to control workflow mode | |||
|  |             if (target.allowMaterialOverride) | |||
|  |             { | |||
|  |                 collector.AddFloatProperty(Property.CastShadows, target.castShadows ? 1.0f : 0.0f); | |||
|  |                 collector.AddToggleProperty(Property.ReceiveShadows, target.receiveShadows); | |||
|  | 
 | |||
|  |                 // setup properties using the defaults | |||
|  |                 collector.AddFloatProperty(Property.SurfaceType, (float)target.surfaceType); | |||
|  |                 collector.AddFloatProperty(Property.BlendMode, (float)target.alphaMode); | |||
|  |                 collector.AddFloatProperty(Property.AlphaClip, target.alphaClip ? 1.0f : 0.0f); | |||
|  |                 collector.AddFloatProperty(Property.SrcBlend, 1.0f);    // always set by material inspector, ok to have incorrect values here | |||
|  |                 collector.AddFloatProperty(Property.DstBlend, 0.0f);    // always set by material inspector, ok to have incorrect values here | |||
|  |                 collector.AddToggleProperty(Property.ZWrite, (target.surfaceType == SurfaceType.Opaque)); | |||
|  |                 collector.AddFloatProperty(Property.ZWriteControl, (float)target.zWriteControl); | |||
|  |                 collector.AddFloatProperty(Property.ZTest, (float)target.zTestMode);    // ztest mode is designed to directly pass as ztest | |||
|  |                 collector.AddFloatProperty(Property.CullMode, (float)target.renderFace);    // render face enum is designed to directly pass as a cull mode | |||
|  | 
 | |||
|  |                 bool enableAlphaToMask = (target.alphaClip && (target.surfaceType == SurfaceType.Opaque)); | |||
|  |                 collector.AddFloatProperty(Property.AlphaToMask, enableAlphaToMask ? 1.0f : 0.0f); | |||
|  | 
 | |||
|  |                 collector.AddToggleProperty(SixWayProperties.UseColorAbsorption, useColorAbsorption); | |||
|  |             } | |||
|  | 
 | |||
|  |             // We always need these properties regardless of whether the material is allowed to override other shader properties. | |||
|  |             // Queue control & offset enable correct automatic render queue behavior.  Control == 0 is automatic, 1 is user-specified. | |||
|  |             // We initialize queue control to -1 to indicate to UpdateMaterial that it needs to initialize it properly on the material. | |||
|  |             collector.AddFloatProperty(Property.QueueOffset, 0.0f); | |||
|  |             collector.AddFloatProperty(Property.QueueControl, -1.0f); | |||
|  |         } | |||
|  | 
 | |||
|  |         public override void GetPropertiesGUI(ref TargetPropertyGUIContext context, Action onChange, Action<String> registerUndo) | |||
|  |         { | |||
|  |             var universalTarget = (target as UniversalTarget); | |||
|  |             universalTarget.AddDefaultMaterialOverrideGUI(ref context, onChange, registerUndo); | |||
|  | 
 | |||
|  |             universalTarget.AddDefaultSurfacePropertiesGUI(ref context, onChange, registerUndo, showReceiveShadows: true); | |||
|  | 
 | |||
|  |             context.AddProperty("Use Color Absorption", new Toggle() { value = useColorAbsorption }, (evt) => | |||
|  |             { | |||
|  |                 if (Equals(useColorAbsorption, evt.newValue)) | |||
|  |                     return; | |||
|  | 
 | |||
|  |                 registerUndo("Change Use Color Absorption"); | |||
|  |                 useColorAbsorption = evt.newValue; | |||
|  |                 onChange(); | |||
|  |             }); | |||
|  | 
 | |||
|  |         } | |||
|  | 
 | |||
|  |         protected override int ComputeMaterialNeedsUpdateHash() | |||
|  |         { | |||
|  |             int hash = base.ComputeMaterialNeedsUpdateHash(); | |||
|  |             hash = hash * 23 + target.allowMaterialOverride.GetHashCode(); | |||
|  |             return hash; | |||
|  |         } | |||
|  | 
 | |||
|  |         #region SubShader | |||
|  |         static class SubShaders | |||
|  |         { | |||
|  |             const string kSixWayMaterialTypeTag = "\"UniversalMaterialType\" = \"SixWayLit\""; | |||
|  | 
 | |||
|  |             public static SubShaderDescriptor SixWaySubShader(UniversalTarget target, string renderType, string renderQueue, string disableBatchingTag, bool useColorAbsorption) | |||
|  |             { | |||
|  |                 SubShaderDescriptor result = new SubShaderDescriptor() | |||
|  |                 { | |||
|  |                     pipelineTag = UniversalTarget.kPipelineTag, | |||
|  |                     customTags = kSixWayMaterialTypeTag, | |||
|  |                     renderType = renderType, | |||
|  |                     renderQueue = renderQueue, | |||
|  |                     disableBatchingTag = disableBatchingTag, | |||
|  |                     generatesPreview = true, | |||
|  |                     passes = new PassCollection() | |||
|  |                 }; | |||
|  | 
 | |||
|  |                 result.passes.Add(SixWayPasses.ForwardOnly(target,  CoreBlockMasks.Vertex, SixWayBlockMasks.FragmentLit, CorePragmas.Forward, SixWayKeywords.Forward, useColorAbsorption)); | |||
|  | 
 | |||
|  |                 // cull the shadowcaster pass if we know it will never be used | |||
|  |                 if (target.castShadows || target.allowMaterialOverride) | |||
|  |                     result.passes.Add(PassVariant(CorePasses.ShadowCaster(target), CorePragmas.Instanced)); | |||
|  | 
 | |||
|  |                 if (target.mayWriteDepth) | |||
|  |                     result.passes.Add(PassVariant(CorePasses.DepthOnly(target), CorePragmas.Instanced)); | |||
|  | 
 | |||
|  |                 result.passes.Add(PassVariant(SixWayPasses.Meta(target), CorePragmas.Default)); | |||
|  | 
 | |||
|  |                 // Currently neither of these passes (selection/picking) can be last for the game view for | |||
|  |                 // UI shaders to render correctly. Verify [1352225] before changing this order. | |||
|  |                 result.passes.Add(PassVariant(CorePasses.SceneSelection(target), CorePragmas.Default)); | |||
|  |                 result.passes.Add(PassVariant(CorePasses.ScenePicking(target), CorePragmas.Default)); | |||
|  | 
 | |||
|  |                 return result; | |||
|  |             } | |||
|  |         } | |||
|  |         #endregion | |||
|  | 
 | |||
|  |         #region Passes | |||
|  |         static class SixWayPasses | |||
|  |         { | |||
|  |             static void AddReceiveShadowsControlToPass(ref PassDescriptor pass, UniversalTarget target, bool receiveShadows) | |||
|  |             { | |||
|  |                 if (target.allowMaterialOverride) | |||
|  |                     pass.keywords.Add(SixWayKeywords.ReceiveShadowsOff); | |||
|  |                 else if (!receiveShadows) | |||
|  |                     pass.defines.Add(SixWayKeywords.ReceiveShadowsOff, 1); | |||
|  |             } | |||
|  | 
 | |||
|  |             static void AddColorAbsorptionControlToPass(ref PassDescriptor pass, UniversalTarget target, | |||
|  |                 bool useColorAbsorption) | |||
|  |             { | |||
|  |                 if (target.allowMaterialOverride) | |||
|  |                     pass.keywords.Add(SixWayKeywords.UseColorAbsorption); | |||
|  |                 else if (useColorAbsorption) | |||
|  |                     pass.defines.Add(SixWayKeywords.UseColorAbsorption, 1); | |||
|  |             } | |||
|  | 
 | |||
|  |             static StructDescriptor ForwardVaryings | |||
|  |             { | |||
|  |                 get | |||
|  |                 { | |||
|  |                     var baseVaryingsDescriptor = UniversalStructs.Varyings; | |||
|  | 
 | |||
|  |                     FieldDescriptor[] varyingsDescriptorFields = | |||
|  |                         new FieldDescriptor[baseVaryingsDescriptor.fields.Length + 3]; | |||
|  | 
 | |||
|  |                     varyingsDescriptorFields[0] = Varyings.diffuseGIData0; | |||
|  |                     varyingsDescriptorFields[1] = Varyings.diffuseGIData1; | |||
|  |                     varyingsDescriptorFields[2] = Varyings.diffuseGIData2; | |||
|  |                     baseVaryingsDescriptor.fields.CopyTo(varyingsDescriptorFields,3); | |||
|  |                     baseVaryingsDescriptor.fields = varyingsDescriptorFields; | |||
|  | 
 | |||
|  |                     return baseVaryingsDescriptor; | |||
|  |                 } | |||
|  |             } | |||
|  | 
 | |||
|  |             static readonly StructCollection ForwardStructCollection = new StructCollection | |||
|  |             { | |||
|  |                 { Structs.Attributes }, | |||
|  |                 { ForwardVaryings }, | |||
|  |                 { Structs.SurfaceDescriptionInputs }, | |||
|  |                 { Structs.VertexDescriptionInputs }, | |||
|  |             }; | |||
|  | 
 | |||
|  |             public static PassDescriptor ForwardOnly( | |||
|  |                 UniversalTarget target, | |||
|  |                 BlockFieldDescriptor[] vertexBlocks, | |||
|  |                 BlockFieldDescriptor[] pixelBlocks, | |||
|  |                 PragmaCollection pragmas, | |||
|  |                 KeywordCollection keywords, | |||
|  |                 bool useColorAbsorption) | |||
|  |             { | |||
|  |                 var result = new PassDescriptor | |||
|  |                 { | |||
|  |                     // Definition | |||
|  |                     displayName = "Universal Forward Only", | |||
|  |                     referenceName = "SHADERPASS_FORWARDONLY", | |||
|  |                     lightMode = "UniversalForwardOnly", | |||
|  |                     useInPreview = true, | |||
|  | 
 | |||
|  |                     // Template | |||
|  |                     passTemplatePath = UniversalTarget.kUberTemplatePath, | |||
|  |                     sharedTemplateDirectories = UniversalTarget.kSharedTemplateDirectories, | |||
|  | 
 | |||
|  |                     // Port Mask | |||
|  |                     validVertexBlocks = vertexBlocks, | |||
|  |                     validPixelBlocks = pixelBlocks, | |||
|  | 
 | |||
|  |                     // Fields | |||
|  |                     structs = ForwardStructCollection, | |||
|  |                     requiredFields = SixWayRequiredFields.Forward, | |||
|  |                     fieldDependencies = CoreFieldDependencies.Default, | |||
|  | 
 | |||
|  |                     // Conditional State | |||
|  |                     renderStates = CoreRenderStates.UberSwitchedRenderState(target), | |||
|  |                     pragmas = pragmas, | |||
|  |                     defines = new DefineCollection { CoreDefines.UseFragmentFog }, | |||
|  |                     keywords = new KeywordCollection { keywords }, | |||
|  |                     includes = new IncludeCollection { SixWayIncludes.Forward }, | |||
|  | 
 | |||
|  |                     // Custom Interpolator Support | |||
|  |                     customInterpolators = CoreCustomInterpDescriptors.Common | |||
|  |                 }; | |||
|  | 
 | |||
|  |                 CorePasses.AddTargetSurfaceControlsToPass(ref result, target); | |||
|  |                 CorePasses.AddAlphaToMaskControlToPass(ref result, target); | |||
|  |                 AddReceiveShadowsControlToPass(ref result, target, target.receiveShadows); | |||
|  |                 CorePasses.AddLODCrossFadeControlToPass(ref result, target); | |||
|  |                 AddColorAbsorptionControlToPass(ref result, target, useColorAbsorption); | |||
|  | 
 | |||
|  |                 return result; | |||
|  |             } | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  |             public static PassDescriptor Meta(UniversalTarget target) | |||
|  |             { | |||
|  |                 var result = new PassDescriptor() | |||
|  |                 { | |||
|  |                     // Definition | |||
|  |                     displayName = "Meta", | |||
|  |                     referenceName = "SHADERPASS_META", | |||
|  |                     lightMode = "Meta", | |||
|  | 
 | |||
|  |                     // Template | |||
|  |                     passTemplatePath = UniversalTarget.kUberTemplatePath, | |||
|  |                     sharedTemplateDirectories = UniversalTarget.kSharedTemplateDirectories, | |||
|  | 
 | |||
|  |                     // Port Mask | |||
|  |                     validVertexBlocks = CoreBlockMasks.Vertex, | |||
|  |                     validPixelBlocks = SixWayBlockMasks.FragmentMeta, | |||
|  | 
 | |||
|  |                     // Fields | |||
|  |                     structs = CoreStructCollections.Default, | |||
|  |                     requiredFields = SixWayRequiredFields.Meta, | |||
|  |                     fieldDependencies = CoreFieldDependencies.Default, | |||
|  | 
 | |||
|  |                     // Conditional State | |||
|  |                     renderStates = CoreRenderStates.Meta, | |||
|  |                     pragmas = CorePragmas.Default, | |||
|  |                     defines = new DefineCollection() { CoreDefines.UseFragmentFog }, | |||
|  |                     keywords = new KeywordCollection() { CoreKeywordDescriptors.EditorVisualization }, | |||
|  |                     includes = SixWayIncludes.Meta, | |||
|  | 
 | |||
|  |                     // Custom Interpolator Support | |||
|  |                     customInterpolators = CoreCustomInterpDescriptors.Common | |||
|  |                 }; | |||
|  | 
 | |||
|  |                 CorePasses.AddAlphaClipControlToPass(ref result, target); | |||
|  | 
 | |||
|  |                 return result; | |||
|  |             } | |||
|  |         } | |||
|  |         #endregion | |||
|  | 
 | |||
|  |         #region PortMasks | |||
|  |         static class SixWayBlockMasks | |||
|  |         { | |||
|  |             public static readonly BlockFieldDescriptor[] FragmentLit = new BlockFieldDescriptor[] | |||
|  |             { | |||
|  |                 BlockFields.SurfaceDescription.BaseColor, | |||
|  |                 BlockFields.SurfaceDescription.MapRightTopBack, | |||
|  |                 BlockFields.SurfaceDescription.MapLeftBottomFront, | |||
|  |                 BlockFields.SurfaceDescription.AbsorptionStrength, | |||
|  |                 BlockFields.SurfaceDescription.Emission, | |||
|  |                 BlockFields.SurfaceDescription.Occlusion, | |||
|  |                 BlockFields.SurfaceDescription.Alpha, | |||
|  |                 BlockFields.SurfaceDescription.AlphaClipThreshold, | |||
|  |             }; | |||
|  | 
 | |||
|  | 
 | |||
|  |             public static readonly BlockFieldDescriptor[] FragmentMeta = new BlockFieldDescriptor[] | |||
|  |             { | |||
|  |                 BlockFields.SurfaceDescription.BaseColor, | |||
|  |                 BlockFields.SurfaceDescription.Emission, | |||
|  |                 BlockFields.SurfaceDescription.Alpha, | |||
|  |                 BlockFields.SurfaceDescription.AlphaClipThreshold, | |||
|  |             }; | |||
|  |         } | |||
|  |         #endregion | |||
|  | 
 | |||
|  |         #region RequiredFields | |||
|  |         static class SixWayRequiredFields | |||
|  |         { | |||
|  |             public static readonly FieldCollection Forward = new FieldCollection() | |||
|  |             { | |||
|  |                 StructFields.Attributes.uv1, | |||
|  |                 StructFields.Attributes.uv2, | |||
|  |                 StructFields.Varyings.positionWS, | |||
|  |                 StructFields.Varyings.normalWS, | |||
|  |                 StructFields.Varyings.tangentWS,                        // needed for vertex lighting | |||
|  |                 UniversalStructFields.Varyings.staticLightmapUV, | |||
|  |                 UniversalStructFields.Varyings.dynamicLightmapUV, | |||
|  |                 UniversalStructFields.Varyings.sh, | |||
|  |                 UniversalStructFields.Varyings.probeOcclusion, | |||
|  |                 UniversalStructFields.Varyings.fogFactorAndVertexLight, // fog and vertex lighting, vert input is dependency | |||
|  |                 UniversalStructFields.Varyings.shadowCoord,             // shadow coord, vert input is dependency | |||
|  |                 Varyings.diffuseGIData0, | |||
|  |                 Varyings.diffuseGIData1, | |||
|  |                 Varyings.diffuseGIData2, | |||
|  |             }; | |||
|  | 
 | |||
|  |             public static readonly FieldCollection Meta = new FieldCollection() | |||
|  |             { | |||
|  |                 StructFields.Attributes.positionOS, | |||
|  |                 StructFields.Attributes.normalOS, | |||
|  |                 StructFields.Attributes.uv0,                            // | |||
|  |                 StructFields.Attributes.uv1,                            // needed for meta vertex position | |||
|  |                 StructFields.Attributes.uv2,                            // needed for meta UVs | |||
|  |                 StructFields.Attributes.instanceID,                     // needed for rendering instanced terrain | |||
|  |                 StructFields.Varyings.positionCS, | |||
|  |                 StructFields.Varyings.texCoord0,                        // needed for meta UVs | |||
|  |                 StructFields.Varyings.texCoord1,                        // VizUV | |||
|  |                 StructFields.Varyings.texCoord2,                        // LightCoord | |||
|  |             }; | |||
|  |         } | |||
|  |         #endregion | |||
|  | 
 | |||
|  |         #region Defines | |||
|  | 
 | |||
|  |         public static class SixWayProperties | |||
|  |         { | |||
|  |             public static readonly string UseColorAbsorption = "_UseColorAbsorption"; | |||
|  |         } | |||
|  | 
 | |||
|  |         #endregion | |||
|  | 
 | |||
|  |         #region Keywords | |||
|  |         static class SixWayKeywords | |||
|  |         { | |||
|  |             public static readonly KeywordDescriptor ReceiveShadowsOff = new KeywordDescriptor() | |||
|  |             { | |||
|  |                 displayName = "Receive Shadows Off", | |||
|  |                 referenceName = ShaderKeywordStrings._RECEIVE_SHADOWS_OFF, | |||
|  |                 type = KeywordType.Boolean, | |||
|  |                 definition = KeywordDefinition.ShaderFeature, | |||
|  |                 scope = KeywordScope.Local, | |||
|  |             }; | |||
|  | 
 | |||
|  |             public static readonly KeywordDescriptor UseColorAbsorption = new KeywordDescriptor() | |||
|  |             { | |||
|  |                 displayName = "Use Color Absorption", | |||
|  |                 referenceName = "_SIX_WAY_COLOR_ABSORPTION", | |||
|  |                 type = KeywordType.Boolean, | |||
|  |                 definition = KeywordDefinition.ShaderFeature, | |||
|  |                 scope = KeywordScope.Local, | |||
|  |                 stages = KeywordShaderStage.Fragment | |||
|  |             }; | |||
|  | 
 | |||
|  |             public static readonly KeywordCollection Forward = new KeywordCollection | |||
|  |             { | |||
|  |                 { CoreKeywordDescriptors.MainLightShadows }, | |||
|  |                 { CoreKeywordDescriptors.AdditionalLights }, | |||
|  |                 { CoreKeywordDescriptors.AdditionalLightShadows }, | |||
|  |                 { CoreKeywordDescriptors.ShadowsSoft }, | |||
|  |                 { CoreKeywordDescriptors.ShadowsShadowmask }, | |||
|  |                 { CoreKeywordDescriptors.LightLayers }, | |||
|  |                 { CoreKeywordDescriptors.DebugDisplay }, | |||
|  |                 { CoreKeywordDescriptors.LightCookies }, | |||
|  |                 { CoreKeywordDescriptors.ClusterLightLoop }, | |||
|  |             }; | |||
|  | 
 | |||
|  |         } | |||
|  |         #endregion | |||
|  | 
 | |||
|  |         #region Includes | |||
|  |         static class SixWayIncludes | |||
|  |         { | |||
|  |             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/SixWayForwardPass.hlsl"; | |||
|  |             const string kLightingMetaPass = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/LightingMetaPass.hlsl"; | |||
|  |             const string kSixWayLighting = "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SixWayLighting.hlsl"; | |||
|  | 
 | |||
|  |             public static readonly IncludeCollection Forward = new IncludeCollection | |||
|  |             { | |||
|  |                 // Pre-graph | |||
|  |                 { CoreIncludes.DOTSPregraph }, | |||
|  |                 { CoreIncludes.WriteRenderLayersPregraph }, | |||
|  |                 { CoreIncludes.ProbeVolumePregraph }, | |||
|  |                 { CoreIncludes.CorePregraph }, | |||
|  |                 { kShadows, IncludeLocation.Pregraph }, | |||
|  |                 { CoreIncludes.ShaderGraphPregraph }, | |||
|  |                 { CoreIncludes.DBufferPregraph }, | |||
|  | 
 | |||
|  | 
 | |||
|  |                 // Post-graph | |||
|  |                 { kSixWayLighting, IncludeLocation.Postgraph}, | |||
|  |                 { CoreIncludes.CorePostgraph }, | |||
|  |                 { kForwardPass, 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 }, | |||
|  |             }; | |||
|  |         } | |||
|  |         #endregion | |||
|  |     } | |||
|  | } |