123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350 |
- using System;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEditor.ShaderGraph;
- using UnityEditor.ShaderGraph.Legacy;
- using static UnityEditor.Rendering.Universal.ShaderGraph.SubShaderUtils;
- using static Unity.Rendering.Universal.ShaderUtils;
- namespace UnityEditor.Rendering.Universal.ShaderGraph
- {
- sealed class UniversalUnlitSubTarget : UniversalSubTarget, ILegacyTarget
- {
- static readonly GUID kSourceCodeGuid = new GUID("97c3f7dcb477ec842aa878573640313a"); // UniversalUnlitSubTarget.cs
- public UniversalUnlitSubTarget()
- {
- displayName = "Unlit";
- }
- protected override ShaderID shaderID => ShaderID.SG_Unlit;
- public override bool IsActive() => true;
- 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(ShaderGraphUnlitGUI);
- #if HAS_VFX_GRAPH
- if (TargetsVFX())
- gui = typeof(VFXShaderGraphUnlitGUI);
- #endif
- context.AddCustomEditorForRenderPipeline(gui.FullName, universalRPType);
- }
- // Process SubShaders
- context.AddSubShader(PostProcessSubShader(SubShaders.UnlitDOTS(target, target.renderType, target.renderQueue)));
- context.AddSubShader(PostProcessSubShader(SubShaders.Unlit(target, target.renderType, target.renderQueue)));
- }
- 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.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.CastShadows, target.castShadows ? 1.0f : 0.0f);
- material.SetFloat(Property.ZWriteControl, (float)target.zWriteControl);
- material.SetFloat(Property.ZTest, (float)target.zTestMode);
- }
- // 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
- ShaderGraphUnlitGUI.UpdateMaterial(material, MaterialUpdateType.CreatedNewMaterial);
- }
- public override void GetFields(ref TargetFieldContext context)
- {
- base.GetFields(ref context);
- }
- public override void GetActiveBlocks(ref TargetActiveBlockContext context)
- {
- 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 (target.allowMaterialOverride)
- {
- collector.AddFloatProperty(Property.CastShadows, target.castShadows ? 1.0f : 0.0f);
- 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
- collector.AddFloatProperty(Property.DstBlend, 0.0f); // always set by material inspector
- 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
- }
- // 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: false);
- }
- public bool TryUpgradeFromMasterNode(IMasterNode1 masterNode, out Dictionary<BlockFieldDescriptor, int> blockMap)
- {
- blockMap = null;
- if (!(masterNode is UnlitMasterNode1 unlitMasterNode))
- return false;
- // Set blockmap
- blockMap = new Dictionary<BlockFieldDescriptor, int>()
- {
- { BlockFields.VertexDescription.Position, 9 },
- { BlockFields.VertexDescription.Normal, 10 },
- { BlockFields.VertexDescription.Tangent, 11 },
- { BlockFields.SurfaceDescription.BaseColor, 0 },
- { BlockFields.SurfaceDescription.Alpha, 7 },
- { BlockFields.SurfaceDescription.AlphaClipThreshold, 8 },
- };
- return true;
- }
- #region SubShader
- static class SubShaders
- {
- public static SubShaderDescriptor Unlit(UniversalTarget target, string renderType, string renderQueue)
- {
- var result = new SubShaderDescriptor()
- {
- pipelineTag = UniversalTarget.kPipelineTag,
- customTags = UniversalTarget.kUnlitMaterialTypeTag,
- renderType = renderType,
- renderQueue = renderQueue,
- generatesPreview = true,
- passes = new PassCollection()
- };
- result.passes.Add(UnlitPasses.Forward(target));
- if (target.mayWriteDepth)
- result.passes.Add(CorePasses.DepthOnly(target));
- result.passes.Add(CorePasses.DepthNormalOnly(target));
- if (target.castShadows || target.allowMaterialOverride)
- result.passes.Add(CorePasses.ShadowCaster(target));
- // 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(CorePasses.SceneSelection(target));
- result.passes.Add(CorePasses.ScenePicking(target));
- result.passes.Add(UnlitPasses.DepthNormalOnly(target));
- result.passes.Add(CorePasses.MotionVectors(target));
- return result;
- }
- public static SubShaderDescriptor UnlitDOTS(UniversalTarget target, string renderType, string renderQueue)
- {
- var result = new SubShaderDescriptor()
- {
- pipelineTag = UniversalTarget.kPipelineTag,
- customTags = UniversalTarget.kUnlitMaterialTypeTag,
- renderType = renderType,
- renderQueue = renderQueue,
- generatesPreview = true,
- passes = new PassCollection()
- };
- result.passes.Add(PassVariant(UnlitPasses.Forward(target), CorePragmas.DOTSForward));
- if (target.mayWriteDepth)
- result.passes.Add(PassVariant(CorePasses.DepthOnly(target), CorePragmas.DOTSInstanced));
- result.passes.Add(PassVariant(CorePasses.DepthNormalOnly(target), CorePragmas.DOTSInstanced));
- if (target.castShadows || target.allowMaterialOverride)
- result.passes.Add(PassVariant(CorePasses.ShadowCaster(target), CorePragmas.DOTSInstanced));
- // 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.DOTSDefault));
- result.passes.Add(PassVariant(CorePasses.ScenePicking(target), CorePragmas.DOTSDefault));
- result.passes.Add(PassVariant(UnlitPasses.DepthNormalOnly(target), CorePragmas.DOTSInstanced));
- return result;
- }
- }
- #endregion
- #region Pass
- static class UnlitPasses
- {
- public static PassDescriptor Forward(UniversalTarget target)
- {
- var result = new PassDescriptor
- {
- // Definition
- displayName = "Universal Forward",
- referenceName = "SHADERPASS_UNLIT",
- useInPreview = true,
- // Template
- passTemplatePath = UniversalTarget.kUberTemplatePath,
- sharedTemplateDirectories = UniversalTarget.kSharedTemplateDirectories,
- // Port Mask
- validVertexBlocks = CoreBlockMasks.Vertex,
- validPixelBlocks = CoreBlockMasks.FragmentColorAlpha,
- // Fields
- structs = CoreStructCollections.Default,
- requiredFields = UnlitRequiredFields.Unlit,
- fieldDependencies = CoreFieldDependencies.Default,
- // Conditional State
- renderStates = CoreRenderStates.UberSwitchedRenderState(target),
- pragmas = CorePragmas.Forward,
- defines = new DefineCollection() { CoreDefines.UseFragmentFog },
- keywords = new KeywordCollection() { UnlitKeywords.UnlitBaseKeywords },
- includes = UnlitIncludes.Unlit,
- // Custom Interpolator Support
- customInterpolators = CoreCustomInterpDescriptors.Common
- };
- CorePasses.AddTargetSurfaceControlsToPass(ref result, target);
- return result;
- }
- public static PassDescriptor DepthNormalOnly(UniversalTarget target)
- {
- var result = new PassDescriptor
- {
- // Definition
- displayName = "DepthNormals",
- referenceName = "SHADERPASS_DEPTHNORMALSONLY",
- lightMode = "DepthNormalsOnly",
- useInPreview = false,
- // Template
- passTemplatePath = UniversalTarget.kUberTemplatePath,
- sharedTemplateDirectories = UniversalTarget.kSharedTemplateDirectories,
- // Port Mask
- validVertexBlocks = CoreBlockMasks.Vertex,
- validPixelBlocks = UnlitBlockMasks.FragmentDepthNormals,
- // Fields
- structs = CoreStructCollections.Default,
- requiredFields = UnlitRequiredFields.DepthNormalsOnly,
- fieldDependencies = CoreFieldDependencies.Default,
- // Conditional State
- renderStates = CoreRenderStates.DepthNormalsOnly(target),
- pragmas = CorePragmas.Forward,
- defines = new DefineCollection(),
- keywords = new KeywordCollection(),
- includes = CoreIncludes.DepthNormalsOnly,
- // Custom Interpolator Support
- customInterpolators = CoreCustomInterpDescriptors.Common
- };
- CorePasses.AddTargetSurfaceControlsToPass(ref result, target);
- return result;
- }
- #region PortMasks
- static class UnlitBlockMasks
- {
- public static readonly BlockFieldDescriptor[] FragmentDepthNormals = new BlockFieldDescriptor[]
- {
- BlockFields.SurfaceDescription.NormalWS,
- BlockFields.SurfaceDescription.Alpha,
- BlockFields.SurfaceDescription.AlphaClipThreshold,
- };
- }
- #endregion
- #region RequiredFields
- static class UnlitRequiredFields
- {
- public static readonly FieldCollection Unlit = new FieldCollection()
- {
- StructFields.Varyings.positionWS,
- StructFields.Varyings.normalWS,
- StructFields.Varyings.viewDirectionWS,
- };
- public static readonly FieldCollection DepthNormalsOnly = new FieldCollection()
- {
- StructFields.Varyings.normalWS,
- };
- }
- #endregion
- }
- #endregion
- #region Keywords
- static class UnlitKeywords
- {
- public static readonly KeywordCollection UnlitBaseKeywords = new KeywordCollection()
- {
- // This contain lightmaps because without a proper custom lighting solution in Shadergraph,
- // people start with the unlit then add lightmapping nodes to it.
- // If we removed lightmaps from the unlit target this would ruin a lot of peoples days.
- CoreKeywordDescriptors.StaticLightmap,
- CoreKeywordDescriptors.DirectionalLightmapCombined,
- CoreKeywordDescriptors.SampleGI,
- CoreKeywordDescriptors.DBuffer,
- CoreKeywordDescriptors.DebugDisplay,
- };
- }
- #endregion
- #region Includes
- static class UnlitIncludes
- {
- const string kUnlitPass = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/UnlitPass.hlsl";
- public static IncludeCollection Unlit = new IncludeCollection
- {
- // Pre-graph
- { CoreIncludes.CorePregraph },
- { CoreIncludes.ShaderGraphPregraph },
- { CoreIncludes.DBufferPregraph },
- // Post-graph
- { CoreIncludes.CorePostgraph },
- { kUnlitPass, IncludeLocation.Postgraph },
- };
- }
- #endregion
- }
- }
|