No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

UniversalLitSubTarget.cs 44KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946
  1. using System;
  2. using System.Linq;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using UnityEditor.ShaderGraph;
  6. using UnityEditor.UIElements;
  7. using UnityEngine.UIElements;
  8. using UnityEditor.ShaderGraph.Legacy;
  9. using UnityEngine.Assertions;
  10. using static UnityEditor.Rendering.Universal.ShaderGraph.SubShaderUtils;
  11. using UnityEngine.Rendering.Universal;
  12. using static Unity.Rendering.Universal.ShaderUtils;
  13. namespace UnityEditor.Rendering.Universal.ShaderGraph
  14. {
  15. sealed class UniversalLitSubTarget : UniversalSubTarget, ILegacyTarget
  16. {
  17. static readonly GUID kSourceCodeGuid = new GUID("d6c78107b64145745805d963de80cc17"); // UniversalLitSubTarget.cs
  18. public override int latestVersion => 2;
  19. [SerializeField]
  20. WorkflowMode m_WorkflowMode = WorkflowMode.Metallic;
  21. [SerializeField]
  22. NormalDropOffSpace m_NormalDropOffSpace = NormalDropOffSpace.Tangent;
  23. [SerializeField]
  24. bool m_ClearCoat = false;
  25. [SerializeField]
  26. bool m_BlendModePreserveSpecular = true;
  27. public UniversalLitSubTarget()
  28. {
  29. displayName = "Lit";
  30. }
  31. protected override ShaderID shaderID => ShaderID.SG_Lit;
  32. public WorkflowMode workflowMode
  33. {
  34. get => m_WorkflowMode;
  35. set => m_WorkflowMode = value;
  36. }
  37. public NormalDropOffSpace normalDropOffSpace
  38. {
  39. get => m_NormalDropOffSpace;
  40. set => m_NormalDropOffSpace = value;
  41. }
  42. public bool clearCoat
  43. {
  44. get => m_ClearCoat;
  45. set => m_ClearCoat = value;
  46. }
  47. private bool complexLit
  48. {
  49. get
  50. {
  51. // Rules for switching to ComplexLit with forward only pass
  52. return clearCoat; // && <complex feature>
  53. }
  54. }
  55. public bool blendModePreserveSpecular
  56. {
  57. get => m_BlendModePreserveSpecular;
  58. set => m_BlendModePreserveSpecular = value;
  59. }
  60. public override bool IsActive() => true;
  61. public override void Setup(ref TargetSetupContext context)
  62. {
  63. context.AddAssetDependency(kSourceCodeGuid, AssetCollection.Flags.SourceDependency);
  64. base.Setup(ref context);
  65. var universalRPType = typeof(UnityEngine.Rendering.Universal.UniversalRenderPipelineAsset);
  66. if (!context.HasCustomEditorForRenderPipeline(universalRPType))
  67. {
  68. var gui = typeof(ShaderGraphLitGUI);
  69. #if HAS_VFX_GRAPH
  70. if (TargetsVFX())
  71. gui = typeof(VFXShaderGraphLitGUI);
  72. #endif
  73. context.AddCustomEditorForRenderPipeline(gui.FullName, universalRPType);
  74. }
  75. // Process SubShaders
  76. context.AddSubShader(PostProcessSubShader(SubShaders.LitSubShader(target, workflowMode, target.renderType, target.renderQueue, target.disableBatching, complexLit, blendModePreserveSpecular)));
  77. }
  78. public override void ProcessPreviewMaterial(Material material)
  79. {
  80. if (target.allowMaterialOverride)
  81. {
  82. // copy our target's default settings into the material
  83. // (technically not necessary since we are always recreating the material from the shader each time,
  84. // which will pull over the defaults from the shader definition)
  85. // but if that ever changes, this will ensure the defaults are set
  86. material.SetFloat(Property.SpecularWorkflowMode, (float)workflowMode);
  87. material.SetFloat(Property.CastShadows, target.castShadows ? 1.0f : 0.0f);
  88. material.SetFloat(Property.ReceiveShadows, target.receiveShadows ? 1.0f : 0.0f);
  89. material.SetFloat(Property.SurfaceType, (float)target.surfaceType);
  90. material.SetFloat(Property.BlendMode, (float)target.alphaMode);
  91. material.SetFloat(Property.AlphaClip, target.alphaClip ? 1.0f : 0.0f);
  92. material.SetFloat(Property.CullMode, (int)target.renderFace);
  93. material.SetFloat(Property.ZWriteControl, (float)target.zWriteControl);
  94. material.SetFloat(Property.ZTest, (float)target.zTestMode);
  95. }
  96. // We always need these properties regardless of whether the material is allowed to override
  97. // Queue control & offset enable correct automatic render queue behavior
  98. // Control == 0 is automatic, 1 is user-specified render queue
  99. material.SetFloat(Property.QueueOffset, 0.0f);
  100. material.SetFloat(Property.QueueControl, (float)BaseShaderGUI.QueueControl.Auto);
  101. // call the full unlit material setup function
  102. ShaderGraphLitGUI.UpdateMaterial(material, MaterialUpdateType.CreatedNewMaterial);
  103. }
  104. public override void GetFields(ref TargetFieldContext context)
  105. {
  106. base.GetFields(ref context);
  107. var descs = context.blocks.Select(x => x.descriptor);
  108. // Lit -- always controlled by subtarget
  109. context.AddField(UniversalFields.NormalDropOffOS, normalDropOffSpace == NormalDropOffSpace.Object);
  110. context.AddField(UniversalFields.NormalDropOffTS, normalDropOffSpace == NormalDropOffSpace.Tangent);
  111. context.AddField(UniversalFields.NormalDropOffWS, normalDropOffSpace == NormalDropOffSpace.World);
  112. context.AddField(UniversalFields.Normal, descs.Contains(BlockFields.SurfaceDescription.NormalOS) ||
  113. descs.Contains(BlockFields.SurfaceDescription.NormalTS) ||
  114. descs.Contains(BlockFields.SurfaceDescription.NormalWS));
  115. // Complex Lit
  116. // Template Predicates
  117. //context.AddField(UniversalFields.PredicateClearCoat, clearCoat);
  118. }
  119. public override void GetActiveBlocks(ref TargetActiveBlockContext context)
  120. {
  121. context.AddBlock(UniversalBlockFields.VertexDescription.MotionVector, target.additionalMotionVectorMode == AdditionalMotionVectorMode.Custom);
  122. context.AddBlock(BlockFields.SurfaceDescription.Smoothness);
  123. context.AddBlock(BlockFields.SurfaceDescription.NormalOS, normalDropOffSpace == NormalDropOffSpace.Object);
  124. context.AddBlock(BlockFields.SurfaceDescription.NormalTS, normalDropOffSpace == NormalDropOffSpace.Tangent);
  125. context.AddBlock(BlockFields.SurfaceDescription.NormalWS, normalDropOffSpace == NormalDropOffSpace.World);
  126. context.AddBlock(BlockFields.SurfaceDescription.Emission);
  127. context.AddBlock(BlockFields.SurfaceDescription.Occlusion);
  128. // when the surface options are material controlled, we must show all of these blocks
  129. // when target controlled, we can cull the unnecessary blocks
  130. context.AddBlock(BlockFields.SurfaceDescription.Specular, (workflowMode == WorkflowMode.Specular) || target.allowMaterialOverride);
  131. context.AddBlock(BlockFields.SurfaceDescription.Metallic, (workflowMode == WorkflowMode.Metallic) || target.allowMaterialOverride);
  132. context.AddBlock(BlockFields.SurfaceDescription.Alpha, (target.surfaceType == SurfaceType.Transparent || target.alphaClip) || target.allowMaterialOverride);
  133. context.AddBlock(BlockFields.SurfaceDescription.AlphaClipThreshold, (target.alphaClip) || target.allowMaterialOverride);
  134. // always controlled by subtarget clearCoat checkbox (no Material control)
  135. context.AddBlock(BlockFields.SurfaceDescription.CoatMask, clearCoat);
  136. context.AddBlock(BlockFields.SurfaceDescription.CoatSmoothness, clearCoat);
  137. }
  138. public override void CollectShaderProperties(PropertyCollector collector, GenerationMode generationMode)
  139. {
  140. // if using material control, add the material property to control workflow mode
  141. if (target.allowMaterialOverride)
  142. {
  143. collector.AddFloatProperty(Property.SpecularWorkflowMode, (float)workflowMode);
  144. collector.AddFloatProperty(Property.CastShadows, target.castShadows ? 1.0f : 0.0f);
  145. collector.AddFloatProperty(Property.ReceiveShadows, target.receiveShadows ? 1.0f : 0.0f);
  146. // setup properties using the defaults
  147. collector.AddFloatProperty(Property.SurfaceType, (float)target.surfaceType);
  148. collector.AddFloatProperty(Property.BlendMode, (float)target.alphaMode);
  149. collector.AddFloatProperty(Property.AlphaClip, target.alphaClip ? 1.0f : 0.0f);
  150. collector.AddFloatProperty(Property.BlendModePreserveSpecular, blendModePreserveSpecular ? 1.0f : 0.0f);
  151. collector.AddFloatProperty(Property.SrcBlend, 1.0f); // always set by material inspector, ok to have incorrect values here
  152. collector.AddFloatProperty(Property.DstBlend, 0.0f); // always set by material inspector, ok to have incorrect values here
  153. collector.AddToggleProperty(Property.ZWrite, (target.surfaceType == SurfaceType.Opaque));
  154. collector.AddFloatProperty(Property.ZWriteControl, (float)target.zWriteControl);
  155. collector.AddFloatProperty(Property.ZTest, (float)target.zTestMode); // ztest mode is designed to directly pass as ztest
  156. collector.AddFloatProperty(Property.CullMode, (float)target.renderFace); // render face enum is designed to directly pass as a cull mode
  157. bool enableAlphaToMask = (target.alphaClip && (target.surfaceType == SurfaceType.Opaque));
  158. collector.AddFloatProperty(Property.AlphaToMask, enableAlphaToMask ? 1.0f : 0.0f);
  159. }
  160. // We always need these properties regardless of whether the material is allowed to override other shader properties.
  161. // Queue control & offset enable correct automatic render queue behavior. Control == 0 is automatic, 1 is user-specified.
  162. // We initialize queue control to -1 to indicate to UpdateMaterial that it needs to initialize it properly on the material.
  163. collector.AddFloatProperty(Property.QueueOffset, 0.0f);
  164. collector.AddFloatProperty(Property.QueueControl, -1.0f);
  165. }
  166. public override void GetPropertiesGUI(ref TargetPropertyGUIContext context, Action onChange, Action<String> registerUndo)
  167. {
  168. var universalTarget = (target as UniversalTarget);
  169. universalTarget.AddDefaultMaterialOverrideGUI(ref context, onChange, registerUndo);
  170. context.AddProperty("Workflow Mode", new EnumField(WorkflowMode.Metallic) { value = workflowMode }, (evt) =>
  171. {
  172. if (Equals(workflowMode, evt.newValue))
  173. return;
  174. registerUndo("Change Workflow");
  175. workflowMode = (WorkflowMode)evt.newValue;
  176. onChange();
  177. });
  178. universalTarget.AddDefaultSurfacePropertiesGUI(ref context, onChange, registerUndo, showReceiveShadows: true);
  179. context.AddProperty("Fragment Normal Space", new EnumField(NormalDropOffSpace.Tangent) { value = normalDropOffSpace }, (evt) =>
  180. {
  181. if (Equals(normalDropOffSpace, evt.newValue))
  182. return;
  183. registerUndo("Change Fragment Normal Space");
  184. normalDropOffSpace = (NormalDropOffSpace)evt.newValue;
  185. onChange();
  186. });
  187. context.AddProperty("Clear Coat", new Toggle() { value = clearCoat }, (evt) =>
  188. {
  189. if (Equals(clearCoat, evt.newValue))
  190. return;
  191. registerUndo("Change Clear Coat");
  192. clearCoat = evt.newValue;
  193. onChange();
  194. });
  195. if (target.surfaceType == SurfaceType.Transparent)
  196. {
  197. if (target.alphaMode == AlphaMode.Alpha || target.alphaMode == AlphaMode.Additive)
  198. context.AddProperty("Preserve Specular Lighting", new Toggle() { value = blendModePreserveSpecular }, (evt) =>
  199. {
  200. if (Equals(blendModePreserveSpecular, evt.newValue))
  201. return;
  202. registerUndo("Change Preserve Specular");
  203. blendModePreserveSpecular = evt.newValue;
  204. onChange();
  205. });
  206. }
  207. }
  208. protected override int ComputeMaterialNeedsUpdateHash()
  209. {
  210. int hash = base.ComputeMaterialNeedsUpdateHash();
  211. hash = hash * 23 + target.allowMaterialOverride.GetHashCode();
  212. return hash;
  213. }
  214. public bool TryUpgradeFromMasterNode(IMasterNode1 masterNode, out Dictionary<BlockFieldDescriptor, int> blockMap)
  215. {
  216. blockMap = null;
  217. if (!(masterNode is PBRMasterNode1 pbrMasterNode))
  218. return false;
  219. m_WorkflowMode = (WorkflowMode)pbrMasterNode.m_Model;
  220. m_NormalDropOffSpace = (NormalDropOffSpace)pbrMasterNode.m_NormalDropOffSpace;
  221. // Handle mapping of Normal block specifically
  222. BlockFieldDescriptor normalBlock;
  223. switch (m_NormalDropOffSpace)
  224. {
  225. case NormalDropOffSpace.Object:
  226. normalBlock = BlockFields.SurfaceDescription.NormalOS;
  227. break;
  228. case NormalDropOffSpace.World:
  229. normalBlock = BlockFields.SurfaceDescription.NormalWS;
  230. break;
  231. default:
  232. normalBlock = BlockFields.SurfaceDescription.NormalTS;
  233. break;
  234. }
  235. // Set blockmap
  236. blockMap = new Dictionary<BlockFieldDescriptor, int>()
  237. {
  238. { BlockFields.VertexDescription.Position, 9 },
  239. { BlockFields.VertexDescription.Normal, 10 },
  240. { BlockFields.VertexDescription.Tangent, 11 },
  241. { BlockFields.SurfaceDescription.BaseColor, 0 },
  242. { normalBlock, 1 },
  243. { BlockFields.SurfaceDescription.Emission, 4 },
  244. { BlockFields.SurfaceDescription.Smoothness, 5 },
  245. { BlockFields.SurfaceDescription.Occlusion, 6 },
  246. { BlockFields.SurfaceDescription.Alpha, 7 },
  247. { BlockFields.SurfaceDescription.AlphaClipThreshold, 8 },
  248. };
  249. // PBRMasterNode adds/removes Metallic/Specular based on settings
  250. if (m_WorkflowMode == WorkflowMode.Specular)
  251. blockMap.Add(BlockFields.SurfaceDescription.Specular, 3);
  252. else if (m_WorkflowMode == WorkflowMode.Metallic)
  253. blockMap.Add(BlockFields.SurfaceDescription.Metallic, 2);
  254. return true;
  255. }
  256. internal override void OnAfterParentTargetDeserialized()
  257. {
  258. Assert.IsNotNull(target);
  259. if (this.sgVersion < latestVersion)
  260. {
  261. // Upgrade old incorrect Premultiplied blend into
  262. // equivalent Alpha + Preserve Specular blend mode.
  263. if (this.sgVersion < 1)
  264. {
  265. if (target.alphaMode == AlphaMode.Premultiply)
  266. {
  267. target.alphaMode = AlphaMode.Alpha;
  268. blendModePreserveSpecular = true;
  269. }
  270. else
  271. blendModePreserveSpecular = false;
  272. }
  273. ChangeVersion(latestVersion);
  274. }
  275. }
  276. #region SubShader
  277. static class SubShaders
  278. {
  279. public static SubShaderDescriptor LitSubShader(UniversalTarget target, WorkflowMode workflowMode, string renderType, string renderQueue, string disableBatchingTag, bool complexLit, bool blendModePreserveSpecular)
  280. {
  281. SubShaderDescriptor result = new SubShaderDescriptor()
  282. {
  283. pipelineTag = UniversalTarget.kPipelineTag,
  284. customTags = complexLit ? UniversalTarget.kComplexLitMaterialTypeTag : UniversalTarget.kLitMaterialTypeTag,
  285. renderType = renderType,
  286. renderQueue = renderQueue,
  287. disableBatchingTag = disableBatchingTag,
  288. generatesPreview = true,
  289. passes = new PassCollection()
  290. };
  291. if (complexLit)
  292. result.passes.Add(LitPasses.ForwardOnly(target, workflowMode, complexLit, blendModePreserveSpecular, CoreBlockMasks.Vertex, LitBlockMasks.FragmentComplexLit, CorePragmas.Forward, LitKeywords.Forward));
  293. else
  294. result.passes.Add(LitPasses.Forward(target, workflowMode, blendModePreserveSpecular, CorePragmas.Forward, LitKeywords.Forward));
  295. // ForwardOnly ComplexLit fills GBuffer too for potential custom usage of the GBuffer.
  296. result.passes.Add(LitPasses.GBuffer(target, workflowMode, blendModePreserveSpecular));
  297. // cull the shadowcaster pass if we know it will never be used
  298. if (target.castShadows || target.allowMaterialOverride)
  299. result.passes.Add(PassVariant(CorePasses.ShadowCaster(target), CorePragmas.Instanced));
  300. if (target.alwaysRenderMotionVectors)
  301. result.customTags = string.Concat(result.customTags, " ", UniversalTarget.kAlwaysRenderMotionVectorsTag);
  302. result.passes.Add(PassVariant(CorePasses.MotionVectors(target), CorePragmas.MotionVectors));
  303. if (target.mayWriteDepth)
  304. result.passes.Add(PassVariant(CorePasses.DepthOnly(target), CorePragmas.Instanced));
  305. if (complexLit)
  306. result.passes.Add(PassVariant(LitPasses.DepthNormalOnly(target), CorePragmas.Instanced));
  307. else
  308. result.passes.Add(PassVariant(LitPasses.DepthNormal(target), CorePragmas.Instanced));
  309. result.passes.Add(PassVariant(LitPasses.Meta(target), CorePragmas.Default));
  310. // Currently neither of these passes (selection/picking) can be last for the game view for
  311. // UI shaders to render correctly. Verify [1352225] before changing this order.
  312. result.passes.Add(PassVariant(CorePasses.SceneSelection(target), CorePragmas.Default));
  313. result.passes.Add(PassVariant(CorePasses.ScenePicking(target), CorePragmas.Default));
  314. result.passes.Add(PassVariant(LitPasses._2D(target), CorePragmas.Default));
  315. return result;
  316. }
  317. }
  318. #endregion
  319. #region Passes
  320. static class LitPasses
  321. {
  322. static void AddWorkflowModeControlToPass(ref PassDescriptor pass, UniversalTarget target, WorkflowMode workflowMode)
  323. {
  324. if (target.allowMaterialOverride)
  325. pass.keywords.Add(LitDefines.SpecularSetup);
  326. else if (workflowMode == WorkflowMode.Specular)
  327. pass.defines.Add(LitDefines.SpecularSetup, 1);
  328. }
  329. static void AddReceiveShadowsControlToPass(ref PassDescriptor pass, UniversalTarget target, bool receiveShadows)
  330. {
  331. if (target.allowMaterialOverride)
  332. pass.keywords.Add(LitKeywords.ReceiveShadowsOff);
  333. else if (!receiveShadows)
  334. pass.defines.Add(LitKeywords.ReceiveShadowsOff, 1);
  335. }
  336. public static PassDescriptor Forward(
  337. UniversalTarget target,
  338. WorkflowMode workflowMode,
  339. bool blendModePreserveSpecular,
  340. PragmaCollection pragmas,
  341. KeywordCollection keywords)
  342. {
  343. var result = new PassDescriptor()
  344. {
  345. // Definition
  346. displayName = "Universal Forward",
  347. referenceName = "SHADERPASS_FORWARD",
  348. lightMode = "UniversalForward",
  349. useInPreview = true,
  350. // Template
  351. passTemplatePath = UniversalTarget.kUberTemplatePath,
  352. sharedTemplateDirectories = UniversalTarget.kSharedTemplateDirectories,
  353. // Port Mask
  354. validVertexBlocks = CoreBlockMasks.Vertex,
  355. validPixelBlocks = LitBlockMasks.FragmentLit,
  356. // Fields
  357. structs = CoreStructCollections.Default,
  358. requiredFields = LitRequiredFields.Forward,
  359. fieldDependencies = CoreFieldDependencies.Default,
  360. // Conditional State
  361. renderStates = CoreRenderStates.UberSwitchedRenderState(target, blendModePreserveSpecular),
  362. pragmas = pragmas ?? CorePragmas.Forward, // NOTE: SM 2.0 only GL
  363. defines = new DefineCollection() { CoreDefines.UseFragmentFog },
  364. keywords = new KeywordCollection() { keywords },
  365. includes = LitIncludes.Forward,
  366. // Custom Interpolator Support
  367. customInterpolators = CoreCustomInterpDescriptors.Common
  368. };
  369. CorePasses.AddTargetSurfaceControlsToPass(ref result, target, blendModePreserveSpecular);
  370. CorePasses.AddAlphaToMaskControlToPass(ref result, target);
  371. AddWorkflowModeControlToPass(ref result, target, workflowMode);
  372. AddReceiveShadowsControlToPass(ref result, target, target.receiveShadows);
  373. CorePasses.AddLODCrossFadeControlToPass(ref result, target);
  374. return result;
  375. }
  376. public static PassDescriptor ForwardOnly(
  377. UniversalTarget target,
  378. WorkflowMode workflowMode,
  379. bool complexLit,
  380. bool blendModePreserveSpecular,
  381. BlockFieldDescriptor[] vertexBlocks,
  382. BlockFieldDescriptor[] pixelBlocks,
  383. PragmaCollection pragmas,
  384. KeywordCollection keywords)
  385. {
  386. var result = new PassDescriptor
  387. {
  388. // Definition
  389. displayName = "Universal Forward Only",
  390. referenceName = "SHADERPASS_FORWARDONLY",
  391. lightMode = "UniversalForwardOnly",
  392. useInPreview = true,
  393. // Template
  394. passTemplatePath = UniversalTarget.kUberTemplatePath,
  395. sharedTemplateDirectories = UniversalTarget.kSharedTemplateDirectories,
  396. // Port Mask
  397. validVertexBlocks = vertexBlocks,
  398. validPixelBlocks = pixelBlocks,
  399. // Fields
  400. structs = CoreStructCollections.Default,
  401. requiredFields = LitRequiredFields.Forward,
  402. fieldDependencies = CoreFieldDependencies.Default,
  403. // Conditional State
  404. renderStates = CoreRenderStates.UberSwitchedRenderState(target, blendModePreserveSpecular),
  405. pragmas = pragmas,
  406. defines = new DefineCollection { CoreDefines.UseFragmentFog },
  407. keywords = new KeywordCollection { keywords },
  408. includes = new IncludeCollection { LitIncludes.Forward },
  409. // Custom Interpolator Support
  410. customInterpolators = CoreCustomInterpDescriptors.Common
  411. };
  412. if (complexLit)
  413. result.defines.Add(LitDefines.ClearCoat, 1);
  414. CorePasses.AddTargetSurfaceControlsToPass(ref result, target, blendModePreserveSpecular);
  415. CorePasses.AddAlphaToMaskControlToPass(ref result, target);
  416. AddWorkflowModeControlToPass(ref result, target, workflowMode);
  417. AddReceiveShadowsControlToPass(ref result, target, target.receiveShadows);
  418. CorePasses.AddLODCrossFadeControlToPass(ref result, target);
  419. return result;
  420. }
  421. // Deferred only in SM4.5
  422. public static PassDescriptor GBuffer(UniversalTarget target, WorkflowMode workflowMode, bool blendModePreserveSpecular)
  423. {
  424. var result = new PassDescriptor
  425. {
  426. // Definition
  427. displayName = "GBuffer",
  428. referenceName = "SHADERPASS_GBUFFER",
  429. lightMode = "UniversalGBuffer",
  430. useInPreview = true,
  431. // Template
  432. passTemplatePath = UniversalTarget.kUberTemplatePath,
  433. sharedTemplateDirectories = UniversalTarget.kSharedTemplateDirectories,
  434. // Port Mask
  435. validVertexBlocks = CoreBlockMasks.Vertex,
  436. validPixelBlocks = LitBlockMasks.FragmentLit,
  437. // Fields
  438. structs = CoreStructCollections.Default,
  439. requiredFields = LitRequiredFields.GBuffer,
  440. fieldDependencies = CoreFieldDependencies.Default,
  441. // Conditional State
  442. renderStates = CoreRenderStates.UberSwitchedRenderState(target, blendModePreserveSpecular),
  443. pragmas = CorePragmas.GBuffer,
  444. defines = new DefineCollection { CoreDefines.UseFragmentFog },
  445. keywords = new KeywordCollection { LitKeywords.GBuffer },
  446. includes = new IncludeCollection { LitIncludes.GBuffer },
  447. // Custom Interpolator Support
  448. customInterpolators = CoreCustomInterpDescriptors.Common
  449. };
  450. CorePasses.AddTargetSurfaceControlsToPass(ref result, target, blendModePreserveSpecular);
  451. AddWorkflowModeControlToPass(ref result, target, workflowMode);
  452. AddReceiveShadowsControlToPass(ref result, target, target.receiveShadows);
  453. CorePasses.AddLODCrossFadeControlToPass(ref result, target);
  454. return result;
  455. }
  456. public static PassDescriptor Meta(UniversalTarget target)
  457. {
  458. var result = new PassDescriptor()
  459. {
  460. // Definition
  461. displayName = "Meta",
  462. referenceName = "SHADERPASS_META",
  463. lightMode = "Meta",
  464. // Template
  465. passTemplatePath = UniversalTarget.kUberTemplatePath,
  466. sharedTemplateDirectories = UniversalTarget.kSharedTemplateDirectories,
  467. // Port Mask
  468. validVertexBlocks = CoreBlockMasks.Vertex,
  469. validPixelBlocks = LitBlockMasks.FragmentMeta,
  470. // Fields
  471. structs = CoreStructCollections.Default,
  472. requiredFields = LitRequiredFields.Meta,
  473. fieldDependencies = CoreFieldDependencies.Default,
  474. // Conditional State
  475. renderStates = CoreRenderStates.Meta,
  476. pragmas = CorePragmas.Default,
  477. defines = new DefineCollection() { CoreDefines.UseFragmentFog },
  478. keywords = new KeywordCollection() { CoreKeywordDescriptors.EditorVisualization },
  479. includes = LitIncludes.Meta,
  480. // Custom Interpolator Support
  481. customInterpolators = CoreCustomInterpDescriptors.Common
  482. };
  483. CorePasses.AddAlphaClipControlToPass(ref result, target);
  484. return result;
  485. }
  486. public static PassDescriptor _2D(UniversalTarget target)
  487. {
  488. var result = new PassDescriptor()
  489. {
  490. // Definition
  491. displayName = "Universal 2D",
  492. referenceName = "SHADERPASS_2D",
  493. lightMode = "Universal2D",
  494. // Template
  495. passTemplatePath = UniversalTarget.kUberTemplatePath,
  496. sharedTemplateDirectories = UniversalTarget.kSharedTemplateDirectories,
  497. // Port Mask
  498. validVertexBlocks = CoreBlockMasks.Vertex,
  499. validPixelBlocks = CoreBlockMasks.FragmentColorAlpha,
  500. // Fields
  501. structs = CoreStructCollections.Default,
  502. fieldDependencies = CoreFieldDependencies.Default,
  503. // Conditional State
  504. renderStates = CoreRenderStates.UberSwitchedRenderState(target),
  505. pragmas = CorePragmas.Instanced,
  506. defines = new DefineCollection(),
  507. keywords = new KeywordCollection(),
  508. includes = LitIncludes._2D,
  509. // Custom Interpolator Support
  510. customInterpolators = CoreCustomInterpDescriptors.Common
  511. };
  512. CorePasses.AddAlphaClipControlToPass(ref result, target);
  513. return result;
  514. }
  515. public static PassDescriptor DepthNormal(UniversalTarget target)
  516. {
  517. var result = new PassDescriptor()
  518. {
  519. // Definition
  520. displayName = "DepthNormals",
  521. referenceName = "SHADERPASS_DEPTHNORMALS",
  522. lightMode = "DepthNormals",
  523. useInPreview = true,
  524. // Template
  525. passTemplatePath = UniversalTarget.kUberTemplatePath,
  526. sharedTemplateDirectories = UniversalTarget.kSharedTemplateDirectories,
  527. // Port Mask
  528. validVertexBlocks = CoreBlockMasks.Vertex,
  529. validPixelBlocks = CoreBlockMasks.FragmentDepthNormals,
  530. // Fields
  531. structs = CoreStructCollections.Default,
  532. requiredFields = CoreRequiredFields.DepthNormals,
  533. fieldDependencies = CoreFieldDependencies.Default,
  534. // Conditional State
  535. renderStates = CoreRenderStates.DepthNormalsOnly(target),
  536. pragmas = CorePragmas.Instanced,
  537. defines = new DefineCollection(),
  538. keywords = new KeywordCollection(),
  539. includes = new IncludeCollection { CoreIncludes.DepthNormalsOnly },
  540. // Custom Interpolator Support
  541. customInterpolators = CoreCustomInterpDescriptors.Common
  542. };
  543. CorePasses.AddAlphaClipControlToPass(ref result, target);
  544. CorePasses.AddLODCrossFadeControlToPass(ref result, target);
  545. return result;
  546. }
  547. public static PassDescriptor DepthNormalOnly(UniversalTarget target)
  548. {
  549. var result = new PassDescriptor()
  550. {
  551. // Definition
  552. displayName = "DepthNormalsOnly",
  553. referenceName = "SHADERPASS_DEPTHNORMALSONLY",
  554. lightMode = "DepthNormalsOnly",
  555. useInPreview = true,
  556. // Template
  557. passTemplatePath = UniversalTarget.kUberTemplatePath,
  558. sharedTemplateDirectories = UniversalTarget.kSharedTemplateDirectories,
  559. // Port Mask
  560. validVertexBlocks = CoreBlockMasks.Vertex,
  561. validPixelBlocks = CoreBlockMasks.FragmentDepthNormals,
  562. // Fields
  563. structs = CoreStructCollections.Default,
  564. requiredFields = CoreRequiredFields.DepthNormals,
  565. fieldDependencies = CoreFieldDependencies.Default,
  566. // Conditional State
  567. renderStates = CoreRenderStates.DepthNormalsOnly(target),
  568. pragmas = CorePragmas.Instanced,
  569. defines = new DefineCollection(),
  570. keywords = new KeywordCollection(),
  571. includes = new IncludeCollection { CoreIncludes.DepthNormalsOnly },
  572. // Custom Interpolator Support
  573. customInterpolators = CoreCustomInterpDescriptors.Common
  574. };
  575. CorePasses.AddAlphaClipControlToPass(ref result, target);
  576. CorePasses.AddLODCrossFadeControlToPass(ref result, target);
  577. return result;
  578. }
  579. }
  580. #endregion
  581. #region PortMasks
  582. static class LitBlockMasks
  583. {
  584. public static readonly BlockFieldDescriptor[] FragmentLit = new BlockFieldDescriptor[]
  585. {
  586. BlockFields.SurfaceDescription.BaseColor,
  587. BlockFields.SurfaceDescription.NormalOS,
  588. BlockFields.SurfaceDescription.NormalTS,
  589. BlockFields.SurfaceDescription.NormalWS,
  590. BlockFields.SurfaceDescription.Emission,
  591. BlockFields.SurfaceDescription.Metallic,
  592. BlockFields.SurfaceDescription.Specular,
  593. BlockFields.SurfaceDescription.Smoothness,
  594. BlockFields.SurfaceDescription.Occlusion,
  595. BlockFields.SurfaceDescription.Alpha,
  596. BlockFields.SurfaceDescription.AlphaClipThreshold,
  597. };
  598. public static readonly BlockFieldDescriptor[] FragmentComplexLit = new BlockFieldDescriptor[]
  599. {
  600. BlockFields.SurfaceDescription.BaseColor,
  601. BlockFields.SurfaceDescription.NormalOS,
  602. BlockFields.SurfaceDescription.NormalTS,
  603. BlockFields.SurfaceDescription.NormalWS,
  604. BlockFields.SurfaceDescription.Emission,
  605. BlockFields.SurfaceDescription.Metallic,
  606. BlockFields.SurfaceDescription.Specular,
  607. BlockFields.SurfaceDescription.Smoothness,
  608. BlockFields.SurfaceDescription.Occlusion,
  609. BlockFields.SurfaceDescription.Alpha,
  610. BlockFields.SurfaceDescription.AlphaClipThreshold,
  611. BlockFields.SurfaceDescription.CoatMask,
  612. BlockFields.SurfaceDescription.CoatSmoothness,
  613. };
  614. public static readonly BlockFieldDescriptor[] FragmentMeta = new BlockFieldDescriptor[]
  615. {
  616. BlockFields.SurfaceDescription.BaseColor,
  617. BlockFields.SurfaceDescription.Emission,
  618. BlockFields.SurfaceDescription.Alpha,
  619. BlockFields.SurfaceDescription.AlphaClipThreshold,
  620. };
  621. }
  622. #endregion
  623. #region RequiredFields
  624. static class LitRequiredFields
  625. {
  626. public static readonly FieldCollection Forward = new FieldCollection()
  627. {
  628. StructFields.Attributes.uv1,
  629. StructFields.Attributes.uv2,
  630. StructFields.Varyings.positionWS,
  631. StructFields.Varyings.normalWS,
  632. StructFields.Varyings.tangentWS, // needed for vertex lighting
  633. UniversalStructFields.Varyings.staticLightmapUV,
  634. UniversalStructFields.Varyings.dynamicLightmapUV,
  635. UniversalStructFields.Varyings.sh,
  636. UniversalStructFields.Varyings.probeOcclusion,
  637. UniversalStructFields.Varyings.fogFactorAndVertexLight, // fog and vertex lighting, vert input is dependency
  638. UniversalStructFields.Varyings.shadowCoord, // shadow coord, vert input is dependency
  639. };
  640. public static readonly FieldCollection GBuffer = new FieldCollection()
  641. {
  642. StructFields.Attributes.uv1,
  643. StructFields.Attributes.uv2,
  644. StructFields.Varyings.positionWS,
  645. StructFields.Varyings.normalWS,
  646. StructFields.Varyings.tangentWS, // needed for vertex lighting
  647. UniversalStructFields.Varyings.staticLightmapUV,
  648. UniversalStructFields.Varyings.dynamicLightmapUV,
  649. UniversalStructFields.Varyings.sh,
  650. UniversalStructFields.Varyings.probeOcclusion,
  651. UniversalStructFields.Varyings.fogFactorAndVertexLight, // fog and vertex lighting, vert input is dependency
  652. UniversalStructFields.Varyings.shadowCoord, // shadow coord, vert input is dependency
  653. };
  654. public static readonly FieldCollection Meta = new FieldCollection()
  655. {
  656. StructFields.Attributes.positionOS,
  657. StructFields.Attributes.normalOS,
  658. StructFields.Attributes.uv0, //
  659. StructFields.Attributes.uv1, // needed for meta vertex position
  660. StructFields.Attributes.uv2, // needed for meta UVs
  661. StructFields.Attributes.instanceID, // needed for rendering instanced terrain
  662. StructFields.Varyings.positionCS,
  663. StructFields.Varyings.texCoord0, // needed for meta UVs
  664. StructFields.Varyings.texCoord1, // VizUV
  665. StructFields.Varyings.texCoord2, // LightCoord
  666. };
  667. }
  668. #endregion
  669. #region Defines
  670. static class LitDefines
  671. {
  672. public static readonly KeywordDescriptor ClearCoat = new KeywordDescriptor()
  673. {
  674. displayName = "Clear Coat",
  675. referenceName = "_CLEARCOAT",
  676. type = KeywordType.Boolean,
  677. definition = KeywordDefinition.ShaderFeature,
  678. scope = KeywordScope.Local,
  679. stages = KeywordShaderStage.Fragment
  680. };
  681. public static readonly KeywordDescriptor SpecularSetup = new KeywordDescriptor()
  682. {
  683. displayName = "Specular Setup",
  684. referenceName = "_SPECULAR_SETUP",
  685. type = KeywordType.Boolean,
  686. definition = KeywordDefinition.ShaderFeature,
  687. scope = KeywordScope.Local,
  688. stages = KeywordShaderStage.Fragment
  689. };
  690. }
  691. #endregion
  692. #region Keywords
  693. static class LitKeywords
  694. {
  695. public static readonly KeywordDescriptor ReceiveShadowsOff = new KeywordDescriptor()
  696. {
  697. displayName = "Receive Shadows Off",
  698. referenceName = ShaderKeywordStrings._RECEIVE_SHADOWS_OFF,
  699. type = KeywordType.Boolean,
  700. definition = KeywordDefinition.ShaderFeature,
  701. scope = KeywordScope.Local,
  702. };
  703. public static readonly KeywordCollection Forward = new KeywordCollection
  704. {
  705. { CoreKeywordDescriptors.ScreenSpaceAmbientOcclusion },
  706. { CoreKeywordDescriptors.StaticLightmap },
  707. { CoreKeywordDescriptors.DynamicLightmap },
  708. { CoreKeywordDescriptors.DirectionalLightmapCombined },
  709. { CoreKeywordDescriptors.UseLegacyLightmaps },
  710. { CoreKeywordDescriptors.MainLightShadows },
  711. { CoreKeywordDescriptors.AdditionalLights },
  712. { CoreKeywordDescriptors.AdditionalLightShadows },
  713. { CoreKeywordDescriptors.ReflectionProbeBlending },
  714. { CoreKeywordDescriptors.ReflectionProbeBoxProjection },
  715. { CoreKeywordDescriptors.ShadowsSoft },
  716. { CoreKeywordDescriptors.LightmapShadowMixing },
  717. { CoreKeywordDescriptors.ShadowsShadowmask },
  718. { CoreKeywordDescriptors.DBuffer },
  719. { CoreKeywordDescriptors.LightLayers },
  720. { CoreKeywordDescriptors.DebugDisplay },
  721. { CoreKeywordDescriptors.LightCookies },
  722. { CoreKeywordDescriptors.ForwardPlus },
  723. { CoreKeywordDescriptors.EvaluateSh },
  724. };
  725. public static readonly KeywordCollection GBuffer = new KeywordCollection
  726. {
  727. { CoreKeywordDescriptors.StaticLightmap },
  728. { CoreKeywordDescriptors.DynamicLightmap },
  729. { CoreKeywordDescriptors.DirectionalLightmapCombined },
  730. { CoreKeywordDescriptors.UseLegacyLightmaps },
  731. { CoreKeywordDescriptors.MainLightShadows },
  732. { CoreKeywordDescriptors.ReflectionProbeBlending },
  733. { CoreKeywordDescriptors.ReflectionProbeBoxProjection },
  734. { CoreKeywordDescriptors.ShadowsSoft },
  735. { CoreKeywordDescriptors.LightmapShadowMixing },
  736. { CoreKeywordDescriptors.ShadowsShadowmask },
  737. { CoreKeywordDescriptors.MixedLightingSubtractive },
  738. { CoreKeywordDescriptors.DBuffer },
  739. { CoreKeywordDescriptors.GBufferNormalsOct },
  740. { CoreKeywordDescriptors.RenderPassEnabled },
  741. { CoreKeywordDescriptors.DebugDisplay },
  742. };
  743. }
  744. #endregion
  745. #region Includes
  746. static class LitIncludes
  747. {
  748. const string kShadows = "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl";
  749. const string kMetaInput = "Packages/com.unity.render-pipelines.universal/ShaderLibrary/MetaInput.hlsl";
  750. const string kForwardPass = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRForwardPass.hlsl";
  751. const string kGBuffer = "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityGBuffer.hlsl";
  752. const string kPBRGBufferPass = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRGBufferPass.hlsl";
  753. const string kLightingMetaPass = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/LightingMetaPass.hlsl";
  754. const string k2DPass = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBR2DPass.hlsl";
  755. public static readonly IncludeCollection Forward = new IncludeCollection
  756. {
  757. // Pre-graph
  758. { CoreIncludes.DOTSPregraph },
  759. { CoreIncludes.WriteRenderLayersPregraph },
  760. { CoreIncludes.ProbeVolumePregraph },
  761. { CoreIncludes.CorePregraph },
  762. { kShadows, IncludeLocation.Pregraph },
  763. { CoreIncludes.ShaderGraphPregraph },
  764. { CoreIncludes.DBufferPregraph },
  765. // Post-graph
  766. { CoreIncludes.CorePostgraph },
  767. { kForwardPass, IncludeLocation.Postgraph },
  768. };
  769. public static readonly IncludeCollection GBuffer = new IncludeCollection
  770. {
  771. // Pre-graph
  772. { CoreIncludes.DOTSPregraph },
  773. { CoreIncludes.WriteRenderLayersPregraph },
  774. { CoreIncludes.ProbeVolumePregraph },
  775. { CoreIncludes.CorePregraph },
  776. { kShadows, IncludeLocation.Pregraph },
  777. { CoreIncludes.ShaderGraphPregraph },
  778. { CoreIncludes.DBufferPregraph },
  779. // Post-graph
  780. { CoreIncludes.CorePostgraph },
  781. { kGBuffer, IncludeLocation.Postgraph },
  782. { kPBRGBufferPass, IncludeLocation.Postgraph },
  783. };
  784. public static readonly IncludeCollection Meta = new IncludeCollection
  785. {
  786. // Pre-graph
  787. { CoreIncludes.CorePregraph },
  788. { CoreIncludes.ShaderGraphPregraph },
  789. { kMetaInput, IncludeLocation.Pregraph },
  790. // Post-graph
  791. { CoreIncludes.CorePostgraph },
  792. { kLightingMetaPass, IncludeLocation.Postgraph },
  793. };
  794. public static readonly IncludeCollection _2D = new IncludeCollection
  795. {
  796. // Pre-graph
  797. { CoreIncludes.CorePregraph },
  798. { CoreIncludes.ShaderGraphPregraph },
  799. // Post-graph
  800. { CoreIncludes.CorePostgraph },
  801. { k2DPass, IncludeLocation.Postgraph },
  802. };
  803. }
  804. #endregion
  805. }
  806. }