暫無描述
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.

FullscreenSubTarget.cs 42KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904
  1. using UnityEditor.ShaderGraph;
  2. using UnityEngine;
  3. using System;
  4. using UnityEditor.ShaderGraph.Internal;
  5. using System.Linq;
  6. using BlendMode = UnityEngine.Rendering.BlendMode;
  7. using BlendOp = UnityEditor.ShaderGraph.BlendOp;
  8. using UnityEngine.UIElements;
  9. using UnityEditor.UIElements;
  10. using UnityEngine.Rendering;
  11. namespace UnityEditor.Rendering.Fullscreen.ShaderGraph
  12. {
  13. [GenerateBlocks("Fullscreen")]
  14. internal struct FullscreenBlocks
  15. {
  16. public static BlockFieldDescriptor color = new BlockFieldDescriptor(BlockFields.SurfaceDescription.name, "FullscreenColor", "Color",
  17. "SURFACEDESCRIPTION_COLOR", new ColorControl(UnityEngine.Color.grey, true), ShaderStage.Fragment);
  18. public static BlockFieldDescriptor eyeDepth = new BlockFieldDescriptor(BlockFields.SurfaceDescription.name, "FullscreenEyeDepth", "Eye Depth",
  19. "SURFACEDESCRIPTION_EYE_DEPTH", new FloatControl(0), ShaderStage.Fragment);
  20. public static BlockFieldDescriptor linear01Depth = new BlockFieldDescriptor(BlockFields.SurfaceDescription.name, "FullscreenLinear01Depth", "Linear01 Depth",
  21. "SURFACEDESCRIPTION_LINEAR01_DEPTH", new FloatControl(0), ShaderStage.Fragment);
  22. public static BlockFieldDescriptor rawDepth = new BlockFieldDescriptor(BlockFields.SurfaceDescription.name, "FullscreenRawDepth", "Raw Depth",
  23. "SURFACEDESCRIPTION_RAW_DEPTH", new FloatControl(0), ShaderStage.Fragment);
  24. }
  25. [GenerationAPI]
  26. internal struct FullscreenFields
  27. {
  28. public static FieldDescriptor depth = new FieldDescriptor("OUTPUT", "depth", "OUTPUT_DEPTH");
  29. }
  30. internal enum FullscreenMode
  31. {
  32. FullScreen,
  33. CustomRenderTexture,
  34. }
  35. internal enum FullscreenCompatibility
  36. {
  37. Blit,
  38. DrawProcedural,
  39. }
  40. internal enum FullscreenBlendMode
  41. {
  42. Disabled,
  43. Alpha,
  44. Premultiply,
  45. Additive,
  46. Multiply,
  47. Custom,
  48. }
  49. internal enum FullscreenDepthWriteMode
  50. {
  51. LinearEye,
  52. Linear01,
  53. Raw,
  54. }
  55. internal static class FullscreenUniforms
  56. {
  57. public static readonly string blendModeProperty = "_Fullscreen_BlendMode";
  58. public static readonly string srcColorBlendProperty = "_Fullscreen_SrcColorBlend";
  59. public static readonly string dstColorBlendProperty = "_Fullscreen_DstColorBlend";
  60. public static readonly string srcAlphaBlendProperty = "_Fullscreen_SrcAlphaBlend";
  61. public static readonly string dstAlphaBlendProperty = "_Fullscreen_DstAlphaBlend";
  62. public static readonly string colorBlendOperationProperty = "_Fullscreen_ColorBlendOperation";
  63. public static readonly string alphaBlendOperationProperty = "_Fullscreen_AlphaBlendOperation";
  64. public static readonly string depthWriteProperty = "_Fullscreen_DepthWrite";
  65. public static readonly string depthTestProperty = "_Fullscreen_DepthTest";
  66. public static readonly string stencilEnableProperty = "_Fullscreen_Stencil";
  67. public static readonly string stencilReferenceProperty = "_Fullscreen_StencilReference";
  68. public static readonly string stencilReadMaskProperty = "_Fullscreen_StencilReadMask";
  69. public static readonly string stencilWriteMaskProperty = "_Fullscreen_StencilWriteMask";
  70. public static readonly string stencilComparisonProperty = "_Fullscreen_StencilComparison";
  71. public static readonly string stencilPassProperty = "_Fullscreen_StencilPass";
  72. public static readonly string stencilFailProperty = "_Fullscreen_StencilFail";
  73. public static readonly string stencilDepthFailProperty = "_Fullscreen_StencilDepthFail";
  74. public static readonly string srcColorBlend = "[" + srcColorBlendProperty + "]";
  75. public static readonly string dstColorBlend = "[" + dstColorBlendProperty + "]";
  76. public static readonly string srcAlphaBlend = "[" + srcAlphaBlendProperty + "]";
  77. public static readonly string dstAlphaBlend = "[" + dstAlphaBlendProperty + "]";
  78. public static readonly string colorBlendOperation = "[" + colorBlendOperationProperty + "]";
  79. public static readonly string alphaBlendOperation = "[" + alphaBlendOperationProperty + "]";
  80. public static readonly string depthWrite = "[" + depthWriteProperty + "]";
  81. public static readonly string depthTest = "[" + depthTestProperty + "]";
  82. public static readonly string stencilReference = "[" + stencilReferenceProperty + "]";
  83. public static readonly string stencilReadMask = "[" + stencilReadMaskProperty + "]";
  84. public static readonly string stencilWriteMask = "[" + stencilWriteMaskProperty + "]";
  85. public static readonly string stencilComparison = "[" + stencilComparisonProperty + "]";
  86. public static readonly string stencilPass = "[" + stencilPassProperty + "]";
  87. public static readonly string stencilFail = "[" + stencilFailProperty + "]";
  88. public static readonly string stencilDepthFail = "[" + stencilDepthFailProperty + "]";
  89. }
  90. internal abstract class FullscreenSubTarget<T> : SubTarget<T>, IRequiresData<FullscreenData>, IHasMetadata where T : Target
  91. {
  92. static readonly GUID kSourceCodeGuid = new GUID("1cfc804c75474e144be5d4158b9522ed"); // FullscreenSubTarget.cs // TODO
  93. static readonly string[] kSharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories().Union(new string[] { "Packages/com.unity.shadergraph/Editor/Generation/Targets/Fullscreen/Templates" }).ToArray();
  94. // HLSL includes
  95. protected static readonly string kFullscreenCommon = "Packages/com.unity.shadergraph/Editor/Generation/Targets/Fullscreen/Includes/FullscreenCommon.hlsl";
  96. protected static readonly string kTemplatePath = "Packages/com.unity.shadergraph/Editor/Generation/Targets/Fullscreen/Templates/ShaderPass.template";
  97. protected static readonly string kCommon = "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl";
  98. protected static readonly string kColor = "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl";
  99. protected static readonly string kTexture = "Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl";
  100. protected static readonly string kInstancing = "Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl";
  101. protected static readonly string kFullscreenShaderPass = "Packages/com.unity.shadergraph/Editor/Generation/Targets/Fullscreen/Includes/FullscreenShaderPass.cs.hlsl";
  102. protected static readonly string kSpaceTransforms = "Packages/com.unity.render-pipelines.core/ShaderLibrary/SpaceTransforms.hlsl";
  103. protected static readonly string kFunctions = "Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl";
  104. protected static readonly string kTextureStack = "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl";
  105. protected virtual string fullscreenDrawProceduralInclude => "Packages/com.unity.shadergraph/Editor/Generation/Targets/Fullscreen/Includes/FullscreenDrawProcedural.hlsl";
  106. protected virtual string fullscreenBlitInclude => "Packages/com.unity.shadergraph/Editor/Generation/Targets/Fullscreen/Includes/FullscreenBlit.hlsl";
  107. FullscreenData m_FullscreenData;
  108. FullscreenData IRequiresData<FullscreenData>.data
  109. {
  110. get => m_FullscreenData;
  111. set => m_FullscreenData = value;
  112. }
  113. public FullscreenData fullscreenData
  114. {
  115. get => m_FullscreenData;
  116. set => m_FullscreenData = value;
  117. }
  118. public override void Setup(ref TargetSetupContext context)
  119. {
  120. context.AddAssetDependency(kSourceCodeGuid, AssetCollection.Flags.SourceDependency);
  121. context.SetDefaultShaderGUI(GetDefaultShaderGUI().FullName);
  122. context.AddSubShader(GenerateSubShader());
  123. }
  124. protected virtual IncludeCollection pregraphIncludes => new IncludeCollection();
  125. protected abstract string pipelineTag { get; }
  126. protected virtual Type GetDefaultShaderGUI() => typeof(FullscreenShaderGUI);
  127. public virtual string identifier => GetType().Name;
  128. public virtual ScriptableObject GetMetadataObject(GraphDataReadOnly graph)
  129. {
  130. var bultInMetadata = ScriptableObject.CreateInstance<FullscreenMetaData>();
  131. bultInMetadata.fullscreenMode = fullscreenData.fullscreenMode;
  132. return bultInMetadata;
  133. }
  134. public RenderStateCollection GetRenderState()
  135. {
  136. var result = new RenderStateCollection();
  137. if (fullscreenData.allowMaterialOverride)
  138. {
  139. if (fullscreenData.depthTestMode != CompareFunction.Disabled)
  140. result.Add(RenderState.ZTest(FullscreenUniforms.depthTest));
  141. else
  142. result.Add(RenderState.ZTest("Off"));
  143. result.Add(RenderState.ZWrite(FullscreenUniforms.depthWrite));
  144. if (fullscreenData.blendMode != FullscreenBlendMode.Disabled)
  145. {
  146. result.Add(RenderState.Blend(FullscreenUniforms.srcColorBlend, FullscreenUniforms.dstColorBlend, FullscreenUniforms.srcAlphaBlend, FullscreenUniforms.dstAlphaBlend));
  147. result.Add(RenderState.BlendOp(FullscreenUniforms.colorBlendOperation, FullscreenUniforms.alphaBlendOperation));
  148. }
  149. else
  150. {
  151. result.Add(RenderState.Blend("Blend Off"));
  152. }
  153. if (fullscreenData.enableStencil)
  154. {
  155. result.Add(RenderState.Stencil(new StencilDescriptor { Ref = FullscreenUniforms.stencilReference, ReadMask = FullscreenUniforms.stencilReadMask, WriteMask = FullscreenUniforms.stencilWriteMask, Comp = FullscreenUniforms.stencilComparison, ZFail = FullscreenUniforms.stencilDepthFail, Fail = FullscreenUniforms.stencilFail, Pass = FullscreenUniforms.stencilPass }));
  156. }
  157. }
  158. else
  159. {
  160. if (fullscreenData.depthTestMode == CompareFunction.Disabled)
  161. result.Add(RenderState.ZTest("Off"));
  162. else
  163. result.Add(RenderState.ZTest(CompareFunctionToZTest(fullscreenData.depthTestMode).ToString()));
  164. result.Add(RenderState.ZWrite(fullscreenData.depthWrite ? ZWrite.On.ToString() : ZWrite.Off.ToString()));
  165. // Blend mode
  166. if (fullscreenData.blendMode == FullscreenBlendMode.Alpha)
  167. result.Add(RenderState.Blend(Blend.SrcAlpha, Blend.OneMinusSrcAlpha, Blend.One, Blend.OneMinusSrcAlpha));
  168. else if (fullscreenData.blendMode == FullscreenBlendMode.Premultiply)
  169. result.Add(RenderState.Blend(Blend.One, Blend.OneMinusSrcAlpha, Blend.One, Blend.OneMinusSrcAlpha));
  170. else if (fullscreenData.blendMode == FullscreenBlendMode.Additive)
  171. result.Add(RenderState.Blend(Blend.SrcAlpha, Blend.One, Blend.One, Blend.One));
  172. else if (fullscreenData.blendMode == FullscreenBlendMode.Multiply)
  173. result.Add(RenderState.Blend(Blend.DstColor, Blend.Zero));
  174. else if (fullscreenData.blendMode == FullscreenBlendMode.Disabled)
  175. result.Add(RenderState.Blend("Blend Off"));
  176. else
  177. {
  178. result.Add(RenderState.Blend(BlendModeToBlend(fullscreenData.srcColorBlendMode), BlendModeToBlend(fullscreenData.dstColorBlendMode), BlendModeToBlend(fullscreenData.srcAlphaBlendMode), BlendModeToBlend(fullscreenData.dstAlphaBlendMode)));
  179. result.Add(RenderState.BlendOp(fullscreenData.colorBlendOperation, fullscreenData.alphaBlendOperation));
  180. }
  181. if (fullscreenData.enableStencil)
  182. {
  183. result.Add(RenderState.Stencil(new StencilDescriptor
  184. {
  185. Ref = fullscreenData.stencilReference.ToString(),
  186. ReadMask = fullscreenData.stencilReadMask.ToString(),
  187. WriteMask = fullscreenData.stencilWriteMask.ToString(),
  188. Comp = CompareFunctionToStencilString(fullscreenData.stencilCompareFunction),
  189. ZFail = StencilOpToStencilString(fullscreenData.stencilDepthTestFailOperation),
  190. Fail = StencilOpToStencilString(fullscreenData.stencilFailOperation),
  191. Pass = StencilOpToStencilString(fullscreenData.stencilPassOperation),
  192. }));
  193. }
  194. }
  195. result.Add(RenderState.Cull(UnityEditor.ShaderGraph.Cull.Off));
  196. return result;
  197. }
  198. public static Blend BlendModeToBlend(BlendMode mode)
  199. {
  200. switch (mode)
  201. {
  202. case BlendMode.Zero: return Blend.Zero;
  203. case BlendMode.One: return Blend.One;
  204. case BlendMode.DstColor: return Blend.DstColor;
  205. case BlendMode.SrcColor: return Blend.SrcColor;
  206. case BlendMode.OneMinusDstColor: return Blend.OneMinusDstColor;
  207. case BlendMode.SrcAlpha: return Blend.SrcAlpha;
  208. case BlendMode.OneMinusSrcColor: return Blend.OneMinusSrcColor;
  209. case BlendMode.DstAlpha: return Blend.DstAlpha;
  210. case BlendMode.OneMinusDstAlpha: return Blend.OneMinusDstAlpha;
  211. case BlendMode.SrcAlphaSaturate: return Blend.SrcAlpha;
  212. case BlendMode.OneMinusSrcAlpha: return Blend.OneMinusSrcAlpha;
  213. default: return Blend.Zero;
  214. }
  215. ;
  216. }
  217. public static ZTest CompareFunctionToZTest(CompareFunction mode)
  218. {
  219. switch (mode)
  220. {
  221. case CompareFunction.Equal: return ZTest.Equal;
  222. case CompareFunction.NotEqual: return ZTest.NotEqual;
  223. case CompareFunction.Greater: return ZTest.Greater;
  224. case CompareFunction.Less: return ZTest.Less;
  225. case CompareFunction.GreaterEqual: return ZTest.GEqual;
  226. case CompareFunction.LessEqual: return ZTest.LEqual;
  227. case CompareFunction.Always: return ZTest.Always;
  228. case CompareFunction.Disabled: return ZTest.Always;
  229. default: return ZTest.Always;
  230. }
  231. ;
  232. }
  233. public static string CompareFunctionToStencilString(CompareFunction compare)
  234. {
  235. switch (compare)
  236. {
  237. case CompareFunction.Never: return "Never";
  238. case CompareFunction.Equal: return "Equal";
  239. case CompareFunction.NotEqual: return "NotEqual";
  240. case CompareFunction.Greater: return "Greater";
  241. case CompareFunction.Less: return "Less";
  242. case CompareFunction.GreaterEqual: return "GEqual";
  243. case CompareFunction.LessEqual: return "LEqual";
  244. case CompareFunction.Always: return "Always";
  245. default: return "Always";
  246. }
  247. ;
  248. }
  249. public static string StencilOpToStencilString(StencilOp op)
  250. {
  251. switch (op)
  252. {
  253. case StencilOp.Keep: return "Keep";
  254. case StencilOp.Zero: return "Zero";
  255. case StencilOp.Replace: return "Replace";
  256. case StencilOp.IncrementSaturate: return "IncrSat";
  257. case StencilOp.DecrementSaturate: return "DecrSat";
  258. case StencilOp.Invert: return "Invert";
  259. case StencilOp.IncrementWrap: return "IncrWrap";
  260. case StencilOp.DecrementWrap: return "DecrWrap";
  261. default: return "Keep";
  262. }
  263. ;
  264. }
  265. public virtual SubShaderDescriptor GenerateSubShader()
  266. {
  267. var result = new SubShaderDescriptor()
  268. {
  269. generatesPreview = true,
  270. passes = new PassCollection(),
  271. pipelineTag = pipelineTag,
  272. };
  273. result.passes.Add(GenerateFullscreenPass(FullscreenCompatibility.DrawProcedural));
  274. result.passes.Add(GenerateFullscreenPass(FullscreenCompatibility.Blit));
  275. return result;
  276. }
  277. public virtual IncludeCollection GetPreGraphIncludes()
  278. {
  279. return new IncludeCollection
  280. {
  281. { kCommon, IncludeLocation.Pregraph },
  282. { kColor, IncludeLocation.Pregraph },
  283. { kTexture, IncludeLocation.Pregraph },
  284. { kTextureStack, IncludeLocation.Pregraph },
  285. { kFullscreenShaderPass, IncludeLocation.Pregraph }, // For VR
  286. { pregraphIncludes },
  287. { kSpaceTransforms, IncludeLocation.Pregraph },
  288. { kFunctions, IncludeLocation.Pregraph },
  289. };
  290. }
  291. public virtual IncludeCollection GetPostGraphIncludes()
  292. {
  293. return new IncludeCollection { { kFullscreenCommon, IncludeLocation.Postgraph } };
  294. }
  295. static readonly KeywordDescriptor depthWriteKeyword = new KeywordDescriptor
  296. {
  297. displayName = "Depth Write",
  298. referenceName = "DEPTH_WRITE",
  299. type = KeywordType.Boolean,
  300. definition = KeywordDefinition.ShaderFeature,
  301. stages = KeywordShaderStage.Fragment,
  302. };
  303. static readonly KeywordDescriptor depthWriteModeKeyword = new KeywordDescriptor
  304. {
  305. displayName = "Depth Write Mode",
  306. referenceName = "DEPTH_WRITE_MODE",
  307. type = KeywordType.Enum,
  308. definition = KeywordDefinition.Predefined,
  309. entries = new KeywordEntry[]
  310. {
  311. new KeywordEntry("Eye Depth", "EYE"),
  312. new KeywordEntry("Eye Linear 01", "LINEAR01"),
  313. new KeywordEntry("Eye Raw", "RAW"),
  314. },
  315. stages = KeywordShaderStage.Fragment,
  316. };
  317. public static StructDescriptor Varyings = new StructDescriptor()
  318. {
  319. name = "Varyings",
  320. packFields = true,
  321. populateWithCustomInterpolators = false,
  322. fields = new FieldDescriptor[]
  323. {
  324. StructFields.Varyings.positionCS,
  325. StructFields.Varyings.texCoord0,
  326. StructFields.Varyings.texCoord1,
  327. StructFields.Varyings.instanceID,
  328. StructFields.Varyings.stereoTargetEyeIndexAsBlendIdx0,
  329. StructFields.Varyings.stereoTargetEyeIndexAsRTArrayIdx,
  330. }
  331. };
  332. protected virtual DefineCollection GetPassDefines(FullscreenCompatibility compatibility)
  333. => new DefineCollection();
  334. protected virtual KeywordCollection GetPassKeywords(FullscreenCompatibility compatibility)
  335. => new KeywordCollection();
  336. static StructDescriptor GetFullscreenAttributes(FullscreenCompatibility compatibility)
  337. {
  338. var desc = new StructDescriptor()
  339. {
  340. name = "Attributes",
  341. packFields = false,
  342. };
  343. if (compatibility == FullscreenCompatibility.Blit)
  344. {
  345. desc.fields = new FieldDescriptor[]
  346. {
  347. StructFields.Attributes.instanceID,
  348. StructFields.Attributes.vertexID,
  349. StructFields.Attributes.positionOS,
  350. };
  351. }
  352. else
  353. {
  354. desc.fields = new FieldDescriptor[]
  355. {
  356. StructFields.Attributes.instanceID,
  357. StructFields.Attributes.vertexID,
  358. };
  359. }
  360. return desc;
  361. }
  362. public virtual PassDescriptor GenerateFullscreenPass(FullscreenCompatibility compatibility)
  363. {
  364. var fullscreenPass = new PassDescriptor
  365. {
  366. // Definition
  367. displayName = compatibility.ToString(),
  368. referenceName = "SHADERPASS_" + compatibility.ToString().ToUpper(),
  369. useInPreview = true,
  370. // Template
  371. passTemplatePath = kTemplatePath,
  372. sharedTemplateDirectories = kSharedTemplateDirectories,
  373. // Port Mask
  374. validVertexBlocks = null,
  375. validPixelBlocks = new BlockFieldDescriptor[]
  376. {
  377. BlockFields.SurfaceDescription.BaseColor,
  378. BlockFields.SurfaceDescription.Alpha,
  379. FullscreenBlocks.eyeDepth,
  380. FullscreenBlocks.linear01Depth,
  381. FullscreenBlocks.rawDepth,
  382. },
  383. // Fields
  384. structs = new StructCollection
  385. {
  386. { GetFullscreenAttributes(compatibility) },
  387. { Structs.SurfaceDescriptionInputs },
  388. { Varyings },
  389. { Structs.VertexDescriptionInputs },
  390. },
  391. fieldDependencies = FieldDependencies.Default,
  392. requiredFields = new FieldCollection
  393. {
  394. StructFields.Varyings.texCoord0, // Always need texCoord0 to calculate the other properties in fullscreen node code
  395. StructFields.Varyings.texCoord1, // We store the view direction computed in the vertex in the texCoord1
  396. StructFields.Attributes.vertexID, // Need the vertex Id for the DrawProcedural case
  397. },
  398. // Conditional State
  399. renderStates = GetRenderState(),
  400. pragmas = new PragmaCollection
  401. {
  402. { Pragma.Target(ShaderModel.Target30) },
  403. { Pragma.Vertex("vert") },
  404. { Pragma.Fragment("frag") },
  405. },
  406. defines = new DefineCollection
  407. {
  408. {depthWriteKeyword, 1, new FieldCondition(FullscreenFields.depth, true)},
  409. {depthWriteModeKeyword, (int)fullscreenData.depthWriteMode, new FieldCondition(FullscreenFields.depth, true)},
  410. GetPassDefines(compatibility),
  411. },
  412. keywords = GetPassKeywords(compatibility),
  413. includes = new IncludeCollection
  414. {
  415. // Pre-graph
  416. GetPreGraphIncludes(),
  417. // Post-graph
  418. GetPostGraphIncludes(),
  419. },
  420. };
  421. switch (compatibility)
  422. {
  423. default:
  424. case FullscreenCompatibility.Blit:
  425. fullscreenPass.includes.Add(fullscreenBlitInclude, IncludeLocation.Postgraph);
  426. break;
  427. case FullscreenCompatibility.DrawProcedural:
  428. fullscreenPass.includes.Add(fullscreenDrawProceduralInclude, IncludeLocation.Postgraph);
  429. break;
  430. }
  431. return fullscreenPass;
  432. }
  433. // We don't need the save context / update materials for now
  434. public override object saveContext => null;
  435. public FullscreenSubTarget()
  436. {
  437. displayName = "Fullscreen";
  438. }
  439. public override bool IsNodeAllowedBySubTarget(Type nodeType)
  440. {
  441. var interfaces = nodeType.GetInterfaces();
  442. bool allowed = true;
  443. // Subgraph nodes inherits all the interfaces including vertex ones.
  444. if (nodeType == typeof(SubGraphNode))
  445. return true;
  446. // There is no input in the vertex block for now
  447. if (interfaces.Contains(typeof(IMayRequireVertexID))
  448. || interfaces.Contains(typeof(IMayRequireVertexSkinning))
  449. || interfaces.Contains(typeof(IMayRequireInstanceID)))
  450. allowed = false;
  451. return allowed;
  452. }
  453. public override bool IsActive() => true;
  454. public override void GetFields(ref TargetFieldContext context)
  455. {
  456. context.AddField(UnityEditor.ShaderGraph.Fields.GraphPixel);
  457. context.AddField(FullscreenFields.depth, fullscreenData.depthWrite || fullscreenData.depthTestMode != CompareFunction.Disabled);
  458. }
  459. public override void GetActiveBlocks(ref TargetActiveBlockContext context)
  460. {
  461. context.AddBlock(BlockFields.SurfaceDescription.BaseColor);
  462. context.AddBlock(BlockFields.SurfaceDescription.Alpha);
  463. var depthBlock = FullscreenBlocks.eyeDepth;
  464. if (fullscreenData.depthWriteMode == FullscreenDepthWriteMode.Linear01)
  465. depthBlock = FullscreenBlocks.linear01Depth;
  466. if (fullscreenData.depthWriteMode == FullscreenDepthWriteMode.Raw)
  467. depthBlock = FullscreenBlocks.rawDepth;
  468. context.AddBlock(depthBlock, fullscreenData.depthWrite || fullscreenData.depthTestMode != CompareFunction.Disabled);
  469. }
  470. public override void CollectShaderProperties(PropertyCollector collector, GenerationMode generationMode)
  471. {
  472. if (fullscreenData.allowMaterialOverride)
  473. {
  474. base.CollectShaderProperties(collector, generationMode);
  475. CollectRenderStateShaderProperties(collector, generationMode);
  476. }
  477. collector.AddFloatProperty("_FlipY", 0, HLSLDeclaration.Global, false);
  478. }
  479. public void CollectRenderStateShaderProperties(PropertyCollector collector, GenerationMode generationMode)
  480. {
  481. if (generationMode != GenerationMode.Preview && fullscreenData.allowMaterialOverride)
  482. {
  483. // When blend mode is disabled, we can't override
  484. if (fullscreenData.blendMode != FullscreenBlendMode.Disabled)
  485. {
  486. BlendMode srcColorBlend = fullscreenData.srcColorBlendMode;
  487. BlendMode srcAlphaBlend = fullscreenData.srcAlphaBlendMode;
  488. BlendMode dstColorBlend = fullscreenData.dstColorBlendMode;
  489. BlendMode dstAlphaBlend = fullscreenData.dstAlphaBlendMode;
  490. BlendOp colorBlendOp = fullscreenData.colorBlendOperation;
  491. BlendOp alphaBlendOp = fullscreenData.alphaBlendOperation;
  492. // Patch the default blend values depending on the Blend Mode:
  493. if (fullscreenData.blendMode != FullscreenBlendMode.Custom)
  494. {
  495. colorBlendOp = BlendOp.Add;
  496. alphaBlendOp = BlendOp.Add;
  497. }
  498. if (fullscreenData.blendMode == FullscreenBlendMode.Alpha)
  499. {
  500. srcColorBlend = BlendMode.SrcAlpha;
  501. dstColorBlend = BlendMode.OneMinusSrcAlpha;
  502. srcAlphaBlend = BlendMode.One;
  503. dstAlphaBlend = BlendMode.OneMinusSrcAlpha;
  504. }
  505. else if (fullscreenData.blendMode == FullscreenBlendMode.Premultiply)
  506. {
  507. srcColorBlend = BlendMode.One;
  508. dstColorBlend = BlendMode.OneMinusSrcAlpha;
  509. srcAlphaBlend = BlendMode.One;
  510. dstAlphaBlend = BlendMode.OneMinusSrcAlpha;
  511. }
  512. else if (fullscreenData.blendMode == FullscreenBlendMode.Additive)
  513. {
  514. srcColorBlend = BlendMode.SrcAlpha;
  515. dstColorBlend = BlendMode.One;
  516. srcAlphaBlend = BlendMode.One;
  517. dstAlphaBlend = BlendMode.One;
  518. }
  519. else if (fullscreenData.blendMode == FullscreenBlendMode.Multiply)
  520. {
  521. srcColorBlend = BlendMode.DstColor;
  522. dstColorBlend = BlendMode.Zero;
  523. srcAlphaBlend = BlendMode.One;
  524. dstAlphaBlend = BlendMode.OneMinusSrcAlpha;
  525. }
  526. collector.AddEnumProperty(FullscreenUniforms.blendModeProperty, fullscreenData.blendMode);
  527. collector.AddEnumProperty(FullscreenUniforms.srcColorBlendProperty, srcColorBlend);
  528. collector.AddEnumProperty(FullscreenUniforms.dstColorBlendProperty, dstColorBlend);
  529. collector.AddEnumProperty(FullscreenUniforms.srcAlphaBlendProperty, srcAlphaBlend);
  530. collector.AddEnumProperty(FullscreenUniforms.dstAlphaBlendProperty, dstAlphaBlend);
  531. collector.AddEnumProperty(FullscreenUniforms.colorBlendOperationProperty, colorBlendOp);
  532. collector.AddEnumProperty(FullscreenUniforms.alphaBlendOperationProperty, alphaBlendOp);
  533. }
  534. collector.AddBoolProperty(FullscreenUniforms.depthWriteProperty, fullscreenData.depthWrite);
  535. if (fullscreenData.depthTestMode != CompareFunction.Disabled)
  536. collector.AddEnumProperty(FullscreenUniforms.depthTestProperty, fullscreenData.depthTestMode);
  537. // When stencil is disabled, we can't override
  538. if (fullscreenData.enableStencil)
  539. {
  540. collector.AddBoolProperty(FullscreenUniforms.stencilEnableProperty, fullscreenData.enableStencil);
  541. collector.AddIntProperty(FullscreenUniforms.stencilReferenceProperty, fullscreenData.stencilReference);
  542. collector.AddIntProperty(FullscreenUniforms.stencilReadMaskProperty, fullscreenData.stencilReadMask);
  543. collector.AddIntProperty(FullscreenUniforms.stencilWriteMaskProperty, fullscreenData.stencilWriteMask);
  544. collector.AddEnumProperty(FullscreenUniforms.stencilComparisonProperty, fullscreenData.stencilCompareFunction);
  545. collector.AddEnumProperty(FullscreenUniforms.stencilPassProperty, fullscreenData.stencilPassOperation);
  546. collector.AddEnumProperty(FullscreenUniforms.stencilFailProperty, fullscreenData.stencilFailOperation);
  547. collector.AddEnumProperty(FullscreenUniforms.stencilDepthFailProperty, fullscreenData.stencilDepthTestFailOperation);
  548. }
  549. }
  550. }
  551. public override void GetPropertiesGUI(ref TargetPropertyGUIContext context, Action onChange, Action<String> registerUndo)
  552. {
  553. context.AddProperty("Allow Material Override", new Toggle() { value = fullscreenData.allowMaterialOverride }, (evt) =>
  554. {
  555. if (Equals(fullscreenData.allowMaterialOverride, evt.newValue))
  556. return;
  557. registerUndo("Change Allow Material Override");
  558. fullscreenData.allowMaterialOverride = evt.newValue;
  559. onChange();
  560. });
  561. GetRenderStatePropertiesGUI(ref context, onChange, registerUndo);
  562. }
  563. protected virtual void GetRenderStatePropertiesGUI(ref TargetPropertyGUIContext context, Action onChange, Action<String> registerUndo)
  564. {
  565. GetBlendingPropertiesGUI(ref context, onChange, registerUndo);
  566. context.AddProperty("Depth Test", new EnumField(fullscreenData.depthTestMode) { value = fullscreenData.depthTestMode }, (evt) =>
  567. {
  568. if (Equals(fullscreenData.depthTestMode, evt.newValue))
  569. return;
  570. registerUndo("Change Depth Test");
  571. fullscreenData.depthTestMode = (CompareFunction)evt.newValue;
  572. onChange();
  573. });
  574. context.AddProperty("Depth Write", new Toggle { value = fullscreenData.depthWrite }, (evt) =>
  575. {
  576. if (Equals(fullscreenData.depthWrite, evt.newValue))
  577. return;
  578. registerUndo("Change Depth Write");
  579. fullscreenData.depthWrite = evt.newValue;
  580. onChange();
  581. });
  582. if (fullscreenData.depthWrite || fullscreenData.depthTestMode != CompareFunction.Disabled)
  583. {
  584. context.AddProperty("Depth Write Mode", new EnumField(fullscreenData.depthWriteMode) { value = fullscreenData.depthWriteMode }, (evt) =>
  585. {
  586. if (Equals(fullscreenData.depthWriteMode, evt.newValue))
  587. return;
  588. registerUndo("Change Depth Write Mode");
  589. fullscreenData.depthWriteMode = (FullscreenDepthWriteMode)evt.newValue;
  590. onChange();
  591. });
  592. }
  593. GetStencilPropertiesGUI(ref context, onChange, registerUndo);
  594. }
  595. protected virtual void GetBlendingPropertiesGUI(ref TargetPropertyGUIContext context, Action onChange, Action<String> registerUndo)
  596. {
  597. context.AddProperty("Blend Mode", new EnumField(fullscreenData.blendMode) { value = fullscreenData.blendMode }, (evt) =>
  598. {
  599. if (Equals(fullscreenData.blendMode, evt.newValue))
  600. return;
  601. registerUndo("Change Blend Mode");
  602. fullscreenData.blendMode = (FullscreenBlendMode)evt.newValue;
  603. onChange();
  604. });
  605. if (fullscreenData.blendMode == FullscreenBlendMode.Custom)
  606. {
  607. context.globalIndentLevel++;
  608. context.AddLabel("Color Blend Mode", 0);
  609. context.AddProperty("Src Color", new EnumField(fullscreenData.srcColorBlendMode) { value = fullscreenData.srcColorBlendMode }, (evt) =>
  610. {
  611. if (Equals(fullscreenData.srcColorBlendMode, evt.newValue))
  612. return;
  613. registerUndo("Change Blend Mode");
  614. fullscreenData.srcColorBlendMode = (BlendMode)evt.newValue;
  615. onChange();
  616. });
  617. context.AddProperty("Dst Color", new EnumField(fullscreenData.dstColorBlendMode) { value = fullscreenData.dstColorBlendMode }, (evt) =>
  618. {
  619. if (Equals(fullscreenData.dstColorBlendMode, evt.newValue))
  620. return;
  621. registerUndo("Change Blend Mode");
  622. fullscreenData.dstColorBlendMode = (BlendMode)evt.newValue;
  623. onChange();
  624. });
  625. context.AddProperty("Color Operation", new EnumField(fullscreenData.colorBlendOperation) { value = fullscreenData.colorBlendOperation }, (evt) =>
  626. {
  627. if (Equals(fullscreenData.colorBlendOperation, evt.newValue))
  628. return;
  629. registerUndo("Change Blend Mode");
  630. fullscreenData.colorBlendOperation = (BlendOp)evt.newValue;
  631. onChange();
  632. });
  633. context.AddLabel("Alpha Blend Mode", 0);
  634. context.AddProperty("Src", new EnumField(fullscreenData.srcAlphaBlendMode) { value = fullscreenData.srcAlphaBlendMode }, (evt) =>
  635. {
  636. if (Equals(fullscreenData.srcAlphaBlendMode, evt.newValue))
  637. return;
  638. registerUndo("Change Blend Mode");
  639. fullscreenData.srcAlphaBlendMode = (BlendMode)evt.newValue;
  640. onChange();
  641. });
  642. context.AddProperty("Dst", new EnumField(fullscreenData.dstAlphaBlendMode) { value = fullscreenData.dstAlphaBlendMode }, (evt) =>
  643. {
  644. if (Equals(fullscreenData.dstAlphaBlendMode, evt.newValue))
  645. return;
  646. registerUndo("Change Blend Mode");
  647. fullscreenData.dstAlphaBlendMode = (BlendMode)evt.newValue;
  648. onChange();
  649. });
  650. context.AddProperty("Blend Operation Alpha", new EnumField(fullscreenData.alphaBlendOperation) { value = fullscreenData.alphaBlendOperation }, (evt) =>
  651. {
  652. if (Equals(fullscreenData.alphaBlendOperation, evt.newValue))
  653. return;
  654. registerUndo("Change Blend Mode");
  655. fullscreenData.alphaBlendOperation = (BlendOp)evt.newValue;
  656. onChange();
  657. });
  658. context.globalIndentLevel--;
  659. }
  660. }
  661. protected virtual void GetStencilPropertiesGUI(ref TargetPropertyGUIContext context, Action onChange, Action<String> registerUndo)
  662. {
  663. context.AddProperty("Enable Stencil", new Toggle { value = fullscreenData.enableStencil }, (evt) =>
  664. {
  665. if (Equals(fullscreenData.enableStencil, evt.newValue))
  666. return;
  667. registerUndo("Change Enable Stencil");
  668. fullscreenData.enableStencil = evt.newValue;
  669. onChange();
  670. });
  671. if (fullscreenData.enableStencil)
  672. {
  673. context.globalIndentLevel++;
  674. context.AddProperty("Reference", new IntegerField { value = fullscreenData.stencilReference, isDelayed = true }, (evt) =>
  675. {
  676. if (Equals(fullscreenData.stencilReference, evt.newValue))
  677. return;
  678. registerUndo("Change Stencil Reference");
  679. fullscreenData.stencilReference = evt.newValue;
  680. onChange();
  681. });
  682. context.AddProperty("Read Mask", new IntegerField { value = fullscreenData.stencilReadMask, isDelayed = true }, (evt) =>
  683. {
  684. if (Equals(fullscreenData.stencilReadMask, evt.newValue))
  685. return;
  686. registerUndo("Change Stencil Read Mask");
  687. fullscreenData.stencilReadMask = evt.newValue;
  688. onChange();
  689. });
  690. context.AddProperty("Write Mask", new IntegerField { value = fullscreenData.stencilWriteMask, isDelayed = true }, (evt) =>
  691. {
  692. if (Equals(fullscreenData.stencilWriteMask, evt.newValue))
  693. return;
  694. registerUndo("Change Stencil Write Mask");
  695. fullscreenData.stencilWriteMask = evt.newValue;
  696. onChange();
  697. });
  698. context.AddProperty("Comparison", new EnumField(fullscreenData.stencilCompareFunction) { value = fullscreenData.stencilCompareFunction }, (evt) =>
  699. {
  700. if (Equals(fullscreenData.stencilCompareFunction, evt.newValue))
  701. return;
  702. registerUndo("Change Stencil Comparison");
  703. fullscreenData.stencilCompareFunction = (CompareFunction)evt.newValue;
  704. onChange();
  705. });
  706. context.AddProperty("Pass", new EnumField(fullscreenData.stencilPassOperation) { value = fullscreenData.stencilPassOperation }, (evt) =>
  707. {
  708. if (Equals(fullscreenData.stencilPassOperation, evt.newValue))
  709. return;
  710. registerUndo("Change Stencil Pass Operation");
  711. fullscreenData.stencilPassOperation = (StencilOp)evt.newValue;
  712. onChange();
  713. });
  714. context.AddProperty("Fail", new EnumField(fullscreenData.stencilFailOperation) { value = fullscreenData.stencilFailOperation }, (evt) =>
  715. {
  716. if (Equals(fullscreenData.stencilFailOperation, evt.newValue))
  717. return;
  718. registerUndo("Change Stencil Fail Operation");
  719. fullscreenData.stencilFailOperation = (StencilOp)evt.newValue;
  720. onChange();
  721. });
  722. context.AddProperty("Depth Fail", new EnumField(fullscreenData.stencilDepthTestFailOperation) { value = fullscreenData.stencilDepthTestFailOperation }, (evt) =>
  723. {
  724. if (Equals(fullscreenData.stencilDepthTestFailOperation, evt.newValue))
  725. return;
  726. registerUndo("Change Stencil Depth Fail Operation");
  727. fullscreenData.stencilDepthTestFailOperation = (StencilOp)evt.newValue;
  728. onChange();
  729. });
  730. context.globalIndentLevel--;
  731. }
  732. }
  733. }
  734. internal static class FullscreenPropertyCollectorExtension
  735. {
  736. public static void AddEnumProperty<T>(this PropertyCollector collector, string prop, T value, HLSLDeclaration hlslDeclaration = HLSLDeclaration.DoNotDeclare) where T : Enum
  737. {
  738. collector.AddShaderProperty(new Vector1ShaderProperty
  739. {
  740. floatType = FloatType.Enum,
  741. enumType = EnumType.CSharpEnum,
  742. cSharpEnumType = typeof(T),
  743. hidden = true,
  744. overrideHLSLDeclaration = true,
  745. hlslDeclarationOverride = hlslDeclaration,
  746. value = Convert.ToInt32(value),
  747. overrideReferenceName = prop,
  748. });
  749. }
  750. public static void AddIntProperty(this PropertyCollector collector, string prop, int value, HLSLDeclaration hlslDeclaration = HLSLDeclaration.DoNotDeclare)
  751. {
  752. collector.AddShaderProperty(new Vector1ShaderProperty
  753. {
  754. floatType = FloatType.Integer,
  755. hidden = true,
  756. overrideHLSLDeclaration = true,
  757. hlslDeclarationOverride = hlslDeclaration,
  758. value = value,
  759. overrideReferenceName = prop,
  760. });
  761. }
  762. public static void AddBoolProperty(this PropertyCollector collector, string prop, bool value, HLSLDeclaration hlslDeclaration = HLSLDeclaration.DoNotDeclare)
  763. {
  764. collector.AddShaderProperty(new BooleanShaderProperty
  765. {
  766. hidden = true,
  767. overrideHLSLDeclaration = true,
  768. hlslDeclarationOverride = hlslDeclaration,
  769. value = value,
  770. overrideReferenceName = prop,
  771. });
  772. }
  773. public static void AddFloatProperty(this PropertyCollector collector, string referenceName, float defaultValue, HLSLDeclaration declarationType = HLSLDeclaration.DoNotDeclare, bool generatePropertyBlock = true)
  774. {
  775. collector.AddShaderProperty(new Vector1ShaderProperty
  776. {
  777. floatType = FloatType.Default,
  778. hidden = true,
  779. overrideHLSLDeclaration = true,
  780. hlslDeclarationOverride = declarationType,
  781. value = defaultValue,
  782. generatePropertyBlock = generatePropertyBlock,
  783. overrideReferenceName = referenceName,
  784. });
  785. }
  786. }
  787. }