UniversalLitSubTarget.cs 42 KB

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