UniversalPBRSubShader.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEditor.Graphing;
  5. using UnityEditor.ShaderGraph;
  6. using UnityEditor.ShaderGraph.Internal;
  7. using UnityEngine.Rendering;
  8. using UnityEngine.Rendering.Universal;
  9. using Data.Util;
  10. namespace UnityEditor.Rendering.Universal
  11. {
  12. [Serializable]
  13. [FormerName("UnityEditor.Experimental.Rendering.LightweightPipeline.LightWeightPBRSubShader")]
  14. [FormerName("UnityEditor.ShaderGraph.LightWeightPBRSubShader")]
  15. [FormerName("UnityEditor.Rendering.LWRP.LightWeightPBRSubShader")]
  16. class UniversalPBRSubShader : IPBRSubShader
  17. {
  18. #region Passes
  19. ShaderPass m_ForwardPass = new ShaderPass
  20. {
  21. // Definition
  22. displayName = "Universal Forward",
  23. referenceName = "SHADERPASS_FORWARD",
  24. lightMode = "UniversalForward",
  25. passInclude = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRForwardPass.hlsl",
  26. varyingsInclude = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Varyings.hlsl",
  27. useInPreview = true,
  28. // Port mask
  29. vertexPorts = new List<int>()
  30. {
  31. PBRMasterNode.PositionSlotId,
  32. PBRMasterNode.VertNormalSlotId,
  33. PBRMasterNode.VertTangentSlotId
  34. },
  35. pixelPorts = new List<int>
  36. {
  37. PBRMasterNode.AlbedoSlotId,
  38. PBRMasterNode.NormalSlotId,
  39. PBRMasterNode.EmissionSlotId,
  40. PBRMasterNode.MetallicSlotId,
  41. PBRMasterNode.SpecularSlotId,
  42. PBRMasterNode.SmoothnessSlotId,
  43. PBRMasterNode.OcclusionSlotId,
  44. PBRMasterNode.AlphaSlotId,
  45. PBRMasterNode.AlphaThresholdSlotId
  46. },
  47. // Required fields
  48. requiredAttributes = new List<string>()
  49. {
  50. "Attributes.uv1", //needed for meta vertex position
  51. },
  52. // Required fields
  53. requiredVaryings = new List<string>()
  54. {
  55. "Varyings.positionWS",
  56. "Varyings.normalWS",
  57. "Varyings.tangentWS", //needed for vertex lighting
  58. "Varyings.viewDirectionWS",
  59. "Varyings.lightmapUV",
  60. "Varyings.sh",
  61. "Varyings.fogFactorAndVertexLight", //fog and vertex lighting, vert input is dependency
  62. "Varyings.shadowCoord", //shadow coord, vert input is dependency
  63. },
  64. // Pass setup
  65. includes = new List<string>()
  66. {
  67. "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl",
  68. "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl",
  69. "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl",
  70. "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl",
  71. "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl",
  72. "Packages/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariablesFunctions.hlsl"
  73. },
  74. pragmas = new List<string>()
  75. {
  76. "prefer_hlslcc gles",
  77. "exclude_renderers d3d11_9x",
  78. "target 2.0",
  79. "multi_compile_fog",
  80. "multi_compile_instancing",
  81. },
  82. keywords = new KeywordDescriptor[]
  83. {
  84. s_LightmapKeyword,
  85. s_DirectionalLightmapCombinedKeyword,
  86. s_MainLightShadowsKeyword,
  87. s_MainLightShadowsCascadeKeyword,
  88. s_AdditionalLightsKeyword,
  89. s_AdditionalLightShadowsKeyword,
  90. s_ShadowsSoftKeyword,
  91. s_MixedLightingSubtractiveKeyword,
  92. },
  93. };
  94. ShaderPass m_DepthOnlyPass = new ShaderPass()
  95. {
  96. // Definition
  97. displayName = "DepthOnly",
  98. referenceName = "SHADERPASS_DEPTHONLY",
  99. lightMode = "DepthOnly",
  100. passInclude = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/DepthOnlyPass.hlsl",
  101. varyingsInclude = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Varyings.hlsl",
  102. useInPreview = true,
  103. // Port mask
  104. vertexPorts = new List<int>()
  105. {
  106. PBRMasterNode.PositionSlotId,
  107. PBRMasterNode.VertNormalSlotId,
  108. PBRMasterNode.VertTangentSlotId
  109. },
  110. pixelPorts = new List<int>()
  111. {
  112. PBRMasterNode.AlphaSlotId,
  113. PBRMasterNode.AlphaThresholdSlotId
  114. },
  115. // Render State Overrides
  116. ZWriteOverride = "ZWrite On",
  117. ColorMaskOverride = "ColorMask 0",
  118. // Pass setup
  119. includes = new List<string>()
  120. {
  121. "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl",
  122. "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl",
  123. "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl",
  124. "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl",
  125. "Packages/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariablesFunctions.hlsl"
  126. },
  127. pragmas = new List<string>()
  128. {
  129. "prefer_hlslcc gles",
  130. "exclude_renderers d3d11_9x",
  131. "target 2.0",
  132. "multi_compile_instancing",
  133. },
  134. };
  135. ShaderPass m_ShadowCasterPass = new ShaderPass()
  136. {
  137. // Definition
  138. displayName = "ShadowCaster",
  139. referenceName = "SHADERPASS_SHADOWCASTER",
  140. lightMode = "ShadowCaster",
  141. passInclude = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShadowCasterPass.hlsl",
  142. varyingsInclude = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Varyings.hlsl",
  143. // Port mask
  144. vertexPorts = new List<int>()
  145. {
  146. PBRMasterNode.PositionSlotId,
  147. PBRMasterNode.VertNormalSlotId,
  148. PBRMasterNode.VertTangentSlotId
  149. },
  150. pixelPorts = new List<int>()
  151. {
  152. PBRMasterNode.AlphaSlotId,
  153. PBRMasterNode.AlphaThresholdSlotId
  154. },
  155. // Required fields
  156. requiredAttributes = new List<string>()
  157. {
  158. "Attributes.normalOS",
  159. },
  160. // Render State Overrides
  161. ZWriteOverride = "ZWrite On",
  162. ZTestOverride = "ZTest LEqual",
  163. // Pass setup
  164. includes = new List<string>()
  165. {
  166. "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl",
  167. "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl",
  168. "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl",
  169. "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl",
  170. "Packages/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariablesFunctions.hlsl"
  171. },
  172. pragmas = new List<string>()
  173. {
  174. "prefer_hlslcc gles",
  175. "exclude_renderers d3d11_9x",
  176. "target 2.0",
  177. "multi_compile_instancing",
  178. },
  179. };
  180. ShaderPass m_LitMetaPass = new ShaderPass()
  181. {
  182. // Definition
  183. displayName = "Meta",
  184. referenceName = "SHADERPASS_META",
  185. lightMode = "Meta",
  186. passInclude = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/LightingMetaPass.hlsl",
  187. varyingsInclude = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Varyings.hlsl",
  188. // Port mask
  189. vertexPorts = new List<int>()
  190. {
  191. PBRMasterNode.PositionSlotId,
  192. PBRMasterNode.VertNormalSlotId,
  193. PBRMasterNode.VertTangentSlotId
  194. },
  195. pixelPorts = new List<int>()
  196. {
  197. PBRMasterNode.AlbedoSlotId,
  198. PBRMasterNode.EmissionSlotId,
  199. PBRMasterNode.AlphaSlotId,
  200. PBRMasterNode.AlphaThresholdSlotId
  201. },
  202. // Required fields
  203. requiredAttributes = new List<string>()
  204. {
  205. "Attributes.uv1", //needed for meta vertex position
  206. "Attributes.uv2", //needed for meta vertex position
  207. },
  208. // Render State Overrides
  209. ZWriteOverride = "ZWrite On",
  210. ZTestOverride = "ZTest LEqual",
  211. // Pass setup
  212. includes = new List<string>()
  213. {
  214. "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl",
  215. "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl",
  216. "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl",
  217. "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl",
  218. "Packages/com.unity.render-pipelines.universal/ShaderLibrary/MetaInput.hlsl",
  219. "Packages/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariablesFunctions.hlsl"
  220. },
  221. pragmas = new List<string>()
  222. {
  223. "prefer_hlslcc gles",
  224. "exclude_renderers d3d11_9x",
  225. "target 2.0",
  226. },
  227. keywords = new KeywordDescriptor[]
  228. {
  229. s_SmoothnessChannelKeyword,
  230. },
  231. };
  232. ShaderPass m_2DPass = new ShaderPass()
  233. {
  234. // Definition
  235. referenceName = "SHADERPASS_2D",
  236. lightMode = "Universal2D",
  237. passInclude = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBR2DPass.hlsl",
  238. varyingsInclude = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Varyings.hlsl",
  239. // Port mask
  240. vertexPorts = new List<int>()
  241. {
  242. PBRMasterNode.PositionSlotId,
  243. PBRMasterNode.VertNormalSlotId,
  244. PBRMasterNode.VertTangentSlotId
  245. },
  246. pixelPorts = new List<int>()
  247. {
  248. PBRMasterNode.AlbedoSlotId,
  249. PBRMasterNode.AlphaSlotId,
  250. PBRMasterNode.AlphaThresholdSlotId
  251. },
  252. // Pass setup
  253. includes = new List<string>()
  254. {
  255. "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl",
  256. "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl",
  257. "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl",
  258. "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl",
  259. "Packages/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariablesFunctions.hlsl"
  260. },
  261. pragmas = new List<string>()
  262. {
  263. "prefer_hlslcc gles",
  264. "exclude_renderers d3d11_9x",
  265. "target 2.0",
  266. "multi_compile_instancing",
  267. },
  268. };
  269. #endregion
  270. #region Keywords
  271. static KeywordDescriptor s_LightmapKeyword = new KeywordDescriptor()
  272. {
  273. displayName = "Lightmap",
  274. referenceName = "LIGHTMAP_ON",
  275. type = KeywordType.Boolean,
  276. definition = KeywordDefinition.MultiCompile,
  277. scope = KeywordScope.Global,
  278. };
  279. static KeywordDescriptor s_DirectionalLightmapCombinedKeyword = new KeywordDescriptor()
  280. {
  281. displayName = "Directional Lightmap Combined",
  282. referenceName = "DIRLIGHTMAP_COMBINED",
  283. type = KeywordType.Boolean,
  284. definition = KeywordDefinition.MultiCompile,
  285. scope = KeywordScope.Global,
  286. };
  287. static KeywordDescriptor s_SampleGIKeyword = new KeywordDescriptor()
  288. {
  289. displayName = "Sample GI",
  290. referenceName = "_SAMPLE_GI",
  291. type = KeywordType.Boolean,
  292. definition = KeywordDefinition.ShaderFeature,
  293. scope = KeywordScope.Global,
  294. };
  295. static KeywordDescriptor s_MainLightShadowsKeyword = new KeywordDescriptor()
  296. {
  297. displayName = "Main Light Shadows",
  298. referenceName = "_MAIN_LIGHT_SHADOWS",
  299. type = KeywordType.Boolean,
  300. definition = KeywordDefinition.MultiCompile,
  301. scope = KeywordScope.Global,
  302. };
  303. static KeywordDescriptor s_MainLightShadowsCascadeKeyword = new KeywordDescriptor()
  304. {
  305. displayName = "Main Light Shadows Cascade",
  306. referenceName = "_MAIN_LIGHT_SHADOWS_CASCADE",
  307. type = KeywordType.Boolean,
  308. definition = KeywordDefinition.MultiCompile,
  309. scope = KeywordScope.Global,
  310. };
  311. static KeywordDescriptor s_AdditionalLightsKeyword = new KeywordDescriptor()
  312. {
  313. displayName = "Additional Lights",
  314. referenceName = "_ADDITIONAL",
  315. type = KeywordType.Enum,
  316. definition = KeywordDefinition.MultiCompile,
  317. scope = KeywordScope.Global,
  318. entries = new KeywordEntry[]
  319. {
  320. new KeywordEntry() { displayName = "Vertex", referenceName = "LIGHTS_VERTEX" },
  321. new KeywordEntry() { displayName = "Fragment", referenceName = "LIGHTS" },
  322. new KeywordEntry() { displayName = "Off", referenceName = "OFF" },
  323. }
  324. };
  325. static KeywordDescriptor s_AdditionalLightShadowsKeyword = new KeywordDescriptor()
  326. {
  327. displayName = "Additional Light Shadows",
  328. referenceName = "_ADDITIONAL_LIGHT_SHADOWS",
  329. type = KeywordType.Boolean,
  330. definition = KeywordDefinition.MultiCompile,
  331. scope = KeywordScope.Global,
  332. };
  333. static KeywordDescriptor s_ShadowsSoftKeyword = new KeywordDescriptor()
  334. {
  335. displayName = "Shadows Soft",
  336. referenceName = "_SHADOWS_SOFT",
  337. type = KeywordType.Boolean,
  338. definition = KeywordDefinition.MultiCompile,
  339. scope = KeywordScope.Global,
  340. };
  341. static KeywordDescriptor s_MixedLightingSubtractiveKeyword = new KeywordDescriptor()
  342. {
  343. displayName = "Mixed Lighting Subtractive",
  344. referenceName = "_MIXED_LIGHTING_SUBTRACTIVE",
  345. type = KeywordType.Boolean,
  346. definition = KeywordDefinition.MultiCompile,
  347. scope = KeywordScope.Global,
  348. };
  349. static KeywordDescriptor s_SmoothnessChannelKeyword = new KeywordDescriptor()
  350. {
  351. displayName = "Smoothness Channel",
  352. referenceName = "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A",
  353. type = KeywordType.Boolean,
  354. definition = KeywordDefinition.ShaderFeature,
  355. scope = KeywordScope.Global,
  356. };
  357. #endregion
  358. public int GetPreviewPassIndex() { return 0; }
  359. ActiveFields GetActiveFieldsFromMasterNode(PBRMasterNode masterNode, ShaderPass pass)
  360. {
  361. var activeFields = new ActiveFields();
  362. var baseActiveFields = activeFields.baseInstance;
  363. // Graph Vertex
  364. if(masterNode.IsSlotConnected(PBRMasterNode.PositionSlotId) ||
  365. masterNode.IsSlotConnected(PBRMasterNode.VertNormalSlotId) ||
  366. masterNode.IsSlotConnected(PBRMasterNode.VertTangentSlotId))
  367. {
  368. baseActiveFields.Add("features.graphVertex");
  369. }
  370. // Graph Pixel (always enabled)
  371. baseActiveFields.Add("features.graphPixel");
  372. if (masterNode.IsSlotConnected(PBRMasterNode.AlphaThresholdSlotId) ||
  373. masterNode.GetInputSlots<Vector1MaterialSlot>().First(x => x.id == PBRMasterNode.AlphaThresholdSlotId).value > 0.0f)
  374. {
  375. baseActiveFields.Add("AlphaClip");
  376. }
  377. if (masterNode.model == PBRMasterNode.Model.Specular)
  378. baseActiveFields.Add("SpecularSetup");
  379. if (masterNode.IsSlotConnected(PBRMasterNode.NormalSlotId))
  380. {
  381. baseActiveFields.Add("Normal");
  382. }
  383. switch(masterNode.normalDropOffSpace)
  384. {
  385. case NormalDropOffSpace.Tangent:
  386. baseActiveFields.AddAll("features.NormalDropOffTS");
  387. break;
  388. case NormalDropOffSpace.Object:
  389. baseActiveFields.AddAll("features.NormalDropOffOS");
  390. break;
  391. case NormalDropOffSpace.World:
  392. baseActiveFields.AddAll("features.NormalDropOffWS");
  393. break;
  394. default:
  395. UnityEngine.Debug.LogError("Unknown normal drop off space: " + masterNode.normalDropOffSpace);
  396. break;
  397. }
  398. // Keywords for transparent
  399. // #pragma shader_feature _SURFACE_TYPE_TRANSPARENT
  400. if (masterNode.surfaceType != ShaderGraph.SurfaceType.Opaque)
  401. {
  402. // transparent-only defines
  403. baseActiveFields.Add("SurfaceType.Transparent");
  404. // #pragma shader_feature _ _BLENDMODE_ALPHA _BLENDMODE_ADD _BLENDMODE_PRE_MULTIPLY
  405. if (masterNode.alphaMode == AlphaMode.Alpha)
  406. {
  407. baseActiveFields.Add("BlendMode.Alpha");
  408. }
  409. else if (masterNode.alphaMode == AlphaMode.Additive)
  410. {
  411. baseActiveFields.Add("BlendMode.Add");
  412. }
  413. else if (masterNode.alphaMode == AlphaMode.Premultiply)
  414. {
  415. baseActiveFields.Add("BlendMode.Premultiply");
  416. }
  417. }
  418. return activeFields;
  419. }
  420. bool GenerateShaderPass(PBRMasterNode masterNode, ShaderPass pass, GenerationMode mode, ShaderGenerator result, List<string> sourceAssetDependencyPaths)
  421. {
  422. UniversalShaderGraphUtilities.SetRenderState(masterNode.surfaceType, masterNode.alphaMode, masterNode.twoSided.isOn, ref pass);
  423. // apply master node options to active fields
  424. var activeFields = GetActiveFieldsFromMasterNode(masterNode, pass);
  425. return ShaderGraph.GenerationUtils.GenerateShaderPass(masterNode, pass, mode, activeFields, result, sourceAssetDependencyPaths,
  426. UniversalShaderGraphResources.s_Dependencies, UniversalShaderGraphResources.s_ResourceClassName, UniversalShaderGraphResources.s_AssemblyName);
  427. }
  428. public string GetSubshader(IMasterNode masterNode, GenerationMode mode, List<string> sourceAssetDependencyPaths = null)
  429. {
  430. if (sourceAssetDependencyPaths != null)
  431. {
  432. // UniversalPBRSubShader.cs
  433. sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("f2df349d00ec920488971bb77440b7bc"));
  434. }
  435. // Master Node data
  436. var pbrMasterNode = masterNode as PBRMasterNode;
  437. var subShader = new ShaderGenerator();
  438. subShader.AddShaderChunk("SubShader", true);
  439. subShader.AddShaderChunk("{", true);
  440. subShader.Indent();
  441. {
  442. var surfaceTags = ShaderGenerator.BuildMaterialTags(pbrMasterNode.surfaceType);
  443. var tagsBuilder = new ShaderStringBuilder(0);
  444. surfaceTags.GetTags(tagsBuilder, "UniversalPipeline");
  445. subShader.AddShaderChunk(tagsBuilder.ToString());
  446. GenerateShaderPass(pbrMasterNode, m_ForwardPass, mode, subShader, sourceAssetDependencyPaths);
  447. GenerateShaderPass(pbrMasterNode, m_ShadowCasterPass, mode, subShader, sourceAssetDependencyPaths);
  448. GenerateShaderPass(pbrMasterNode, m_DepthOnlyPass, mode, subShader, sourceAssetDependencyPaths);
  449. GenerateShaderPass(pbrMasterNode, m_LitMetaPass, mode, subShader, sourceAssetDependencyPaths);
  450. GenerateShaderPass(pbrMasterNode, m_2DPass, mode, subShader, sourceAssetDependencyPaths);
  451. }
  452. subShader.Deindent();
  453. subShader.AddShaderChunk("}", true);
  454. subShader.AddShaderChunk(@"CustomEditor ""UnityEditor.ShaderGraph.PBRMasterGUI""");
  455. return subShader.GetShaderString(0);
  456. }
  457. public bool IsPipelineCompatible(RenderPipelineAsset renderPipelineAsset)
  458. {
  459. return renderPipelineAsset is UniversalRenderPipelineAsset;
  460. }
  461. public UniversalPBRSubShader() { }
  462. }
  463. }