PBRMasterNode.cs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. using System;
  2. using System.Linq;
  3. using System.Collections.Generic;
  4. using UnityEditor.Graphing;
  5. using UnityEditor.ShaderGraph.Drawing;
  6. using UnityEditor.ShaderGraph.Drawing.Controls;
  7. using UnityEditor.ShaderGraph.Internal;
  8. using UnityEngine;
  9. using UnityEngine.UIElements;
  10. namespace UnityEditor.ShaderGraph
  11. {
  12. [Serializable]
  13. [Title("Master", "PBR")]
  14. class PBRMasterNode : MasterNode<IPBRSubShader>, IMayRequirePosition, IMayRequireNormal, IMayRequireTangent
  15. {
  16. public const string AlbedoSlotName = "Albedo";
  17. public const string NormalSlotName = "Normal";
  18. public const string EmissionSlotName = "Emission";
  19. public const string MetallicSlotName = "Metallic";
  20. public const string SpecularSlotName = "Specular";
  21. public const string SmoothnessSlotName = "Smoothness";
  22. public const string OcclusionSlotName = "Occlusion";
  23. public const string AlphaSlotName = "Alpha";
  24. public const string AlphaClipThresholdSlotName = "AlphaClipThreshold";
  25. public const string PositionName = "Vertex Position";
  26. public const string NormalName = "Vertex Normal";
  27. public const string TangentName = "Vertex Tangent";
  28. public const int AlbedoSlotId = 0;
  29. public const int NormalSlotId = 1;
  30. public const int MetallicSlotId = 2;
  31. public const int SpecularSlotId = 3;
  32. public const int EmissionSlotId = 4;
  33. public const int SmoothnessSlotId = 5;
  34. public const int OcclusionSlotId = 6;
  35. public const int AlphaSlotId = 7;
  36. public const int AlphaThresholdSlotId = 8;
  37. public const int PositionSlotId = 9;
  38. public const int VertNormalSlotId = 10;
  39. public const int VertTangentSlotId = 11;
  40. public enum Model
  41. {
  42. Specular,
  43. Metallic
  44. }
  45. [SerializeField]
  46. Model m_Model = Model.Metallic;
  47. public Model model
  48. {
  49. get { return m_Model; }
  50. set
  51. {
  52. if (m_Model == value)
  53. return;
  54. m_Model = value;
  55. UpdateNodeAfterDeserialization();
  56. Dirty(ModificationScope.Topological);
  57. }
  58. }
  59. [SerializeField]
  60. SurfaceType m_SurfaceType;
  61. public SurfaceType surfaceType
  62. {
  63. get { return m_SurfaceType; }
  64. set
  65. {
  66. if (m_SurfaceType == value)
  67. return;
  68. m_SurfaceType = value;
  69. Dirty(ModificationScope.Graph);
  70. }
  71. }
  72. [SerializeField]
  73. AlphaMode m_AlphaMode;
  74. public AlphaMode alphaMode
  75. {
  76. get { return m_AlphaMode; }
  77. set
  78. {
  79. if (m_AlphaMode == value)
  80. return;
  81. m_AlphaMode = value;
  82. Dirty(ModificationScope.Graph);
  83. }
  84. }
  85. [SerializeField]
  86. bool m_TwoSided;
  87. public ToggleData twoSided
  88. {
  89. get { return new ToggleData(m_TwoSided); }
  90. set
  91. {
  92. if (m_TwoSided == value.isOn)
  93. return;
  94. m_TwoSided = value.isOn;
  95. Dirty(ModificationScope.Graph);
  96. }
  97. }
  98. [SerializeField]
  99. NormalDropOffSpace m_NormalDropOffSpace;
  100. public NormalDropOffSpace normalDropOffSpace
  101. {
  102. get { return m_NormalDropOffSpace; }
  103. set
  104. {
  105. if (m_NormalDropOffSpace == value)
  106. return;
  107. m_NormalDropOffSpace = value;
  108. if (!IsSlotConnected(NormalSlotId))
  109. updateNormalSlot = true;
  110. UpdateNodeAfterDeserialization();
  111. Dirty(ModificationScope.Topological);
  112. }
  113. }
  114. bool updateNormalSlot;
  115. public PBRMasterNode()
  116. {
  117. UpdateNodeAfterDeserialization();
  118. }
  119. public sealed override void UpdateNodeAfterDeserialization()
  120. {
  121. base.UpdateNodeAfterDeserialization();
  122. name = "PBR Master";
  123. AddSlot(new PositionMaterialSlot(PositionSlotId, PositionName, PositionName, CoordinateSpace.Object, ShaderStageCapability.Vertex));
  124. AddSlot(new NormalMaterialSlot(VertNormalSlotId, NormalName, NormalName, CoordinateSpace.Object, ShaderStageCapability.Vertex));
  125. AddSlot(new TangentMaterialSlot(VertTangentSlotId, TangentName, TangentName, CoordinateSpace.Object, ShaderStageCapability.Vertex));
  126. AddSlot(new ColorRGBMaterialSlot(AlbedoSlotId, AlbedoSlotName, AlbedoSlotName, SlotType.Input, Color.grey.gamma, ColorMode.Default, ShaderStageCapability.Fragment));
  127. //switch drop off delivery space for normal values
  128. var coordSpace = CoordinateSpace.Tangent;
  129. if (updateNormalSlot)
  130. {
  131. RemoveSlot(NormalSlotId);
  132. switch (m_NormalDropOffSpace)
  133. {
  134. case NormalDropOffSpace.Tangent:
  135. coordSpace = CoordinateSpace.Tangent;
  136. break;
  137. case NormalDropOffSpace.World:
  138. coordSpace = CoordinateSpace.World;
  139. break;
  140. case NormalDropOffSpace.Object:
  141. coordSpace = CoordinateSpace.Object;
  142. break;
  143. }
  144. updateNormalSlot = false;
  145. }
  146. AddSlot(new NormalMaterialSlot(NormalSlotId, NormalSlotName, NormalSlotName, coordSpace, ShaderStageCapability.Fragment));
  147. AddSlot(new ColorRGBMaterialSlot(EmissionSlotId, EmissionSlotName, EmissionSlotName, SlotType.Input, Color.black, ColorMode.Default, ShaderStageCapability.Fragment));
  148. if (model == Model.Metallic)
  149. AddSlot(new Vector1MaterialSlot(MetallicSlotId, MetallicSlotName, MetallicSlotName, SlotType.Input, 0, ShaderStageCapability.Fragment));
  150. else
  151. AddSlot(new ColorRGBMaterialSlot(SpecularSlotId, SpecularSlotName, SpecularSlotName, SlotType.Input, Color.grey, ColorMode.Default, ShaderStageCapability.Fragment));
  152. AddSlot(new Vector1MaterialSlot(SmoothnessSlotId, SmoothnessSlotName, SmoothnessSlotName, SlotType.Input, 0.5f, ShaderStageCapability.Fragment));
  153. AddSlot(new Vector1MaterialSlot(OcclusionSlotId, OcclusionSlotName, OcclusionSlotName, SlotType.Input, 1f, ShaderStageCapability.Fragment));
  154. AddSlot(new Vector1MaterialSlot(AlphaSlotId, AlphaSlotName, AlphaSlotName, SlotType.Input, 1f, ShaderStageCapability.Fragment));
  155. AddSlot(new Vector1MaterialSlot(AlphaThresholdSlotId, AlphaClipThresholdSlotName, AlphaClipThresholdSlotName, SlotType.Input, 0.0f, ShaderStageCapability.Fragment));
  156. // clear out slot names that do not match the slots
  157. // we support
  158. RemoveSlotsNameNotMatching(
  159. new[]
  160. {
  161. PositionSlotId,
  162. VertNormalSlotId,
  163. VertTangentSlotId,
  164. AlbedoSlotId,
  165. NormalSlotId,
  166. EmissionSlotId,
  167. model == Model.Metallic ? MetallicSlotId : SpecularSlotId,
  168. SmoothnessSlotId,
  169. OcclusionSlotId,
  170. AlphaSlotId,
  171. AlphaThresholdSlotId
  172. }, true);
  173. }
  174. protected override VisualElement CreateCommonSettingsElement()
  175. {
  176. return new PBRSettingsView(this);
  177. }
  178. public NeededCoordinateSpace RequiresNormal(ShaderStageCapability stageCapability)
  179. {
  180. List<MaterialSlot> slots = new List<MaterialSlot>();
  181. GetSlots(slots);
  182. List<MaterialSlot> validSlots = new List<MaterialSlot>();
  183. for (int i = 0; i < slots.Count; i++)
  184. {
  185. if (slots[i].stageCapability != ShaderStageCapability.All && slots[i].stageCapability != stageCapability)
  186. continue;
  187. validSlots.Add(slots[i]);
  188. }
  189. return validSlots.OfType<IMayRequireNormal>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresNormal(stageCapability));
  190. }
  191. public NeededCoordinateSpace RequiresPosition(ShaderStageCapability stageCapability)
  192. {
  193. List<MaterialSlot> slots = new List<MaterialSlot>();
  194. GetSlots(slots);
  195. List<MaterialSlot> validSlots = new List<MaterialSlot>();
  196. for (int i = 0; i < slots.Count; i++)
  197. {
  198. if (slots[i].stageCapability != ShaderStageCapability.All && slots[i].stageCapability != stageCapability)
  199. continue;
  200. validSlots.Add(slots[i]);
  201. }
  202. return validSlots.OfType<IMayRequirePosition>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresPosition(stageCapability));
  203. }
  204. public NeededCoordinateSpace RequiresTangent(ShaderStageCapability stageCapability)
  205. {
  206. List<MaterialSlot> slots = new List<MaterialSlot>();
  207. GetSlots(slots);
  208. List<MaterialSlot> validSlots = new List<MaterialSlot>();
  209. for (int i = 0; i < slots.Count; i++)
  210. {
  211. if (slots[i].stageCapability != ShaderStageCapability.All && slots[i].stageCapability != stageCapability)
  212. continue;
  213. validSlots.Add(slots[i]);
  214. }
  215. return validSlots.OfType<IMayRequireTangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresTangent(stageCapability));
  216. }
  217. }
  218. }