1138 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			1138 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|  | using System; | ||
|  | using System.Linq; | ||
|  | using System.Collections.Generic; | ||
|  | using UnityEngine; | ||
|  | using UnityEditor.ShaderGraph; | ||
|  | using Unity.Rendering.Universal; | ||
|  | using UnityEditor.UIElements; | ||
|  | using UnityEngine.UIElements; | ||
|  | using UnityEditor.ShaderGraph.Legacy; | ||
|  | using UnityEngine.Rendering.Universal; | ||
|  | using UnityEditor.ShaderGraph.Internal; | ||
|  | using ShaderUtils = Unity.Rendering.Universal.ShaderUtils; | ||
|  | 
 | ||
|  | namespace UnityEditor.Rendering.Universal.ShaderGraph | ||
|  | { | ||
|  |     sealed class UniversalDecalSubTarget : UniversalSubTarget | ||
|  |     { | ||
|  |         static readonly GUID kSourceCodeGuid = new GUID("f6cdcb0f9c306bf4895b74013d29ed47"); // UniversalDecalSubTarget.cs | ||
|  | 
 | ||
|  |         internal class Styles | ||
|  |         { | ||
|  |             public const string header = "Surface Options"; | ||
|  | 
 | ||
|  |             public static GUIContent affectAlbedoText = new GUIContent("Affect BaseColor", "When enabled, this decal uses its base color. When disabled, the decal has no base color effect."); | ||
|  |             public static GUIContent affectNormalText = new GUIContent("Affect Normal", "When enabled, this decal uses its normal. When disabled, the decal has no normal effect."); | ||
|  |             public static GUIContent affectNormalBlendText = new GUIContent("Affect Normal Blend", "When enabled, this decal uses its normal blending. When disabled, the decal has no normal blending effect."); | ||
|  |             public static GUIContent affectMetalText = new GUIContent("Affect Metal", "When enabled, this decal uses the metallic channel of its Mask Map. When disabled, the decal has no metallic effect."); | ||
|  |             public static GUIContent affectAmbientOcclusionText = new GUIContent("Affect Ambient Occlusion", "When enabled, this decal uses the smoothness channel of its Mask Map. When disabled, the decal has no smoothness effect."); | ||
|  |             public static GUIContent affectSmoothnessText = new GUIContent("Affect Smoothness", "When enabled, this decal uses the ambient occlusion channel of its Mask Map. When disabled, the decal has no ambient occlusion effect."); | ||
|  |             public static GUIContent affectEmissionText = new GUIContent("Affect Emission", "When enabled, this decal becomes emissive and appears self-illuminated. Affect Emission does not support Affects Transparent option on Decal Projector."); | ||
|  |             public static GUIContent supportLodCrossFadeText = new GUIContent("Support LOD CrossFade", "When enabled, this decal material supports LOD Cross fade if use on a Mesh."); | ||
|  |         } | ||
|  | 
 | ||
|  |         private const string kMaterial = "Material"; | ||
|  |         private static FieldDescriptor AffectsAlbedo = new FieldDescriptor(kMaterial, "AffectsAlbedo", ""); | ||
|  |         private static FieldDescriptor AffectsNormal = new FieldDescriptor(kMaterial, "AffectsNormal", ""); | ||
|  |         private static FieldDescriptor AffectsNormalBlend = new FieldDescriptor(kMaterial, "AffectsNormalBlend", ""); | ||
|  |         private static FieldDescriptor AffectsMAOS = new FieldDescriptor(kMaterial, "AffectsAO", ""); | ||
|  |         private static FieldDescriptor AffectsEmission = new FieldDescriptor(kMaterial, "AffectsEmission", ""); | ||
|  |         private static FieldDescriptor AffectsDBuffer = new FieldDescriptor(kMaterial, "AffectsDBuffer", ""); | ||
|  |         private static FieldDescriptor DecalDefault = new FieldDescriptor(kMaterial, "DecalDefault", ""); | ||
|  |         private static FieldDescriptor AngleFade = new FieldDescriptor(kMaterial, "AngleFade", ""); | ||
|  | 
 | ||
|  |         [System.Serializable] | ||
|  |         class DecalData | ||
|  |         { | ||
|  |             public bool affectsAlbedo = true; | ||
|  |             public bool affectsNormalBlend = true; | ||
|  |             public bool affectsNormal = true; | ||
|  |             public bool affectsMAOS; | ||
|  |             public bool affectsEmission; | ||
|  |             public int drawOrder; | ||
|  |             public bool supportLodCrossFade; | ||
|  |             public bool angleFade; | ||
|  |         } | ||
|  | 
 | ||
|  |         [SerializeField] | ||
|  |         DecalData m_DecalData; | ||
|  | 
 | ||
|  |         [SerializeField] | ||
|  |         private DecalData decalData | ||
|  |         { | ||
|  |             get | ||
|  |             { | ||
|  |                 if (m_DecalData == null) | ||
|  |                     m_DecalData = new DecalData(); | ||
|  |                 return m_DecalData; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         public UniversalDecalSubTarget() | ||
|  |         { | ||
|  |             displayName = "Decal"; | ||
|  |         } | ||
|  | 
 | ||
|  |         public override bool IsActive() => true; | ||
|  | 
 | ||
|  |         protected override ShaderUtils.ShaderID shaderID => ShaderUtils.ShaderID.SG_Decal; | ||
|  | 
 | ||
|  |         public override void Setup(ref TargetSetupContext context) | ||
|  |         { | ||
|  |             base.Setup(ref context); | ||
|  |             context.AddAssetDependency(kSourceCodeGuid, AssetCollection.Flags.SourceDependency); | ||
|  |             context.AddCustomEditorForRenderPipeline("UnityEditor.Rendering.Universal.DecalShaderGraphGUI", typeof(UnityEngine.Rendering.Universal.UniversalRenderPipelineAsset)); // TODO: This should be owned by URP | ||
|  | 
 | ||
|  |             { | ||
|  |                 SubShaderDescriptor subShader = SubShaders.Decal(decalData.supportLodCrossFade ? $"{UnityEditor.ShaderGraph.DisableBatching.LODFading}" : $"{UnityEditor.ShaderGraph.DisableBatching.False}"); | ||
|  | 
 | ||
|  |                 var passes = new PassCollection(); | ||
|  |                 foreach (var pass in subShader.passes) | ||
|  |                 { | ||
|  |                     var passDescriptor = pass.descriptor; | ||
|  | 
 | ||
|  |                     CollectPassRenderState(ref passDescriptor); | ||
|  | 
 | ||
|  |                     passes.Add(passDescriptor, pass.fieldConditions); | ||
|  |                 } | ||
|  |                 subShader.passes = passes; | ||
|  | 
 | ||
|  |                 context.AddSubShader(subShader); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         private void CollectPassRenderState(ref PassDescriptor pass) | ||
|  |         { | ||
|  |             if (pass.lightMode == DecalShaderPassNames.DecalGBufferProjector || | ||
|  |                 pass.lightMode == DecalShaderPassNames.DecalGBufferMesh) | ||
|  |             { | ||
|  |                 // Make copy to avoid overwriting static | ||
|  |                 pass.renderStates = new RenderStateCollection() { pass.renderStates }; | ||
|  | 
 | ||
|  |                 if (decalData.affectsAlbedo) | ||
|  |                     pass.renderStates.Add(RenderState.ColorMask("ColorMask RGB")); | ||
|  |                 else | ||
|  |                     pass.renderStates.Add(RenderState.ColorMask("ColorMask 0")); | ||
|  | 
 | ||
|  |                 pass.renderStates.Add(RenderState.ColorMask("ColorMask 0 1")); | ||
|  | 
 | ||
|  |                 if (decalData.affectsNormal) | ||
|  |                     pass.renderStates.Add(RenderState.ColorMask("ColorMask RGB 2")); | ||
|  |                 else | ||
|  |                     pass.renderStates.Add(RenderState.ColorMask("ColorMask 0 2")); | ||
|  | 
 | ||
|  |                 // GI needs it unconditionaly | ||
|  |                 pass.renderStates.Add(RenderState.ColorMask("ColorMask RGB 3")); | ||
|  |             } | ||
|  | 
 | ||
|  |             if (pass.lightMode == DecalShaderPassNames.DBufferProjector || | ||
|  |                 pass.lightMode == DecalShaderPassNames.DBufferMesh) | ||
|  |             { | ||
|  |                 // Make copy to avoid overwriting static | ||
|  |                 pass.renderStates = new RenderStateCollection() { pass.renderStates }; | ||
|  | 
 | ||
|  |                 if (decalData.affectsAlbedo) | ||
|  |                     pass.renderStates.Add(DecalColorMasks.ColorMaskRGBA0); | ||
|  |                 else | ||
|  |                     pass.renderStates.Add(DecalColorMasks.ColorMaskNone0); | ||
|  | 
 | ||
|  |                 if (decalData.affectsNormal) | ||
|  |                     pass.renderStates.Add(DecalColorMasks.ColorMaskRGBA1); | ||
|  |                 else | ||
|  |                     pass.renderStates.Add(DecalColorMasks.ColorMaskNone1); | ||
|  | 
 | ||
|  |                 if (decalData.affectsMAOS) | ||
|  |                     pass.renderStates.Add(DecalColorMasks.ColorMaskRGBA2); | ||
|  |                 else | ||
|  |                     pass.renderStates.Add(DecalColorMasks.ColorMaskNone2); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         public override void CollectShaderProperties(PropertyCollector collector, GenerationMode generationMode) | ||
|  |         { | ||
|  |             Vector1ShaderProperty drawOrder = new Vector1ShaderProperty(); | ||
|  |             drawOrder.overrideReferenceName = "_DrawOrder"; | ||
|  |             drawOrder.displayName = "Draw Order"; | ||
|  |             drawOrder.floatType = FloatType.Slider; | ||
|  |             drawOrder.rangeValues = new Vector2(-50, 50); | ||
|  |             drawOrder.hidden = true; | ||
|  |             drawOrder.value = 0; | ||
|  |             collector.AddShaderProperty(drawOrder); | ||
|  | 
 | ||
|  |             collector.AddShaderProperty(new Vector1ShaderProperty | ||
|  |             { | ||
|  |                 overrideReferenceName = "_DecalMeshBiasType", | ||
|  |                 displayName = "DecalMesh BiasType", | ||
|  |                 floatType = FloatType.Enum, | ||
|  |                 value = (int)DecalMeshDepthBiasType.DepthBias, | ||
|  |                 enumNames = { "Depth Bias", "View Bias" }, | ||
|  |                 enumValues = { (int)DecalMeshDepthBiasType.DepthBias, (int)DecalMeshDepthBiasType.ViewBias }, | ||
|  |                 hidden = true | ||
|  |             }); | ||
|  | 
 | ||
|  |             Vector1ShaderProperty decalMeshDepthBias = new Vector1ShaderProperty(); | ||
|  |             decalMeshDepthBias.overrideReferenceName = "_DecalMeshDepthBias"; | ||
|  |             decalMeshDepthBias.displayName = "DecalMesh DepthBias"; | ||
|  |             decalMeshDepthBias.hidden = true; | ||
|  |             decalMeshDepthBias.floatType = FloatType.Default; | ||
|  |             decalMeshDepthBias.value = 0; | ||
|  |             collector.AddShaderProperty(decalMeshDepthBias); | ||
|  | 
 | ||
|  |             Vector1ShaderProperty decalMeshViewBias = new Vector1ShaderProperty(); | ||
|  |             decalMeshViewBias.overrideReferenceName = "_DecalMeshViewBias"; | ||
|  |             decalMeshViewBias.displayName = "DecalMesh ViewBias"; | ||
|  |             decalMeshViewBias.hidden = true; | ||
|  |             decalMeshViewBias.floatType = FloatType.Default; | ||
|  |             decalMeshViewBias.value = 0; | ||
|  |             collector.AddShaderProperty(decalMeshViewBias); | ||
|  | 
 | ||
|  |             if (decalData.angleFade) | ||
|  |             { | ||
|  |                 Vector1ShaderProperty decalAngleFadeSupported = new Vector1ShaderProperty(); | ||
|  |                 decalAngleFadeSupported.overrideReferenceName = "_DecalAngleFadeSupported"; | ||
|  |                 decalAngleFadeSupported.displayName = "Decal Angle Fade Supported"; | ||
|  |                 decalAngleFadeSupported.hidden = true; | ||
|  |                 decalAngleFadeSupported.floatType = FloatType.Default; | ||
|  |                 decalAngleFadeSupported.value = 1; | ||
|  |                 collector.AddShaderProperty(decalAngleFadeSupported); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         public override void GetFields(ref TargetFieldContext context) | ||
|  |         { | ||
|  |             // Decal properties | ||
|  |             context.AddField(AffectsAlbedo, decalData.affectsAlbedo); | ||
|  |             context.AddField(AffectsNormal, decalData.affectsNormal); | ||
|  |             context.AddField(AffectsNormalBlend, decalData.affectsNormalBlend); | ||
|  |             context.AddField(AffectsMAOS, decalData.affectsMAOS); | ||
|  |             context.AddField(AffectsEmission, decalData.affectsEmission); | ||
|  |             context.AddField(AffectsDBuffer, decalData.affectsAlbedo || decalData.affectsNormal || decalData.affectsMAOS); | ||
|  |             context.AddField(DecalDefault, decalData.affectsAlbedo || decalData.affectsNormal || decalData.affectsMAOS || decalData.affectsEmission); | ||
|  |             context.AddField(Fields.LodCrossFade, decalData.supportLodCrossFade); | ||
|  |             context.AddField(AngleFade, decalData.angleFade); | ||
|  |         } | ||
|  | 
 | ||
|  |         public override void GetActiveBlocks(ref TargetActiveBlockContext context) | ||
|  |         { | ||
|  |             // Vertex | ||
|  |             context.AddBlock(BlockFields.VertexDescription.Position); | ||
|  |             context.AddBlock(BlockFields.VertexDescription.Normal); | ||
|  |             context.AddBlock(BlockFields.VertexDescription.Tangent); | ||
|  | 
 | ||
|  |             // Decal | ||
|  |             context.AddBlock(BlockFields.SurfaceDescription.BaseColor, decalData.affectsAlbedo); | ||
|  |             context.AddBlock(BlockFields.SurfaceDescription.Alpha, decalData.affectsAlbedo || decalData.affectsEmission); | ||
|  |             context.AddBlock(BlockFields.SurfaceDescription.NormalTS, decalData.affectsNormal); | ||
|  |             context.AddBlock(UniversalBlockFields.SurfaceDescription.NormalAlpha, decalData.affectsNormal && decalData.affectsNormalBlend); | ||
|  |             context.AddBlock(BlockFields.SurfaceDescription.Metallic, decalData.affectsMAOS); | ||
|  |             context.AddBlock(BlockFields.SurfaceDescription.Occlusion, decalData.affectsMAOS); | ||
|  |             context.AddBlock(BlockFields.SurfaceDescription.Smoothness, decalData.affectsMAOS); | ||
|  |             context.AddBlock(UniversalBlockFields.SurfaceDescription.MAOSAlpha, decalData.affectsMAOS); | ||
|  |             context.AddBlock(BlockFields.SurfaceDescription.Emission, decalData.affectsEmission); | ||
|  |         } | ||
|  | 
 | ||
|  |         public override void GetPropertiesGUI(ref TargetPropertyGUIContext context, Action onChange, Action<String> registerUndo) | ||
|  |         { | ||
|  |             context.AddProperty("Affect BaseColor", new Toggle() { value = decalData.affectsAlbedo }, (evt) => | ||
|  |             { | ||
|  |                 if (Equals(decalData.affectsAlbedo, evt.newValue)) | ||
|  |                     return; | ||
|  | 
 | ||
|  |                 registerUndo("Change Affect BaseColor"); | ||
|  |                 decalData.affectsAlbedo = (bool)evt.newValue; | ||
|  |                 onChange(); | ||
|  |             }); | ||
|  | 
 | ||
|  |             context.AddProperty("Affect Normal", new Toggle() { value = decalData.affectsNormal }, (evt) => | ||
|  |             { | ||
|  |                 if (Equals(decalData.affectsNormal, evt.newValue)) | ||
|  |                     return; | ||
|  | 
 | ||
|  |                 registerUndo("Change Affects Normal"); | ||
|  |                 decalData.affectsNormal = (bool)evt.newValue; | ||
|  |                 onChange(); | ||
|  |             }); | ||
|  | 
 | ||
|  |             context.globalIndentLevel++; | ||
|  |             context.AddProperty("Blend", new Toggle() { value = decalData.affectsNormalBlend }, (evt) => | ||
|  |             { | ||
|  |                 if (Equals(decalData.affectsNormalBlend, evt.newValue)) | ||
|  |                     return; | ||
|  | 
 | ||
|  |                 registerUndo("Change Affects Normal Blend"); | ||
|  |                 decalData.affectsNormalBlend = (bool)evt.newValue; | ||
|  |                 onChange(); | ||
|  |             }); | ||
|  |             context.globalIndentLevel--; | ||
|  | 
 | ||
|  |             context.AddProperty("Affect MAOS", new Toggle() { value = decalData.affectsMAOS }, (evt) => | ||
|  |             { | ||
|  |                 if (Equals(decalData.affectsMAOS, evt.newValue)) | ||
|  |                     return; | ||
|  | 
 | ||
|  |                 registerUndo("Change Affect MAOS"); | ||
|  |                 decalData.affectsMAOS = (bool)evt.newValue; | ||
|  |                 onChange(); | ||
|  |             }); | ||
|  | 
 | ||
|  |             context.AddProperty("Affect Emission", new Toggle() { value = decalData.affectsEmission }, (evt) => | ||
|  |             { | ||
|  |                 if (Equals(decalData.affectsEmission, evt.newValue)) | ||
|  |                     return; | ||
|  | 
 | ||
|  |                 registerUndo("Change Affect Emission"); | ||
|  |                 decalData.affectsEmission = (bool)evt.newValue; | ||
|  |                 onChange(); | ||
|  |             }); | ||
|  | 
 | ||
|  |             context.AddProperty("Supports LOD Cross Fade", new Toggle() { value = decalData.supportLodCrossFade }, (evt) => | ||
|  |             { | ||
|  |                 if (Equals(decalData.supportLodCrossFade, evt.newValue)) | ||
|  |                     return; | ||
|  | 
 | ||
|  |                 registerUndo("Change Supports LOD Cross Fade"); | ||
|  |                 decalData.supportLodCrossFade = (bool)evt.newValue; | ||
|  |                 onChange(); | ||
|  |             }); | ||
|  | 
 | ||
|  |             context.AddProperty("Angle Fade", new Toggle() { value = decalData.angleFade }, (evt) => | ||
|  |             { | ||
|  |                 if (Equals(decalData.angleFade, evt.newValue)) | ||
|  |                     return; | ||
|  | 
 | ||
|  |                 registerUndo("Change Angle Fade"); | ||
|  |                 decalData.angleFade = (bool)evt.newValue; | ||
|  |                 onChange(); | ||
|  |             }); | ||
|  |         } | ||
|  | 
 | ||
|  |         #region SubShader | ||
|  |         static class SubShaders | ||
|  |         { | ||
|  |             public static SubShaderDescriptor Decal(string disableBatchingTag) | ||
|  |             { | ||
|  |                 return new SubShaderDescriptor() | ||
|  |                 { | ||
|  |                     pipelineTag = UniversalTarget.kPipelineTag, | ||
|  |                     customTags = "\"PreviewType\"=\"Plane\"", | ||
|  |                     disableBatchingTag = disableBatchingTag, | ||
|  |                     generatesPreview = true, | ||
|  |                     passes = new PassCollection | ||
|  |                     { | ||
|  |                         { DecalPasses.DBufferProjector, new FieldCondition(AffectsDBuffer, true) }, | ||
|  |                         { DecalPasses.ForwardEmissiveProjector, new FieldCondition(AffectsEmission, true) }, | ||
|  |                         { DecalPasses.ScreenSpaceProjector, new FieldCondition(DecalDefault, true) }, | ||
|  |                         { DecalPasses.GBufferProjector, new FieldCondition(DecalDefault, true) }, | ||
|  |                         { DecalPasses.DBufferMesh, new FieldCondition(AffectsDBuffer, true) }, | ||
|  |                         { DecalPasses.ForwardEmissiveMesh, new FieldCondition(AffectsEmission, true) }, | ||
|  |                         { DecalPasses.ScreenSpaceMesh, new FieldCondition(DecalDefault, true) }, | ||
|  |                         { DecalPasses.GBufferMesh, new FieldCondition(DecalDefault, true) }, | ||
|  |                         { DecalPasses.ScenePicking, new FieldCondition(DecalDefault, true) }, | ||
|  |                     }, | ||
|  |                 }; | ||
|  |             } | ||
|  |         } | ||
|  |         #endregion | ||
|  | 
 | ||
|  |         #region Passes | ||
|  |         static class DecalPasses | ||
|  |         { | ||
|  |             public static PassDescriptor ScenePicking = GetScenePicking(DecalPragmas.Instanced); | ||
|  |             public static PassDescriptor GetScenePicking(PragmaCollection pragma) | ||
|  |             { | ||
|  |                 return new PassDescriptor | ||
|  |                 { | ||
|  |                     // Definition | ||
|  |                     displayName = "ScenePickingPass", | ||
|  |                     referenceName = "SHADERPASS_DEPTHONLY", | ||
|  |                     lightMode = "Picking", | ||
|  |                     useInPreview = false, | ||
|  | 
 | ||
|  |                     // Template | ||
|  |                     passTemplatePath = "Packages/com.unity.render-pipelines.universal/Editor/Decal/DecalPass.template", | ||
|  |                     sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), | ||
|  | 
 | ||
|  |                     // Collections | ||
|  |                     renderStates = DecalRenderStates.ScenePicking, | ||
|  |                     pragmas = pragma, | ||
|  |                     defines = DecalDefines.ScenePicking, | ||
|  |                     includes = DecalIncludes.ScenePicking, | ||
|  | 
 | ||
|  |                     structs = CoreStructCollections.Default, | ||
|  |                     fieldDependencies = CoreFieldDependencies.Default, | ||
|  |                 }; | ||
|  |             } | ||
|  | 
 | ||
|  |             public static PassDescriptor DBufferProjector = new PassDescriptor() | ||
|  |             { | ||
|  |                 // Definition | ||
|  |                 displayName = DecalShaderPassNames.DBufferProjector, | ||
|  |                 referenceName = "SHADERPASS_DBUFFER_PROJECTOR", | ||
|  |                 lightMode = DecalShaderPassNames.DBufferProjector, | ||
|  |                 useInPreview = false, | ||
|  | 
 | ||
|  |                 // Template | ||
|  |                 passTemplatePath = "Packages/com.unity.render-pipelines.universal/Editor/Decal/DecalPass.template", | ||
|  |                 sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), | ||
|  | 
 | ||
|  |                 // Port mask | ||
|  |                 validPixelBlocks = DecalBlockMasks.FragmentWithoutEmessive, | ||
|  | 
 | ||
|  |                 //Fields | ||
|  |                 structs = CoreStructCollections.Default, | ||
|  |                 fieldDependencies = CoreFieldDependencies.Default, | ||
|  |                 renderStates = DecalRenderStates.DBufferProjector, | ||
|  |                 pragmas = DecalPragmas.MultipleRenderTargets, | ||
|  |                 keywords = DecalKeywords.DBufferProjector, | ||
|  |                 defines = DecalDefines.Projector, | ||
|  |                 includes = DecalIncludes.DBuffer, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static PassDescriptor ForwardEmissiveProjector = new PassDescriptor() | ||
|  |             { | ||
|  |                 // Definition | ||
|  |                 displayName = DecalShaderPassNames.DecalProjectorForwardEmissive, | ||
|  |                 referenceName = "SHADERPASS_FORWARD_EMISSIVE_PROJECTOR", | ||
|  |                 lightMode = DecalShaderPassNames.DecalProjectorForwardEmissive, | ||
|  |                 useInPreview = false, | ||
|  | 
 | ||
|  |                 // Template | ||
|  |                 passTemplatePath = "Packages/com.unity.render-pipelines.universal/Editor/Decal/DecalPass.template", | ||
|  |                 sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), | ||
|  | 
 | ||
|  |                 // Port mask | ||
|  |                 validPixelBlocks = DecalBlockMasks.ForwardOnlyEmissive, | ||
|  | 
 | ||
|  |                 //Fields | ||
|  |                 structs = CoreStructCollections.Default, | ||
|  |                 fieldDependencies = CoreFieldDependencies.Default, | ||
|  | 
 | ||
|  |                 // Conditional State | ||
|  |                 renderStates = DecalRenderStates.ForwardEmissiveProjector, | ||
|  |                 pragmas = DecalPragmas.MultipleRenderTargets, | ||
|  |                 defines = DecalDefines.ProjectorWithEmission, | ||
|  |                 keywords = DecalKeywords.ForwardEmissiveProjector, | ||
|  |                 includes = DecalIncludes.DBuffer, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static PassDescriptor ScreenSpaceProjector = GetScreenSpaceProjector(DecalPragmas.ScreenSpace, DecalKeywords.ScreenSpaceProjector); | ||
|  | 
 | ||
|  |             public static PassDescriptor GetScreenSpaceProjector(PragmaCollection pragma, KeywordCollection keywords) | ||
|  |             { | ||
|  |                 return new PassDescriptor | ||
|  |                 { | ||
|  |                     // Definition | ||
|  |                     displayName = DecalShaderPassNames.DecalScreenSpaceProjector, | ||
|  |                     referenceName = "SHADERPASS_DECAL_SCREEN_SPACE_PROJECTOR", | ||
|  |                     lightMode = DecalShaderPassNames.DecalScreenSpaceProjector, | ||
|  |                     useInPreview = false, | ||
|  | 
 | ||
|  |                     // Template | ||
|  |                     passTemplatePath = "Packages/com.unity.render-pipelines.universal/Editor/Decal/DecalPass.template", | ||
|  |                     sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), | ||
|  | 
 | ||
|  |                     // Port mask | ||
|  |                     validPixelBlocks = DecalBlockMasks.Fragment, | ||
|  | 
 | ||
|  |                     //Fields | ||
|  |                     structs = CoreStructCollections.Default, | ||
|  |                     requiredFields = DecalRequiredFields.ScreenSpaceProjector, | ||
|  |                     fieldDependencies = CoreFieldDependencies.Default, | ||
|  | 
 | ||
|  |                     renderStates = DecalRenderStates.ScreenSpaceProjector, | ||
|  |                     pragmas = pragma, | ||
|  |                     defines = DecalDefines.ProjectorWithEmission, | ||
|  |                     keywords = keywords, | ||
|  |                     includes = DecalIncludes.ScreenSpace, | ||
|  |                 }; | ||
|  |             } | ||
|  | 
 | ||
|  |             public static PassDescriptor GBufferProjector = new PassDescriptor() | ||
|  |             { | ||
|  |                 // Definition | ||
|  |                 displayName = DecalShaderPassNames.DecalGBufferProjector, | ||
|  |                 referenceName = "SHADERPASS_DECAL_GBUFFER_PROJECTOR", | ||
|  |                 lightMode = DecalShaderPassNames.DecalGBufferProjector, | ||
|  |                 useInPreview = false, | ||
|  | 
 | ||
|  |                 // Template | ||
|  |                 passTemplatePath = "Packages/com.unity.render-pipelines.universal/Editor/Decal/DecalPass.template", | ||
|  |                 sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), | ||
|  | 
 | ||
|  |                 // Port mask | ||
|  |                 validPixelBlocks = DecalBlockMasks.Fragment, | ||
|  | 
 | ||
|  |                 //Fields | ||
|  |                 structs = CoreStructCollections.Default, | ||
|  |                 requiredFields = DecalRequiredFields.GBufferProjector, | ||
|  |                 fieldDependencies = CoreFieldDependencies.Default, | ||
|  | 
 | ||
|  |                 renderStates = DecalRenderStates.GBufferProjector, | ||
|  |                 pragmas = DecalPragmas.GBuffer, | ||
|  |                 defines = DecalDefines.ProjectorWithEmission, | ||
|  |                 keywords = DecalKeywords.GBufferProjector, | ||
|  |                 includes = DecalIncludes.GBuffer, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static PassDescriptor DBufferMesh = new PassDescriptor() | ||
|  |             { | ||
|  |                 // Definition | ||
|  |                 displayName = DecalShaderPassNames.DBufferMesh, | ||
|  |                 referenceName = "SHADERPASS_DBUFFER_MESH", | ||
|  |                 lightMode = DecalShaderPassNames.DBufferMesh, | ||
|  |                 useInPreview = false, | ||
|  | 
 | ||
|  |                 // Template | ||
|  |                 passTemplatePath = "Packages/com.unity.render-pipelines.universal/Editor/Decal/DecalPass.template", | ||
|  |                 sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), | ||
|  | 
 | ||
|  |                 // Port mask | ||
|  |                 validPixelBlocks = DecalBlockMasks.FragmentWithoutEmessive, | ||
|  | 
 | ||
|  |                 //Fields | ||
|  |                 structs = CoreStructCollections.Default, | ||
|  |                 requiredFields = DecalRequiredFields.Mesh, | ||
|  |                 fieldDependencies = CoreFieldDependencies.Default, | ||
|  | 
 | ||
|  |                 // Conditional State | ||
|  |                 renderStates = DecalRenderStates.DBufferMesh, | ||
|  |                 pragmas = DecalPragmas.MultipleRenderTargets, | ||
|  |                 defines = DecalDefines.Mesh, | ||
|  |                 keywords = DecalKeywords.DBufferMesh, | ||
|  |                 includes = DecalIncludes.DBuffer, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static PassDescriptor ForwardEmissiveMesh = new PassDescriptor() | ||
|  |             { | ||
|  |                 // Definition | ||
|  |                 displayName = DecalShaderPassNames.DecalMeshForwardEmissive, | ||
|  |                 referenceName = "SHADERPASS_FORWARD_EMISSIVE_MESH", | ||
|  |                 lightMode = DecalShaderPassNames.DecalMeshForwardEmissive, | ||
|  |                 useInPreview = false, | ||
|  | 
 | ||
|  |                 // Template | ||
|  |                 passTemplatePath = "Packages/com.unity.render-pipelines.universal/Editor/Decal/DecalPass.template", | ||
|  |                 sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), | ||
|  | 
 | ||
|  |                 // Port mask | ||
|  |                 validPixelBlocks = DecalBlockMasks.Fragment, | ||
|  | 
 | ||
|  |                 //Fields | ||
|  |                 structs = CoreStructCollections.Default, | ||
|  |                 requiredFields = DecalRequiredFields.Mesh, | ||
|  |                 fieldDependencies = CoreFieldDependencies.Default, | ||
|  | 
 | ||
|  |                 // Conditional State | ||
|  |                 renderStates = DecalRenderStates.ForwardEmissiveMesh, | ||
|  |                 pragmas = DecalPragmas.MultipleRenderTargets, | ||
|  |                 defines = DecalDefines.MeshWithEmission, | ||
|  |                 keywords = DecalKeywords.ForwardEmissiveProjector, | ||
|  |                 includes = DecalIncludes.DBuffer, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static PassDescriptor ScreenSpaceMesh = GetScreenSpaceMesh(DecalPragmas.ScreenSpace, DecalKeywords.ScreenSpaceMesh); | ||
|  | 
 | ||
|  |             public static PassDescriptor GetScreenSpaceMesh(PragmaCollection pragma, KeywordCollection keywords) | ||
|  |             { | ||
|  |                 return new PassDescriptor | ||
|  |                 { | ||
|  |                     // Definition | ||
|  |                     displayName = DecalShaderPassNames.DecalScreenSpaceMesh, | ||
|  |                     referenceName = "SHADERPASS_DECAL_SCREEN_SPACE_MESH", | ||
|  |                     lightMode = DecalShaderPassNames.DecalScreenSpaceMesh, | ||
|  |                     useInPreview = true, | ||
|  | 
 | ||
|  |                     // Template | ||
|  |                     passTemplatePath = "Packages/com.unity.render-pipelines.universal/Editor/Decal/DecalPass.template", | ||
|  |                     sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), | ||
|  | 
 | ||
|  |                     // Port mask | ||
|  |                     validPixelBlocks = DecalBlockMasks.Fragment, // todo | ||
|  | 
 | ||
|  |                     //Fields | ||
|  |                     structs = CoreStructCollections.Default, | ||
|  |                     requiredFields = DecalRequiredFields.ScreenSpaceMesh, | ||
|  |                     fieldDependencies = CoreFieldDependencies.Default, | ||
|  | 
 | ||
|  |                     renderStates = DecalRenderStates.ScreenSpaceMesh, | ||
|  |                     pragmas = pragma, | ||
|  |                     defines = DecalDefines.MeshWithEmission, | ||
|  |                     keywords = keywords, | ||
|  |                     includes = DecalIncludes.ScreenSpace, | ||
|  |                 }; | ||
|  |             } | ||
|  | 
 | ||
|  |             public static PassDescriptor GBufferMesh = new PassDescriptor() | ||
|  |             { | ||
|  |                 // Definition | ||
|  |                 displayName = DecalShaderPassNames.DecalGBufferMesh, | ||
|  |                 referenceName = "SHADERPASS_DECAL_GBUFFER_MESH", | ||
|  |                 lightMode = DecalShaderPassNames.DecalGBufferMesh, | ||
|  |                 useInPreview = false, | ||
|  | 
 | ||
|  |                 // Template | ||
|  |                 passTemplatePath = "Packages/com.unity.render-pipelines.universal/Editor/Decal/DecalPass.template", | ||
|  |                 sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), | ||
|  | 
 | ||
|  |                 // Port mask | ||
|  |                 validPixelBlocks = DecalBlockMasks.Fragment, // todo | ||
|  | 
 | ||
|  |                 //Fields | ||
|  |                 structs = CoreStructCollections.Default, | ||
|  |                 requiredFields = DecalRequiredFields.ScreenSpaceMesh, | ||
|  |                 fieldDependencies = CoreFieldDependencies.Default, | ||
|  | 
 | ||
|  |                 renderStates = DecalRenderStates.GBufferMesh, | ||
|  |                 pragmas = DecalPragmas.GBuffer, | ||
|  |                 defines = DecalDefines.MeshWithEmission, | ||
|  |                 keywords = DecalKeywords.GBufferMesh, | ||
|  |                 includes = DecalIncludes.GBuffer, | ||
|  |             }; | ||
|  |         } | ||
|  |         #endregion | ||
|  | 
 | ||
|  |         #region PortMasks | ||
|  |         static class DecalBlockMasks | ||
|  |         { | ||
|  |             public static BlockFieldDescriptor[] FragmentWithoutEmessive = new BlockFieldDescriptor[] | ||
|  |             { | ||
|  |                 BlockFields.SurfaceDescription.BaseColor, | ||
|  |                 BlockFields.SurfaceDescription.Alpha, | ||
|  |                 BlockFields.SurfaceDescription.NormalTS, | ||
|  |                 UniversalBlockFields.SurfaceDescription.NormalAlpha, | ||
|  |                 BlockFields.SurfaceDescription.Metallic, | ||
|  |                 BlockFields.SurfaceDescription.Occlusion, | ||
|  |                 BlockFields.SurfaceDescription.Smoothness, | ||
|  |                 UniversalBlockFields.SurfaceDescription.MAOSAlpha, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static BlockFieldDescriptor[] ForwardOnlyEmissive = new BlockFieldDescriptor[] | ||
|  |             { | ||
|  |                 BlockFields.SurfaceDescription.Alpha, | ||
|  |                 BlockFields.SurfaceDescription.Emission, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static BlockFieldDescriptor[] Fragment = new BlockFieldDescriptor[] | ||
|  |             { | ||
|  |                 BlockFields.SurfaceDescription.BaseColor, | ||
|  |                 BlockFields.SurfaceDescription.Alpha, | ||
|  |                 BlockFields.SurfaceDescription.NormalTS, | ||
|  |                 UniversalBlockFields.SurfaceDescription.NormalAlpha, | ||
|  |                 BlockFields.SurfaceDescription.Metallic, | ||
|  |                 BlockFields.SurfaceDescription.Occlusion, | ||
|  |                 BlockFields.SurfaceDescription.Smoothness, | ||
|  | 
 | ||
|  |                 UniversalBlockFields.SurfaceDescription.MAOSAlpha, | ||
|  |                 BlockFields.SurfaceDescription.Emission, | ||
|  |             }; | ||
|  |         } | ||
|  |         #endregion | ||
|  | 
 | ||
|  |         #region RequiredFields | ||
|  |         static class DecalRequiredFields | ||
|  |         { | ||
|  |             public static FieldCollection Mesh = new FieldCollection() | ||
|  |             { | ||
|  |                 StructFields.Attributes.normalOS, | ||
|  |                 StructFields.Attributes.tangentOS, | ||
|  |                 StructFields.Attributes.uv1, | ||
|  |                 StructFields.Attributes.uv2, | ||
|  |                 StructFields.Varyings.normalWS, | ||
|  |                 StructFields.Varyings.tangentWS, | ||
|  |                 StructFields.Varyings.positionWS, | ||
|  |                 StructFields.Varyings.texCoord0, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static FieldCollection ScreenSpaceProjector = new FieldCollection() | ||
|  |             { | ||
|  |                 StructFields.Varyings.normalWS, | ||
|  |                 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 | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static FieldCollection GBufferProjector = new FieldCollection() | ||
|  |             { | ||
|  |                 StructFields.Varyings.normalWS, | ||
|  |                 UniversalStructFields.Varyings.staticLightmapUV, | ||
|  |                 UniversalStructFields.Varyings.dynamicLightmapUV, | ||
|  |                 UniversalStructFields.Varyings.sh, | ||
|  |                 UniversalStructFields.Varyings.probeOcclusion, | ||
|  |                 UniversalStructFields.Varyings.shadowCoord,             // shadow coord, vert input is dependency | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static FieldCollection ScreenSpaceMesh = new FieldCollection() | ||
|  |             { | ||
|  |                 StructFields.Attributes.normalOS, | ||
|  |                 StructFields.Attributes.tangentOS, | ||
|  |                 StructFields.Attributes.uv1, | ||
|  |                 StructFields.Attributes.uv2, | ||
|  |                 StructFields.Varyings.normalWS, | ||
|  |                 StructFields.Varyings.tangentWS, | ||
|  |                 StructFields.Varyings.positionWS, | ||
|  |                 StructFields.Varyings.texCoord0, | ||
|  |                 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 | ||
|  |             }; | ||
|  |         } | ||
|  |         #endregion | ||
|  | 
 | ||
|  |         #region ColorMask | ||
|  |         static class DecalColorMasks | ||
|  |         { | ||
|  |             public static RenderStateDescriptor ColorMaskRGBA0 = RenderState.ColorMask("ColorMask RGBA"); | ||
|  |             public static RenderStateDescriptor ColorMaskNone0 = RenderState.ColorMask("ColorMask 0"); | ||
|  |             public static RenderStateDescriptor ColorMaskRGBA1 = RenderState.ColorMask("ColorMask RGBA 1"); | ||
|  |             public static RenderStateDescriptor ColorMaskNone1 = RenderState.ColorMask("ColorMask 0 1"); | ||
|  |             public static RenderStateDescriptor ColorMaskRGBA2 = RenderState.ColorMask("ColorMask RGBA 2"); | ||
|  |             public static RenderStateDescriptor ColorMaskNone2 = RenderState.ColorMask("ColorMask 0 2"); | ||
|  |         } | ||
|  |         #endregion | ||
|  | 
 | ||
|  |         #region RenderStates | ||
|  |         static class DecalRenderStates | ||
|  |         { | ||
|  |             private readonly static string[] s_DBufferBlends = new string[] | ||
|  |             { | ||
|  |                 "Blend 0 SrcAlpha OneMinusSrcAlpha, Zero OneMinusSrcAlpha", | ||
|  |                 "Blend 1 SrcAlpha OneMinusSrcAlpha, Zero OneMinusSrcAlpha", | ||
|  |                 "Blend 2 SrcAlpha OneMinusSrcAlpha, Zero OneMinusSrcAlpha", | ||
|  |             }; | ||
|  |             private readonly static string[] s_GBufferBlends = new string[] | ||
|  |             { | ||
|  |                 "Blend 0 SrcAlpha OneMinusSrcAlpha", | ||
|  |                 "Blend 1 SrcAlpha OneMinusSrcAlpha", | ||
|  |                 "Blend 2 SrcAlpha OneMinusSrcAlpha", | ||
|  |                 "Blend 3 SrcAlpha OneMinusSrcAlpha", | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static RenderStateCollection ScenePicking = new RenderStateCollection | ||
|  |             { | ||
|  |                 { RenderState.Cull(Cull.Back) }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static RenderStateCollection DBufferProjector = new RenderStateCollection | ||
|  |             { | ||
|  |                 { RenderState.Blend(s_DBufferBlends[0]) }, | ||
|  |                 { RenderState.Blend(s_DBufferBlends[1]) }, | ||
|  |                 { RenderState.Blend(s_DBufferBlends[2]) }, | ||
|  |                 { RenderState.Cull(Cull.Front) }, | ||
|  |                 { RenderState.ZTest(ZTest.Greater) }, | ||
|  |                 { RenderState.ZWrite(ZWrite.Off) }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static RenderStateCollection ForwardEmissiveProjector = new RenderStateCollection | ||
|  |             { | ||
|  |                 { RenderState.Blend("Blend 0 SrcAlpha One") }, | ||
|  |                 { RenderState.Cull(Cull.Front) }, | ||
|  |                 { RenderState.ZTest(ZTest.Greater) }, | ||
|  |                 { RenderState.ZWrite(ZWrite.Off) }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static RenderStateCollection ScreenSpaceProjector = new RenderStateCollection | ||
|  |             { | ||
|  |                 { RenderState.Blend("Blend SrcAlpha OneMinusSrcAlpha") }, | ||
|  |                 { RenderState.Cull(Cull.Front) }, | ||
|  |                 { RenderState.ZTest(ZTest.Greater) }, | ||
|  |                 { RenderState.ZWrite(ZWrite.Off) }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static RenderStateCollection GBufferProjector = new RenderStateCollection | ||
|  |             { | ||
|  |                 { RenderState.Blend(s_GBufferBlends[0]) }, | ||
|  |                 { RenderState.Blend(s_GBufferBlends[1]) }, | ||
|  |                 { RenderState.Blend(s_GBufferBlends[2]) }, | ||
|  |                 { RenderState.Blend(s_GBufferBlends[3]) }, | ||
|  |                 { RenderState.Cull(Cull.Front) }, | ||
|  |                 { RenderState.ZTest(ZTest.Greater) }, | ||
|  |                 { RenderState.ZWrite(ZWrite.Off) }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static RenderStateCollection DBufferMesh = new RenderStateCollection | ||
|  |             { | ||
|  |                 { RenderState.Blend(s_DBufferBlends[0]) }, | ||
|  |                 { RenderState.Blend(s_DBufferBlends[1]) }, | ||
|  |                 { RenderState.Blend(s_DBufferBlends[2]) }, | ||
|  |                 { RenderState.ZTest(ZTest.LEqual) }, | ||
|  |                 { RenderState.ZWrite(ZWrite.Off) }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static RenderStateCollection ForwardEmissiveMesh = new RenderStateCollection | ||
|  |             { | ||
|  |                 { RenderState.Blend("Blend 0 SrcAlpha One") }, | ||
|  |                 { RenderState.ZTest(ZTest.LEqual) }, | ||
|  |                 { RenderState.ZWrite(ZWrite.Off) }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static RenderStateCollection ScreenSpaceMesh = new RenderStateCollection | ||
|  |             { | ||
|  |                 { RenderState.Blend("Blend SrcAlpha OneMinusSrcAlpha") }, | ||
|  |                 { RenderState.ZTest(ZTest.LEqual) }, | ||
|  |                 { RenderState.ZWrite(ZWrite.Off) }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static RenderStateCollection GBufferMesh = new RenderStateCollection | ||
|  |             { | ||
|  |                 { RenderState.Blend(s_GBufferBlends[0]) }, | ||
|  |                 { RenderState.Blend(s_GBufferBlends[1]) }, | ||
|  |                 { RenderState.Blend(s_GBufferBlends[2]) }, | ||
|  |                 { RenderState.Blend(s_GBufferBlends[3]) }, | ||
|  |                 { RenderState.ZWrite(ZWrite.Off) }, | ||
|  |             }; | ||
|  |         } | ||
|  |         #endregion | ||
|  | 
 | ||
|  |         #region Pragmas | ||
|  |         static class DecalPragmas | ||
|  |         { | ||
|  |             public static PragmaCollection ScreenSpace = new PragmaCollection | ||
|  |             { | ||
|  |                 { Pragma.Target(ShaderModel.Target25) }, | ||
|  |                 { Pragma.Vertex("Vert") }, | ||
|  |                 { Pragma.Fragment("Frag") }, | ||
|  |                 { Pragma.MultiCompileInstancing }, | ||
|  |                 { Pragma.EditorSyncCompilation }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static PragmaCollection GBuffer = new PragmaCollection | ||
|  |             { | ||
|  |                 { Pragma.Target(ShaderModel.Target45) }, // MRT4 | ||
|  |                 { Pragma.ExcludeRenderers(new[] { Platform.GLES3, Platform.GLCore }) }, | ||
|  |                 { Pragma.Vertex("Vert") }, | ||
|  |                 { Pragma.Fragment("Frag") }, | ||
|  |                 { Pragma.MultiCompileInstancing }, | ||
|  |                 { Pragma.EditorSyncCompilation }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static PragmaCollection MultipleRenderTargets = new PragmaCollection | ||
|  |             { | ||
|  |                 { Pragma.Target(ShaderModel.Target45) }, // MRT4 | ||
|  |                 { Pragma.ExcludeRenderers(new[] { Platform.GLES3, Platform.GLCore }) }, | ||
|  |                 { Pragma.Vertex("Vert") }, | ||
|  |                 { Pragma.Fragment("Frag") }, | ||
|  |                 { Pragma.MultiCompileInstancing }, | ||
|  |                 { Pragma.EditorSyncCompilation }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static readonly PragmaCollection Instanced = new PragmaCollection | ||
|  |             { | ||
|  |                 { Pragma.Target(ShaderModel.Target20) }, | ||
|  |                 { Pragma.MultiCompileInstancing }, | ||
|  |                 { Pragma.EditorSyncCompilation }, | ||
|  |                 { Pragma.Vertex("Vert") }, | ||
|  |                 { Pragma.Fragment("Frag") }, | ||
|  |             }; | ||
|  |         } | ||
|  |         #endregion | ||
|  | 
 | ||
|  |         #region Defines | ||
|  |         static class DecalDefines | ||
|  |         { | ||
|  |             private static class Descriptors | ||
|  |             { | ||
|  |                 public static KeywordDescriptor AffectsAlbedo = new KeywordDescriptor() | ||
|  |                 { | ||
|  |                     displayName = "Affects Albedo", | ||
|  |                     referenceName = "_MATERIAL_AFFECTS_ALBEDO", | ||
|  |                     type = KeywordType.Boolean, | ||
|  |                 }; | ||
|  | 
 | ||
|  |                 public static KeywordDescriptor AffectsNormal = new KeywordDescriptor() | ||
|  |                 { | ||
|  |                     displayName = "Affects Normal", | ||
|  |                     referenceName = "_MATERIAL_AFFECTS_NORMAL", | ||
|  |                     type = KeywordType.Boolean, | ||
|  |                 }; | ||
|  | 
 | ||
|  |                 public static KeywordDescriptor AffectsNormalBlend = new KeywordDescriptor() | ||
|  |                 { | ||
|  |                     displayName = "Affects Normal Blend", | ||
|  |                     referenceName = "_MATERIAL_AFFECTS_NORMAL_BLEND", | ||
|  |                     type = KeywordType.Boolean, | ||
|  |                 }; | ||
|  | 
 | ||
|  |                 public static KeywordDescriptor AffectsMAOS = new KeywordDescriptor() | ||
|  |                 { | ||
|  |                     displayName = "Affects Metal", | ||
|  |                     referenceName = "_MATERIAL_AFFECTS_MAOS", | ||
|  |                     type = KeywordType.Boolean, | ||
|  |                 }; | ||
|  | 
 | ||
|  |                 public static KeywordDescriptor AffectsEmission = new KeywordDescriptor() | ||
|  |                 { | ||
|  |                     displayName = "Affects Emission", | ||
|  |                     referenceName = "_MATERIAL_AFFECTS_EMISSION", | ||
|  |                     type = KeywordType.Boolean, | ||
|  |                 }; | ||
|  | 
 | ||
|  |                 public static KeywordDescriptor AngleFade = new KeywordDescriptor() | ||
|  |                 { | ||
|  |                     displayName = "Angle Fade", | ||
|  |                     referenceName = "DECAL_ANGLE_FADE", | ||
|  |                     type = KeywordType.Boolean, | ||
|  |                 }; | ||
|  | 
 | ||
|  |                 public static KeywordDescriptor ScenePickingPass = new KeywordDescriptor() | ||
|  |                 { | ||
|  |                     displayName = "Scene Picking Pass", | ||
|  |                     referenceName = "SCENEPICKINGPASS", | ||
|  |                     type = KeywordType.Boolean, | ||
|  |                 }; | ||
|  |             } | ||
|  | 
 | ||
|  |             public static DefineCollection Projector = new DefineCollection | ||
|  |             { | ||
|  |                 { Descriptors.AffectsAlbedo, 1, new FieldCondition(AffectsAlbedo, true) }, | ||
|  |                 { Descriptors.AffectsNormal, 1, new FieldCondition(AffectsNormal, true) }, | ||
|  |                 { Descriptors.AffectsNormalBlend, 1, new FieldCondition(AffectsNormalBlend, true) }, | ||
|  |                 { Descriptors.AffectsMAOS, 1, new FieldCondition(AffectsMAOS, true) }, | ||
|  |                 { Descriptors.AngleFade, 1, new FieldCondition(AngleFade, true) } | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static DefineCollection ProjectorEmission = new DefineCollection | ||
|  |             { | ||
|  |                 { Descriptors.AngleFade, 1, new FieldCondition(AngleFade, true) }, | ||
|  |                 { Descriptors.AffectsEmission, 1, new FieldCondition(AffectsEmission, true) }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static DefineCollection ProjectorWithEmission = new DefineCollection | ||
|  |             { | ||
|  |                 { Projector }, | ||
|  |                 { Descriptors.AffectsEmission, 1, new FieldCondition(AffectsEmission, true) }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static DefineCollection Mesh = new DefineCollection | ||
|  |             { | ||
|  |                 { Descriptors.AffectsAlbedo, 1, new FieldCondition(AffectsAlbedo, true) }, | ||
|  |                 { Descriptors.AffectsNormal, 1, new FieldCondition(AffectsNormal, true) }, | ||
|  |                 { Descriptors.AffectsNormalBlend, 1, new FieldCondition(AffectsNormalBlend, true) }, | ||
|  |                 { Descriptors.AffectsMAOS, 1, new FieldCondition(AffectsMAOS, true) }, | ||
|  |                 { CoreKeywordDescriptors.UseUnityCrossFade, 1, new FieldCondition(Fields.LodCrossFade, true) } | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static DefineCollection MeshEmission = new DefineCollection | ||
|  |             { | ||
|  |                 { Descriptors.AffectsEmission, 1, new FieldCondition(AffectsEmission, true) }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static DefineCollection MeshWithEmission = new DefineCollection | ||
|  |             { | ||
|  |                 { Mesh }, | ||
|  |                 { Descriptors.AffectsEmission, 1, new FieldCondition(AffectsEmission, true) }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static DefineCollection ScenePicking = new DefineCollection { { Descriptors.ScenePickingPass, 1 }, }; | ||
|  |         } | ||
|  |         #endregion | ||
|  | 
 | ||
|  |         #region Keywords | ||
|  |         static class DecalKeywords | ||
|  |         { | ||
|  |             static class Descriptors | ||
|  |             { | ||
|  |                 public static KeywordDescriptor DecalsNormalBlend = new KeywordDescriptor() | ||
|  |                 { | ||
|  |                     displayName = "Decal Normal Blend", | ||
|  |                     referenceName = "_DECAL_NORMAL_BLEND", | ||
|  |                     type = KeywordType.Enum, | ||
|  |                     definition = KeywordDefinition.MultiCompile, | ||
|  |                     scope = KeywordScope.Global, | ||
|  |                     entries = new KeywordEntry[] | ||
|  |                     { | ||
|  |                         new KeywordEntry() { displayName = "LOW", referenceName = "LOW" }, | ||
|  |                         new KeywordEntry() { displayName = "MEDIUM", referenceName = "MEDIUM" }, | ||
|  |                         new KeywordEntry() { displayName = "HIGH", referenceName = "HIGH" }, | ||
|  |                     } | ||
|  |                 }; | ||
|  | 
 | ||
|  |                 public static readonly KeywordDescriptor DecalLayers = new KeywordDescriptor() | ||
|  |                 { | ||
|  |                     displayName = "Decal Layers", | ||
|  |                     referenceName = "_DECAL_LAYERS", | ||
|  |                     type = KeywordType.Boolean, | ||
|  |                     definition = KeywordDefinition.MultiCompile, | ||
|  |                     scope = KeywordScope.Global, | ||
|  |                 }; | ||
|  |             } | ||
|  | 
 | ||
|  |             public static KeywordCollection DBufferMesh = new KeywordCollection | ||
|  |             { | ||
|  |                 { CoreKeywordDescriptors.DBuffer }, | ||
|  |                 { CoreKeywordDescriptors.LODFadeCrossFade, new FieldCondition(Fields.LodCrossFade, true) }, | ||
|  |                 { Descriptors.DecalLayers }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static KeywordCollection DBufferProjector = new KeywordCollection | ||
|  |             { | ||
|  |                 { CoreKeywordDescriptors.DBuffer }, | ||
|  |                 { Descriptors.DecalLayers }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static KeywordCollection ForwardEmissiveProjector = new KeywordCollection | ||
|  |             { | ||
|  |                 { Descriptors.DecalLayers }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static readonly KeywordCollection ScreenSpaceMeshGl = new KeywordCollection | ||
|  |             { | ||
|  |                 { CoreKeywordDescriptors.StaticLightmap }, | ||
|  |                 { CoreKeywordDescriptors.DynamicLightmap }, | ||
|  |                 { CoreKeywordDescriptors.DirectionalLightmapCombined }, | ||
|  |                 { CoreKeywordDescriptors.UseLegacyLightmaps }, | ||
|  |                 { CoreKeywordDescriptors.LightmapBicubicSampling }, | ||
|  |                 { CoreKeywordDescriptors.MainLightShadows }, | ||
|  |                 { CoreKeywordDescriptors.AdditionalLights }, | ||
|  |                 { CoreKeywordDescriptors.AdditionalLightShadows }, | ||
|  |                 { CoreKeywordDescriptors.ShadowsSoft }, | ||
|  |                 { CoreKeywordDescriptors.LightmapShadowMixing }, | ||
|  |                 { CoreKeywordDescriptors.ShadowsShadowmask }, | ||
|  |                 { CoreKeywordDescriptors.ClusterLightLoop }, | ||
|  |                 { Descriptors.DecalsNormalBlend }, | ||
|  |                 { CoreKeywordDescriptors.LODFadeCrossFade, new FieldCondition(Fields.LodCrossFade, true) }, | ||
|  |                 { CoreKeywordDescriptors.DebugDisplay }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static readonly KeywordCollection ScreenSpaceMesh = new KeywordCollection | ||
|  |             { | ||
|  |                 { ScreenSpaceMeshGl }, | ||
|  |                 { Descriptors.DecalLayers }, | ||
|  | 
 | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static readonly KeywordCollection ScreenSpaceProjector = new KeywordCollection | ||
|  |             { | ||
|  |                 { CoreKeywordDescriptors.MainLightShadows }, | ||
|  |                 { CoreKeywordDescriptors.AdditionalLights }, | ||
|  |                 { CoreKeywordDescriptors.AdditionalLightShadows }, | ||
|  |                 { CoreKeywordDescriptors.ShadowsSoft }, | ||
|  |                 { CoreKeywordDescriptors.ClusterLightLoop }, | ||
|  |                 { CoreKeywordDescriptors.LightCookies }, | ||
|  |                 { CoreKeywordDescriptors.DebugDisplay }, | ||
|  |                 { Descriptors.DecalsNormalBlend }, | ||
|  |                 { Descriptors.DecalLayers }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static readonly KeywordCollection GBufferMesh = new KeywordCollection | ||
|  |             { | ||
|  |                 { CoreKeywordDescriptors.StaticLightmap }, | ||
|  |                 { CoreKeywordDescriptors.DynamicLightmap }, | ||
|  |                 { CoreKeywordDescriptors.DirectionalLightmapCombined }, | ||
|  |                 { CoreKeywordDescriptors.UseLegacyLightmaps }, | ||
|  |                 { CoreKeywordDescriptors.LightmapBicubicSampling }, | ||
|  |                 { CoreKeywordDescriptors.MainLightShadows }, | ||
|  |                 { CoreKeywordDescriptors.ShadowsSoft }, | ||
|  |                 { CoreKeywordDescriptors.LightmapShadowMixing }, | ||
|  |                 { CoreKeywordDescriptors.MixedLightingSubtractive }, | ||
|  |                 { Descriptors.DecalsNormalBlend }, | ||
|  |                 { Descriptors.DecalLayers }, | ||
|  |                 { CoreKeywordDescriptors.GBufferNormalsOct }, | ||
|  |                 { CoreKeywordDescriptors.RenderPassEnabled }, | ||
|  |                 { CoreKeywordDescriptors.LODFadeCrossFade, new FieldCondition(Fields.LodCrossFade, true) }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static readonly KeywordCollection GBufferProjector = new KeywordCollection | ||
|  |             { | ||
|  |                 { CoreKeywordDescriptors.MainLightShadows }, | ||
|  |                 { CoreKeywordDescriptors.ShadowsSoft }, | ||
|  |                 { Descriptors.DecalsNormalBlend }, | ||
|  |                 { Descriptors.DecalLayers }, | ||
|  |                 { CoreKeywordDescriptors.GBufferNormalsOct }, | ||
|  |                 { CoreKeywordDescriptors.RenderPassEnabled }, | ||
|  |             }; | ||
|  |         } | ||
|  |         #endregion | ||
|  | 
 | ||
|  |         #region Includes | ||
|  |         static class DecalIncludes | ||
|  |         { | ||
|  |             const string kDecalInput = "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DecalInput.hlsl"; | ||
|  |             const string kShaderVariablesDecal = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderVariablesDecal.hlsl"; | ||
|  |             const string kPassDecal = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPassDecal.hlsl"; | ||
|  |             const string kShaderPass = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPass.hlsl"; | ||
|  |             const string kVaryings = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Varyings.hlsl"; | ||
|  |             const string kDBuffer = "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl"; | ||
|  |             const string kGBuffer = "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.hlsl"; | ||
|  |             const string kLODCrossFade = "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl"; | ||
|  | 
 | ||
|  |             public static IncludeCollection DecalPregraph = new IncludeCollection | ||
|  |             { | ||
|  |                 { kShaderPass, IncludeLocation.Pregraph }, | ||
|  |                 { kDecalInput, IncludeLocation.Pregraph }, | ||
|  |                 { kShaderVariablesDecal, IncludeLocation.Pregraph }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static IncludeCollection DecalPostgraph = new IncludeCollection | ||
|  |             { | ||
|  |                 { kVaryings, IncludeLocation.Postgraph }, | ||
|  |                 { kPassDecal, IncludeLocation.Postgraph }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static IncludeCollection DBuffer = new IncludeCollection | ||
|  |             { | ||
|  |                 // Pre-graph | ||
|  |                 { CoreIncludes.DOTSPregraph }, | ||
|  |                 { CoreIncludes.FogPregraph }, | ||
|  |                 { CoreIncludes.CorePregraph }, | ||
|  |                 { CoreIncludes.ShaderGraphPregraph }, | ||
|  |                 { CoreIncludes.ProbeVolumePregraph }, | ||
|  |                 { DecalPregraph }, | ||
|  |                 { kDBuffer, IncludeLocation.Pregraph }, | ||
|  |                 { kLODCrossFade, IncludeLocation.Pregraph, new FieldCondition(Fields.LodCrossFade, true) }, | ||
|  | 
 | ||
|  |                 // Post-graph | ||
|  |                 { DecalPostgraph }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static IncludeCollection ScreenSpace = new IncludeCollection | ||
|  |             { | ||
|  |                 // Pre-graph | ||
|  |                 { CoreIncludes.DOTSPregraph }, | ||
|  |                 { CoreIncludes.FogPregraph }, | ||
|  |                 { CoreIncludes.CorePregraph }, | ||
|  |                 { CoreIncludes.ShaderGraphPregraph }, | ||
|  |                 { CoreIncludes.ProbeVolumePregraph }, | ||
|  |                 { DecalPregraph }, | ||
|  |                 { kLODCrossFade, IncludeLocation.Pregraph, new FieldCondition(Fields.LodCrossFade, true) }, | ||
|  | 
 | ||
|  |                 // Post-graph | ||
|  |                 { DecalPostgraph }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static IncludeCollection GBuffer = new IncludeCollection | ||
|  |             { | ||
|  |                 // Pre-graph | ||
|  |                 { CoreIncludes.DOTSPregraph }, | ||
|  |                 { CoreIncludes.FogPregraph }, | ||
|  |                 { CoreIncludes.CorePregraph }, | ||
|  |                 { CoreIncludes.ShaderGraphPregraph }, | ||
|  |                 { CoreIncludes.ProbeVolumePregraph }, | ||
|  |                 { kGBuffer, IncludeLocation.Pregraph }, | ||
|  |                 { DecalPregraph }, | ||
|  |                 { kLODCrossFade, IncludeLocation.Pregraph, new FieldCondition(Fields.LodCrossFade, true) }, | ||
|  | 
 | ||
|  |                 // Post-graph | ||
|  |                 { DecalPostgraph }, | ||
|  |             }; | ||
|  | 
 | ||
|  |             public static IncludeCollection ScenePicking = new IncludeCollection | ||
|  |             { | ||
|  |                 // Pre-graph | ||
|  |                 { CoreIncludes.CorePregraph }, | ||
|  |                 { CoreIncludes.ShaderGraphPregraph }, | ||
|  |                 { DecalPregraph }, | ||
|  | 
 | ||
|  |                 // Post-graph | ||
|  |                 { DecalPostgraph }, | ||
|  |             }; | ||
|  |         } | ||
|  |         #endregion | ||
|  |     } | ||
|  | } |