浏览代码

Merge master

/main
Tim Cooper 7 年前
当前提交
5c979fc8
共有 180 个文件被更改,包括 2549 次插入1379 次删除
  1. 26
      MaterialGraphProject/Assets/PartyPreview.ShaderGraph
  2. 798
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/AbstractMaterialGraph.cs
  3. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/AbstractShaderProperty.cs
  4. 42
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ColorMaterialSlot.cs
  5. 45
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ColorRGBMaterialSlot.cs
  6. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ColorShaderProperty.cs
  7. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/CubemapShaderProperty.cs
  8. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/DynamicVectorMaterialSlot.cs
  9. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/FloatShaderProperty.cs
  10. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/IShaderProperty.cs
  11. 128
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/MaterialSlot.cs
  12. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/SamplerStateShaderProperty.cs
  13. 36
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/SerializableCubemap.cs
  14. 49
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ShaderGraphRequirements.cs
  15. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/TextureShaderProperty.cs
  16. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector1MaterialSlot.cs
  17. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector2MaterialSlot.cs
  18. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector2ShaderProperty.cs
  19. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector3MaterialSlot.cs
  20. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector3ShaderProperty.cs
  21. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector4MaterialSlot.cs
  22. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector4ShaderProperty.cs
  23. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/IMaterialSlotHasValue.cs.meta
  24. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Interfaces/IGeneratesFunction.cs
  25. 72
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/LightweightPipeline/LightWeightPBRSubShader.cs
  26. 30
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/LightweightPipeline/LightWeightUnlitSubShader.cs
  27. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/MasterNodes/PBRMasterNode.cs
  28. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/MasterNodes/UnlitMasterNode.cs
  29. 269
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/AbstractMaterialNode.cs
  30. 53
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/ChannelMixerNode.cs
  31. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/HueNode.cs
  32. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Blend/BlendNode.cs
  33. 59
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Mask/ChannelMaskNode.cs
  34. 119
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Normal/NormalCreateNode.cs
  35. 80
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Channel/FlipNode.cs
  36. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Channel/SplitNode.cs
  37. 100
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Channel/SwizzleNode.cs
  38. 17
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/CodeFunctionNode.cs
  39. 9
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Basic/ColorNode.cs
  40. 1
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/NormalVectorNode.cs
  41. 1
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/PositionNode.cs
  42. 1
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/ViewDirectionNode.cs
  43. 38
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/CameraNode.cs
  44. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Texture/SamplerStateNode.cs
  45. 9
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Texture/SampleTexture2DNode.cs
  46. 9
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Texture/SampleCubemapNode.cs
  47. 68
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Derivative/DDXNode.cs
  48. 63
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Derivative/DDXYNode.cs
  49. 61
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Derivative/DDYNode.cs
  50. 23
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Matrix/MatrixMultiplyByVectorNode.cs
  51. 16
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Matrix/MatrixMultiplyNode.cs
  52. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Vector/FresnelEffectNode.cs
  53. 86
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Vector/TransformNode.cs
  54. 15
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Procedural/Noise/SimpleNoiseNode.cs
  55. 9
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Procedural/Noise/VoronoiNode.cs
  56. 27
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/SlotValue.cs
  57. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Utility/SubGraphNode.cs
  58. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/SubGraph/AbstractSubGraph.cs
  59. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/SubGraph/AbstractSubGraphNode.cs
  60. 14
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Util/PropertyCollector.cs
  61. 19
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Util/ShaderGenerator.cs
  62. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ChannelEnumControl.cs
  63. 136
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Inspector/GraphInspectorView.cs
  64. 7
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Manipulators/Draggable.cs
  65. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Manipulators/GraphDropTarget.cs
  66. 17
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/MaterialGraphEditWindow.cs
  67. 57
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/PreviewManager.cs
  68. 38
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/GraphEditorView.cs
  69. 21
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/MaterialNodeView.cs
  70. 80
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Resources/Styles/MaterialGraph.uss
  71. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Templates/lightweightPBRForwardPass.template
  72. 15
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/IntegrationTests/SerializationTests.cs
  73. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/AbstractMaterialGraphTests.cs
  74. 20
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/MaterialNodeTests.cs
  75. 175
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/SerializedGraphTests.cs
  76. 2
      MaterialGraphProject/Assets/UnityShaderEditor/package.json
  77. 26
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Procedural/Shape/EllipseNode.cs
  78. 22
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Procedural/Shape/RectangleNode.cs
  79. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Implementation/GraphObject.cs
  80. 59
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Implementation/NodeUtils.cs
  81. 35
      MaterialGraphProject/Assets/NewNodes/Editor/Sampler2DShaderProperty.cs
  82. 3
      MaterialGraphProject/Assets/NewNodes/Editor/Sampler2DShaderProperty.cs.meta
  83. 112
      MaterialGraphProject/Assets/NewNodes/Editor/SceneDepthNode.cs
  84. 8
      MaterialGraphProject/Assets/NewNodes/Editor/SceneDepthNode.cs.meta
  85. 114
      MaterialGraphProject/Assets/NewNodes/Editor/SceneNormalsNode.cs
  86. 8
      MaterialGraphProject/Assets/NewNodes/Editor/SceneNormalsNode.cs.meta
  87. 109
      MaterialGraphProject/Assets/NewNodes/Editor/SceneVelocityNode.cs
  88. 8
      MaterialGraphProject/Assets/NewNodes/Editor/SceneVelocityNode.cs.meta
  89. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/IMaterialSlotHasValue.cs
  90. 56
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/MaterialGraphAsset.cs
  91. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Interfaces/Graph.meta
  92. 15
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/FormerNameAttribute.cs
  93. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/FormerNameAttribute.cs.meta
  94. 49
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/AmbientNode.cs
  95. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/AmbientNode.cs.meta
  96. 93
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/FogNode.cs
  97. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/FogNode.cs.meta
  98. 41
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/ObjectNode.cs
  99. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/ObjectNode.cs.meta
  100. 39
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/ScreenNode.cs

26
MaterialGraphProject/Assets/PartyPreview.ShaderGraph


"typeInfo": {
"fullName": "UnityEditor.ShaderGraph.MultiplyNode"
},
"JSONnodeData": "{\n \"m_GuidSerialized\": \"9e517333-68bd-4055-b03f-c63b8a7de8a2\",\n \"m_Name\": \"Multiply\",\n \"m_DrawState\": {\n \"m_Expanded\": true,\n \"m_Position\": {\n \"serializedVersion\": \"2\",\n \"x\": 2887.60498046875,\n \"y\": 252.38739013671876,\n \"width\": 208.0,\n \"height\": 302.0\n }\n },\n \"m_SerializableSlots\": [\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.DynamicVectorMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 0,\\n \\\"m_DisplayName\\\": \\\"A\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"A\\\",\\n \\\"m_ShaderStage\\\": 0,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0,\\n \\\"w\\\": 0.0\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0,\\n \\\"w\\\": 0.0\\n }\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.DynamicVectorMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 1,\\n \\\"m_DisplayName\\\": \\\"B\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"B\\\",\\n \\\"m_ShaderStage\\\": 0,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0,\\n \\\"w\\\": 0.0\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0,\\n \\\"w\\\": 0.0\\n }\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.DynamicVectorMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 2,\\n \\\"m_DisplayName\\\": \\\"Out\\\",\\n \\\"m_SlotType\\\": 1,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Out\\\",\\n \\\"m_ShaderStage\\\": 0,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0,\\n \\\"w\\\": 0.0\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0,\\n \\\"w\\\": 0.0\\n }\\n}\"\n }\n ],\n \"m_PreviewExpanded\": true\n}"
"JSONnodeData": "{\n \"m_GuidSerialized\": \"9e517333-68bd-4055-b03f-c63b8a7de8a2\",\n \"m_Name\": \"Multiply\",\n \"m_DrawState\": {\n \"m_Expanded\": true,\n \"m_Position\": {\n \"serializedVersion\": \"2\",\n \"x\": 2777.60498046875,\n \"y\": 251.38739013671876,\n \"width\": 208.0,\n \"height\": 302.0\n }\n },\n \"m_SerializableSlots\": [\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.DynamicVectorMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 0,\\n \\\"m_DisplayName\\\": \\\"A\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"A\\\",\\n \\\"m_ShaderStage\\\": 0,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0,\\n \\\"w\\\": 0.0\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0,\\n \\\"w\\\": 0.0\\n }\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.DynamicVectorMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 1,\\n \\\"m_DisplayName\\\": \\\"B\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"B\\\",\\n \\\"m_ShaderStage\\\": 0,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0,\\n \\\"w\\\": 0.0\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0,\\n \\\"w\\\": 0.0\\n }\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.DynamicVectorMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 2,\\n \\\"m_DisplayName\\\": \\\"Out\\\",\\n \\\"m_SlotType\\\": 1,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Out\\\",\\n \\\"m_ShaderStage\\\": 0,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0,\\n \\\"w\\\": 0.0\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0,\\n \\\"w\\\": 0.0\\n }\\n}\"\n }\n ],\n \"m_PreviewExpanded\": true\n}"
},
{
"typeInfo": {

},
{
"typeInfo": {
"fullName": "UnityEditor.ShaderGraph.NormalVectorNode"
},
"JSONnodeData": "{\n \"m_GuidSerialized\": \"a6dc09a5-41ca-46c0-a9fa-4a8e63d32682\",\n \"m_Name\": \"Normal Vector\",\n \"m_DrawState\": {\n \"m_Expanded\": true,\n \"m_Position\": {\n \"serializedVersion\": \"2\",\n \"x\": 2149.842041015625,\n \"y\": -928.1676025390625,\n \"width\": 208.0,\n \"height\": 311.0\n }\n },\n \"m_SerializableSlots\": [\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Vector3MaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 0,\\n \\\"m_DisplayName\\\": \\\"Out\\\",\\n \\\"m_SlotType\\\": 1,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Out\\\",\\n \\\"m_ShaderStage\\\": 0,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 1.0\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0\\n }\\n}\"\n }\n ],\n \"m_PreviewExpanded\": true,\n \"m_Space\": 2\n}"
},
{
"typeInfo": {
"fullName": "UnityEditor.ShaderGraph.PowerNode"
},
"JSONnodeData": "{\n \"m_GuidSerialized\": \"4c3b5066-b6af-40e9-9eb5-4626f9721d6e\",\n \"m_Name\": \"Power\",\n \"m_DrawState\": {\n \"m_Expanded\": true,\n \"m_Position\": {\n \"serializedVersion\": \"2\",\n \"x\": 2999.491455078125,\n \"y\": 1005.4030151367188,\n \"width\": 208.0,\n \"height\": 302.0\n }\n },\n \"m_SerializableSlots\": [\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.DynamicVectorMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 0,\\n \\\"m_DisplayName\\\": \\\"A\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"A\\\",\\n \\\"m_ShaderStage\\\": 0,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0,\\n \\\"w\\\": 0.0\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0,\\n \\\"w\\\": 0.0\\n }\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.DynamicVectorMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 1,\\n \\\"m_DisplayName\\\": \\\"B\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"B\\\",\\n \\\"m_ShaderStage\\\": 0,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 8.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0,\\n \\\"w\\\": 0.0\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0,\\n \\\"w\\\": 0.0\\n }\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.DynamicVectorMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 2,\\n \\\"m_DisplayName\\\": \\\"Out\\\",\\n \\\"m_SlotType\\\": 1,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Out\\\",\\n \\\"m_ShaderStage\\\": 0,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0,\\n \\\"w\\\": 0.0\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0,\\n \\\"w\\\": 0.0\\n }\\n}\"\n }\n ],\n \"m_PreviewExpanded\": true\n}"

"typeInfo": {
"fullName": "UnityEditor.ShaderGraph.ViewDirectionNode"
},
"JSONnodeData": "{\n \"m_GuidSerialized\": \"89008682-e13c-4f58-9d53-e5578ccf9db4\",\n \"m_Name\": \"ViewDirection\",\n \"m_DrawState\": {\n \"m_Expanded\": true,\n \"m_Position\": {\n \"serializedVersion\": \"2\",\n \"x\": 2151.986083984375,\n \"y\": -604.21435546875,\n \"width\": 208.0,\n \"height\": 311.0\n }\n },\n \"m_SerializableSlots\": [\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Vector3MaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 0,\\n \\\"m_DisplayName\\\": \\\"Out\\\",\\n \\\"m_SlotType\\\": 1,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Out\\\",\\n \\\"m_ShaderStage\\\": 0,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0\\n }\\n}\"\n }\n ],\n \"m_PreviewExpanded\": true,\n \"m_Space\": 2\n}"
"JSONnodeData": "{\n \"m_GuidSerialized\": \"89008682-e13c-4f58-9d53-e5578ccf9db4\",\n \"m_Name\": \"ViewDirection\",\n \"m_DrawState\": {\n \"m_Expanded\": true,\n \"m_Position\": {\n \"serializedVersion\": \"2\",\n \"x\": 2151.986083984375,\n \"y\": -604.21435546875,\n \"width\": 208.0,\n \"height\": 311.0\n }\n },\n \"m_SerializableSlots\": [\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Vector3MaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 0,\\n \\\"m_DisplayName\\\": \\\"Out\\\",\\n \\\"m_SlotType\\\": 1,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Out\\\",\\n \\\"m_ShaderStage\\\": 0,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0\\n }\\n}\"\n }\n ],\n \"m_PreviewExpanded\": true,\n \"m_Space\": 3\n}"
},
{
"typeInfo": {

"typeInfo": {
"fullName": "UnityEditor.ShaderGraph.PropertyNode"
},
"JSONnodeData": "{\n \"m_GuidSerialized\": \"db88f193-bb55-420d-baf6-9c644ddae245\",\n \"m_Name\": \"Property\",\n \"m_DrawState\": {\n \"m_Expanded\": true,\n \"m_Position\": {\n \"serializedVersion\": \"2\",\n \"x\": 2775.07373046875,\n \"y\": 588.0489501953125,\n \"width\": 91.0,\n \"height\": 111.0\n }\n },\n \"m_SerializableSlots\": [\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Texture2DMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 0,\\n \\\"m_DisplayName\\\": \\\"Out\\\",\\n \\\"m_SlotType\\\": 1,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Out\\\",\\n \\\"m_ShaderStage\\\": 0\\n}\"\n }\n ],\n \"m_PreviewExpanded\": true,\n \"m_PropertyGuidSerialized\": \"cd76b423-d24c-43c8-8fe8-6719654b4483\"\n}"
"JSONnodeData": "{\n \"m_GuidSerialized\": \"db88f193-bb55-420d-baf6-9c644ddae245\",\n \"m_Name\": \"Property\",\n \"m_DrawState\": {\n \"m_Expanded\": true,\n \"m_Position\": {\n \"serializedVersion\": \"2\",\n \"x\": 1975.7779541015625,\n \"y\": -977.3115844726563,\n \"width\": 91.0,\n \"height\": 111.0\n }\n },\n \"m_SerializableSlots\": [\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Texture2DMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 0,\\n \\\"m_DisplayName\\\": \\\"Out\\\",\\n \\\"m_SlotType\\\": 1,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Out\\\",\\n \\\"m_ShaderStage\\\": 0\\n}\"\n }\n ],\n \"m_PreviewExpanded\": true,\n \"m_PropertyGuidSerialized\": \"cd76b423-d24c-43c8-8fe8-6719654b4483\"\n}"
},
{
"typeInfo": {

"typeInfo": {
"fullName": "UnityEditor.ShaderGraph.NormalCreateNode"
},
"JSONnodeData": "{\n \"m_GuidSerialized\": \"305e6be3-3e66-4792-ac6c-d7df894da0b3\",\n \"m_Name\": \"Normal Create\",\n \"m_DrawState\": {\n \"m_Expanded\": true,\n \"m_Position\": {\n \"serializedVersion\": \"2\",\n \"x\": 2954.62744140625,\n \"y\": 580.0418090820313,\n \"width\": 208.0,\n \"height\": 374.0\n }\n },\n \"m_SerializableSlots\": [\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Texture2DInputMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 0,\\n \\\"m_DisplayName\\\": \\\"Texture\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Texture\\\",\\n \\\"m_ShaderStage\\\": 0,\\n \\\"m_Texture\\\": {\\n \\\"m_SerializedTexture\\\": \\\"{\\\\n \\\\\\\"texture\\\\\\\": {\\\\n \\\\\\\"instanceID\\\\\\\": 0\\\\n }\\\\n}\\\"\\n }\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.UVMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 1,\\n \\\"m_DisplayName\\\": \\\"UV\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"UV\\\",\\n \\\"m_ShaderStage\\\": 0,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0\\n }\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.SamplerStateMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 2,\\n \\\"m_DisplayName\\\": \\\"Sampler\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Sampler\\\",\\n \\\"m_ShaderStage\\\": 0\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Vector1MaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 3,\\n \\\"m_DisplayName\\\": \\\"Offset\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Offset\\\",\\n \\\"m_ShaderStage\\\": 0,\\n \\\"m_Value\\\": 0.5,\\n \\\"m_DefaultValue\\\": 0.5\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Vector1MaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 4,\\n \\\"m_DisplayName\\\": \\\"Strength\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Strength\\\",\\n \\\"m_ShaderStage\\\": 0,\\n \\\"m_Value\\\": 2.0,\\n \\\"m_DefaultValue\\\": 8.0\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Vector3MaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 5,\\n \\\"m_DisplayName\\\": \\\"Out\\\",\\n \\\"m_SlotType\\\": 1,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Out\\\",\\n \\\"m_ShaderStage\\\": 0,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0\\n }\\n}\"\n }\n ],\n \"m_PreviewExpanded\": true\n}"
"JSONnodeData": "{\n \"m_GuidSerialized\": \"305e6be3-3e66-4792-ac6c-d7df894da0b3\",\n \"m_Name\": \"Normal Create\",\n \"m_DrawState\": {\n \"m_Expanded\": true,\n \"m_Position\": {\n \"serializedVersion\": \"2\",\n \"x\": 2158.82958984375,\n \"y\": -987.0677490234375,\n \"width\": 208.0,\n \"height\": 374.0\n }\n },\n \"m_SerializableSlots\": [\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Texture2DInputMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 0,\\n \\\"m_DisplayName\\\": \\\"Texture\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Texture\\\",\\n \\\"m_ShaderStage\\\": 0,\\n \\\"m_Texture\\\": {\\n \\\"m_SerializedTexture\\\": \\\"{\\\\n \\\\\\\"texture\\\\\\\": {\\\\n \\\\\\\"instanceID\\\\\\\": 0\\\\n }\\\\n}\\\"\\n }\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.UVMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 1,\\n \\\"m_DisplayName\\\": \\\"UV\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"UV\\\",\\n \\\"m_ShaderStage\\\": 0,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0\\n }\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.SamplerStateMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 2,\\n \\\"m_DisplayName\\\": \\\"Sampler\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Sampler\\\",\\n \\\"m_ShaderStage\\\": 0\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Vector1MaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 3,\\n \\\"m_DisplayName\\\": \\\"Offset\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Offset\\\",\\n \\\"m_ShaderStage\\\": 0,\\n \\\"m_Value\\\": 0.5,\\n \\\"m_DefaultValue\\\": 0.5\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Vector1MaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 4,\\n \\\"m_DisplayName\\\": \\\"Strength\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Strength\\\",\\n \\\"m_ShaderStage\\\": 0,\\n \\\"m_Value\\\": 2.0,\\n \\\"m_DefaultValue\\\": 8.0\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Vector3MaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 5,\\n \\\"m_DisplayName\\\": \\\"Out\\\",\\n \\\"m_SlotType\\\": 1,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Out\\\",\\n \\\"m_ShaderStage\\\": 0,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0\\n }\\n}\"\n }\n ],\n \"m_PreviewExpanded\": true\n}"
},
{
"typeInfo": {

"typeInfo": {
"fullName": "UnityEditor.Graphing.Edge"
},
"JSONnodeData": "{\n \"m_OutputSlot\": {\n \"m_SlotId\": 0,\n \"m_NodeGUIDSerialized\": \"a6dc09a5-41ca-46c0-a9fa-4a8e63d32682\"\n },\n \"m_InputSlot\": {\n \"m_SlotId\": 0,\n \"m_NodeGUIDSerialized\": \"8f799120-8488-43e7-a74d-9dc94058e802\"\n }\n}"
},
{
"typeInfo": {
"fullName": "UnityEditor.Graphing.Edge"
},
"JSONnodeData": "{\n \"m_OutputSlot\": {\n \"m_SlotId\": 0,\n \"m_NodeGUIDSerialized\": \"89008682-e13c-4f58-9d53-e5578ccf9db4\"\n },\n \"m_InputSlot\": {\n \"m_SlotId\": 1,\n \"m_NodeGUIDSerialized\": \"8f799120-8488-43e7-a74d-9dc94058e802\"\n }\n}"
},
{

"fullName": "UnityEditor.Graphing.Edge"
},
"JSONnodeData": "{\n \"m_OutputSlot\": {\n \"m_SlotId\": 2,\n \"m_NodeGUIDSerialized\": \"78f42ff7-f712-4062-b644-4e9c6b6aebd2\"\n },\n \"m_InputSlot\": {\n \"m_SlotId\": 0,\n \"m_NodeGUIDSerialized\": \"6c3f0674-ea3b-489a-81d5-4976d6d29771\"\n }\n}"
},
{
"typeInfo": {
"fullName": "UnityEditor.Graphing.Edge"
},
"JSONnodeData": "{\n \"m_OutputSlot\": {\n \"m_SlotId\": 5,\n \"m_NodeGUIDSerialized\": \"305e6be3-3e66-4792-ac6c-d7df894da0b3\"\n },\n \"m_InputSlot\": {\n \"m_SlotId\": 0,\n \"m_NodeGUIDSerialized\": \"8f799120-8488-43e7-a74d-9dc94058e802\"\n }\n}"
}
],
"m_SerializedProperties": [

798
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/AbstractMaterialGraph.cs


using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEditor.Compilation;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.Graphing.Util;

[Serializable]
public abstract class AbstractMaterialGraph : SerializableGraph, IGenerateProperties
public abstract class AbstractMaterialGraph : IGraph, ISerializationCallbackReceiver, IGenerateProperties
public IGraphObject owner { get; set; }
#region Property data
public IEnumerable<IShaderProperty> properties
{
get { return m_Properties; }
}
[SerializeField]
List<SerializationHelper.JSONSerializedElement> m_SerializedProperties = new List<SerializationHelper.JSONSerializedElement>();

public IEnumerable<IShaderProperty> addedProperties
{
get { return m_AddedProperties; }
}
public IEnumerable<Guid> removedProperties
{
get { return m_RemovedProperties; }
}
#endregion
#region Node data
public InspectorPreviewData previewData = new InspectorPreviewData();
Dictionary<Guid, INode> m_Nodes = new Dictionary<Guid, INode>();
public Mesh previewMesh
public IEnumerable<T> GetNodes<T>() where T : INode
get { return previewData.mesh; }
set { previewData.mesh = value; }
return m_Nodes.Values.OfType<T>();
public IEnumerable<IShaderProperty> properties
[SerializeField]
List<SerializationHelper.JSONSerializedElement> m_SerializableNodes = new List<SerializationHelper.JSONSerializedElement>();
[NonSerialized]
List<INode> m_AddedNodes = new List<INode>();
public IEnumerable<INode> addedNodes
get { return m_Properties; }
get { return m_AddedNodes; }
public IEnumerable<IShaderProperty> addedProperties
[NonSerialized]
List<INode> m_RemovedNodes = new List<INode>();
public IEnumerable<INode> removedNodes
get { return m_AddedProperties; }
get { return m_RemovedNodes; }
public IEnumerable<Guid> removedProperties
#endregion
#region Edge data
[NonSerialized]
List<IEdge> m_Edges = new List<IEdge>();
public IEnumerable<IEdge> edges
get { return m_RemovedProperties; }
get { return m_Edges; }
public override void ClearChanges()
[SerializeField]
List<SerializationHelper.JSONSerializedElement> m_SerializableEdges = new List<SerializationHelper.JSONSerializedElement>();
[NonSerialized]
Dictionary<Guid, List<IEdge>> m_NodeEdges = new Dictionary<Guid, List<IEdge>>();
[NonSerialized]
List<IEdge> m_AddedEdges = new List<IEdge>();
public IEnumerable<IEdge> addedEdges
base.ClearChanges();
get { return m_AddedEdges; }
}
[NonSerialized]
List<IEdge> m_RemovedEdges = new List<IEdge>();
public IEnumerable<IEdge> removedEdges
{
get { return m_RemovedEdges; }
}
#endregion
[SerializeField]
InspectorPreviewData m_PreviewData = new InspectorPreviewData();
public InspectorPreviewData previewData
{
get { return m_PreviewData; }
set { m_PreviewData = value; }
}
public void ClearChanges()
{
m_AddedNodes.Clear();
m_RemovedNodes.Clear();
m_AddedEdges.Clear();
m_RemovedEdges.Clear();
public override void AddNode(INode node)
public virtual void AddNode(INode node)
base.AddNode(node);
AddNodeNoValidate(node);
ValidateGraph();
}
else
{

void AddNodeNoValidate(INode node)
{
m_Nodes.Add(node.guid, node);
node.owner = this;
m_AddedNodes.Add(node);
}
public void RemoveNode(INode node)
{
if (!node.canDeleteNode)
return;
m_Nodes.Remove(node.guid);
m_RemovedNodes.Add(node);
ValidateGraph();
}
void RemoveNodeNoValidate(INode node)
{
if (!node.canDeleteNode)
return;
m_Nodes.Remove(node.guid);
m_RemovedNodes.Add(node);
}
void AddEdgeToNodeEdges(IEdge edge)
{
List<IEdge> inputEdges;
if (!m_NodeEdges.TryGetValue(edge.inputSlot.nodeGuid, out inputEdges))
m_NodeEdges[edge.inputSlot.nodeGuid] = inputEdges = new List<IEdge>();
inputEdges.Add(edge);
List<IEdge> outputEdges;
if (!m_NodeEdges.TryGetValue(edge.outputSlot.nodeGuid, out outputEdges))
m_NodeEdges[edge.outputSlot.nodeGuid] = outputEdges = new List<IEdge>();
outputEdges.Add(edge);
}
IEdge ConnectNoValidate(SlotReference fromSlotRef, SlotReference toSlotRef)
{
var fromNode = GetNodeFromGuid(fromSlotRef.nodeGuid);
var toNode = GetNodeFromGuid(toSlotRef.nodeGuid);
if (fromNode == null || toNode == null)
return null;
// if fromNode is already connected to toNode
// do now allow a connection as toNode will then
// have an edge to fromNode creating a cycle.
// if this is parsed it will lead to an infinite loop.
var dependentNodes = new List<INode>();
NodeUtils.CollectNodesNodeFeedsInto(dependentNodes, toNode);
if (dependentNodes.Contains(fromNode))
return null;
var fromSlot = fromNode.FindSlot<ISlot>(fromSlotRef.slotId);
var toSlot = toNode.FindSlot<ISlot>(toSlotRef.slotId);
if (fromSlot.isOutputSlot == toSlot.isOutputSlot)
return null;
var outputSlot = fromSlot.isOutputSlot ? fromSlotRef : toSlotRef;
var inputSlot = fromSlot.isInputSlot ? fromSlotRef : toSlotRef;
s_TempEdges.Clear();
GetEdges(inputSlot, s_TempEdges);
// remove any inputs that exits before adding
foreach (var edge in s_TempEdges)
{
RemoveEdgeNoValidate(edge);
}
var newEdge = new Edge(outputSlot, inputSlot);
m_Edges.Add(newEdge);
m_AddedEdges.Add(newEdge);
AddEdgeToNodeEdges(newEdge);
//Debug.LogFormat("Connected edge: {0} -> {1} ({2} -> {3})\n{4}", newEdge.outputSlot.nodeGuid, newEdge.inputSlot.nodeGuid, fromNode.name, toNode.name, Environment.StackTrace);
return newEdge;
}
public virtual IEdge Connect(SlotReference fromSlotRef, SlotReference toSlotRef)
{
var newEdge = ConnectNoValidate(fromSlotRef, toSlotRef);
ValidateGraph();
return newEdge;
}
public virtual void RemoveEdge(IEdge e)
{
RemoveEdgeNoValidate(e);
ValidateGraph();
}
public void RemoveElements(IEnumerable<INode> nodes, IEnumerable<IEdge> edges)
{
foreach (var edge in edges.ToArray())
RemoveEdgeNoValidate(edge);
foreach (var serializableNode in nodes.ToArray())
RemoveNodeNoValidate(serializableNode);
ValidateGraph();
}
protected void RemoveEdgeNoValidate(IEdge e)
{
e = m_Edges.FirstOrDefault(x => x.Equals(e));
if (e == null)
throw new ArgumentException("Trying to remove an edge that does not exist.", "e");
m_Edges.Remove(e);
List<IEdge> inputNodeEdges;
if (m_NodeEdges.TryGetValue(e.inputSlot.nodeGuid, out inputNodeEdges))
inputNodeEdges.Remove(e);
List<IEdge> outputNodeEdges;
if (m_NodeEdges.TryGetValue(e.outputSlot.nodeGuid, out outputNodeEdges))
outputNodeEdges.Remove(e);
m_RemovedEdges.Add(e);
}
public INode GetNodeFromGuid(Guid guid)
{
INode node;
m_Nodes.TryGetValue(guid, out node);
return node;
}
public bool ContainsNodeGuid(Guid guid)
{
return m_Nodes.ContainsKey(guid);
}
public T GetNodeFromGuid<T>(Guid guid) where T : INode
{
var node = GetNodeFromGuid(guid);
if (node is T)
return (T)node;
return default(T);
}
public void GetEdges(SlotReference s, List<IEdge> foundEdges)
{
var node = GetNodeFromGuid(s.nodeGuid);
if (node == null)
{
Debug.LogWarning("Node does not exist");
return;
}
ISlot slot = node.FindSlot<ISlot>(s.slotId);
List<IEdge> candidateEdges;
if (!m_NodeEdges.TryGetValue(s.nodeGuid, out candidateEdges))
return;
foreach (var edge in candidateEdges)
{
var cs = slot.isInputSlot ? edge.inputSlot : edge.outputSlot;
if (cs.nodeGuid == s.nodeGuid && cs.slotId == s.slotId)
foundEdges.Add(edge);
}
}
public virtual void CollectShaderProperties(PropertyCollector collector, GenerationMode generationMode)
{
foreach (var prop in properties)

public virtual void AddShaderProperty(IShaderProperty property)
public void AddShaderProperty(IShaderProperty property)
{
if (property == null)
return;

public void RemoveShaderProperty(Guid guid)
{
var propertyNodes = GetNodes<PropertyNode>().Where(x => x.propertyGuid == guid).ToList();
foreach (var propNode in propertyNodes)
ReplacePropertyNodeWithConcreteNodeNoValidate(propNode);
var propertyNodes = GetNodes<PropertyNode>().Where(x => x.propertyGuid == guid).ToList();
foreach (var propNode in propertyNodes)
ReplacePropertyNodeWithConcreteNode(propNode);
if (m_Properties.RemoveAll(x => x.guid == guid) > 0)
m_RemovedProperties.Add(guid);
}

public void ReplacePropertyNodeWithConcreteNode(PropertyNode propertyNode)
{
var property = properties.FirstOrDefault(x => x.guid == propertyNode.propertyGuid);
if (property != null)
{
AbstractMaterialNode node = null;
int slotId = -1;
if (property is FloatShaderProperty)
{
var createdNode = new Vector1Node();
createdNode.value = ((FloatShaderProperty)property).value;
slotId = Vector1Node.OutputSlotId;
node = createdNode;
ReplacePropertyNodeWithConcreteNodeNoValidate(propertyNode);
ValidateGraph();
else if (property is Vector2ShaderProperty)
void ReplacePropertyNodeWithConcreteNodeNoValidate(PropertyNode propertyNode)
var createdNode = new Vector2Node();
createdNode.value = ((Vector2ShaderProperty)property).value;
slotId = Vector2Node.OutputSlotId;
node = createdNode;
}
else if (property is Vector3ShaderProperty)
{
var createdNode = new Vector3Node();
createdNode.value = ((Vector3ShaderProperty)property).value;
slotId = Vector3Node.OutputSlotId;
node = createdNode;
}
else if (property is Vector4ShaderProperty)
{
var createdNode = new Vector4Node();
createdNode.value = ((Vector4ShaderProperty)property).value;
slotId = Vector4Node.OutputSlotId;
node = createdNode;
}
else if (property is ColorShaderProperty)
{
var createdNode = new ColorNode();
createdNode.color = ((ColorShaderProperty)property).value;
slotId = ColorNode.OutputSlotId;
node = createdNode;
}
else if (property is TextureShaderProperty)
{
var createdNode = new Texture2DAssetNode();
createdNode.texture = ((TextureShaderProperty)property).value.texture;
slotId = Texture2DAssetNode.OutputSlotId;
node = createdNode;
}
else if (property is CubemapShaderProperty)
{
var createdNode = new CubemapAssetNode();
createdNode.cubemap = ((CubemapShaderProperty)property).value.cubemap;
slotId = CubemapAssetNode.OutputSlotId;
node = createdNode;
}
var property = properties.FirstOrDefault(x => x.guid == propertyNode.propertyGuid);
if (property == null)
return;
if (node == null)
var node = property.ToConcreteNode();
if (!(node is AbstractMaterialNode))
var newSlot = node.GetOutputSlots<MaterialSlot>().FirstOrDefault(s => s.valueType == slot.valueType);
if (newSlot == null)
return;
s_TempEdges.Clear();
GetEdges(slot.slotReference, s_TempEdges);
foreach (var edge in s_TempEdges)
ConnectNoValidate(node.GetSlotReference(slotId), edge.inputSlot);
foreach (var edge in this.GetEdges(slot.slotReference))
ConnectNoValidate(newSlot.slotReference, edge.inputSlot);
}
public override void ValidateGraph()
public void ValidateGraph()
ReplacePropertyNodeWithConcreteNode(pNode);
base.ValidateGraph();
}
ReplacePropertyNodeWithConcreteNodeNoValidate(pNode);
public override Dictionary<SerializationHelper.TypeSerializationInfo, SerializationHelper.TypeSerializationInfo> GetLegacyTypeRemapping()
//First validate edges, remove any
//orphans. This can happen if a user
//manually modifies serialized data
//of if they delete a node in the inspector
//debug view.
foreach (var edge in edges.ToArray())
var result = base.GetLegacyTypeRemapping();
var viewNode = new SerializationHelper.TypeSerializationInfo
{
fullName = "UnityEngine.MaterialGraph.ViewDirectionNode"
};
result[viewNode] = SerializationHelper.GetTypeSerializableAsString(typeof(ViewDirectionNode));
var outputNode = GetNodeFromGuid(edge.outputSlot.nodeGuid);
var inputNode = GetNodeFromGuid(edge.inputSlot.nodeGuid);
var normalNode = new SerializationHelper.TypeSerializationInfo
if (outputNode == null
|| inputNode == null
|| outputNode.FindOutputSlot<ISlot>(edge.outputSlot.slotId) == null
|| inputNode.FindInputSlot<ISlot>(edge.inputSlot.slotId) == null)
fullName = "UnityEngine.MaterialGraph.NormalNode"
};
result[normalNode] = SerializationHelper.GetTypeSerializableAsString(typeof(NormalVectorNode));
//orphaned edge
RemoveEdgeNoValidate(edge);
}
}
var worldPosNode = new SerializationHelper.TypeSerializationInfo
{
fullName = "UnityEngine.MaterialGraph.WorldPosNode"
};
result[worldPosNode] = SerializationHelper.GetTypeSerializableAsString(typeof(PositionNode));
foreach (var node in GetNodes<INode>())
node.ValidateNode();
return result;
foreach (var edge in m_AddedEdges.ToList())
{
if (!ContainsNodeGuid(edge.outputSlot.nodeGuid) || !ContainsNodeGuid(edge.inputSlot.nodeGuid))
{
Debug.LogWarningFormat("Added edge is invalid: {0} -> {1}\n{2}", edge.outputSlot.nodeGuid, edge.inputSlot.nodeGuid, Environment.StackTrace);
m_AddedEdges.Remove(edge);
}
}
public override void ReplaceWith(IGraph other)
{
var otherMG = other as AbstractMaterialGraph;
if (otherMG != null)
public void ReplaceWith(IGraph other)
var otherMg = other as AbstractMaterialGraph;
if (otherMg == null)
throw new ArgumentException("Can only replace with another AbstractMaterialGraph", "other");
using (var removedPropertiesPooledObject = ListPool<Guid>.GetDisposable())
{
var removedPropertyGuids = removedPropertiesPooledObject.value;

RemoveShaderPropertyNoValidate(propertyGuid);
}
foreach (var otherProperty in otherMG.properties)
foreach (var otherProperty in otherMg.properties)
}
base.ReplaceWith(other);
}
public override void OnBeforeSerialize()
{
base.OnBeforeSerialize();
m_SerializedProperties = SerializationHelper.Serialize<IShaderProperty>(m_Properties);
}
other.ValidateGraph();
ValidateGraph();
public override void OnAfterDeserialize()
// Current tactic is to remove all nodes and edges and then re-add them, such that depending systems
// will re-initialize with new references.
using (var pooledList = ListPool<IEdge>.GetDisposable())
// have to deserialize 'globals' before nodes
m_Properties = SerializationHelper.Deserialize<IShaderProperty>(m_SerializedProperties, null);
base.OnAfterDeserialize();
var removedNodeEdges = pooledList.value;
removedNodeEdges.AddRange(m_Edges);
foreach (var edge in removedNodeEdges)
RemoveEdgeNoValidate(edge);
internal static ShaderGraphRequirements GetRequirements(List<INode> nodes)
{
NeededCoordinateSpace requiresNormal = nodes.OfType<IMayRequireNormal>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresNormal());
NeededCoordinateSpace requiresBitangent = nodes.OfType<IMayRequireBitangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresBitangent());
NeededCoordinateSpace requiresTangent = nodes.OfType<IMayRequireTangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresTangent());
NeededCoordinateSpace requiresViewDir = nodes.OfType<IMayRequireViewDirection>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresViewDirection());
NeededCoordinateSpace requiresPosition = nodes.OfType<IMayRequirePosition>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresPosition());
bool requiresScreenPosition = nodes.OfType<IMayRequireScreenPosition>().Any(x => x.RequiresScreenPosition());
bool requiresVertexColor = nodes.OfType<IMayRequireVertexColor>().Any(x => x.RequiresVertexColor());
var meshUV = new List<UVChannel>();
for (int uvIndex = 0; uvIndex < ShaderGeneratorNames.UVCount; ++uvIndex)
using (var removedNodesPooledObject = ListPool<Guid>.GetDisposable())
var channel = (UVChannel)uvIndex;
if (nodes.OfType<IMayRequireMeshUV>().Any(x => x.RequiresMeshUV(channel)))
meshUV.Add(channel);
var removedNodeGuids = removedNodesPooledObject.value;
removedNodeGuids.AddRange(m_Nodes.Keys);
foreach (var nodeGuid in removedNodeGuids)
RemoveNodeNoValidate(m_Nodes[nodeGuid]);
// if anything needs tangentspace we have make
// sure to have our othonormal basis!
var compoundSpaces = requiresBitangent | requiresNormal | requiresPosition
| requiresTangent | requiresViewDir | requiresPosition
| requiresNormal;
ValidateGraph();
var needsTangentSpace = (compoundSpaces & NeededCoordinateSpace.Tangent) > 0;
if (needsTangentSpace)
{
requiresBitangent |= NeededCoordinateSpace.Object;
requiresNormal |= NeededCoordinateSpace.Object;
requiresTangent |= NeededCoordinateSpace.Object;
}
var reqs = new ShaderGraphRequirements()
{
requiresNormal = requiresNormal,
requiresBitangent = requiresBitangent,
requiresTangent = requiresTangent,
requiresViewDir = requiresViewDir,
requiresPosition = requiresPosition,
requiresScreenPosition = requiresScreenPosition,
requiresVertexColor = requiresVertexColor,
requiresMeshUVs = meshUV
};
foreach (var node in other.GetNodes<INode>())
AddNodeNoValidate(node);
return reqs;
}
foreach (var edge in other.edges)
ConnectNoValidate(edge.outputSlot, edge.inputSlot);
public string GetPreviewShader(AbstractMaterialNode node, out PreviewMode previewMode)
{
List<PropertyCollector.TextureInfo> configuredTextures;
FloatShaderProperty outputIdProperty;
return GetShader(node, GenerationMode.Preview, string.Format("hidden/preview/{0}", node.GetVariableNameForNode()), out configuredTextures, out previewMode, out outputIdProperty);
ValidateGraph();
public string GetUberPreviewShader(Dictionary<Guid, int> ids, out FloatShaderProperty outputIdProperty)
public void OnBeforeSerialize()
List<PropertyCollector.TextureInfo> configuredTextures;
PreviewMode previewMode;
return GetShader(null, GenerationMode.Preview, "hidden/preview", out configuredTextures, out previewMode, out outputIdProperty, ids);
m_SerializableNodes = SerializationHelper.Serialize<INode>(m_Nodes.Values);
m_SerializableEdges = SerializationHelper.Serialize<IEdge>(m_Edges);
m_SerializedProperties = SerializationHelper.Serialize<IShaderProperty>(m_Properties);
internal static void GenerateSurfaceDescriptionStruct(ShaderGenerator surfaceDescriptionStruct, List<MaterialSlot> slots, bool isMaster)
public virtual void OnAfterDeserialize()
surfaceDescriptionStruct.AddShaderChunk("struct SurfaceDescription{", false);
surfaceDescriptionStruct.Indent();
if (isMaster)
// have to deserialize 'globals' before nodes
m_Properties = SerializationHelper.Deserialize<IShaderProperty>(m_SerializedProperties, null);
var nodes = SerializationHelper.Deserialize<INode>(m_SerializableNodes, GraphUtil.GetLegacyTypeRemapping());
m_Nodes = new Dictionary<Guid, INode>(nodes.Count);
foreach (var node in nodes)
foreach (var slot in slots)
surfaceDescriptionStruct.AddShaderChunk(string.Format("{0} {1};", AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType), AbstractMaterialNode.GetHLSLSafeName(slot.shaderOutputName)), false);
surfaceDescriptionStruct.Deindent();
}
else
{
surfaceDescriptionStruct.AddShaderChunk("float4 PreviewOutput;", false);
}
surfaceDescriptionStruct.Deindent();
surfaceDescriptionStruct.AddShaderChunk("};", false);
node.owner = this;
node.UpdateNodeAfterDeserialization();
m_Nodes.Add(node.guid, node);
internal static void GenerateSurfaceDescription(
List<INode> activeNodeList,
AbstractMaterialNode masterNode,
AbstractMaterialGraph graph,
ShaderGenerator surfaceDescriptionFunction,
ShaderGenerator shaderFunctionVisitor,
PropertyCollector shaderProperties,
ShaderGraphRequirements requirements,
GenerationMode mode,
string functionName = "PopulateSurfaceData",
string surfaceDescriptionName = "SurfaceDescription",
FloatShaderProperty outputIdProperty = null,
Dictionary<Guid, int> ids = null,
IEnumerable<MaterialSlot> slots = null)
{
if (graph == null)
return;
surfaceDescriptionFunction.AddShaderChunk(string.Format("{0} {1}(SurfaceInputs IN) {{", surfaceDescriptionName, functionName), false);
surfaceDescriptionFunction.Indent();
surfaceDescriptionFunction.AddShaderChunk(string.Format("{0} surface = ({0})0;", surfaceDescriptionName), false);
m_SerializableNodes = null;
foreach (CoordinateSpace space in Enum.GetValues(typeof(CoordinateSpace)))
{
var neededCoordinateSpace = space.ToNeededCoordinateSpace();
if ((requirements.requiresNormal & neededCoordinateSpace) > 0)
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", space.ToVariableName(InterpolatorType.Normal)), false);
if ((requirements.requiresTangent & neededCoordinateSpace) > 0)
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", space.ToVariableName(InterpolatorType.Tangent)), false);
if ((requirements.requiresBitangent & neededCoordinateSpace) > 0)
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", space.ToVariableName(InterpolatorType.BiTangent)), false);
if ((requirements.requiresViewDir & neededCoordinateSpace) > 0)
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", space.ToVariableName(InterpolatorType.ViewDirection)), false);
if ((requirements.requiresPosition & neededCoordinateSpace) > 0)
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", space.ToVariableName(InterpolatorType.Position)), false);
m_Edges = SerializationHelper.Deserialize<IEdge>(m_SerializableEdges, null);
m_SerializableEdges = null;
foreach (var edge in m_Edges)
AddEdgeToNodeEdges(edge);
if (requirements.requiresScreenPosition)
surfaceDescriptionFunction.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.ScreenPosition), false);
if (requirements.requiresVertexColor)
surfaceDescriptionFunction.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.VertexColor), false);
foreach (var channel in requirements.requiresMeshUVs.Distinct())
surfaceDescriptionFunction.AddShaderChunk(string.Format("half4 {0} = IN.{0};", channel.GetUVName()), false);
graph.CollectShaderProperties(shaderProperties, mode);
var currentId = -1;
foreach (var activeNode in activeNodeList.OfType<AbstractMaterialNode>())
{
if (activeNode is IGeneratesFunction)
(activeNode as IGeneratesFunction).GenerateNodeFunction(shaderFunctionVisitor, mode);
if (activeNode is IGeneratesBodyCode)
(activeNode as IGeneratesBodyCode).GenerateNodeCode(surfaceDescriptionFunction, mode);
if (masterNode == null && activeNode.hasPreview)
public void OnEnable()
var outputSlot = activeNode.GetOutputSlots<MaterialSlot>().FirstOrDefault();
if (outputSlot != null)
foreach (var node in GetNodes<INode>().OfType<IOnAssetEnabled>())
currentId++;
ids[activeNode.guid] = currentId;
surfaceDescriptionFunction.AddShaderChunk(string.Format("if ({0} == {1}) {{ surface.PreviewOutput = {2}; return surface; }}", outputIdProperty.referenceName, currentId, ShaderGenerator.AdaptNodeOutputForPreview(activeNode, outputSlot.id, activeNode.GetVariableNameForSlot(outputSlot.id))), false);
node.OnEnable();
activeNode.CollectShaderProperties(shaderProperties, mode);
if (masterNode != null)
{
if (masterNode is IMasterNode)
[Serializable]
public class InspectorPreviewData
var usedSlots = slots ?? masterNode.GetInputSlots<MaterialSlot>();
foreach (var input in usedSlots)
{
var foundEdges = graph.GetEdges(input.slotReference).ToArray();
if (foundEdges.Any())
{
var outputRef = foundEdges[0].outputSlot;
var fromNode = graph.GetNodeFromGuid<AbstractMaterialNode>(outputRef.nodeGuid);
surfaceDescriptionFunction.AddShaderChunk(string.Format("surface.{0} = {1};", AbstractMaterialNode.GetHLSLSafeName(input.shaderOutputName), fromNode.GetVariableNameForSlot(outputRef.slotId)), true);
}
else
{
surfaceDescriptionFunction.AddShaderChunk(string.Format("surface.{0} = {1};", AbstractMaterialNode.GetHLSLSafeName(input.shaderOutputName), input.GetDefaultValue(mode)), true);
}
}
}
else if (masterNode.hasPreview)
{
foreach (var slot in masterNode.GetOutputSlots<MaterialSlot>())
surfaceDescriptionFunction.AddShaderChunk(string.Format("surface.{0} = {1};", AbstractMaterialNode.GetHLSLSafeName(slot.shaderOutputName), masterNode.GetVariableNameForSlot(slot.id)), true);
}
}
surfaceDescriptionFunction.AddShaderChunk("return surface;", false);
surfaceDescriptionFunction.Deindent();
surfaceDescriptionFunction.AddShaderChunk("}", false);
}
static void Visit(List<INode> outputList, Dictionary<Guid, INode> unmarkedNodes, INode node)
{
if (!unmarkedNodes.ContainsKey(node.guid))
return;
foreach (var slot in node.GetInputSlots<ISlot>())
{
foreach (var edge in node.owner.GetEdges(slot.slotReference))
{
var inputNode = node.owner.GetNodeFromGuid(edge.outputSlot.nodeGuid);
Visit(outputList, unmarkedNodes, inputNode);
}
}
unmarkedNodes.Remove(node.guid);
outputList.Add(node);
}
public string GetShader(AbstractMaterialNode node, GenerationMode mode, string name, out List<PropertyCollector.TextureInfo> configuredTextures, out PreviewMode previewMode, out FloatShaderProperty outputIdProperty, Dictionary<Guid, int> ids = null)
{
bool isUber = node == null;
var vertexShader = new ShaderGenerator();
var surfaceDescriptionFunction = new ShaderGenerator();
var surfaceDescriptionStruct = new ShaderGenerator();
var shaderFunctionVisitor = new ShaderGenerator();
var surfaceInputs = new ShaderGenerator();
var graphVertexInput = @"
struct GraphVertexInput
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float4 color : COLOR;
float4 texcoord0 : TEXCOORD0;
float4 lightmapUV : TEXCOORD1;
//UNITY_VERTEX_INPUT_INSTANCE_ID
};";
surfaceInputs.AddShaderChunk("struct SurfaceInputs{", false);
surfaceInputs.Indent();
var activeNodeList = ListPool<INode>.Get();
if (isUber)
{
var unmarkedNodes = GetNodes<INode>().Where(x => !(x is IMasterNode)).ToDictionary(x => x.guid);
while (unmarkedNodes.Any())
{
var unmarkedNode = unmarkedNodes.FirstOrDefault();
Visit(activeNodeList, unmarkedNodes, unmarkedNode.Value);
}
}
else
{
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, node);
}
public SerializableMesh serializedMesh = new SerializableMesh();
var requirements = GetRequirements(activeNodeList);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresNormal, InterpolatorType.Normal, surfaceInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresTangent, InterpolatorType.Tangent, surfaceInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresBitangent, InterpolatorType.BiTangent, surfaceInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresViewDir, InterpolatorType.ViewDirection, surfaceInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresPosition, InterpolatorType.Position, surfaceInputs);
if (requirements.requiresVertexColor)
surfaceInputs.AddShaderChunk(string.Format("float4 {0};", ShaderGeneratorNames.VertexColor), false);
if (requirements.requiresScreenPosition)
surfaceInputs.AddShaderChunk(string.Format("float4 {0};", ShaderGeneratorNames.ScreenPosition), false);
previewMode = PreviewMode.Preview3D;
if (!isUber)
{
foreach (var pNode in activeNodeList.OfType<AbstractMaterialNode>())
{
if (pNode.previewMode == PreviewMode.Preview3D)
{
previewMode = PreviewMode.Preview3D;
break;
}
}
}
foreach (var channel in requirements.requiresMeshUVs.Distinct())
surfaceInputs.AddShaderChunk(string.Format("half4 {0};", channel.GetUVName()), false);
surfaceInputs.Deindent();
surfaceInputs.AddShaderChunk("};", false);
vertexShader.AddShaderChunk("GraphVertexInput PopulateVertexData(GraphVertexInput v){", false);
vertexShader.Indent();
vertexShader.AddShaderChunk("return v;", false);
vertexShader.Deindent();
vertexShader.AddShaderChunk("}", false);
var slots = new List<MaterialSlot>();
foreach (var activeNode in isUber ? activeNodeList.Where(n => ((AbstractMaterialNode)n).hasPreview) : ((INode)node).ToEnumerable())
{
if (activeNode is IMasterNode)
slots.AddRange(activeNode.GetInputSlots<MaterialSlot>());
else
slots.AddRange(activeNode.GetOutputSlots<MaterialSlot>());
}
GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, slots, !isUber);
var shaderProperties = new PropertyCollector();
outputIdProperty = new FloatShaderProperty
{
displayName = "OutputId",
generatePropertyBlock = false,
value = -1
};
if (isUber)
shaderProperties.AddShaderProperty(outputIdProperty);
GenerateSurfaceDescription(
activeNodeList,
node,
this,
surfaceDescriptionFunction,
shaderFunctionVisitor,
shaderProperties,
requirements,
mode,
outputIdProperty: outputIdProperty,
ids: ids);
var finalShader = new ShaderGenerator();
finalShader.AddShaderChunk(string.Format(@"Shader ""{0}""", name), false);
finalShader.AddShaderChunk("{", false);
finalShader.Indent();
finalShader.AddShaderChunk("Properties", false);
finalShader.AddShaderChunk("{", false);
finalShader.Indent();
finalShader.AddShaderChunk(shaderProperties.GetPropertiesBlock(2), false);
finalShader.Deindent();
finalShader.AddShaderChunk("}", false);
finalShader.AddShaderChunk("HLSLINCLUDE", false);
finalShader.AddShaderChunk("#define USE_LEGACY_UNITY_MATRIX_VARIABLES", false);
finalShader.AddShaderChunk("#include \"Common.hlsl\"", false);
finalShader.AddShaderChunk("#include \"Packing.hlsl\"", false);
finalShader.AddShaderChunk("#include \"ShaderVariables.hlsl\"", false);
finalShader.AddShaderChunk("#include \"ShaderVariablesFunctions.hlsl\"", false);
finalShader.AddShaderChunk(shaderFunctionVisitor.GetShaderString(2), false);
finalShader.AddShaderChunk(graphVertexInput, false);
finalShader.AddShaderChunk(surfaceInputs.GetShaderString(2), false);
finalShader.AddShaderChunk(surfaceDescriptionStruct.GetShaderString(2), false);
finalShader.AddShaderChunk(shaderProperties.GetPropertiesDeclaration(2), false);
finalShader.AddShaderChunk(vertexShader.GetShaderString(2), false);
finalShader.AddShaderChunk(surfaceDescriptionFunction.GetShaderString(2), false);
finalShader.AddShaderChunk("ENDHLSL", false);
finalShader.AddShaderChunk(ShaderGenerator.GetPreviewSubShader(node, requirements), false);
ListPool<INode>.Release(activeNodeList);
finalShader.Deindent();
finalShader.AddShaderChunk("}", false);
configuredTextures = shaderProperties.GetConfiguredTexutres();
return finalShader.GetShaderString(0);
}
}
public class InspectorPreviewData
{
public Mesh mesh;
[NonSerialized]
public float scale = 1f;
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/AbstractShaderProperty.cs


using System;
using UnityEditor.Graphing;
using UnityEngine;
namespace UnityEditor.ShaderGraph

}
public abstract PreviewProperty GetPreviewMaterialProperty();
public abstract INode ToConcreteNode();
}
}

42
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ColorMaterialSlot.cs


using System;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Slots;
using UnityEngine;

public override VisualElement InstantiateControl()
{
return new ColorRGBASlotControlView(this);
}
protected override string ConcreteSlotValueAsVariable(AbstractMaterialNode.OutputPrecision precision)
{
return string.Format("IsGammaSpace() ? {0}4({1}, {2}, {3}, {4}) : {0}4 (GammaToLinearSpace({0}3({1}, {2}, {3})), {4})"
, precision
, value.x
, value.y
, value.z
, value.w);
}
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
{
if (!generationMode.IsPreview())
return;
var matOwner = owner as AbstractMaterialNode;
if (matOwner == null)
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
var property = new ColorShaderProperty()
{
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
generatePropertyBlock = false,
value = value
};
properties.AddShaderProperty(property);
}
public override PreviewProperty GetPreviewProperty(string name)
{
var pp = new PreviewProperty
{
name = name,
propType = PropertyType.Color,
vector4Value = new Vector4(value.x, value.y, value.z, value.w),
floatValue = value.x,
colorValue = new Vector4(value.x, value.x, value.z, value.w),
};
return pp;
}
}
}

45
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ColorRGBMaterialSlot.cs


using System;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Slots;
using UnityEngine;

string displayName,
string shaderOutputName,
SlotType slotType,
Vector4 value,
Color value,
: base(slotId, displayName, shaderOutputName, slotType, value, shaderStage, hidden)
: base(slotId, displayName, shaderOutputName, slotType, (Vector4)value, shaderStage, hidden)
{
}

}
protected override string ConcreteSlotValueAsVariable(AbstractMaterialNode.OutputPrecision precision)
{
return string.Format("IsGammaSpace() ? {0}3({1}, {2}, {3}) : GammaToLinearSpace({0}3({1}, {2}, {3}))"
, precision
, value.x
, value.y
, value.z);
}
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
{
if (!generationMode.IsPreview())
return;
var matOwner = owner as AbstractMaterialNode;
if (matOwner == null)
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
var property = new ColorShaderProperty()
{
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
generatePropertyBlock = false,
value = new Color(value.x, value.y, value.z)
};
properties.AddShaderProperty(property);
}
public override PreviewProperty GetPreviewProperty(string name)
{
var pp = new PreviewProperty
{
name = name,
propType = PropertyType.Color,
vector4Value = new Vector4(value.x, value.y, value.z, 1),
floatValue = value.x,
colorValue = new Vector4(value.x, value.y, value.z, 1),
};
return pp;
}
}
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ColorShaderProperty.cs


using System;
using System.Text;
using UnityEditor.Graphing;
using UnityEngine;
namespace UnityEditor.ShaderGraph

propType = PropertyType.Color,
colorValue = value
};
}
public override INode ToConcreteNode()
{
return new ColorNode { color = value };
}
}
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/CubemapShaderProperty.cs


using System;
using System.Text;
using UnityEditor.Graphing;
using UnityEngine;
namespace UnityEditor.ShaderGraph

propType = PropertyType.Cubemap,
cubemapValue = value.cubemap
};
}
public override INode ToConcreteNode()
{
return new CubemapAssetNode { cubemap = value.cubemap };
}
}
}

4
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/DynamicVectorMaterialSlot.cs


namespace UnityEditor.ShaderGraph
{
[Serializable]
public class DynamicVectorMaterialSlot : MaterialSlot, IMaterialSlotHasVaule<Vector4>
public class DynamicVectorMaterialSlot : MaterialSlot, IMaterialSlotHasValue<Vector4>
{
[SerializeField]
private Vector4 m_Value;

protected override string ConcreteSlotValueAsVariable(AbstractMaterialNode.OutputPrecision precision)
{
var channelCount = (int)SlotValueHelper.GetChannelCount(concreteValueType);
var channelCount = SlotValueHelper.GetChannelCount(concreteValueType);
var values = value.x.ToString();
if (channelCount == 1)
return values;

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/FloatShaderProperty.cs


using System;
using System.Text;
using UnityEditor.Graphing;
using UnityEngine;
namespace UnityEditor.ShaderGraph

propType = PropertyType.Float,
floatValue = value
};
}
public override INode ToConcreteNode()
{
return new Vector1Node { value = value };
}
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/IShaderProperty.cs


using System;
using UnityEditor.Graphing;
using UnityEngine;
namespace UnityEditor.ShaderGraph

string GetPropertyDeclarationString();
string GetInlinePropertyDeclarationString();
PreviewProperty GetPreviewMaterialProperty();
INode ToConcreteNode();
}
}

128
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/MaterialSlot.cs


using System;
using System.Linq;
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("com.unity.shadergraph.EditorTests")]
public abstract class MaterialSlot : SerializableSlot
public abstract class MaterialSlot : ISlot
const string k_NotInit = "Not Initilaized";
[SerializeField]
int m_Id;
[SerializeField]
string m_DisplayName = k_NotInit;
[SerializeField]
SlotType m_SlotType = SlotType.Input;
[SerializeField]
int m_Priority = int.MaxValue;
[SerializeField]
bool m_Hidden;
[SerializeField]
string m_ShaderOutputName;

private bool m_HasError;
bool m_HasError;
: base(slotId, displayName, slotType, hidden)
m_Id = slotId;
m_DisplayName = displayName;
m_SlotType = slotType;
m_Hidden = hidden;
m_ShaderOutputName = shaderOutputName;
this.shaderStage = shaderStage;
}
protected MaterialSlot(int slotId, string displayName, string shaderOutputName, SlotType slotType, int priority, ShaderStage shaderStage = ShaderStage.Dynamic, bool hidden = false)
{
m_Id = slotId;
m_DisplayName = displayName;
m_SlotType = slotType;
m_Priority = priority;
m_Hidden = hidden;
m_ShaderOutputName = shaderOutputName;
this.shaderStage = shaderStage;
}

}
}
public override string displayName
public virtual string displayName
get { return base.displayName + ConcreteSlotValueTypeAsString(concreteValueType); }
set { base.displayName = value; }
get { return m_DisplayName + ConcreteSlotValueTypeAsString(concreteValueType); }
set { m_DisplayName = value; }
return base.displayName;
return m_DisplayName;
}
public static MaterialSlot CreateMaterialSlot(SlotValueType type, int slotId, string displayName, string shaderOutputName, SlotType slotType, Vector4 defaultValue, ShaderStage shaderStage = ShaderStage.Dynamic, bool hidden = false)

throw new ArgumentOutOfRangeException("type", type, null);
}
public SlotReference slotReference
{
get { return new SlotReference(owner.guid, m_Id); }
}
public INode owner { get; set; }
public bool hidden
{
get { return m_Hidden; }
set { m_Hidden = value; }
}
public int id
{
get { return m_Id; }
}
public int priority
{
get { return m_Priority; }
set { m_Priority = value; }
}
public bool isInputSlot
{
get { return m_SlotType == SlotType.Input; }
}
public bool isOutputSlot
{
get { return m_SlotType == SlotType.Output; }
}
public SlotType slotType
{
get { return m_SlotType; }
}
public bool isConnected
{
get
{
// node and graph respectivly
if (owner == null || owner.owner == null)
return false;
var graph = owner.owner;
var edges = graph.GetEdges(slotReference);
return edges.Any();
}
}
public abstract SlotValueType valueType { get; }
public abstract ConcreteSlotValueType concreteValueType { get; }

}
public abstract void CopyValuesFrom(MaterialSlot foundSlot);
bool Equals(MaterialSlot other)
{
return m_Id == other.m_Id && owner.guid.Equals(other.owner.guid);
}
public bool Equals(ISlot other)
{
return Equals(other as object);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((MaterialSlot)obj);
}
public override int GetHashCode()
{
unchecked
{
return (m_Id * 397) ^ (owner != null ? owner.GetHashCode() : 0);
}
}
}
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/SamplerStateShaderProperty.cs


using System;
using UnityEditor.Graphing;
using UnityEngine;
namespace UnityEditor.ShaderGraph

public override PreviewProperty GetPreviewMaterialProperty()
{
return default(PreviewProperty);
}
public override INode ToConcreteNode()
{
return new SamplerStateNode();
}
}
}

36
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/SerializableCubemap.cs


namespace UnityEditor.ShaderGraph
{
[Serializable]
public class SerializableCubemap
public class SerializableCubemap : ISerializationCallbackReceiver
{
[SerializeField]
private string m_SerializedCubemap;

public Cubemap cubemap;
}
Cubemap m_Cubemap;
if (string.IsNullOrEmpty(m_SerializedCubemap))
return null;
var cube = new CubemapHelper();
EditorJsonUtility.FromJsonOverwrite(m_SerializedCubemap, cube);
return cube.cubemap;
if (m_Cubemap == null && !string.IsNullOrEmpty(m_SerializedCubemap))
{
var cube = new CubemapHelper();
EditorJsonUtility.FromJsonOverwrite(m_SerializedCubemap, cube);
m_Cubemap = cube.cubemap;
m_SerializedCubemap = null;
}
return m_Cubemap;
set
{
if (cubemap == value)
return;
set { m_Cubemap = value; }
}
var cube = new CubemapHelper();
cube.cubemap = value;
m_SerializedCubemap = EditorJsonUtility.ToJson(cube, true);
}
public void OnBeforeSerialize()
{
var cube = new CubemapHelper { cubemap = cubemap };
m_SerializedCubemap = EditorJsonUtility.ToJson(cube, true);
}
public void OnAfterDeserialize()
{
}
}
}

49
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ShaderGraphRequirements.cs


using System.Collections.Generic;
using System.Linq;
using UnityEditor.Graphing;
namespace UnityEditor.ShaderGraph
{

if (other.requiresMeshUVs != null)
newReqs.requiresMeshUVs.AddRange(other.requiresMeshUVs);
return newReqs;
}
public static ShaderGraphRequirements FromNodes(List<INode> nodes)
{
NeededCoordinateSpace requiresNormal = nodes.OfType<IMayRequireNormal>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresNormal());
NeededCoordinateSpace requiresBitangent = nodes.OfType<IMayRequireBitangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresBitangent());
NeededCoordinateSpace requiresTangent = nodes.OfType<IMayRequireTangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresTangent());
NeededCoordinateSpace requiresViewDir = nodes.OfType<IMayRequireViewDirection>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresViewDirection());
NeededCoordinateSpace requiresPosition = nodes.OfType<IMayRequirePosition>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresPosition());
bool requiresScreenPosition = nodes.OfType<IMayRequireScreenPosition>().Any(x => x.RequiresScreenPosition());
bool requiresVertexColor = nodes.OfType<IMayRequireVertexColor>().Any(x => x.RequiresVertexColor());
var meshUV = new List<UVChannel>();
for (int uvIndex = 0; uvIndex < ShaderGeneratorNames.UVCount; ++uvIndex)
{
var channel = (UVChannel)uvIndex;
if (nodes.OfType<IMayRequireMeshUV>().Any(x => x.RequiresMeshUV(channel)))
meshUV.Add(channel);
}
// if anything needs tangentspace we have make
// sure to have our othonormal basis!
var compoundSpaces = requiresBitangent | requiresNormal | requiresPosition
| requiresTangent | requiresViewDir | requiresPosition
| requiresNormal;
var needsTangentSpace = (compoundSpaces & NeededCoordinateSpace.Tangent) > 0;
if (needsTangentSpace)
{
requiresBitangent |= NeededCoordinateSpace.Object;
requiresNormal |= NeededCoordinateSpace.Object;
requiresTangent |= NeededCoordinateSpace.Object;
}
var reqs = new ShaderGraphRequirements()
{
requiresNormal = requiresNormal,
requiresBitangent = requiresBitangent,
requiresTangent = requiresTangent,
requiresViewDir = requiresViewDir,
requiresPosition = requiresPosition,
requiresScreenPosition = requiresScreenPosition,
requiresVertexColor = requiresVertexColor,
requiresMeshUVs = meshUV
};
return reqs;
}
}
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/TextureShaderProperty.cs


using System;
using System.Text;
using UnityEditor.Graphing;
using UnityEngine;
namespace UnityEditor.ShaderGraph

propType = PropertyType.Texture,
textureValue = value.texture
};
}
public override INode ToConcreteNode()
{
return new Texture2DAssetNode { texture = value.texture };
}
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector1MaterialSlot.cs


namespace UnityEditor.ShaderGraph
{
[Serializable]
public class Vector1MaterialSlot : MaterialSlot, IMaterialSlotHasVaule<float>
public class Vector1MaterialSlot : MaterialSlot, IMaterialSlotHasValue<float>
{
[SerializeField]
private float m_Value;

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector2MaterialSlot.cs


namespace UnityEditor.ShaderGraph
{
[Serializable]
public class Vector2MaterialSlot : MaterialSlot, IMaterialSlotHasVaule<Vector2>
public class Vector2MaterialSlot : MaterialSlot, IMaterialSlotHasValue<Vector2>
{
[SerializeField]
private Vector2 m_Value;

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector2ShaderProperty.cs


using System;
using UnityEditor.Graphing;
using UnityEngine;
namespace UnityEditor.ShaderGraph

propType = PropertyType.Vector2,
vector4Value = value
};
}
public override INode ToConcreteNode()
{
return new Vector2Node { value = value };
}
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector3MaterialSlot.cs


namespace UnityEditor.ShaderGraph
{
[Serializable]
public class Vector3MaterialSlot : MaterialSlot, IMaterialSlotHasVaule<Vector3>
public class Vector3MaterialSlot : MaterialSlot, IMaterialSlotHasValue<Vector3>
{
[SerializeField]
private Vector3 m_Value;

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector3ShaderProperty.cs


using System;
using UnityEditor.Graphing;
using UnityEngine;
namespace UnityEditor.ShaderGraph

propType = PropertyType.Vector3,
vector4Value = value
};
}
public override INode ToConcreteNode()
{
return new Vector3Node { value = value };
}
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector4MaterialSlot.cs


namespace UnityEditor.ShaderGraph
{
[Serializable]
public class Vector4MaterialSlot : MaterialSlot, IMaterialSlotHasVaule<Vector4>
public class Vector4MaterialSlot : MaterialSlot, IMaterialSlotHasValue<Vector4>
{
[SerializeField]
private Vector4 m_Value;

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector4ShaderProperty.cs


using System;
using UnityEditor.Graphing;
using UnityEngine;
namespace UnityEditor.ShaderGraph

propType = PropertyType.Vector4,
vector4Value = value
};
}
public override INode ToConcreteNode()
{
return new Vector4Node { value = value };
}
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/IMaterialSlotHasValue.cs.meta


fileFormatVersion: 2
guid: 722107fbcd3d86249ac260090e5cc77e
guid: 94492244ef44a2e48b3e7790d7ac681d
MonoImporter:
externalObjects: {}
serializedVersion: 2

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Interfaces/IGeneratesFunction.cs


{
public interface IGeneratesFunction
{
void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode);
void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode);
}
}

72
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/LightweightPipeline/LightWeightPBRSubShader.cs


}
};
private static void GenerateApplicationVertexInputs(ShaderGraphRequirements graphRequiements, ShaderGenerator vertexInputs)
{
vertexInputs.AddShaderChunk("struct GraphVertexInput", false);
vertexInputs.AddShaderChunk("{", false);
vertexInputs.Indent();
vertexInputs.AddShaderChunk("float4 vertex : POSITION;", false);
vertexInputs.AddShaderChunk("float3 normal : NORMAL;", false);
vertexInputs.AddShaderChunk("float4 tangent : TANGENT;", false);
if (graphRequiements.requiresVertexColor)
{
vertexInputs.AddShaderChunk("float4 color : COLOR;", false);
}
foreach (var channel in graphRequiements.requiresMeshUVs.Distinct())
vertexInputs.AddShaderChunk(string.Format("float4 texcoord{0} : TEXCOORD{0};", (int)channel), false);
vertexInputs.AddShaderChunk("UNITY_VERTEX_INPUT_INSTANCE_ID", false);
vertexInputs.Deindent();
vertexInputs.AddShaderChunk("};", false);
}
var builder = new ShaderStringBuilder();
builder.IncreaseIndent();
builder.IncreaseIndent();
var vertexInputs = new ShaderGenerator();
var shaderFunctionVisitor = new ShaderGenerator();
var functionRegistry = new FunctionRegistry(builder);
var graphVertexInput = @"
struct GraphVertexInput
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float4 color : COLOR;
float4 texcoord0 : TEXCOORD0;
float4 lightmapUV : TEXCOORD1;
};";
surfaceInputs.AddShaderChunk("struct SurfaceInputs{", false);
surfaceInputs.Indent();

var requirements = AbstractMaterialGraph.GetRequirements(activeNodeList);
var requirements = ShaderGraphRequirements.FromNodes(activeNodeList);
var modelRequiements = ShaderGraphRequirements.none;
modelRequiements.requiresNormal |= NeededCoordinateSpace.World;
modelRequiements.requiresTangent |= NeededCoordinateSpace.World;
modelRequiements.requiresBitangent |= NeededCoordinateSpace.World;
modelRequiements.requiresPosition |= NeededCoordinateSpace.World;
modelRequiements.requiresViewDir |= NeededCoordinateSpace.World;
modelRequiements.requiresMeshUVs.Add(UVChannel.uv1);
GenerateApplicationVertexInputs(requirements.Union(modelRequiements), vertexInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresNormal, InterpolatorType.Normal, surfaceInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresTangent, InterpolatorType.Tangent, surfaceInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresBitangent, InterpolatorType.BiTangent, surfaceInputs);

var slots = new List<MaterialSlot>();
foreach (var id in pass.PixelShaderSlots)
slots.Add(masterNode.FindSlot<MaterialSlot>(id));
AbstractMaterialGraph.GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, slots, true);
GraphUtil.GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, slots, true);
AbstractMaterialGraph.GenerateSurfaceDescription(
GraphUtil.GenerateSurfaceDescription(
shaderFunctionVisitor,
functionRegistry,
shaderProperties,
requirements,
mode,

usedSlots);
var graph = new ShaderGenerator();
graph.AddShaderChunk(shaderFunctionVisitor.GetShaderString(2), false);
graph.AddShaderChunk(graphVertexInput, false);
graph.AddShaderChunk(builder.ToString(), false);
graph.AddShaderChunk(vertexInputs.GetShaderString(2), false);
graph.AddShaderChunk(surfaceInputs.GetShaderString(2), false);
graph.AddShaderChunk(surfaceDescriptionStruct.GetShaderString(2), false);
graph.AddShaderChunk(shaderProperties.GetPropertiesDeclaration(2), false);

var localSurfaceInputs = new ShaderGenerator();
var surfaceOutputRemap = new ShaderGenerator();
var reqs = ShaderGraphRequirements.none;
reqs.requiresNormal |= NeededCoordinateSpace.World;
reqs.requiresTangent |= NeededCoordinateSpace.World;
reqs.requiresBitangent |= NeededCoordinateSpace.World;
reqs.requiresPosition |= NeededCoordinateSpace.World;
reqs.requiresViewDir |= NeededCoordinateSpace.World;
ShaderGenerator.GenerateStandardTransforms(
3,
10,

localSurfaceInputs,
requirements,
reqs,
modelRequiements,
CoordinateSpace.World);
ShaderGenerator defines = new ShaderGenerator();

}
if (masterNode.IsSlotConnected(PBRMasterNode.AlphaThresholdSlotId))
defines.AddShaderChunk("#define _AlphaClip 1", true);
defines.AddShaderChunk("#define _AlphaClip 1", true);
var templateLocation = ShaderGenerator.GetTemplatePath(template);

30
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/LightweightPipeline/LightWeightUnlitSubShader.cs


private static string GetShaderPassFromTemplate(string template, UnlitMasterNode masterNode, Pass pass, GenerationMode mode)
{
var builder = new ShaderStringBuilder();
builder.IncreaseIndent();
builder.IncreaseIndent();
var vertexInputs = new ShaderGenerator();
var shaderFunctionVisitor = new ShaderGenerator();
var functionRegistry = new FunctionRegistry(builder);
var graphVertexInput = @"
struct GraphVertexInput
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float4 color : COLOR;
float4 texcoord0 : TEXCOORD0;
float4 lightmapUV : TEXCOORD1;
};";
surfaceInputs.AddShaderChunk("struct SurfaceInputs{", false);
surfaceInputs.Indent();

var requirements = AbstractMaterialGraph.GetRequirements(activeNodeList);
var requirements = ShaderGraphRequirements.FromNodes(activeNodeList);
GraphUtil.GenerateApplicationVertexInputs(requirements, vertexInputs, 0, 8);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresNormal, InterpolatorType.Normal, surfaceInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresTangent, InterpolatorType.Tangent, surfaceInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresBitangent, InterpolatorType.BiTangent, surfaceInputs);

if (slot != null)
slots.Add(slot);
}
AbstractMaterialGraph.GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, slots, true);
GraphUtil.GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, slots, true);
AbstractMaterialGraph.GenerateSurfaceDescription(
GraphUtil.GenerateSurfaceDescription(
shaderFunctionVisitor,
functionRegistry,
shaderProperties,
requirements,
mode,

usedSlots);
var graph = new ShaderGenerator();
graph.AddShaderChunk(shaderFunctionVisitor.GetShaderString(2), false);
graph.AddShaderChunk(graphVertexInput, false);
graph.AddShaderChunk(builder.ToString(), false);
graph.AddShaderChunk(vertexInputs.GetShaderString(2), false);
graph.AddShaderChunk(surfaceInputs.GetShaderString(2), false);
graph.AddShaderChunk(surfaceDescriptionStruct.GetShaderString(2), false);
graph.AddShaderChunk(shaderProperties.GetPropertiesDeclaration(2), false);

8
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/MasterNodes/PBRMasterNode.cs


public sealed override void UpdateNodeAfterDeserialization()
{
name = "PBR Master";
AddSlot(new Vector3MaterialSlot(AlbedoSlotId, AlbedoSlotName, AlbedoSlotName, SlotType.Input, new Vector4(0.5f, 0.5f, 0.5f), ShaderStage.Fragment));
AddSlot(new ColorRGBMaterialSlot(AlbedoSlotId, AlbedoSlotName, AlbedoSlotName, SlotType.Input, Color.grey, ShaderStage.Fragment));
AddSlot(new Vector3MaterialSlot(EmissionSlotId, EmissionSlotName, EmissionSlotName, SlotType.Input, Vector3.zero, ShaderStage.Fragment));
AddSlot(new ColorRGBMaterialSlot(EmissionSlotId, EmissionSlotName, EmissionSlotName, SlotType.Input, Color.black, ShaderStage.Fragment));
AddSlot(new Vector3MaterialSlot(SpecularSlotId, SpecularSlotName, SpecularSlotName, SlotType.Input, Vector3.zero, ShaderStage.Fragment));
AddSlot(new ColorRGBMaterialSlot(SpecularSlotId, SpecularSlotName, SpecularSlotName, SlotType.Input, Color.grey, ShaderStage.Fragment));
AddSlot(new Vector1MaterialSlot(SmoothnessSlotId, SmoothnessSlotName, SmoothnessSlotName, SlotType.Input, 0.5f, ShaderStage.Fragment));
AddSlot(new Vector1MaterialSlot(OcclusionSlotId, OcclusionSlotName, OcclusionSlotName, SlotType.Input, 1f, ShaderStage.Fragment));
AddSlot(new Vector1MaterialSlot(AlphaSlotId, AlphaSlotName, AlphaSlotName, SlotType.Input, 1f, ShaderStage.Fragment));

OcclusionSlotId,
AlphaSlotId,
AlphaThresholdSlotId
});
}, true);
}
public override string GetShader(GenerationMode mode, string outputName, out List<PropertyCollector.TextureInfo> configuredTextures)

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/MasterNodes/UnlitMasterNode.cs


public sealed override void UpdateNodeAfterDeserialization()
{
name = "Unlit Master";
AddSlot(new Vector3MaterialSlot(ColorSlotId, ColorSlotName, ColorSlotName, SlotType.Input, new Vector3(0.5f, 0.5f, 0.5f), ShaderStage.Fragment));
AddSlot(new ColorRGBMaterialSlot(ColorSlotId, ColorSlotName, ColorSlotName, SlotType.Input, Color.grey, ShaderStage.Fragment));
AddSlot(new Vector1MaterialSlot(AlphaSlotId, AlphaSlotName, AlphaSlotName, SlotType.Input, 1, ShaderStage.Fragment));
// clear out slot names that do not match the slots

269
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/AbstractMaterialNode.cs


}
[Serializable]
public abstract class AbstractMaterialNode : SerializableNode, IGenerateProperties
public abstract class AbstractMaterialNode : INode, ISerializationCallbackReceiver, IGenerateProperties
{
protected static List<MaterialSlot> s_TempSlots = new List<MaterialSlot>();
protected static List<IEdge> s_TempEdges = new List<IEdge>();

}
[NonSerialized]
private Guid m_Guid;
[SerializeField]
private string m_GuidSerialized;
[SerializeField]
private string m_Name;
[SerializeField]
private DrawState m_DrawState;
[NonSerialized]
private List<ISlot> m_Slots = new List<ISlot>();
[SerializeField]
List<SerializationHelper.JSONSerializedElement> m_SerializableSlots = new List<SerializationHelper.JSONSerializedElement>();
[NonSerialized]
public IGraph owner { get; set; }
public OnNodeModified onModified { get; set; }
public Guid guid
{
get { return m_Guid; }
}
public string name
{
get { return m_Name; }
set { m_Name = value; }
}
public virtual bool canDeleteNode
{
get { return true; }
}
public DrawState drawState
{
get { return m_DrawState; }
set
{
m_DrawState = value;
if (onModified != null)
onModified(this, ModificationScope.Node);
}
}
private OutputPrecision m_OutputPrecision = OutputPrecision.@float;
//[SerializeField]
private OutputPrecision m_OutputPrecision = OutputPrecision.@float;
[SerializeField]
bool m_PreviewExpanded = true;

get { return true; }
}
public override bool hasError
public virtual bool hasError
{
get { return m_HasError; }
protected set { m_HasError = value; }

{
if (m_NameForDefaultVariableName != name || m_GuidForDefaultVariableName != guid)
{
m_DefaultVariableName = string.Format("{0}_{1}", GetHLSLSafeName(name), GuidEncoder.Encode(guid));
m_DefaultVariableName = string.Format("{0}_{1}", NodeUtils.GetHLSLSafeName(name), GuidEncoder.Encode(guid));
m_NameForDefaultVariableName = name;
m_GuidForDefaultVariableName = guid;
}

protected AbstractMaterialNode()
{
m_DrawState.expanded = true;
m_Guid = Guid.NewGuid();
public Guid RewriteGuid()
{
m_Guid = Guid.NewGuid();
return m_Guid;
}
public void GetInputSlots<T>(List<T> foundSlots) where T : ISlot
{
foreach (var slot in m_Slots)
{
if (slot.isInputSlot && slot is T)
foundSlots.Add((T)slot);
}
}
public void GetOutputSlots<T>(List<T> foundSlots) where T : ISlot
{
foreach (var slot in m_Slots)
{
if (slot.isOutputSlot && slot is T)
foundSlots.Add((T)slot);
}
}
public void GetSlots<T>(List<T> foundSlots) where T : ISlot
{
foreach (var slot in m_Slots)
{
if (slot is T)
foundSlots.Add((T)slot);
}
}
public virtual void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
{
foreach (var inputSlot in this.GetInputSlots<MaterialSlot>())

return ConcreteSlotValueType.Vector1;
}
public override void ValidateNode()
public virtual void ValidateNode()
{
var isInError = false;

return false;
}
public static string GetSlotDimension(ConcreteSlotValueType slotValue)
{
switch (slotValue)
{
case ConcreteSlotValueType.Vector1:
return string.Empty;
case ConcreteSlotValueType.Vector2:
return "2";
case ConcreteSlotValueType.Vector3:
return "3";
case ConcreteSlotValueType.Vector4:
return "4";
case ConcreteSlotValueType.Matrix2:
return "2x2";
case ConcreteSlotValueType.Matrix3:
return "3x3";
case ConcreteSlotValueType.Matrix4:
return "4x4";
default:
return "Error";
}
}
public static string ConvertConcreteSlotValueTypeToString(OutputPrecision p, ConcreteSlotValueType slotValue)
{
switch (slotValue)
{
case ConcreteSlotValueType.Vector1:
return p.ToString();
case ConcreteSlotValueType.Vector2:
return p + "2";
case ConcreteSlotValueType.Vector3:
return p + "3";
case ConcreteSlotValueType.Vector4:
return p + "4";
case ConcreteSlotValueType.Texture2D:
return "Texture2D";
case ConcreteSlotValueType.Cubemap:
return "Cubemap";
case ConcreteSlotValueType.Matrix2:
return "Matrix2x2";
case ConcreteSlotValueType.Matrix3:
return "Matrix3x3";
case ConcreteSlotValueType.Matrix4:
return "Matrix4x4";
case ConcreteSlotValueType.SamplerState:
return "SamplerState";
default:
return "Error";
}
}
public virtual void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
s_TempSlots.Clear();

var slot = FindSlot<MaterialSlot>(slotId);
if (slot == null)
throw new ArgumentException(string.Format("Attempting to use MaterialSlot({0}) on node of type {1} where this slot can not be found", slotId, this), "slotId");
return string.Format("_{0}_{1}", GetVariableNameForNode(), GetHLSLSafeName(slot.shaderOutputName));
return string.Format("_{0}_{1}", GetVariableNameForNode(), NodeUtils.GetHLSLSafeName(slot.shaderOutputName));
}
public virtual string GetVariableNameForNode()

public static string GetHLSLSafeName(string input)
{
char[] arr = input.ToCharArray();
arr = Array.FindAll<char>(arr, (c => (char.IsLetterOrDigit(c))));
return new string(arr);
}
public sealed override void AddSlot(ISlot slot)
public void AddSlot(ISlot slot)
{
if (!(slot is MaterialSlot))
throw new ArgumentException(string.Format("Trying to add slot {0} to Material node {1}, but it is not a {2}", slot, this, typeof(MaterialSlot)));

// this will remove the old slot and add a new one
// if an old one was found. This allows updating values
base.AddSlot(slot);
m_Slots.RemoveAll(x => x.id == slot.id);
m_Slots.Add(slot);
slot.owner = this;
if (onModified != null)
{
onModified(this, ModificationScope.Topological);
}
if (foundSlot == null)
return;

public void RemoveSlot(int slotId)
{
// Remove edges that use this slot
// no owner can happen after creation
// but before added to graph
if (owner != null)
{
var edges = owner.GetEdges(GetSlotReference(slotId));
foreach (var edge in edges.ToArray())
owner.RemoveEdge(edge);
}
//remove slots
m_Slots.RemoveAll(x => x.id == slotId);
if (onModified != null)
{
onModified(this, ModificationScope.Topological);
}
}
public void RemoveSlotsNameNotMatching(IEnumerable<int> slotIds, bool supressWarnings = false)
{
var invalidSlots = m_Slots.Select(x => x.id).Except(slotIds);
foreach (var invalidSlot in invalidSlots.ToArray())
{
if (!supressWarnings)
Debug.LogWarningFormat("Removing Invalid MaterialSlot: {0}", invalidSlot);
RemoveSlot(invalidSlot);
}
}
public SlotReference GetSlotReference(int slotId)
{
var slot = FindSlot<ISlot>(slotId);
if (slot == null)
throw new ArgumentException("Slot could not be found", "slotId");
return new SlotReference(guid, slotId);
}
public T FindSlot<T>(int slotId) where T : ISlot
{
foreach (var slot in m_Slots)
{
if (slot.id == slotId && slot is T)
return (T)slot;
}
return default(T);
}
public T FindInputSlot<T>(int slotId) where T : ISlot
{
foreach (var slot in m_Slots)
{
if (slot.isInputSlot && slot.id == slotId && slot is T)
return (T)slot;
}
return default(T);
}
public T FindOutputSlot<T>(int slotId) where T : ISlot
{
foreach (var slot in m_Slots)
{
if (slot.isOutputSlot && slot.id == slotId && slot is T)
return (T)slot;
}
return default(T);
}
public virtual IEnumerable<ISlot> GetInputsWithNoConnection()
{
return this.GetInputSlots<ISlot>().Where(x => !owner.GetEdges(GetSlotReference(x.id)).Any());
}
public virtual void OnBeforeSerialize()
{
m_GuidSerialized = m_Guid.ToString();
m_SerializableSlots = SerializationHelper.Serialize<ISlot>(m_Slots);
}
public virtual void OnAfterDeserialize()
{
if (!string.IsNullOrEmpty(m_GuidSerialized))
m_Guid = new Guid(m_GuidSerialized);
else
m_Guid = Guid.NewGuid();
m_Slots = SerializationHelper.Deserialize<ISlot>(m_SerializableSlots, null);
m_SerializableSlots = null;
foreach (var s in m_Slots)
s.owner = this;
UpdateNodeAfterDeserialization();
}
public virtual void UpdateNodeAfterDeserialization()
{}
}
}

53
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/ChannelMixerNode.cs


}
}
string GetFunctionPrototype(string argIn, string argRed, string argGreen, string argBlue, string argOut)
{
return string.Format("void {0} ({1} {2}, {3} {4}, {3} {5}, {3} {6}, out {7} {8})", GetFunctionName(),
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType), argIn,
precision + "3", argRed, argGreen, argBlue,
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), argOut);
}
string inputValue = GetSlotValue(InputSlotId, generationMode);
string outputValue = GetSlotValue(OutputSlotId, generationMode);
visitor.AddShaderChunk(string.Format("{0} {1};", ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId)), true);
var sb = new ShaderStringBuilder();
var inputValue = GetSlotValue(InputSlotId, generationMode);
var outputValue = GetSlotValue(OutputSlotId, generationMode);
sb.AppendLine("{0} {1};", NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId));
visitor.AddShaderChunk(string.Format("{0}3 _{1}_Red = {0}3 ({2}, {3}, {4});", precision, GetVariableNameForNode(), channelMixer.outRed[0], channelMixer.outRed[1], channelMixer.outRed[2]), true);
visitor.AddShaderChunk(string.Format("{0}3 _{1}_Green = {0}3 ({2}, {3}, {4});", precision, GetVariableNameForNode(), channelMixer.outGreen[0], channelMixer.outGreen[1], channelMixer.outGreen[2]), true);
visitor.AddShaderChunk(string.Format("{0}3 _{1}_Blue = {0}3 ({2}, {3}, {4});", precision, GetVariableNameForNode(), channelMixer.outBlue[0], channelMixer.outBlue[1], channelMixer.outBlue[2]), true);
sb.AppendLine("{0}3 _{1}_Red = {0}3 ({2}, {3}, {4});", precision, GetVariableNameForNode(), channelMixer.outRed[0], channelMixer.outRed[1], channelMixer.outRed[2]);
sb.AppendLine("{0}3 _{1}_Green = {0}3 ({2}, {3}, {4});", precision, GetVariableNameForNode(), channelMixer.outGreen[0], channelMixer.outGreen[1], channelMixer.outGreen[2]);
sb.AppendLine("{0}3 _{1}_Blue = {0}3 ({2}, {3}, {4});", precision, GetVariableNameForNode(), channelMixer.outBlue[0], channelMixer.outBlue[1], channelMixer.outBlue[2]);
visitor.AddShaderChunk(GetFunctionCallBody(inputValue, string.Format("_{0}_Red", GetVariableNameForNode()), string.Format("_{0}_Green", GetVariableNameForNode()), string.Format("_{0}_Blue", GetVariableNameForNode()), outputValue), true);
}
sb.AppendLine("{0}({1}, _{2}_Red, _{2}_Green, _{2}_Blue, {3});", GetFunctionName(), inputValue, GetVariableNameForNode(), outputValue);
string GetFunctionCallBody(string inputValue, string red, string green, string blue, string outputValue)
{
return GetFunctionName() + " (" + inputValue + ", " + red + ", " + green + ", " + blue + ", " + outputValue + ");";
visitor.AddShaderChunk(sb.ToString(), false);
}
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)

});
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
visitor.AddShaderChunk(GetFunctionPrototype("In", "Red", "Green", "Blue", "Out"), false);
visitor.AddShaderChunk("{", false);
visitor.Indent();
visitor.AddShaderChunk(string.Format("Out = {0} (dot(In, Red), dot(In, Green), dot(In, Blue));",
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType)), true);
visitor.Deindent();
visitor.AddShaderChunk("}", false);
registry.ProvideFunction(GetFunctionName(), s =>
{
s.AppendLine("void {0} ({1} In, {2}3 Red, {2}3 Green, {2}3 Blue, out {3} Out)",
GetFunctionName(),
FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType.ToString(precision),
precision,
FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision));
using (s.BlockScope())
{
s.AppendLine("Out = {0}(dot(In, Red), dot(In, Green), dot(In, Blue));",
FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision));
}
});
}
}
}

8
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/HueNode.cs


static string Unity_Hue_Degrees(
[Slot(0, Binding.None)] Vector3 In,
[Slot(1, Binding.None)] Vector1 Hue,
[Slot(1, Binding.None)] Vector1 Offset,
[Slot(2, Binding.None)] out Vector3 Out)
{
Out = Vector3.zero;

{precision} E = 1e-10;
{precision}3 hsv = {precision}3(abs(Q.z + (Q.w - Q.y)/(6.0 * D + E)), D / (Q.x + E), Q.x);
{precision} hue = hsv.x + Hue / 360;
{precision} hue = hsv.x + Offset / 360;
hsv.x = (hue < 0)
? hue + 1
: (hue > 1)

static string Unity_Hue_Normalized(
[Slot(0, Binding.None)] Vector3 In,
[Slot(1, Binding.None, 0.5f, 0.5f, 0.5f, 0.5f)] Vector1 Hue,
[Slot(1, Binding.None, 0.5f, 0.5f, 0.5f, 0.5f)] Vector1 Offset,
[Slot(2, Binding.None)] out Vector3 Out)
{
Out = Vector3.zero;

{precision} E = 1e-10;
{precision}3 hsv = {precision}3(abs(Q.z + (Q.w - Q.y)/(6.0 * D + E)), D / (Q.x + E), Q.x);
{precision} hue = hsv.x + Hue;
{precision} hue = hsv.x + Offset;
hsv.x = (hue < 0)
? hue + 1
: (hue > 1)

4
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Blend/BlendNode.cs


return
@"
{
Out = B / (A + 0.000000000001);
Out = A / (B + 0.000000000001);
}";
}

return
@"
{
Out = B - A;
Out = A - B;
}
";
}

59
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Mask/ChannelMaskNode.cs


using System.Reflection;
using System;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;

void ValidateChannelCount()
{
int channelCount = (int)SlotValueHelper.GetChannelCount(FindSlot<MaterialSlot>(InputSlotId).concreteValueType);
int channelCount = SlotValueHelper.GetChannelCount(FindSlot<MaterialSlot>(InputSlotId).concreteValueType);
if ((int)channel >= channelCount)
channel = TextureChannel.Red;
}

return string.Format("void {0} ({1} {2}, out {3} {4})", GetFunctionName(),
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<DynamicVectorMaterialSlot>(InputSlotId).concreteValueType), argIn,
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<DynamicVectorMaterialSlot>(OutputSlotId).concreteValueType), argOut);
return string.Format("void {0} ({1} {2}, out {3} {4})", GetFunctionName(), NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<DynamicVectorMaterialSlot>(InputSlotId).concreteValueType), argIn, NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<DynamicVectorMaterialSlot>(OutputSlotId).concreteValueType), argOut);
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)

string outputValue = GetSlotValue(OutputSlotId, generationMode);
visitor.AddShaderChunk(string.Format("{0} {1};", ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId)), true);
visitor.AddShaderChunk(string.Format("{0} {1};", NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId)), true);
visitor.AddShaderChunk(GetFunctionCallBody(inputValue, outputValue), true);
}

}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
ValidateChannelCount();
var outputString = new ShaderGenerator();
outputString.AddShaderChunk(GetFunctionPrototype("In", "Out"), false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
switch (channel)
registry.ProvideFunction(GetFunctionName(), s =>
case TextureChannel.Green:
outputString.AddShaderChunk("Out = In.yyyy;", false);
break;
case TextureChannel.Blue:
outputString.AddShaderChunk("Out = In.zzzz;", false);
break;
case TextureChannel.Alpha:
outputString.AddShaderChunk("Out = In.wwww;", false);
break;
default:
outputString.AddShaderChunk("Out = In.xxxx;", false);
break;
}
outputString.Deindent();
outputString.AddShaderChunk("}", false);
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
s.AppendLine(GetFunctionPrototype("In", "Out"));
using (s.BlockScope())
{
switch (channel)
{
case TextureChannel.Green:
s.AppendLine("Out = In.yyyy;");
break;
case TextureChannel.Blue:
s.AppendLine("Out = In.zzzz;");
break;
case TextureChannel.Alpha:
s.AppendLine("Out = In.wwww;");
break;
case TextureChannel.Red:
s.AppendLine("Out = In.xxxx;");
break;
default:
throw new ArgumentOutOfRangeException();
}
}
});
}
}
}

119
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Normal/NormalCreateNode.cs


public const int StrengthInputId = 4;
public const int OutputSlotId = 5;
const string kTextureInputName = "Texture";
const string kUVInputName = "UV";
const string kSamplerInputName = "Sampler";
const string kOffsetInputName = "Offset";
const string kStrengthInputName = "Strength";
const string kOutputSlotName = "Out";
const string k_TextureInputName = "Texture";
const string k_UVInputName = "UV";
const string k_SamplerInputName = "Sampler";
const string k_OffsetInputName = "Offset";
const string k_StrengthInputName = "Strength";
const string k_OutputSlotName = "Out";
public NormalCreateNode()
{

public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new Texture2DInputMaterialSlot(TextureInputId, kTextureInputName, kTextureInputName));
AddSlot(new UVMaterialSlot(UVInputId, kUVInputName, kUVInputName, UVChannel.uv0));
AddSlot(new SamplerStateMaterialSlot(SamplerInputId, kSamplerInputName, kSamplerInputName, SlotType.Input));
AddSlot(new Vector1MaterialSlot(OffsetInputId, kOffsetInputName, kOffsetInputName, SlotType.Input, 0.5f));
AddSlot(new Vector1MaterialSlot(StrengthInputId, kStrengthInputName, kStrengthInputName, SlotType.Input, 8f));
AddSlot(new Vector3MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector3.zero));
AddSlot(new Texture2DInputMaterialSlot(TextureInputId, k_TextureInputName, k_TextureInputName));
AddSlot(new UVMaterialSlot(UVInputId, k_UVInputName, k_UVInputName, UVChannel.uv0));
AddSlot(new SamplerStateMaterialSlot(SamplerInputId, k_SamplerInputName, k_SamplerInputName, SlotType.Input));
AddSlot(new Vector1MaterialSlot(OffsetInputId, k_OffsetInputName, k_OffsetInputName, SlotType.Input, 0.5f));
AddSlot(new Vector1MaterialSlot(StrengthInputId, k_StrengthInputName, k_StrengthInputName, SlotType.Input, 8f));
AddSlot(new Vector3MaterialSlot(OutputSlotId, k_OutputSlotName, k_OutputSlotName, SlotType.Output, Vector3.zero));
string GetFunctionPrototype(string textureIn, string samplerIn, string uvIn, string offsetIn, string strengthIn, string argOut)
{
return string.Format("void {0} ({1} {2}, {3} {4}, {5} {6}, {7} {8}, {9} {10}, out {11} {12})", GetFunctionName(),
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(TextureInputId).concreteValueType), textureIn,
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(SamplerInputId).concreteValueType), samplerIn,
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(UVInputId).concreteValueType), uvIn,
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(OffsetInputId).concreteValueType), offsetIn,
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(StrengthInputId).concreteValueType), strengthIn,
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), argOut);
}
string textureValue = GetSlotValue(TextureInputId, generationMode);
string uvValue = GetSlotValue(UVInputId, generationMode);
string offsetValue = GetSlotValue(OffsetInputId, generationMode);
string strengthValue = GetSlotValue(StrengthInputId, generationMode);
string outputValue = GetSlotValue(OutputSlotId, generationMode);
var textureValue = GetSlotValue(TextureInputId, generationMode);
var uvValue = GetSlotValue(UVInputId, generationMode);
var offsetValue = GetSlotValue(OffsetInputId, generationMode);
var strengthValue = GetSlotValue(StrengthInputId, generationMode);
var outputValue = GetSlotValue(OutputSlotId, generationMode);
var samplerSlot = FindInputSlot<MaterialSlot>(SamplerInputId);
var edgesSampler = owner.GetEdges(samplerSlot.slotReference);

else
samplerValue = string.Format("sampler{0}", GetSlotValue(TextureInputId, generationMode));
visitor.AddShaderChunk(string.Format("{0} {1};", ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId)), true);
visitor.AddShaderChunk(GetFunctionCallBody(textureValue, samplerValue, uvValue, offsetValue, strengthValue, outputValue), true);
}
var sb = new ShaderStringBuilder();
sb.AppendLine("{0} {1};", FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision), GetVariableNameForSlot(OutputSlotId));
sb.AppendLine("{0}({1}, {2}, {3}, {4}, {5}, {6});", GetFunctionName(), textureValue, samplerValue, uvValue, offsetValue, strengthValue, outputValue);
string GetFunctionCallBody(string textureValue, string samplerValue, string uvValue, string offsetValue, string strengthValue, string outputValue)
{
return GetFunctionName() + " (" + textureValue + ", " + samplerValue + ", " + uvValue + ", " + offsetValue + ", " + strengthValue + ", " + outputValue + ");";
visitor.AddShaderChunk(sb.ToString(), false);
visitor.AddShaderChunk(GetFunctionPrototype("Texture", "Sampler", "UV", "Offset", "Strength", "Out"), true);
visitor.AddShaderChunk("{", true);
visitor.Indent();
var sb = new ShaderStringBuilder();
sb.AppendLine("void {0}({1} Texture, {2} Sampler, {3} UV, {4} Offset, {5} Strength, out {6} Out)", GetFunctionName(),
FindInputSlot<MaterialSlot>(TextureInputId).concreteValueType.ToString(precision),
FindInputSlot<MaterialSlot>(SamplerInputId).concreteValueType.ToString(precision),
FindInputSlot<MaterialSlot>(UVInputId).concreteValueType.ToString(precision),
FindInputSlot<MaterialSlot>(OffsetInputId).concreteValueType.ToString(precision),
FindInputSlot<MaterialSlot>(StrengthInputId).concreteValueType.ToString(precision),
FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision));
using (sb.BlockScope())
{
sb.AppendLine("Offset = pow(Offset, 3) * 0.1;");
sb.AppendLine("{0}2 offsetU = float2(UV.x + Offset, UV.y);", precision);
sb.AppendLine("{0}2 offsetV = float2(UV.x, UV.y + Offset);", precision);
visitor.AddShaderChunk("Offset = pow(Offset, 3) * 0.1;", true);
visitor.AddShaderChunk(string.Format("{0}2 offsetU = float2(UV.x + Offset, UV.y);", precision), true);
visitor.AddShaderChunk(string.Format("{0}2 offsetV = float2(UV.x, UV.y + Offset);", precision), true);
sb.AppendLine("{0} normalSample = Texture.Sample(Sampler, UV);", precision);
sb.AppendLine("{0} uSample = Texture.Sample(Sampler, offsetU);", precision);
sb.AppendLine("{0} vSample = Texture.Sample(Sampler, offsetV);", precision);
visitor.AddShaderChunk(string.Format("{0} normalSample = Texture.Sample(Sampler, UV);", precision), true);
visitor.AddShaderChunk(string.Format("{0} uSample = Texture.Sample(Sampler, offsetU);", precision), true);
visitor.AddShaderChunk(string.Format("{0} vSample = Texture.Sample(Sampler, offsetV);", precision), true);
sb.AppendLine("{0}3 va = float3(1, 0, (uSample - normalSample) * Strength);", precision);
sb.AppendLine("{0}3 vb = float3(0, 1, (vSample - normalSample) * Strength);", precision);
sb.AppendLine("Out = normalize(cross(va, vb));");
}
visitor.AddShaderChunk(sb.ToString(), true);
}
public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
{
registry.ProvideFunction(GetFunctionName(), s =>
{
s.AppendLine("void {0}({1} Texture, {2} Sampler, {3} UV, {4} Offset, {5} Strength, out {6} Out)", GetFunctionName(),
FindInputSlot<MaterialSlot>(TextureInputId).concreteValueType.ToString(precision),
FindInputSlot<MaterialSlot>(SamplerInputId).concreteValueType.ToString(precision),
FindInputSlot<MaterialSlot>(UVInputId).concreteValueType.ToString(precision),
FindInputSlot<MaterialSlot>(OffsetInputId).concreteValueType.ToString(precision),
FindInputSlot<MaterialSlot>(StrengthInputId).concreteValueType.ToString(precision),
FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision));
using (s.BlockScope())
{
s.AppendLine("Offset = pow(Offset, 3) * 0.1;");
s.AppendLine("{0}2 offsetU = float2(UV.x + Offset, UV.y);", precision);
s.AppendLine("{0}2 offsetV = float2(UV.x, UV.y + Offset);", precision);
visitor.AddShaderChunk(string.Format("{0}3 va = float3(1, 0, (uSample - normalSample) * Strength);", precision), true);
visitor.AddShaderChunk(string.Format("{0}3 vb = float3(0, 1, (vSample - normalSample) * Strength);", precision), true);
visitor.AddShaderChunk("Out = normalize(cross(va, vb));", true);
s.AppendLine("{0} normalSample = Texture.Sample(Sampler, UV);", precision);
s.AppendLine("{0} uSample = Texture.Sample(Sampler, offsetU);", precision);
s.AppendLine("{0} vSample = Texture.Sample(Sampler, offsetV);", precision);
visitor.Deindent();
visitor.AddShaderChunk("}", true);
s.AppendLine("{0}3 va = float3(1, 0, (uSample - normalSample) * Strength);", precision);
s.AppendLine("{0}3 vb = float3(0, 1, (vSample - normalSample) * Strength);", precision);
s.AppendLine("Out = normalize(cross(va, vb));");
}
});
}
public bool RequiresMeshUV(UVChannel channel)

return false;
}
}
}
}

80
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Channel/FlipNode.cs


string GetFunctionName()
{
return "Unity_Flip_" + ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType);
return "Unity_Flip_" + NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType);
}
public sealed override void UpdateNodeAfterDeserialization()

RemoveSlotsNameNotMatching(new[] { InputSlotId, OutputSlotId });
}
int channelCount { get { return (int)SlotValueHelper.GetChannelCount(FindSlot<MaterialSlot>(InputSlotId).concreteValueType); } }
int channelCount { get { return SlotValueHelper.GetChannelCount(FindSlot<MaterialSlot>(InputSlotId).concreteValueType); } }
[SerializeField]
private bool m_RedChannel;

}
}
string GetFunctionPrototype(string inArg, string flipArg, string outArg)
{
return string.Format("void {0} ({1} {2}, {3} {4}, out {5} {6})", GetFunctionName(),
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType), inArg,
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType), flipArg,
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), outArg);
}
string inputValue = GetSlotValue(InputSlotId, generationMode);
string outputValue = GetSlotValue(OutputSlotId, generationMode);
visitor.AddShaderChunk(string.Format("{0} {1};", ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId)), true);
var sb = new ShaderStringBuilder();
var inputValue = GetSlotValue(InputSlotId, generationMode);
var outputValue = GetSlotValue(OutputSlotId, generationMode);
sb.AppendLine("{0} {1};", FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision), GetVariableNameForSlot(OutputSlotId));
visitor.AddShaderChunk(string.Format("{0} _{1}_Flip = {0} ({2}{3}{4}{5});",
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType),
GetVariableNameForNode(),
Convert.ToInt32(m_RedChannel).ToString(),
channelCount > 1 ? string.Format(", {0}", (Convert.ToInt32(m_GreenChannel)).ToString()) : "",
channelCount > 2 ? string.Format(", {0}", (Convert.ToInt32(m_BlueChannel)).ToString()) : "",
channelCount > 3 ? string.Format(", {0}", (Convert.ToInt32(m_AlphaChannel)).ToString()) : ""), true);
sb.AppendLine("{0} _{1}_Flip = {0} ({2}",
FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision),
GetVariableNameForNode(),
Convert.ToInt32(m_RedChannel));
if (channelCount > 1)
sb.Append(", {0}", Convert.ToInt32(m_GreenChannel));
if (channelCount > 2)
sb.Append(", {0}", Convert.ToInt32(m_BlueChannel));
if (channelCount > 3)
sb.Append(", {0}", Convert.ToInt32(m_AlphaChannel));
sb.Append(");");
visitor.AddShaderChunk(GetFunctionCallBody(inputValue, string.Format("_{0}_Flip", GetVariableNameForNode()), outputValue), true);
}
sb.AppendLine("{0}({1}, _{2}_Flip, {3});", GetFunctionName(), inputValue, GetVariableNameForNode(), outputValue);
string GetFunctionCallBody(string inputValue, string flipValue, string outputValue)
{
return GetFunctionName() + " (" + inputValue + ", " + flipValue + ", " + outputValue + ");";
visitor.AddShaderChunk(sb.ToString(), false);
}
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)

public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputString = new ShaderGenerator();
outputString.AddShaderChunk(GetFunctionPrototype("In", "Flip", "Out"), true);
outputString.AddShaderChunk("{", true);
outputString.Indent();
outputString.AddShaderChunk("Out = abs(Flip - In);", true);
outputString.Deindent();
outputString.AddShaderChunk("}", true);
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
var sb = new ShaderStringBuilder();
sb.AppendLine("void {0}({1} In, {2} Flip, out {3} Out)",
GetFunctionName(),
FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType.ToString(precision),
FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType.ToString(precision),
FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision));
using (sb.BlockScope())
{
sb.AppendLine("Out = abs(Flip - In);");
}
visitor.AddShaderChunk(sb.ToString(), true);
}
public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
{
registry.ProvideFunction(GetFunctionName(), s =>
{
s.AppendLine("void {0}({1} In, {2} Flip, out {3} Out)",
GetFunctionName(),
FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType.ToString(precision),
FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType.ToString(precision),
FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision));
using (s.BlockScope())
{
s.AppendLine("Out = abs(Flip - In);");
}
});
}
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Channel/SplitNode.cs


var numInputChannels = 0;
if (inputSlot != null)
{
numInputChannels = (int)SlotValueHelper.GetChannelCount(inputSlot.concreteValueType);
numInputChannels = SlotValueHelper.GetChannelCount(inputSlot.concreteValueType);
if (numInputChannels > 4)
numInputChannels = 0;

100
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Channel/SwizzleNode.cs


using System;
using System.Collections.Generic;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;

{
[Title("Channel", "Swizzle")]
public class SwizzleNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction
public class SwizzleNode : AbstractMaterialNode, IGeneratesBodyCode
{
public SwizzleNode()
{

get { return true; }
}
string GetFunctionName()
{
return "Unity_Swizzle_" + precision + "_" + GuidEncoder.Encode(guid);
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new DynamicVectorMaterialSlot(InputSlotId, kInputSlotName, kInputSlotName, SlotType.Input, Vector4.zero));

static Dictionary<TextureChannel, string> m_ComponentList = new Dictionary<TextureChannel, string>
static Dictionary<TextureChannel, string> s_ComponentList = new Dictionary<TextureChannel, string>
{TextureChannel.Red, ".r" },
{TextureChannel.Green, ".g" },
{TextureChannel.Blue, ".b" },
{TextureChannel.Alpha, ".a" },
{TextureChannel.Red, "r" },
{TextureChannel.Green, "g" },
{TextureChannel.Blue, "b" },
{TextureChannel.Alpha, "a" },
private TextureChannel m_RedChannel;
TextureChannel m_RedChannel;
[ChannelEnumControl("Red Out")]
public TextureChannel redChannel

m_RedChannel = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
onModified(this, ModificationScope.Node);
private TextureChannel m_GreenChannel;
TextureChannel m_GreenChannel;
[ChannelEnumControl("Green Out")]
public TextureChannel greenChannel

m_GreenChannel = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
onModified(this, ModificationScope.Node);
private TextureChannel m_BlueChannel;
TextureChannel m_BlueChannel;
[ChannelEnumControl("Blue Out")]
public TextureChannel blueChannel

m_BlueChannel = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
onModified(this, ModificationScope.Node);
private TextureChannel m_AlphaChannel;
TextureChannel m_AlphaChannel;
[ChannelEnumControl("Alpha Out")]
public TextureChannel alphaChannel

m_AlphaChannel = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
onModified(this, ModificationScope.Node);
}
}
}

int channelCount = (int)SlotValueHelper.GetChannelCount(FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType);
var channelCount = SlotValueHelper.GetChannelCount(FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType);
if ((int)redChannel >= channelCount)
redChannel = TextureChannel.Red;
if ((int)greenChannel >= channelCount)

alphaChannel = TextureChannel.Red;
}
string GetFunctionPrototype(string inArg, string outArg)
{
return string.Format("void {0} ({1} {2}, out {3} {4})", GetFunctionName(),
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType), inArg,
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), outArg);
}
string inputValue = GetSlotValue(InputSlotId, generationMode);
string outputValue = GetSlotValue(OutputSlotId, generationMode);
visitor.AddShaderChunk(string.Format("{0} {1};", ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId)), true);
visitor.AddShaderChunk(GetFunctionCallBody(inputValue, outputValue), true);
var outputSlotType = FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision);
var outputName = GetVariableNameForSlot(OutputSlotId);
var inputValue = GetSlotValue(InputSlotId, generationMode);
var inputValueType = FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType;
if (inputValueType == ConcreteSlotValueType.Vector1)
visitor.AddShaderChunk(string.Format("{0} {1} = {2};", outputSlotType, outputName, inputValue), false);
else if (generationMode == GenerationMode.ForReals)
visitor.AddShaderChunk(string.Format("{0} {1} = {2}.{3}{4}{5}{6};", outputSlotType, outputName, inputValue, s_ComponentList[m_RedChannel], s_ComponentList[m_GreenChannel], s_ComponentList[m_BlueChannel], s_ComponentList[m_AlphaChannel]), false);
else
visitor.AddShaderChunk(string.Format("{0} {1} = {0}({3}[((int){2} >> 0) & 3], {3}[((int){2} >> 2) & 3], {3}[((int){2} >> 4) & 3], {3}[((int){2} >> 6) & 3]);",
outputSlotType,
outputName,
GetVariableNameForNode(), // Name of the uniform we encode swizzle values into
inputValue), false);
string GetFunctionCallBody(string inputValue, string outputValue)
public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
return GetFunctionName() + " (" + inputValue + ", " + outputValue + ");";
base.CollectShaderProperties(properties, generationMode);
if (generationMode != GenerationMode.Preview)
return;
properties.AddShaderProperty(new FloatShaderProperty
{
overrideReferenceName = GetVariableNameForNode(),
generatePropertyBlock = false
});
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
ValidateChannelCount();
var outputString = new ShaderGenerator();
outputString.AddShaderChunk(GetFunctionPrototype("In", "Out"), true);
outputString.AddShaderChunk("{", true);
outputString.Indent();
outputString.AddShaderChunk(string.Format("Out = {0} ({1}, {2}, {3}, {4});",
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType),
kInputSlotName + m_ComponentList[m_RedChannel],
kInputSlotName + m_ComponentList[m_GreenChannel],
kInputSlotName + m_ComponentList[m_BlueChannel],
kInputSlotName + m_ComponentList[m_AlphaChannel]), true);
outputString.Deindent();
outputString.AddShaderChunk("}", true);
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
base.CollectPreviewMaterialProperties(properties);
// Encode swizzle values into an integer
var value = ((int)redChannel) | ((int)greenChannel << 2) | ((int)blueChannel << 4) | ((int)alphaChannel << 6);
properties.Add(new PreviewProperty
{
name = GetVariableNameForNode(),
propType = PropertyType.Float,
floatValue = value
});
}
}
}

17
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/CodeFunctionNode.cs


private string GetParamTypeName(MaterialSlot slot)
{
return ConvertConcreteSlotValueTypeToString(precision, slot.concreteValueType);
return NodeUtils.ConvertConcreteSlotValueTypeToString(precision, slot.concreteValueType);
return function.Name + "_" + (function.IsStatic ? string.Empty : GuidEncoder.Encode(guid) + "_") + precision;
return function.Name + "_" + (function.IsStatic ? string.Empty : GuidEncoder.Encode(guid) + "_") + precision + (this.GetSlots<DynamicVectorMaterialSlot>().Select(s => NodeUtils.GetSlotDimension(s.concreteValueType)).FirstOrDefault() ?? "");
}
private string GetFunctionHeader()

foreach (var slot in s_TempSlots)
{
var toReplace = string.Format("{{slot{0}dimension}}", slot.id);
var replacement = GetSlotDimension(slot.concreteValueType);
var replacement = NodeUtils.GetSlotDimension(slot.concreteValueType);
public virtual void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
public virtual void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
string function = GetFunctionHeader() + GetFunctionBody(GetFunctionToConvert());
visitor.AddShaderChunk(function, true);
registry.ProvideFunction(GetFunctionName(), s =>
{
s.AppendLine(GetFunctionHeader());
var functionBody = GetFunctionBody(GetFunctionToConvert());
var lines = functionBody.Trim('\r', '\n', '\t', ' ');
s.AppendLines(lines);
});
}
private static SlotAttribute GetSlotAttribute([NotNull] ParameterInfo info)

9
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Basic/ColorNode.cs


if (generationMode.IsPreview())
return;
visitor.AddShaderChunk(precision + "4 " + GetVariableNameForNode() + " = " + precision + "4 (" + color.r + ", " + color.g + ", " + color.b + ", " + color.a + ");", true);
visitor.AddShaderChunk(string.Format(
@"{0}4 {1} = IsGammaSpace() ? {0}4({2}, {3}, {4}, {5}) : {0}4(GammaToLinearSpace({0}3({2}, {3}, {4})), {5});"
, precision
, GetVariableNameForNode()
, color.r
, color.g
, color.b
, color.a), true);
}
public override string GetVariableNameForSlot(int slotId)

1
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/NormalVectorNode.cs


namespace UnityEditor.ShaderGraph
{
[FormerName("UnityEngine.MaterialGraph.NormalNode")]
[Title("Input", "Geometry", "Normal Vector")]
public class NormalVectorNode : GeometryNode, IMayRequireNormal
{

1
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/PositionNode.cs


namespace UnityEditor.ShaderGraph
{
[FormerName("UnityEngine.MaterialGraph.WorldPosNode")]
[Title("Input", "Geometry", "Position")]
public class PositionNode : GeometryNode, IMayRequirePosition
{

1
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/ViewDirectionNode.cs


namespace UnityEditor.ShaderGraph
{
[FormerName("UnityEngine.MaterialGraph.ViewDirectionNode")]
[Title("Input", "Geometry", "View Direction")]
public class ViewDirectionNode : GeometryNode, IMayRequireViewDirection
{

38
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/CameraNode.cs


[Title("Input", "Scene", "Camera")]
public class CameraNode : AbstractMaterialNode
{
private const string kOutputSlotName = "Pos";
private const string kOutputSlot1Name = "Dir";
private const string kOutputSlot2Name = "Near";
private const string kOutputSlot3Name = "Far";
private const string kOutputSlot4Name = "Sign";
const string kOutputSlotName = "Position";
const string kOutputSlot1Name = "Direction";
const string kOutputSlot2Name = "Orthographic";
const string kOutputSlot3Name = "Near Plane";
const string kOutputSlot4Name = "Far Plane";
const string kOutputSlot5Name = "Sign";
const string kOutputSlot6Name = "Width";
const string kOutputSlot7Name = "Height";
public const int OutputSlotId = 0;
public const int OutputSlot1Id = 1;

public const int OutputSlot5Id = 5;
public const int OutputSlot6Id = 6;
public const int OutputSlot7Id = 7;
public CameraNode()
{

AddSlot(new Vector1MaterialSlot(OutputSlot2Id, kOutputSlot2Name, kOutputSlot2Name, SlotType.Output, 0));
AddSlot(new Vector1MaterialSlot(OutputSlot3Id, kOutputSlot3Name, kOutputSlot3Name, SlotType.Output, 0));
AddSlot(new Vector1MaterialSlot(OutputSlot4Id, kOutputSlot4Name, kOutputSlot4Name, SlotType.Output, 1));
RemoveSlotsNameNotMatching(validSlots);
}
protected int[] validSlots
{
get { return new[] { OutputSlotId, OutputSlot1Id, OutputSlot2Id, OutputSlot3Id, OutputSlot4Id }; }
AddSlot(new Vector1MaterialSlot(OutputSlot5Id, kOutputSlot5Name, kOutputSlot5Name, SlotType.Output, 1));
AddSlot(new Vector1MaterialSlot(OutputSlot6Id, kOutputSlot6Name, kOutputSlot6Name, SlotType.Output, 1));
AddSlot(new Vector1MaterialSlot(OutputSlot7Id, kOutputSlot7Name, kOutputSlot7Name, SlotType.Output, 1));
RemoveSlotsNameNotMatching(new[] { OutputSlotId, OutputSlot1Id, OutputSlot2Id, OutputSlot3Id, OutputSlot4Id, OutputSlot5Id, OutputSlot6Id, OutputSlot7Id });
}
public override string GetVariableNameForSlot(int slotId)

case OutputSlot1Id:
return "mul(unity_ObjectToWorld, UNITY_MATRIX_IT_MV [2].xyz)";
return "-1 * mul(unity_ObjectToWorld, UNITY_MATRIX_IT_MV [2].xyz)";
return "unity_OrthoParams.w";
case OutputSlot3Id:
case OutputSlot3Id:
case OutputSlot4Id:
case OutputSlot4Id:
case OutputSlot5Id:
case OutputSlot6Id:
return "unity_OrthoParams.x";
case OutputSlot7Id:
return "unity_OrthoParams.y";
default:
return "_WorldSpaceCameraPos";
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Texture/SamplerStateNode.cs


public override string GetVariableNameForNode()
{
string ss = GetHLSLSafeName(name) + "_"
string ss = NodeUtils.GetHLSLSafeName(name) + "_"
+ Enum.GetName(typeof(TextureSamplerState.FilterMode), filter) + "_"
+ Enum.GetName(typeof(TextureSamplerState.WrapMode), wrap) + "_sampler";
return ss;

9
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Texture/SampleTexture2DNode.cs


Normal
};
[Title("Input", "Texture", "Texture 2D")]
public class Texture2DNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireMeshUV
[FormerName("UnityEditor.ShaderGraph.Texture2DNode")]
[Title("Input", "Texture", "Sample Texture 2D")]
public class SampleTexture2DNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireMeshUV
{
public const int OutputSlotRGBAId = 0;
public const int OutputSlotRId = 4;

public override bool hasPreview { get { return true; } }
public Texture2DNode()
public SampleTexture2DNode()
name = "Texture 2D";
name = "Sample Texture 2D";
UpdateNodeAfterDeserialization();
}

9
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Texture/SampleCubemapNode.cs


namespace UnityEditor.ShaderGraph
{
[Title("Input", "Texture", "Cubemap")]
public class CubemapNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireViewDirection, IMayRequireNormal
[FormerName("UnityEditor.ShaderGraph.CubemapNode")]
[Title("Input", "Texture", "Sample Cubemap")]
public class SampleCubemapNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireViewDirection, IMayRequireNormal
{
public const int OutputSlotId = 0;
public const int CubemapInputId = 1;

public override bool hasPreview { get { return true; } }
public CubemapNode()
public SampleCubemapNode()
name = "Cubemap";
name = "Sample Cubemap";
UpdateNodeAfterDeserialization();
}

68
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Derivative/DDXNode.cs


namespace UnityEditor.ShaderGraph
{
public enum PartialDerivativePrecision
{
Coarse,
Default,
Fine
};
[Title("Math", "Derivative", "DDX")]
public class DDXNode : CodeFunctionNode
{

}
[SerializeField]
private PartialDerivativePrecision m_PartialDerivativePrecision = PartialDerivativePrecision.Default;
[EnumControl("Precision")]
public PartialDerivativePrecision partialDerivativePrecision
{
get { return m_PartialDerivativePrecision; }
set
{
if (m_PartialDerivativePrecision == value)
return;
m_PartialDerivativePrecision = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
}
}
string GetCurrentPrecision()
{
return System.Enum.GetName(typeof(PartialDerivativePrecision), m_PartialDerivativePrecision);
}
switch (m_PartialDerivativePrecision)
{
case PartialDerivativePrecision.Fine:
return GetType().GetMethod("Unity_DDX_Fine", BindingFlags.Static | BindingFlags.NonPublic);
case PartialDerivativePrecision.Coarse:
return GetType().GetMethod("Unity_DDX_Coarse", BindingFlags.Static | BindingFlags.NonPublic);
default:
return GetType().GetMethod("Unity_DDX_Default", BindingFlags.Static | BindingFlags.NonPublic);
}
return GetType().GetMethod("Unity_DDX", BindingFlags.Static | BindingFlags.NonPublic);
static string Unity_DDX_Default(
static string Unity_DDX(
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
{

Out = ddx(In);
}
";
}
static string Unity_DDX_Coarse(
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
{
return
@"
{
Out = ddx_coarse(In);
}
";
}
static string Unity_DDX_Fine(
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
{
return
@"
{
Out = ddx_fine(In);
}
";
}

63
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Derivative/DDXYNode.cs


name = "DDXY";
}
[SerializeField]
private PartialDerivativePrecision m_PartialDerivativePrecision = PartialDerivativePrecision.Default;
[EnumControl("Precision")]
public PartialDerivativePrecision partialDerivativePrecision
{
get { return m_PartialDerivativePrecision; }
set
{
if (m_PartialDerivativePrecision == value)
return;
m_PartialDerivativePrecision = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
}
}
string GetCurrentPrecision()
{
return System.Enum.GetName(typeof(PartialDerivativePrecision), m_PartialDerivativePrecision);
}
switch (m_PartialDerivativePrecision)
{
case PartialDerivativePrecision.Fine:
return GetType().GetMethod("Unity_DDXY_Fine", BindingFlags.Static | BindingFlags.NonPublic);
case PartialDerivativePrecision.Coarse:
return GetType().GetMethod("Unity_DDXY_Coarse", BindingFlags.Static | BindingFlags.NonPublic);
default:
return GetType().GetMethod("Unity_DDXY_Default", BindingFlags.Static | BindingFlags.NonPublic);
}
return GetType().GetMethod("Unity_DDXY", BindingFlags.Static | BindingFlags.NonPublic);
static string Unity_DDXY_Default(
static string Unity_DDXY(
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
{

Out = abs(ddx(In) + ddy(In));
}
";
}
static string Unity_DDXY_Coarse(
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
{
return
@"
{
Out = abs(ddx_coarse(In) + ddy_coarse(In));
}
";
}
static string Unity_DDXY_Fine(
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
{
return
@"
{
Out = abs(ddx_fine(In) + ddy_fine(In));
Out = abs(ddx(In)) + abs(ddy(In));
}
";
}

61
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Derivative/DDYNode.cs


name = "DDY";
}
[SerializeField]
private PartialDerivativePrecision m_PartialDerivativePrecision = PartialDerivativePrecision.Default;
[EnumControl("Precision")]
public PartialDerivativePrecision partialDerivativePrecision
{
get { return m_PartialDerivativePrecision; }
set
{
if (m_PartialDerivativePrecision == value)
return;
m_PartialDerivativePrecision = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
}
}
string GetCurrentPrecision()
{
return System.Enum.GetName(typeof(PartialDerivativePrecision), m_PartialDerivativePrecision);
}
switch (m_PartialDerivativePrecision)
{
case PartialDerivativePrecision.Fine:
return GetType().GetMethod("Unity_DDY_Fine", BindingFlags.Static | BindingFlags.NonPublic);
case PartialDerivativePrecision.Coarse:
return GetType().GetMethod("Unity_DDY_Coarse", BindingFlags.Static | BindingFlags.NonPublic);
default:
return GetType().GetMethod("Unity_DDY_Default", BindingFlags.Static | BindingFlags.NonPublic);
}
return GetType().GetMethod("Unity_DDY", BindingFlags.Static | BindingFlags.NonPublic);
static string Unity_DDY_Default(
static string Unity_DDY(
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
{

Out = ddy(In);
}
";
}
static string Unity_DDY_Coarse(
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
{
return
@"
{
Out = ddy_coarse(In);
}
";
}
static string Unity_DDY_Fine(
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
{
return
@"
{
Out = ddy_fine(In);
}
";
}

23
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Matrix/MatrixMultiplyByVectorNode.cs


protected string GetFunctionPrototype(string arg1Name, string arg2Name)
{
return string.Format("inline {0} {1} ({2} {3}, {4} {5})", ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlot2Id).concreteValueType), GetFunctionName(), ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlot1Id).concreteValueType), arg1Name, ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlot2Id).concreteValueType), arg2Name);
return string.Format("inline {0} {1} ({2} {3}, {4} {5})", NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlot2Id).concreteValueType), GetFunctionName(), NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlot1Id).concreteValueType), arg1Name, NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlot2Id).concreteValueType), arg2Name);
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)

string input2Value = GetSlotValue(InputSlot2Id, generationMode);
visitor.AddShaderChunk(string.Format("{0} {1} = {2};", ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlot2Id).concreteValueType), GetVariableNameForSlot(OutputSlotId), GetFunctionCallBody(input1Value, input2Value)), true);
visitor.AddShaderChunk(string.Format("{0} {1} = {2};", NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlot2Id).concreteValueType), GetVariableNameForSlot(OutputSlotId), GetFunctionCallBody(input1Value, input2Value)), true);
}
protected string GetFunctionCallBody(string input1Value, string input2Value)

public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
var outputString = new ShaderGenerator();
outputString.AddShaderChunk(GetFunctionPrototype("arg1", "arg2"), false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk("return mul(arg1, arg2);", false);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
registry.ProvideFunction(GetFunctionName(), s =>
{
s.AppendLine(GetFunctionPrototype("arg1", "arg2"));
using (s.BlockScope())
{
s.AppendLine("return mul(arg1, arg2);");
}
});
}
}
}

16
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Matrix/MatrixMultiplyNode.cs


protected string GetFunctionPrototype(string arg1Name, string arg2Name)
{
return string.Format("inline {0} {1} ({2} {3}, {4} {5})", ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlot2Id).concreteValueType), GetFunctionName(), ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlot1Id).concreteValueType), arg1Name, ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlot2Id).concreteValueType), arg2Name);
return string.Format("inline {0} {1} ({2} {3}, {4} {5})", NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlot2Id).concreteValueType), GetFunctionName(), NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlot1Id).concreteValueType), arg1Name, NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlot2Id).concreteValueType), arg2Name);
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)

string input2Value = GetSlotValue(InputSlot2Id, generationMode);
visitor.AddShaderChunk(string.Format("{0} {1} = {2};", ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlot2Id).concreteValueType), GetVariableNameForSlot(OutputSlotId), GetFunctionCallBody(input1Value, input2Value)), true);
visitor.AddShaderChunk(string.Format("{0} {1} = {2};", NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlot2Id).concreteValueType), GetVariableNameForSlot(OutputSlotId), GetFunctionCallBody(input1Value, input2Value)), true);
}
protected string GetFunctionCallBody(string input1Value, string input2Value)

outputString.AddShaderChunk("}", false);
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
{
registry.ProvideFunction(GetFunctionName(), s =>
{
s.AppendLine(GetFunctionPrototype("arg1", "arg2"));
using (s.BlockScope())
{
s.AppendLine("return mul(arg1, arg2);");
}
});
}
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Vector/FresnelEffectNode.cs


return
@"
{
Out = pow((1.0 - dot (normalize (Normal), normalize (ViewDir))), Power);
Out = pow((1.0 - saturate(dot(normalize(Normal), normalize(ViewDir)))), Power);
}
";
}

86
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Vector/TransformNode.cs


public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(GetInputSlot());
AddSlot(GetOutputSlot());
RemoveSlotsNameNotMatching(validSlots);
}
protected int[] validSlots
{
get { return new[] { InputSlotId, OutputSlotId }; }
}
protected virtual MaterialSlot GetInputSlot()
{
return new Vector3MaterialSlot(InputSlotId, kInputSlotName, kInputSlotName, SlotType.Input, Vector3.zero);
}
protected virtual MaterialSlot GetOutputSlot()
{
return new Vector3MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector4.zero);
AddSlot(new Vector3MaterialSlot(InputSlotId, kInputSlotName, kInputSlotName, SlotType.Input, Vector3.zero));
AddSlot(new Vector3MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector3.zero));
RemoveSlotsNameNotMatching(new[] { InputSlotId, OutputSlotId });
string inputValue = GetSlotValue(InputSlotId, generationMode);
string inputValue = string.Format("{0}.xyz", GetSlotValue(InputSlotId, generationMode));
string targetTransformString = "tangentTransform_" + conversion.from.ToString();
string transposeTargetTransformString = "transposeTangent";
string tangentTransformSpace = conversion.from.ToString();
bool requiresTransposeTangentTransform = false;
if (conversion.from == CoordinateSpace.World)
{

}
else if (conversion.to == CoordinateSpace.Object)
{
transformString = string.Format("mul({0}, float4({1}, 0)).xyz", MatrixNames.ModelInverse, inputValue);
transformString = "mul(unity_WorldToObject, float4(" + inputValue + ", 0)).xyz";
transformString = string.Format("mul(tangentTransform, {0}).xyz", inputValue);
transformString = "mul(" + inputValue + ", " + targetTransformString + ").xyz";
transformString = string.Format("mul({0}, float4({1}, 0)).xyz", MatrixNames.View, inputValue);
transformString = "mul( UNITY_MATRIX_V, float4(" + inputValue + ", 0)).xyz";
}
}
else if (conversion.from == CoordinateSpace.Object)

transformString = string.Format("mul({0}, float4({1}, 0)).xyz", MatrixNames.Model, inputValue);
transformString = "mul(unity_ObjectToWorld, float4(" + inputValue + ", 0)).xyz";
}
else if (conversion.to == CoordinateSpace.Object)
{

{
requiresTangentTransform = true;
transformString = string.Format("mul(tangentTransform, mul({0}, float4({1}, 0)).xyz).xyz", MatrixNames.Model, inputValue);
transformString = "mul(float4(" + inputValue + ", 0).xyz, " + targetTransformString + ").xyz";
transformString = string.Format("mul({0}, float4({1}, 0)).xyz", MatrixNames.ModelView, inputValue);
transformString = "mul( UNITY_MATRIX_MV, float4(" + inputValue + ", 0)).xyz";
requiresTangentTransform = true;
transformString = string.Format("mul({0}, tangentTransform).xyz", inputValue);
requiresTransposeTangentTransform = true;
transformString = "mul( " + inputValue + ", " + transposeTargetTransformString + " ).xyz";
transformString = string.Format("mul({0}, float4(mul({1}, tangentTransform ), 0)).xyz", MatrixNames.ModelInverse, inputValue);
requiresTransposeTangentTransform = true;
transformString = "mul( unity_WorldToObject, float4(mul(" + inputValue + ", " + transposeTargetTransformString + " ),0) ).xyz";
}
else if (conversion.to == CoordinateSpace.Tangent)
{

{
transformString = string.Format("mul({0}, float4(mul({1}, tangentTransform), 0)).xyz", MatrixNames.View, inputValue);
requiresTransposeTangentTransform = true;
transformString = "mul( UNITY_MATRIX_V, float4(mul(" + inputValue + ", " + transposeTargetTransformString + " ),0) ).xyz";
}
}
else if (conversion.from == CoordinateSpace.View)

transformString = string.Format("mul(float4({0}, 0), {1}).xyz", inputValue, MatrixNames.View);
transformString = "mul( float4(" + inputValue + ", 0), UNITY_MATRIX_V ).xyz";
transformString = string.Format("mul(float4({0}, 0), {1}).xyz", inputValue, MatrixNames.ModelView);
transformString = "mul( float4(" + inputValue + ", 0), UNITY_MATRIX_MV ).xyz";
transformString = string.Format("mul(tangentTransform, mul(float4({0}, 0), {1}).xyz).xyz", inputValue, MatrixNames.View);
tangentTransformSpace = CoordinateSpace.World.ToString();
transformString = "mul( mul( float4(" + inputValue + ", 0), UNITY_MATRIX_V ).xyz, " + targetTransformString + ").xyz";
}
else if (conversion.to == CoordinateSpace.View)
{

if (requiresTangentTransform)
visitor.AddShaderChunk(string.Format("float3x3 tangentTransform = float3x3({0}SpaceTangent, {0}SpaceBiTangent, {0}SpaceNormal);", conversion.from), false);
if (requiresTransposeTangentTransform)
visitor.AddShaderChunk("float3x3 " + transposeTargetTransformString + " = transpose(float3x3(" + CoordinateSpace.World.ToString() + "SpaceTangent, " + CoordinateSpace.World.ToString() + "SpaceBiTangent, " + CoordinateSpace.World.ToString() + "SpaceNormal));", true);
else if (requiresTangentTransform)
visitor.AddShaderChunk("float3x3 " + targetTransformString + " = float3x3(" + tangentTransformSpace + "SpaceTangent, " + tangentTransformSpace + "SpaceBiTangent, " + tangentTransformSpace + "SpaceNormal);", true);
visitor.AddShaderChunk(string.Format("{0} {1} = {2};", NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType),
GetVariableNameForSlot(OutputSlotId),
transformString), true);
}
visitor.AddShaderChunk(string.Format("{0} {1} = {2};",
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType),
GetVariableNameForSlot(OutputSlotId),
transformString), true);
bool RequiresWorldSpaceTangentTransform()
{
if (conversion.from == CoordinateSpace.View && conversion.to == CoordinateSpace.Tangent
|| conversion.from == CoordinateSpace.Tangent)
return true;
else
return false;
if(RequiresWorldSpaceTangentTransform())
return NeededCoordinateSpace.World;
if (RequiresWorldSpaceTangentTransform())
return NeededCoordinateSpace.World;
if (RequiresWorldSpaceTangentTransform())
return NeededCoordinateSpace.World;
}
}

15
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Procedural/Noise/SimpleNoiseNode.cs


";
}
public override void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
public override void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
string functionPreamble = @"
registry.ProvideFunction("unity_noise_randomValue", s => s.Append(@"
}
}"));
registry.ProvideFunction("unity_noise_interpolate", s => s.Append(@"
"));
registry.ProvideFunction("unity_valueNoise", s => s.Append(@"
inline float unity_valueNoise (float2 uv)
{
float2 i = floor(uv);

float topOfGrid = unity_noise_interpolate(r2, r3, f.x);
float t = unity_noise_interpolate(bottomOfGrid, topOfGrid, f.y);
return t;
}";
visitor.AddShaderChunk(functionPreamble, true);
base.GenerateNodeFunction(visitor, generationMode);
}"));
base.GenerateNodeFunction(registry, generationMode);
}
}
}

9
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Procedural/Noise/VoronoiNode.cs


";
}
public override void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
public override void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
var preamble = @"
registry.ProvideFunction("unity_voronoi_noise_randomVector", s => s.Append(@"
inline float2 unity_voronoi_noise_randomVector (float2 UV, float offset)
{
float2x2 m = float2x2(15.27, 47.63, 99.41, 89.98);

";
visitor.AddShaderChunk(preamble, true);
base.GenerateNodeFunction(visitor, generationMode);
"));
base.GenerateNodeFunction(registry, generationMode);
}
}
}

27
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/SlotValue.cs


using System;
using UnityEditor.Graphing;
namespace UnityEditor.ShaderGraph
{

public static class SlotValueHelper
{
public enum ChannelCount
{
Zero = 0,
One = 1,
Two = 2,
Three = 3,
Four = 4,
}
public static ChannelCount GetChannelCount(ConcreteSlotValueType type)
public static int GetChannelCount(ConcreteSlotValueType type)
return ChannelCount.Four;
return 4;
return ChannelCount.Three;
return 3;
return ChannelCount.Two;
return 2;
return ChannelCount.One;
return 1;
return ChannelCount.Zero;
return 0;
}
}

public static string ToClassName(this ConcreteSlotValueType type)
{
return k_ConcreteSlotValueTypeClassNames[(int)type];
}
public static string ToString(this ConcreteSlotValueType type, AbstractMaterialNode.OutputPrecision precision)
{
return NodeUtils.ConvertConcreteSlotValueTypeToString(precision, type);
}
}
}

5
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Utility/SubGraphNode.cs


GetOutputSlots(s_TempSlots);
foreach (var slot in s_TempSlots)
{
var outDimension = ConvertConcreteSlotValueTypeToString(precision, slot.concreteValueType);
var outDimension = NodeUtils.ConvertConcreteSlotValueTypeToString(precision, slot.concreteValueType);
outputString.AddShaderChunk(string.Format("{0} {1} = 0;", outDimension, GetVariableNameForSlot(slot.id)), false);
}

else
{
var varName = prop.referenceName;
outputString.AddShaderChunk(
ConvertConcreteSlotValueTypeToString(precision, inSlot.concreteValueType)
outputString.AddShaderChunk(NodeUtils.ConvertConcreteSlotValueTypeToString(precision, inSlot.concreteValueType)
+ " "
+ varName
+ " = "

4
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/SubGraph/AbstractSubGraph.cs


}
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
(node as IGeneratesFunction).GenerateNodeFunction(visitor, generationMode);
(node as IGeneratesFunction).GenerateNodeFunction(registry, generationMode);
}
}

4
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/SubGraph/AbstractSubGraphNode.cs


properties.AddRange(referencedGraph.GetPreviewProperties());
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
referencedGraph.GenerateNodeFunction(visitor, GenerationMode.ForReals);
referencedGraph.GenerateNodeFunction(registry, GenerationMode.ForReals);
}
public NeededCoordinateSpace RequiresNormal()

14
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Util/PropertyCollector.cs


result.Add(textureInfo);
}
}
foreach (var prop in m_Properties.OfType<CubemapShaderProperty>())
{
if (prop.referenceName != null)
{
var textureInfo = new TextureInfo
{
name = prop.referenceName,
textureId = prop.value.cubemap != null ? prop.value.cubemap.GetInstanceID() : 0,
modifiable = prop.modifiable
};
result.Add(textureInfo);
}
}
return result;
}
}

19
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Util/ShaderGenerator.cs


var sb = new StringBuilder();
foreach (var shaderChunk in m_ShaderChunks)
{
var lines = shaderChunk.chunkString.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
var lines = Regex.Split(shaderChunk.chunkString, Environment.NewLine);
for (int index = 0; index < lines.Length; index++)
{
var line = lines[index];

}
}
public static string EmitTransform(TransformDesc[] matrices, TransformDesc[] invMatrices, string variable, bool isAffine, bool inverseTranspose)
public static string EmitTransform(TransformDesc[] matrices, TransformDesc[] invMatrices, string variable, bool isAffine, bool noMatrixCast, bool inverseTranspose)
{
// Use inverse transpose for situations where
// scale needs to be considered (normals)

foreach (var m in matrices)
{
var matrix = m.name;
if (!isAffine)
if (!isAffine && !noMatrixCast)
{
matrix = "(float3x3)" + matrix;
}

// Ensure that the transform graph is initialized
InitTransforms();
bool isNormal = false;
bool affine = (inputType == InputType.Position);
bool affine = (inputType == InputType.Position && to != CoordinateSpace.World);
bool noMatrixCast = (inputType == InputType.Position && to == CoordinateSpace.World);
if (inputType == InputType.Normal)
{
inputType = InputType.Vector;

variable = EmitTransform(
GetTransformPath(CoordinateSpace.Tangent, tangentMatrixSpace),
GetTransformPath(tangentMatrixSpace, CoordinateSpace.Tangent),
variable, affine, !isNormal);
variable, affine, noMatrixCast, !isNormal);
return EmitTransform(GetTransformPath(from, to), GetTransformPath(to, from), variable, affine, isNormal);
return EmitTransform(GetTransformPath(from, to), GetTransformPath(to, from), variable, affine, noMatrixCast, isNormal);
}
public static void GenerateSpaceTranslationSurfaceInputs(

{
var name = preferedCoordinateSpace.ToVariableName(InterpolatorType.Position);
interpolators.AddShaderChunk(string.Format("float3 {0} : TEXCOORD{1};", name, interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = {1};", name, ConvertBetweenSpace("v.vertex", CoordinateSpace.Object, preferedCoordinateSpace, InputType.Vector)), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = {1};", name, ConvertBetweenSpace("v.vertex", CoordinateSpace.Object, preferedCoordinateSpace, InputType.Position)), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", name), false);
interpolatorIndex++;
}

if (graphRequiements.requiresScreenPosition)
surfaceInputs.AddShaderChunk(string.Format("surfaceInput.{0} = {0};", ShaderGeneratorNames.ScreenPosition), false);
foreach (var channel in combinedRequierments.requiresMeshUVs.Distinct())
surfaceInputs.AddShaderChunk(string.Format("surfaceInput.{0} ={0};", channel.GetUVName()), false);
foreach (var channel in graphRequiements.requiresMeshUVs.Distinct())
surfaceInputs.AddShaderChunk(string.Format("surfaceInput.{0} = {0};", channel.GetUVName()), false);
}
public enum Dimension

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ChannelEnumControl.cs


var value = (int)m_PropertyInfo.GetValue(m_Node, null);
using (var changeCheckScope = new EditorGUI.ChangeCheckScope())
{
int channelCount = (int)SlotValueHelper.GetChannelCount(m_Node.FindSlot<MaterialSlot>(m_SlotId).concreteValueType);
int channelCount = SlotValueHelper.GetChannelCount(m_Node.FindSlot<MaterialSlot>(m_SlotId).concreteValueType);
var enumEntryCount = (Enum)m_PropertyInfo.GetValue(m_Node, null);
string[] enumEntryNames = Enum.GetNames(enumEntryCount.GetType());
string[] popupEntries = new string[channelCount];

136
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Inspector/GraphInspectorView.cs


using System;
using System.Collections.Generic;
using UnityEditor.Graphing.Util;
using UnityEditor.Graphing;
using UnityEditor.Graphing;
using Object = UnityEngine.Object;
enum ResizeDirection
{
Any,
Vertical,
Horizontal
}
VisualElement m_ContentContainer;
TypeMapper m_TypeMapper;
List<INode> m_SelectedNodes;
Vector2 m_PreviewScrollPosition;

public GraphInspectorView(string assetName, PreviewManager previewManager, AbstractMaterialGraph graph)
{
m_Graph = graph;
m_SelectedNodes = new List<INode>();
AddStyleSheetPath("Styles/MaterialGraph");

}
topContainer.Add(headerContainer);
m_ContentContainer = new VisualElement {name = "content"};
topContainer.Add(m_ContentContainer);
}
Add(topContainer);
var bottomContainer = new VisualElement {name = "bottom"};
{
var propertiesContainer = new VisualElement {name = "properties"};
{
var header = new VisualElement {name = "header"};

m_PropertyItems = new VisualContainer {name = "items"};
propertiesContainer.Add(m_PropertyItems);
}
bottomContainer.Add(propertiesContainer);
topContainer.Add(propertiesContainer);
}
Add(topContainer);
var bottomContainer = new VisualElement {name = "bottom"};
{
m_PreviewTextureView.AddManipulator(new Scrollable(OnMouseScroll));
m_PreviewMeshPicker = new ObjectField() { objectType = typeof(Mesh) };
m_PreviewMeshPicker = new ObjectField { objectType = typeof(Mesh) };
m_PreviewMeshPicker.OnValueChanged(OnPreviewMeshChanged);
bottomContainer.Add(m_PreviewMeshPicker);

m_PreviewRenderHandle = previewManager.masterRenderData;
m_PreviewRenderHandle.onPreviewChanged += OnPreviewChanged;
m_PreviewMeshPicker.SetValueAndNotify(m_Graph.previewMesh);
m_PreviewMeshPicker.SetValueAndNotify(m_Graph.previewData.serializedMesh.mesh);
// Nodes missing custom editors:
// - PropertyNode
// - SubGraphInputNode
// - SubGraphOutputNode
m_TypeMapper = new TypeMapper(typeof(INode), typeof(AbstractNodeEditorView), typeof(StandardNodeEditorView))
var resizeHandleTop = new Label { name = "resize-top", text = "" };
resizeHandleTop.AddManipulator(new Draggable(mouseDelta => OnResize(mouseDelta, ResizeDirection.Vertical, true)));
Add(resizeHandleTop);
var resizeHandleRight = new Label { name = "resize-right", text = "" };
resizeHandleRight.AddManipulator(new Draggable(mouseDelta => OnResize(mouseDelta, ResizeDirection.Horizontal, false)));
Add(resizeHandleRight);
var resizeHandleLeft = new Label { name = "resize-left", text = "" };
resizeHandleLeft.AddManipulator(new Draggable(mouseDelta => OnResize(mouseDelta, ResizeDirection.Horizontal, true)));
Add(resizeHandleLeft);
var resizeHandleBottom = new Label { name = "resize-bottom", text = "" };
resizeHandleBottom.AddManipulator(new Draggable(mouseDelta => OnResize(mouseDelta, ResizeDirection.Vertical, false)));
Add(resizeHandleBottom);
}
void OnResize(Vector2 resizeDelta, ResizeDirection direction, bool moveWhileResize)
{
Vector2 normalizedResizeDelta = resizeDelta / 2f;
if (direction == ResizeDirection.Vertical)
// { typeof(AbstractSurfaceMasterNode), typeof(SurfaceMasterNodeEditorView) }
};
normalizedResizeDelta.x = 0f;
}
else if (direction == ResizeDirection.Horizontal)
{
normalizedResizeDelta.y = 0f;
}
Rect newLayout = layout;
// Resize form bottom/right
if (!moveWhileResize)
{
newLayout.width = Mathf.Max(layout.width + normalizedResizeDelta.x, 60f);
newLayout.height = Mathf.Max(layout.height + normalizedResizeDelta.y, 60f);
layout = newLayout;
return;
}
float previousFarX = layout.x + layout.width;
float previousFarY = layout.y + layout.height;
newLayout.width = Mathf.Max(layout.width - normalizedResizeDelta.x, 60f);
newLayout.height = Mathf.Max(layout.height - normalizedResizeDelta.y, 60f);
newLayout.x = Mathf.Min(layout.x + normalizedResizeDelta.x, previousFarX - 60f);
newLayout.y = Mathf.Min(layout.y + normalizedResizeDelta.y, previousFarY - 60f);
layout = newLayout;
}
MasterNode masterNode

m_PreviewScrollPosition.y = Mathf.Clamp(m_PreviewScrollPosition.y, -90f, 90f);
Quaternion previewRotation = Quaternion.Euler(m_PreviewScrollPosition.y, 0, 0) * Quaternion.Euler(0, m_PreviewScrollPosition.x, 0);
m_Graph.previewData.rotation = previewRotation;
}
void OnMouseScroll(float scrollDelta)
{
m_Graph.previewData.scale -= scrollDelta * .01f;
m_Graph.previewData.scale = Mathf.Clamp(m_Graph.previewData.scale, .1f, 4f);
masterNode.onModified(masterNode, ModificationScope.Node);
}
void OnAddProperty()

m_PreviewTextureView.Dirty(ChangeType.Repaint);
}
void OnPreviewMeshChanged(ChangeEvent<UnityEngine.Object> changeEvent)
void OnPreviewMeshChanged(ChangeEvent<Object> changeEvent)
if (m_Graph.previewMesh != changedMesh)
if (m_Graph.previewData.serializedMesh.mesh != changedMesh)
m_Graph.previewData.scale = 1f;
m_Graph.previewMesh = changedMesh;
}
public void UpdateSelection(IEnumerable<INode> nodes)
{
m_SelectedNodes.Clear();
m_SelectedNodes.AddRange(nodes);
var selectionHash = UIUtilities.GetHashCode(m_SelectedNodes.Count,
m_SelectedNodes != null ? m_SelectedNodes.FirstOrDefault() : null);
if (selectionHash != m_SelectionHash)
{
m_SelectionHash = selectionHash;
m_ContentContainer.Clear();
if (m_SelectedNodes.Count > 1)
{
var element = new Label(string.Format("{0} nodes selected.", m_SelectedNodes.Count))
{
name = "selectionCount"
};
m_ContentContainer.Add(element);
}
else if (m_SelectedNodes.Count == 1)
{
var node = m_SelectedNodes.First();
var view = (AbstractNodeEditorView)Activator.CreateInstance(m_TypeMapper.MapType(node.GetType()));
view.node = node;
m_ContentContainer.Add(view);
}
}
m_Graph.previewData.serializedMesh.mesh = changedMesh;
}
public void HandleGraphChanges()

7
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Manipulators/Draggable.cs


void OnMouseUp(MouseUpEvent evt)
{
m_Active = false;
target.ReleaseMouseCapture();
if (target.HasMouseCapture())
{
target.ReleaseMouseCapture();
}
evt.StopPropagation();
}
}

8
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Manipulators/GraphDropTarget.cs


isNormalMap = importer.textureType == TextureImporterType.NormalMap;
}
var node = new Texture2DNode();
var node = new SampleTexture2DNode();
if (isNormalMap)
node.textureType = TextureType.Normal;

m_Graph.AddNode(node);
var inputslot = node.FindSlot<Texture2DInputMaterialSlot>(Texture2DNode.TextureInputId);
var inputslot = node.FindSlot<Texture2DInputMaterialSlot>(SampleTexture2DNode.TextureInputId);
if (inputslot != null)
inputslot.texture = texture2D;
}

m_Graph.owner.RegisterCompleteObjectUndo("Drag Cubemap");
var property = new CubemapShaderProperty { displayName = cubemap.name, value = { cubemap = cubemap } };
m_Graph.AddShaderProperty(property);
var node = new CubemapNode();
var node = new SampleCubemapNode();
var inputslot = node.FindSlot<CubemapInputMaterialSlot>(CubemapNode.CubemapInputId);
var inputslot = node.FindSlot<CubemapInputMaterialSlot>(SampleCubemapNode.CubemapInputId);
if (inputslot != null)
inputslot.cubemap = cubemap;
}

17
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/MaterialGraphEditWindow.cs


string m_Selected;
[SerializeField]
SerializableGraphObject m_GraphObject;
GraphObject m_GraphObject;
[NonSerialized]
bool m_HasError;

}
}
SerializableGraphObject graphObject
GraphObject graphObject
{
get { return m_GraphObject; }
set

void OnDestroy()
{
if (graphObject.isDirty && EditorUtility.DisplayDialog("Shader Graph Might Have Been Modified", "Do you want to save the changes you made in the shader graph?", "Save", "Don't Save"))
UpdateAsset();
Undo.ClearUndo(graphObject);
DestroyImmediate(graphObject);
if (graphObject != null)
{
if (graphObject.isDirty && EditorUtility.DisplayDialog("Shader Graph Has Been Modified", "Do you want to save the changes you made in the shader graph?\n\nYour changes will be lost if you don't save them.", "Save", "Don't Save"))
UpdateAsset();
Undo.ClearUndo(graphObject);
DestroyImmediate(graphObject);
}
graphEditorView = null;
}

selectedGuid = newSelectionGuid;
var textGraph = File.ReadAllText(path, Encoding.UTF8);
graphObject = CreateInstance<SerializableGraphObject>();
graphObject = CreateInstance<GraphObject>();
graphObject.hideFlags = HideFlags.HideAndDontSave;
graphObject.graph = JsonUtility.FromJson(textGraph, graphType) as IGraph;
graphObject.graph.OnEnable();

57
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/PreviewManager.cs


using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using UnityEditor.Graphing.Util;
using UnityEditor.ShaderGraph;
using UnityEngine.Rendering;
using Debug = UnityEngine.Debug;
using Object = UnityEngine.Object;

MaterialPropertyBlock m_PreviewPropertyBlock;
PreviewSceneResources m_SceneResources;
Texture2D m_ErrorTexture;
const bool k_UberShaderEnabled = true;
Shader m_UberShader;
string m_UberShaderString;
Dictionary<Guid, int> m_UberShaderIds;

var node = m_Graph.GetNodeFromGuid(guid);
if (node == null)
continue;
if (!k_UberShaderEnabled || node is IMasterNode)
if (node is IMasterNode)
masterNodes.Add(node);
else
uberNodes.Add(node);

if (uberNodes.Count > 0)
{
m_UberShaderIds.Clear();
m_UberShaderString = m_Graph.GetUberPreviewShader(m_UberShaderIds, out m_OutputIdProperty);
var results = m_Graph.GetUberPreviewShader();
m_UberShaderString = results.shader;
m_OutputIdProperty = results.outputIdProperty;
m_UberShaderIds = results.ids;
var message = "RecreateUberShader: " + Environment.NewLine + m_UberShaderString;
Debug.LogWarning(message);
var errors = MaterialGraphAsset.GetShaderErrors(m_UberShader);
var message = new ShaderStringBuilder();
message.AppendLine(@"Preview shader for graph has {0} error{1}:", errors.Length, errors.Length != 1 ? "s" : "");
foreach (var error in errors)
{
INode node = null;
try
{
node = results.sourceMap.FindNode(error.line);
}
catch (Exception)
{
Debug.LogWarning("ERROR");
continue;
}
message.AppendLine("{0} in {3} at line {1} (on {2})", error.message, error.line, error.platform, node != null ? string.Format("node {0} ({1})", node.name, node.guid) : "graph");
message.AppendLine(error.messageDetails);
message.AppendNewLine();
}
Debug.LogWarning(message.ToString());
ShaderUtil.ClearShaderErrors(m_UberShader);
ShaderUtil.UpdateShaderAsset(m_UberShader, k_EmptyShader);
uberShaderHasError = true;

RenderTexture.active = renderData.renderTexture;
GL.Clear(true, true, Color.black);
Graphics.Blit(Texture2D.whiteTexture, renderData.renderTexture, m_SceneResources.checkerboardMaterial);
var mesh = (renderData == masterRenderData && m_Graph.previewMesh) ? m_Graph.previewMesh : m_SceneResources.sphere;
var mesh = (renderData == masterRenderData && m_Graph.previewData.serializedMesh.mesh) ? m_Graph.previewData.serializedMesh.mesh : m_SceneResources.sphere;
float scale = (renderData == masterRenderData) ? m_Graph.previewData.scale : 1f;
Graphics.DrawMesh(mesh, Matrix4x4.TRS(-mesh.bounds.center, rotation, Vector3.one * scale), m_PreviewMaterial, 1, m_SceneResources.camera, 0, m_PreviewPropertyBlock, ShadowCastingMode.Off, false, null, false);
Matrix4x4 previewTransform = Matrix4x4.identity;
if (renderData == masterRenderData)
{
previewTransform *= Matrix4x4.Rotate(rotation);
previewTransform *= Matrix4x4.Scale(Vector3.one * (Vector3.one).magnitude / mesh.bounds.size.magnitude);
previewTransform *= Matrix4x4.Translate(-mesh.bounds.center);
}
Graphics.DrawMesh(mesh, previewTransform, m_PreviewMaterial, 1, m_SceneResources.camera, 0, m_PreviewPropertyBlock, ShadowCastingMode.Off, false, null, false);
var previousUseSRP = Unsupported.useScriptableRenderPipeline;
Unsupported.useScriptableRenderPipeline = renderData.shaderData.node is IMasterNode;
m_SceneResources.camera.Render();

}
else
{
PreviewMode mode;
if (node is IMasterNode)
var masterNode = node as IMasterNode;
if (masterNode != null)
shaderData.shaderString = ((IMasterNode)node).GetShader(GenerationMode.Preview, node.name, out configuredTextures);
shaderData.shaderString = masterNode.GetShader(GenerationMode.Preview, node.name, out configuredTextures);
shaderData.shaderString = m_Graph.GetPreviewShader(node, out mode);
shaderData.shaderString = m_Graph.GetPreviewShader(node).shader;
}
File.WriteAllText(Application.dataPath + "/../GeneratedShader.shader", (shaderData.shaderString ?? "null").Replace("UnityEngine.MaterialGraph", "Generated"));

38
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/GraphEditorView.cs


content.Add(m_GraphView);
m_GraphInspectorView = new GraphInspectorView(assetName, previewManager, graph) { name = "inspector" };
m_GraphView.onSelectionChanged += m_GraphInspectorView.UpdateSelection;
content.Add(m_GraphInspectorView);
m_GraphInspectorView.AddManipulator(new Draggable(OnMouseDrag, true));
m_GraphInspectorView.RegisterCallback<PostLayoutEvent>(OnPostLayout);
m_GraphView.Add(m_GraphInspectorView);
m_GraphView.graphViewChanged = GraphViewChanged;
}

AddEdge(edge);
Add(content);
}
void OnPostLayout(PostLayoutEvent evt)
{
const float minimumVisibility = 60f;
Rect inspectorViewRect = m_GraphInspectorView.layout;
float minimumXPosition = minimumVisibility - inspectorViewRect.width;
float maximumXPosition = m_GraphView.layout.width - minimumVisibility;
float minimumYPosition = minimumVisibility - inspectorViewRect.height;
float maximumYPosition = m_GraphView.layout.height - minimumVisibility;
inspectorViewRect.x = Mathf.Clamp(inspectorViewRect.x, minimumXPosition, maximumXPosition);
inspectorViewRect.y = Mathf.Clamp(inspectorViewRect.y, minimumYPosition, maximumYPosition);
inspectorViewRect.width = Mathf.Min(inspectorViewRect.width, layout.width);
inspectorViewRect.height = Mathf.Min(inspectorViewRect.height, layout.height);
m_GraphInspectorView.layout = inspectorViewRect;
}
void OnMouseDrag(Vector2 mouseDelta)
{
Vector2 normalizedDelta = mouseDelta / 2f;
Rect inspectorWindowRect = m_GraphInspectorView.layout;
inspectorWindowRect.x += normalizedDelta.x;
inspectorWindowRect.y += normalizedDelta.y;
m_GraphInspectorView.layout = inspectorWindowRect;
}
GraphViewChange GraphViewChanged(GraphViewChange graphViewChange)

21
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/MaterialNodeView.cs


m_Attachers = new List<Attacher>(node.GetInputSlots<MaterialSlot>().Count());
AddSlots(node.GetSlots<MaterialSlot>());
expanded = node.drawState.expanded;
RefreshExpandedState(); //This should not be needed. GraphView needs to improve the extension api here
base.expanded = node.drawState.expanded;
RefreshExpandedState(); //This should not be needed. GraphView needs to improve the extension api here
UpdatePortInputVisibilities();
SetPosition(new Rect(node.drawState.position.x, node.drawState.position.y, 0, 0));

}
else
{
PreviewMode previewMode;
FloatShaderProperty outputIdProperty;
var shader = graph.GetShader(node, GenerationMode.ForReals, node.name, out textureInfo, out previewMode, out outputIdProperty);
GUIUtility.systemCopyBuffer = shader;
GUIUtility.systemCopyBuffer = graph.GetShader(node, GenerationMode.ForReals, node.name).shader;
}
}

{
var slots = node.GetSlots<MaterialSlot>().ToList();
var anchorsToRemove = new List<VisualElement>();
foreach (var anchor in inputContainer.Children())
if (!slots.Contains(anchor.userData as MaterialSlot))
anchorsToRemove.Add(anchor);
var anchorsToRemove = inputContainer.Children().ToList();
foreach (var anchorElement in anchorsToRemove)
{
inputContainer.Remove(anchorElement);

}
}
anchorsToRemove.Clear();
foreach (var anchor in outputContainer.Children())
if (!slots.Contains(anchor.userData as MaterialSlot))
anchorsToRemove.Add(anchor);
anchorsToRemove = outputContainer.Children().ToList();
foreach (var ve in anchorsToRemove)
outputContainer.Remove(ve);

port.portName = slot.displayName;
}
AddSlots(slots.Except(inputContainer.Children().Concat(outputContainer.Children()).Select(data => data.userData as MaterialSlot)));
AddSlots(slots);
if (inputContainer.childCount > 0)
inputContainer.Sort((x, y) => slots.IndexOf(x.userData as MaterialSlot) - slots.IndexOf(y.userData as MaterialSlot));

80
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Resources/Styles/MaterialGraph.uss


}
MaterialNodeView > #resize {
background-color: rgb(0, 0, 255);
background-image : resource("GraphView/Nodes/NodeChevronLeft.png");
}
MaterialNodeView > #resize:hover {
background-color: rgb(0, 127, 127);
}
MaterialNodeView > #resize:active {
background-color: rgb(0, 225, 25);
cursor: resize-up-left;
}
PortInputView {

background-color: rgb(56, 56, 56);
flex-direction: column;
justify-content: space-between;
position-type: absolute;
position-right: 0;
position-top: 0;
width: 600;
height: 800;
}
GraphInspectorView * {
font-size: 11;
}
GraphInspectorView > #top > #header {

padding-bottom: 10;
}
GraphInspectorView > #bottom {
margin-bottom: 20;
}
height: 400;
max-height: 400;
GraphInspectorView > #bottom > #properties {
GraphInspectorView > #top > #properties {
border-color: rgb(41, 41, 41);
border-top-width: 1;
border-bottom-width: 1;

margin-right: 8;
}
GraphInspectorView > #bottom > #properties > #header {
GraphInspectorView > #top > #properties > #header {
border-color: rgb(41, 41, 41);
border-bottom-width: 1;
flex-direction: row;

GraphInspectorView > #bottom > #properties > #header > #title {
GraphInspectorView > #top > #properties > #header > #title {
text-color: rgb(180, 180, 180);
font-style: bold;
padding-top: 8;

}
GraphInspectorView > #bottom > #properties > #header > #addButton {
GraphInspectorView > #top > #properties > #header > #addButton {
height: 24;
margin-top: 0;
margin-bottom: 0;

GraphInspectorView > #bottom > #properties > #items {
GraphInspectorView > #top > #properties > #items {
}
GraphInspectorView > #resize-right {
cursor: resize-horizontal;
background-color: rgba(0, 0, 0, 0);
position-type: absolute;
width: 10;
position-right: 0;
position-top: 0;
position-bottom: 0;
}
GraphInspectorView > #resize-left {
cursor: resize-horizontal;
background-color: rgba(0, 0, 0, 0);
position-type: absolute;
width: 10;
position-left: 0;
position-top: 0;
position-bottom: 0;
padding-left: 0;
margin-left: 0;
}
GraphInspectorView > #resize-top {
cursor: resize-vertical;
background-color: rgba(0, 0, 0, 0);
position-type: absolute;
height: 10;
position-left: 0;
position-right: 0;
position-top: 0;
padding-top: 0;
margin-top: 0;
}
GraphInspectorView > #resize-bottom {
cursor: resize-vertical;
background-color: rgba(0, 0, 0, 0);
position-type: absolute;
height: 10;
position-left: 0;
position-right: 0;
position-bottom: 0;
}
ShaderPropertyView {

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Templates/lightweightPBRForwardPass.template


HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma target 3.0
#pragma target 3.0
#pragma multi_compile _ _MAIN_LIGHT_COOKIE
#pragma multi_compile _MAIN_DIRECTIONAL_LIGHT _MAIN_SPOT_LIGHT

v = PopulateVertexData(v);
GraphVertexOutput o = (GraphVertexOutput)0;
${VertexShader}
float3 lwWNormal = TransformObjectToWorldNormal(v.normal);

OUTPUT_LIGHTMAP_UV(v.lightmapUV, unity_LightmapST, o.lightmapUVOrVertexSH);
OUTPUT_SH(lwWNormal, o.lightmapUVOrVertexSH);
half3 vertexLight = VertexLighting(lwWorldPos, lwWNormal);
half3 vertexLight = VertexLighting(lwWorldPos, lwWNormal);
half fogFactor = ComputeFogFactor(clipPos.z);
o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);

15
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/IntegrationTests/SerializationTests.cs


using NUnit.Framework;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph;
namespace UnityEditor.Graphing.IntegrationTests
{

[Test]
public void TestSerializableSlotCanSerialize()
{
var toSerialize = new List<SerializableSlot>()
var toSerialize = new List<MaterialSlot>()
new SerializableSlot(0, "InSlot", SlotType.Input, 0),
new SerializableSlot(1, "OutSlot", SlotType.Output, 5),
new TestSlot(0, "InSlot", SlotType.Input, 0),
new TestSlot(1, "OutSlot", SlotType.Output, 5),
var serialized = SerializationHelper.Serialize<SerializableSlot>(toSerialize);
var loaded = SerializationHelper.Deserialize<SerializableSlot>(serialized, null);
var serialized = SerializationHelper.Serialize<MaterialSlot>(toSerialize);
var loaded = SerializationHelper.Deserialize<MaterialSlot>(serialized, null);
Assert.IsInstanceOf<SerializableSlot>(loaded[0]);
Assert.IsInstanceOf<SerializableSlot>(loaded[1]);
Assert.IsInstanceOf<MaterialSlot>(loaded[0]);
Assert.IsInstanceOf<MaterialSlot>(loaded[1]);
Assert.AreEqual(0, loaded[0].id);
Assert.AreEqual("InSlot", loaded[0].displayName);

4
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/AbstractMaterialGraphTests.cs


}
[Test]
public void TestCanNotAddSerializableNodeToMaterialGraph()
public void TestCanNotAddTestNodeToMaterialGraph()
var node = new SerializableNode();
var node = new TestNode();
graph.AddNode(node);
Assert.AreEqual(0, graph.edges.Count());
Assert.AreEqual(0, graph.GetNodes<AbstractMaterialNode>().Count());

20
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/MaterialNodeTests.cs


[Test]
public void AddingNonMaterialSlotToNodeThrows()
{
Assert.Throws<ArgumentException>(() => m_NodeA.AddSlot(new SerializableSlot(0, string.Empty, SlotType.Input)));
Assert.Throws<ArgumentException>(() => m_NodeA.AddSlot(new TestSlot(0, string.Empty, SlotType.Input)));
}
[Test]

[Test]
public void CanConvertConcreteSlotValueTypeToOutputChunkProperly()
{
Assert.AreEqual(string.Empty, AbstractMaterialNode.GetSlotDimension(ConcreteSlotValueType.Vector1));
Assert.AreEqual("2", AbstractMaterialNode.GetSlotDimension(ConcreteSlotValueType.Vector2));
Assert.AreEqual("3", AbstractMaterialNode.GetSlotDimension(ConcreteSlotValueType.Vector3));
Assert.AreEqual("4", AbstractMaterialNode.GetSlotDimension(ConcreteSlotValueType.Vector4));
Assert.AreEqual("Texture2D", AbstractMaterialNode.GetSlotDimension(ConcreteSlotValueType.Texture2D));
Assert.AreEqual("2x2", AbstractMaterialNode.GetSlotDimension(ConcreteSlotValueType.Matrix2));
Assert.AreEqual("3x3", AbstractMaterialNode.GetSlotDimension(ConcreteSlotValueType.Matrix3));
Assert.AreEqual("4x4", AbstractMaterialNode.GetSlotDimension(ConcreteSlotValueType.Matrix4));
Assert.AreEqual("SamplerState", AbstractMaterialNode.GetSlotDimension(ConcreteSlotValueType.SamplerState));
Assert.AreEqual(string.Empty, NodeUtils.GetSlotDimension(ConcreteSlotValueType.Vector1));
Assert.AreEqual("2", NodeUtils.GetSlotDimension(ConcreteSlotValueType.Vector2));
Assert.AreEqual("3", NodeUtils.GetSlotDimension(ConcreteSlotValueType.Vector3));
Assert.AreEqual("4", NodeUtils.GetSlotDimension(ConcreteSlotValueType.Vector4));
Assert.AreEqual("Texture2D", NodeUtils.GetSlotDimension(ConcreteSlotValueType.Texture2D));
Assert.AreEqual("2x2", NodeUtils.GetSlotDimension(ConcreteSlotValueType.Matrix2));
Assert.AreEqual("3x3", NodeUtils.GetSlotDimension(ConcreteSlotValueType.Matrix3));
Assert.AreEqual("4x4", NodeUtils.GetSlotDimension(ConcreteSlotValueType.Matrix4));
Assert.AreEqual("SamplerState", NodeUtils.GetSlotDimension(ConcreteSlotValueType.SamplerState));
}
[Test]

175
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/SerializedGraphTests.cs


using NUnit.Framework;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph;
public class SerializableGraphTests
public class BaseMaterialGraphTests
{
[OneTimeSetUp]
public void RunBeforeAnyTests()

[Test]
public void TestCanCreateSerializableGraph()
public void TestCanCreateBaseMaterialGraph()
var graph = new SerializableGraph();
var graph = new TestMaterialGraph();
Assert.AreEqual(0, graph.edges.Count());
Assert.AreEqual(0, graph.GetNodes<INode>().Count());

public void TestCanAddNodeToSerializableGraph()
public void TestCanAddNodeToBaseMaterialGraph()
var graph = new SerializableGraph();
var node = new SerializableNode();
var graph = new TestMaterialGraph();
var node = new TestNode();
node.name = "Test Node";
graph.AddNode(node);

}
[Test]
public void TestCanRemoveNodeFromSerializableGraph()
public void TestCanRemoveNodeFromBaseMaterialGraph()
var graph = new SerializableGraph();
var node = new SerializableNode();
var graph = new TestMaterialGraph();
var node = new TestNode();
node.name = "Test Node";
graph.AddNode(node);
Assert.AreEqual(1, graph.GetNodes<INode>().Count());

[Test]
public void TestCanModifyNodeDrawState()
{
var node = new SerializableNode();
var node = new TestNode();
node.name = "Test Node";
var drawState = node.drawState;

Assert.IsFalse(node.drawState.expanded);
}
private class SetErrorNode : SerializableNode
private class SetErrorNode : TestNode
{
public void SetError()
{

[Test]
public void TestNodeGUIDCanBeRewritten()
{
var node = new SerializableNode();
var node = new TestNode();
public class TestableNode : SerializableNode
public class TestableNode : TestNode
{
public const int Input0 = 0;
public const int Input1 = 1;

public TestableNode()
{
AddSlot(new SerializableSlot(Input0, "Input", SlotType.Input));
AddSlot(new SerializableSlot(Input1, "Input", SlotType.Input));
AddSlot(new SerializableSlot(Input2, "Input", SlotType.Input));
AddSlot(new TestSlot(Input0, "Input", SlotType.Input));
AddSlot(new TestSlot(Input1, "Input", SlotType.Input));
AddSlot(new TestSlot(Input2, "Input", SlotType.Input));
AddSlot(new SerializableSlot(Output0, "Output", SlotType.Output));
AddSlot(new SerializableSlot(Output1, "Output", SlotType.Output));
AddSlot(new SerializableSlot(Output2, "Output", SlotType.Output));
AddSlot(new TestSlot(Output0, "Output", SlotType.Output));
AddSlot(new TestSlot(Output1, "Output", SlotType.Output));
AddSlot(new TestSlot(Output2, "Output", SlotType.Output));
public void TestRemoveNodeFromSerializableGraphCleansEdges()
public void TestRemoveNodeFromBaseMaterialGraphCleansEdges()
var graph = new SerializableGraph();
var graph = new TestMaterialGraph();
var outputNode = new TestableNode();
graph.AddNode(outputNode);

Assert.AreEqual(inputNode, graph.GetNodes<INode>().FirstOrDefault());
}
private class NoDeleteNode : SerializableNode
private class NoDeleteNode : TestNode
public void TestCanNotRemoveNoDeleteNodeFromSerializableGraph()
public void TestCanNotRemoveNoDeleteNodeFromBaseMaterialGraph()
var graph = new SerializableGraph();
var graph = new TestMaterialGraph();
var node = new NoDeleteNode();
node.name = "Test Node";
graph.AddNode(node);

Assert.AreEqual(1, graph.GetNodes<INode>().Count());
}
private class OnEnableNode : SerializableNode, IOnAssetEnabled
private class OnEnableNode : TestNode, IOnAssetEnabled
{
public bool called = false;
public void OnEnable()

[Test]
public void TestSerializedGraphDelegatesOnEnableCalls()
{
var graph = new SerializableGraph();
var graph = new TestMaterialGraph();
var node = new OnEnableNode();
node.name = "Test Node";
graph.AddNode(node);

}
[Test]
public void TestCanFindNodeInSerializableGraph()
public void TestCanFindNodeInBaseMaterialGraph()
var graph = new SerializableGraph();
var node = new SerializableNode();
var graph = new TestMaterialGraph();
var node = new TestNode();
graph.AddNode(node);
Assert.AreEqual(1, graph.GetNodes<INode>().Count());

[Test]
public void TestCanAddSlotToSerializableNode()
public void TestCanAddSlotToTestNode()
var graph = new SerializableGraph();
var node = new SerializableNode();
node.AddSlot(new SerializableSlot(0, "output", SlotType.Output));
node.AddSlot(new SerializableSlot(1, "input", SlotType.Input));
var graph = new TestMaterialGraph();
var node = new TestNode();
node.AddSlot(new TestSlot(0, "output", SlotType.Output));
node.AddSlot(new TestSlot(1, "input", SlotType.Input));
node.name = "Test Node";
graph.AddNode(node);

}
[Test]
public void TestCanNotAddNullSlotToSerializableNode()
public void TestCanNotAddNullSlotToTestNode()
var node = new SerializableNode();
var node = new TestNode();
node.AddSlot(null);
node.name = "Test Node";
Assert.AreEqual(0, node.GetOutputSlots<ISlot>().Count());

public void TestCanRemoveSlotFromSerializableNode()
public void TestCanRemoveSlotFromTestNode()
var graph = new SerializableGraph();
var node = new SerializableNode();
node.AddSlot(new SerializableSlot(0, "output", SlotType.Output));
node.AddSlot(new SerializableSlot(1, "input", SlotType.Input));
var graph = new TestMaterialGraph();
var node = new TestNode();
node.AddSlot(new TestSlot(0, "output", SlotType.Output));
node.AddSlot(new TestSlot(1, "input", SlotType.Input));
graph.AddNode(node);
Assert.AreEqual(2, node.GetSlots<ISlot>().Count());

}
[Test]
public void TestCanRemoveSlotsWithNonMathingNameFromSerializableNode()
public void TestCanRemoveSlotsWithNonMathingNameFromTestNode()
var graph = new SerializableGraph();
var graph = new TestMaterialGraph();
var node = new TestableNode();
graph.AddNode(node);

}
[Test]
public void TestCanNotAddDuplicateSlotToSerializableNode()
public void TestCanNotAddDuplicateSlotToTestNode()
var graph = new SerializableGraph();
var node = new SerializableNode();
node.AddSlot(new SerializableSlot(0, "output", SlotType.Output));
node.AddSlot(new SerializableSlot(0, "output", SlotType.Output));
var graph = new TestMaterialGraph();
var node = new TestNode();
node.AddSlot(new TestSlot(0, "output", SlotType.Output));
node.AddSlot(new TestSlot(0, "output", SlotType.Output));
node.name = "Test Node";
graph.AddNode(node);

}
[Test]
public void TestCanUpdateDisplaynameByReaddingSlotToSerializableNode()
public void TestCanUpdateDisplaynameByReaddingSlotToTestNode()
var graph = new SerializableGraph();
var node = new SerializableNode();
node.AddSlot(new SerializableSlot(0, "output", SlotType.Output));
node.AddSlot(new SerializableSlot(0, "output_updated", SlotType.Output));
var graph = new TestMaterialGraph();
var node = new TestNode();
node.AddSlot(new TestSlot(0, "output", SlotType.Output));
node.AddSlot(new TestSlot(0, "output_updated", SlotType.Output));
node.name = "Test Node";
graph.AddNode(node);

[Test]
public void TestCanUpdateSlotPriority()
{
var graph = new SerializableGraph();
var node = new SerializableNode();
node.AddSlot(new SerializableSlot(0, "output", SlotType.Output, 0));
var graph = new TestMaterialGraph();
var node = new TestNode();
node.AddSlot(new TestSlot(0, "output", SlotType.Output, 0));
node.name = "Test Node";
graph.AddNode(node);

}
[Test]
public void TestCanUpdateSlotPriorityByReaddingSlotToSerializableNode()
public void TestCanUpdateSlotPriorityByReaddingSlotToTestNode()
var graph = new SerializableGraph();
var node = new SerializableNode();
node.AddSlot(new SerializableSlot(0, "output", SlotType.Output, 0));
node.AddSlot(new SerializableSlot(0, "output", SlotType.Output, 5));
var graph = new TestMaterialGraph();
var node = new TestNode();
node.AddSlot(new TestSlot(0, "output", SlotType.Output, 0));
node.AddSlot(new TestSlot(0, "output", SlotType.Output, 5));
node.name = "Test Node";
graph.AddNode(node);

[Test]
public void TestCanUpdateSlotDisplayName()
{
var node = new SerializableNode();
node.AddSlot(new SerializableSlot(0, "output", SlotType.Output));
var node = new TestNode();
node.AddSlot(new TestSlot(0, "output", SlotType.Output));
node.name = "Test Node";
Assert.AreEqual(0, node.GetInputSlots<ISlot>().Count());

}
[Test]
public void TestCanFindSlotOnSerializableNode()
public void TestCanFindSlotOnTestNode()
{
var node = new TestableNode();

}
[Test]
public void TestCanFindSlotReferenceOnSerializableNode()
public void TestCanFindSlotReferenceOnTestNode()
{
var node = new TestableNode();

}
[Test]
public void TestCanConnectAndTraverseTwoNodesOnSerializableGraph()
public void TestCanConnectAndTraverseTwoNodesOnBaseMaterialGraph()
var graph = new SerializableGraph();
var graph = new TestMaterialGraph();
var outputNode = new TestableNode();
graph.AddNode(outputNode);

}
[Test]
public void TestCanConnectAndTraverseThreeNodesOnSerializableGraph()
public void TestCanConnectAndTraverseThreeNodesOnBaseMaterialGraph()
var graph = new SerializableGraph();
var graph = new TestMaterialGraph();
var outputNode = new TestableNode();
graph.AddNode(outputNode);

[Test]
public void TestConectionToSameInputReplacesOldInput()
{
var graph = new SerializableGraph();
var graph = new TestMaterialGraph();
var outputNode = new TestableNode();
graph.AddNode(outputNode);

[Test]
public void TestRemovingSlotRemovesConnectedEdges()
{
var graph = new SerializableGraph();
var graph = new TestMaterialGraph();
var outputNode = new TestableNode();
graph.AddNode(outputNode);

[Test]
public void TestCanNotConnectToNullSlot()
{
var graph = new SerializableGraph();
var graph = new TestMaterialGraph();
var inputNode = new SerializableNode();
var inputNode = new TestNode();
graph.AddNode(inputNode);
Assert.AreEqual(2, graph.GetNodes<INode>().Count());

}
[Test]
public void TestCanNotConnectTwoOuputSlotsOnSerializableGraph()
public void TestCanNotConnectTwoOuputSlotsOnBaseMaterialGraph()
var graph = new SerializableGraph();
var graph = new TestMaterialGraph();
var outputNode = new TestableNode();
graph.AddNode(outputNode);

}
[Test]
public void TestCanNotConnectTwoInputSlotsOnSerializableGraph()
public void TestCanNotConnectTwoInputSlotsOnBaseMaterialGraph()
var graph = new SerializableGraph();
var graph = new TestMaterialGraph();
var inputNode = new TestableNode();
graph.AddNode(inputNode);

}
[Test]
public void TestRemovingNodeRemovesConectedEdgesOnSerializableGraph()
public void TestRemovingNodeRemovesConectedEdgesOnBaseMaterialGraph()
var graph = new SerializableGraph();
var graph = new TestMaterialGraph();
var outputNode = new TestableNode();
graph.AddNode(outputNode);

}
[Test]
public void TestRemovingEdgeOnSerializableGraph()
public void TestRemovingEdgeOnBaseMaterialGraph()
var graph = new SerializableGraph();
var graph = new TestMaterialGraph();
var outputNode = new TestableNode();
graph.AddNode(outputNode);

}
[Test]
public void TestRemovingElementsFromSerializableGraph()
public void TestRemovingElementsFromBaseMaterialGraph()
var graph = new SerializableGraph();
var graph = new TestMaterialGraph();
var outputNode = new TestableNode();
graph.AddNode(outputNode);

}
[Test]
public void TestCanGetEdgesOnSerializableGraphFromSlotReference()
public void TestCanGetEdgesOnBaseMaterialGraphFromSlotReference()
var graph = new SerializableGraph();
var graph = new TestMaterialGraph();
var outputNode = new TestableNode();
graph.AddNode(outputNode);

[Test]
public void TestGetInputsWithNoConnection()
{
var graph = new SerializableGraph();
var graph = new TestMaterialGraph();
var outputNode = new TestableNode();
graph.AddNode(outputNode);

[Test]
public void TestCyclicConnectionsAreNotAllowedOnGraph()
{
var graph = new SerializableGraph();
var graph = new TestMaterialGraph();
var nodeA = new TestableNode();

2
MaterialGraphProject/Assets/UnityShaderEditor/package.json


{
"name": "com.unity.shadergraph",
"description": "Shader Graph",
"version": "0.1.7",
"version": "0.1.10",
"unity": "2018.1",
"dependencies": {
}

26
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Procedural/Shape/EllipseNode.cs


using System.Reflection;
using UnityEngine;
/*namespace UnityEditor.ShaderGraph
namespace UnityEditor.ShaderGraph
[Title("Procedural", "MakeSubgraph", "Repeating Dot")]
public class RepeatingDotNode : CodeFunctionNode
[Title("Procedural", "Shape", "Ellipse")]
public class EllipseNode : CodeFunctionNode
public RepeatingDotNode()
public EllipseNode()
name = "Repeating Dot";
name = "Ellipse";
return GetType().GetMethod("Unity_Repreatingdot", BindingFlags.Static | BindingFlags.NonPublic);
return GetType().GetMethod("Unity_Ellipse", BindingFlags.Static | BindingFlags.NonPublic);
static string Unity_Repreatingdot(
static string Unity_Ellipse(
[Slot(1, Binding.None, 4.0f, 4.0f, 4.0f, 4.0f)] Vector1 Count,
[Slot(2, Binding.None, 0.5f, 0.5f, 0.5f, 0.5f)] Vector1 Radius,
[Slot(2, Binding.None, 0.5f, 0, 0, 0)] Vector1 Width,
[Slot(3, Binding.None, 0.5f, 0, 0, 0)] Vector1 Height,
UV *= 2.0 - 1.0;
UV = fmod(UV * Count, 1.0) * 2.0 - 1.0;
Out = step(length(UV),Radius);
UV = (UV * 2.0 - 1.0);
UV = UV / {precision}2(Width, Height);
Out = step(length(UV), 1);
}*/
}

22
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Procedural/Shape/RectangleNode.cs


using System.Reflection;
using UnityEngine;
/*namespace UnityEditor.ShaderGraph
namespace UnityEditor.ShaderGraph
[Title("Procedural", "MakeSubgraph", "Square")]
public class BoxNode : CodeFunctionNode
[Title("Procedural", "Shape", "Rectangle")]
public class RectangleNode : CodeFunctionNode
public BoxNode()
public RectangleNode()
name = "Square";
name = "Rectangle";
return GetType().GetMethod("Unity_Boxnode", BindingFlags.Static | BindingFlags.NonPublic);
return GetType().GetMethod("Unity_Rectangle", BindingFlags.Static | BindingFlags.NonPublic);
static string Unity_Boxnode(
static string Unity_Rectangle(
[Slot(1, Binding.None, 0.2f, 0.8f, 0, 0)] Vector2 XMinAndMax,
[Slot(2, Binding.None, 0.2f, 0.8f, 0, 0)] Vector2 YMinAndMax,
[Slot(1, Binding.None, 0.5f, 0, 0, 0)] Vector1 Width,
[Slot(2, Binding.None, 0.5f, 0, 0, 0)] Vector1 Height,
{precision}2 XMinAndMax = {precision}2(0.5 - Width / 2, 0.5 + Width / 2);
{precision}2 YMinAndMax = {precision}2(0.5 - Height / 2, 0.5 + Height / 2);
{precision} x = step( XMinAndMax.x, UV.x ) - step( XMinAndMax.y, UV.x );
{precision} y = step( YMinAndMax.x, UV.y ) - step( YMinAndMax.y, UV.y );
Out = x * y;

}*/
}

4
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Implementation/GraphObject.cs


namespace UnityEditor.Graphing
{
public class SerializableGraphObject : ScriptableObject, IGraphObject, ISerializationCallbackReceiver
public class GraphObject : ScriptableObject, IGraphObject, ISerializationCallbackReceiver
{
[SerializeField]
SerializationHelper.JSONSerializedElement m_SerializedGraph;

if (graph == null)
graph = deserializedGraph;
else
m_DeserializedGraph = deserializedGraph; // graph.ReplaceWith(m_DeserializedGraph);
m_DeserializedGraph = deserializedGraph;
}
void Validate()

59
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Implementation/NodeUtils.cs


}
return shaderStage;
}
public static string GetSlotDimension(ConcreteSlotValueType slotValue)
{
switch (slotValue)
{
case ConcreteSlotValueType.Vector1:
return String.Empty;
case ConcreteSlotValueType.Vector2:
return "2";
case ConcreteSlotValueType.Vector3:
return "3";
case ConcreteSlotValueType.Vector4:
return "4";
case ConcreteSlotValueType.Matrix2:
return "2x2";
case ConcreteSlotValueType.Matrix3:
return "3x3";
case ConcreteSlotValueType.Matrix4:
return "4x4";
default:
return "Error";
}
}
public static string ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision p, ConcreteSlotValueType slotValue)
{
switch (slotValue)
{
case ConcreteSlotValueType.Vector1:
return p.ToString();
case ConcreteSlotValueType.Vector2:
return p + "2";
case ConcreteSlotValueType.Vector3:
return p + "3";
case ConcreteSlotValueType.Vector4:
return p + "4";
case ConcreteSlotValueType.Texture2D:
return "Texture2D";
case ConcreteSlotValueType.Cubemap:
return "Cubemap";
case ConcreteSlotValueType.Matrix2:
return "Matrix2x2";
case ConcreteSlotValueType.Matrix3:
return "Matrix3x3";
case ConcreteSlotValueType.Matrix4:
return "Matrix4x4";
case ConcreteSlotValueType.SamplerState:
return "SamplerState";
default:
return "Error";
}
}
public static string GetHLSLSafeName(string input)
{
char[] arr = input.ToCharArray();
arr = Array.FindAll<char>(arr, (c => (Char.IsLetterOrDigit(c))));
return new string(arr);
}
}
}

35
MaterialGraphProject/Assets/NewNodes/Editor/Sampler2DShaderProperty.cs


using System;
using System.Text;
using UnityEngine;
/*namespace UnityEditor.ShaderGraph
{
[Serializable]
public class Sampler2DShaderProperty : AbstractShaderProperty<object>
{
public override PropertyType propertyType
{
get { return PropertyType.SamplerState; }
}
public override Vector4 defaultValue
{
get { return new Vector4(); }
}
public override string GetPropertyBlockString()
{
return string.Empty;
}
public override string GetPropertyDeclarationString()
{
return "sampler2D " + referenceName + ";";
}
public override PreviewProperty GetPreviewMaterialProperty()
{
return default(PreviewProperty);
}
}
}*/

3
MaterialGraphProject/Assets/NewNodes/Editor/Sampler2DShaderProperty.cs.meta


fileFormatVersion: 2
guid: 165606e7f31c5df4ebb94765e37694c2
timeCreated: 1505346922

112
MaterialGraphProject/Assets/NewNodes/Editor/SceneDepthNode.cs


using UnityEditor.Graphing;
using UnityEngine;
using UnityEditor.ShaderGraph.Drawing.Controls;
using System.Collections.Generic;
/*namespace UnityEditor.ShaderGraph
{
public enum SceneDepthMode
{
Default,
Normalized
};
[Title("Input", "Scene", "Scene Depth")]
public sealed class SceneDepthNode : AbstractMaterialNode, IGenerateProperties, IGeneratesBodyCode, IMayRequireScreenPosition
{
const string kUVSlotName = "UV";
const string kOutputSlotName = "Out";
public const int UVSlotId = 0;
public const int OutputSlotId = 1;
public SceneDepthNode()
{
name = "Scene Depth";
UpdateNodeAfterDeserialization();
}
public override bool hasPreview
{
get { return true; }
}
[SerializeField]
private SceneDepthMode m_SceneDepthMode = SceneDepthMode.Default;
[EnumControl("Mode")]
public SceneDepthMode sceneDepthMode
{
get { return m_SceneDepthMode; }
set
{
if (m_SceneDepthMode == value)
return;
m_SceneDepthMode = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
}
}
public override void UpdateNodeAfterDeserialization()
{
AddSlot(new ScreenPositionMaterialSlot(UVSlotId, kUVSlotName, kUVSlotName));
AddSlot(new Vector1MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, 0));
RemoveSlotsNameNotMatching(new[] { UVSlotId, OutputSlotId });
}
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
properties.Add(new PreviewProperty()
{
name = "_CameraDepthTexture",
propType = PropertyType.Float,
vector4Value = new Vector4(1, 1, 1, 1),
floatValue = 1,
colorValue = new Vector4(1, 1, 1, 1),
});
}
public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
{
properties.AddShaderProperty(new Sampler2DShaderProperty
{
overrideReferenceName = "_CameraDepthTexture",
generatePropertyBlock = false
});
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
string uvValue = GetSlotValue(UVSlotId, generationMode);
string outputValue = GetSlotValue(OutputSlotId, generationMode);
string methodName = "";
switch (sceneDepthMode)
{
case SceneDepthMode.Normalized:
methodName = "Linear01Depth";
break;
default:
methodName = "LinearEyeDepth";
break;
}
visitor.AddShaderChunk(string.Format("{0} _DepthTexture = {1}(tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD({2})).r);", precision, methodName, uvValue), true);
visitor.AddShaderChunk(string.Format("{0} {1} = _DepthTexture;", ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId)), true);
}
public bool RequiresScreenPosition()
{
var uvSlot = FindInputSlot<MaterialSlot>(UVSlotId) as ScreenPositionMaterialSlot;
if (uvSlot == null)
return false;
if (uvSlot.isConnected)
return false;
return uvSlot.RequiresScreenPosition();
}
}
}*/

8
MaterialGraphProject/Assets/NewNodes/Editor/SceneDepthNode.cs.meta


fileFormatVersion: 2
guid: 93d2a1d512bd9114a8d1a21ade3d6ea6
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

114
MaterialGraphProject/Assets/NewNodes/Editor/SceneNormalsNode.cs


using UnityEditor.Graphing;
using UnityEngine;
using UnityEditor.ShaderGraph.Drawing.Controls;
using System.Collections.Generic;
/*namespace UnityEditor.ShaderGraph
{
[Title("Input", "Scene", "Scene Normals")]
public class SceneNormalsNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction, IGenerateProperties, IMayRequireScreenPosition
{
const string kUVSlotName = "UV";
const string kOutputSlotName = "Out";
public const int UVSlotId = 0;
public const int OutputSlotId = 1;
public SceneNormalsNode()
{
name = "Scene Normals";
UpdateNodeAfterDeserialization();
}
public override bool hasPreview
{
get { return true; }
}
string GetFunctionName()
{
return "Unity_DecodeViewNormalStereo";
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new ScreenPositionMaterialSlot(UVSlotId, kUVSlotName, kUVSlotName));
AddSlot(new Vector3MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector3.zero));
RemoveSlotsNameNotMatching(new[] { UVSlotId, OutputSlotId });
}
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
properties.Add(new PreviewProperty()
{
name = "_CameraDepthNormalsTexture",
propType = PropertyType.Float,
vector4Value = new Vector4(1, 1, 1, 1),
floatValue = 1,
colorValue = new Vector4(1, 1, 1, 1),
});
}
public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
{
properties.AddShaderProperty(new Sampler2DShaderProperty
{
overrideReferenceName = "_CameraDepthNormalsTexture",
generatePropertyBlock = false
});
}
string GetFunctionPrototype(string argIn, string argOut)
{
return string.Format("void {0} ({1}4 {2}, out {3} {4})", GetFunctionName(),
precision, argIn,
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), argOut);
}
string GetFunctionCallBody(string inputValue, string outputValue)
{
return GetFunctionName() + " (" + inputValue + ", " + outputValue + ");";
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputString = new ShaderGenerator();
outputString.AddShaderChunk(GetFunctionPrototype("Tex", "Out"), false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk(string.Format("{0}3 nn = Tex.xyz * {0}3(2.0 * 1.7777, 2.0 * 1.7777, 0) + {0}3(-1.7777, -1.7777, 1);", precision), true);
outputString.AddShaderChunk(string.Format("{0} g = 2.0 / dot(nn.xyz, nn.xyz);", precision), true);
outputString.AddShaderChunk(string.Format("{0}3 n;", precision), true);
outputString.AddShaderChunk("n.xy = g * nn.xy;", true);
outputString.AddShaderChunk("n.z = g - 1.0;", true);
outputString.AddShaderChunk(string.Format("Out = n;", precision), true);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
string uvValue = GetSlotValue(UVSlotId, generationMode);
string outputValue = GetSlotValue(OutputSlotId, generationMode);
visitor.AddShaderChunk(string.Format("{0}4 _DepthNormalsTexture = tex2D(_CameraDepthNormalsTexture, {1});", precision, uvValue), true);
visitor.AddShaderChunk(string.Format("{0} {1};", ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId)), true);
visitor.AddShaderChunk(GetFunctionCallBody("_DepthNormalsTexture", outputValue), true);
visitor.AddShaderChunk(string.Format("{1} = {1} * {0}3(1.0, 1.0, -1.0);", precision, GetVariableNameForSlot(OutputSlotId)), true);
}
public bool RequiresScreenPosition()
{
var uvSlot = FindInputSlot<MaterialSlot>(UVSlotId) as ScreenPositionMaterialSlot;
if (uvSlot == null)
return false;
if (uvSlot.isConnected)
return false;
return uvSlot.RequiresScreenPosition();
}
}
}*/

8
MaterialGraphProject/Assets/NewNodes/Editor/SceneNormalsNode.cs.meta


fileFormatVersion: 2
guid: e54cf83dd14c5ea4cbecc38ad40a3a4b
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

109
MaterialGraphProject/Assets/NewNodes/Editor/SceneVelocityNode.cs


using UnityEditor.Graphing;
using UnityEngine;
using UnityEditor.ShaderGraph.Drawing.Controls;
using System.Collections.Generic;
/*namespace UnityEditor.ShaderGraph
{
public enum SceneVelocityMode
{
Default,
Hue
};
[Title("Input", "Scene", "Scene Velocity")]
public class SceneVelocityNode : AbstractMaterialNode, IGenerateProperties, IGeneratesBodyCode, IMayRequireScreenPosition
{
const string kUVSlotName = "UV";
const string kOutputSlotName = "Out";
public const int UVSlotId = 0;
public const int OutputSlotId = 1;
public SceneVelocityNode()
{
name = "Scene Velocity";
UpdateNodeAfterDeserialization();
}
public override bool hasPreview
{
get { return true; }
}
[SerializeField]
private SceneVelocityMode m_SceneVelocityMode = SceneVelocityMode.Default;
[EnumControl("Mode")]
public SceneVelocityMode sceneVelocityMode
{
get { return m_SceneVelocityMode; }
set
{
if (m_SceneVelocityMode == value)
return;
m_SceneVelocityMode = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
}
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new ScreenPositionMaterialSlot(UVSlotId, kUVSlotName, kUVSlotName));
AddSlot(new Vector3MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector3.zero));
RemoveSlotsNameNotMatching(new[] { UVSlotId, OutputSlotId });
}
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
properties.Add(new PreviewProperty()
{
name = "_CameraMotionVectorTexture",
propType = PropertyType.Float,
vector4Value = new Vector4(1, 1, 1, 1),
floatValue = 1,
colorValue = new Vector4(1, 1, 1, 1),
});
}
public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
{
properties.AddShaderProperty(new Sampler2DShaderProperty
{
overrideReferenceName = "_CameraMotionVectorTexture",
generatePropertyBlock = false
});
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
string uvValue = GetSlotValue(UVSlotId, generationMode);
string outputValue = GetSlotValue(OutputSlotId, generationMode);
visitor.AddShaderChunk(string.Format("{0}3 _MotionVectorTexture = {0}3(tex2D(_CameraMotionVectorTexture, {1}).rg, 0);", precision, uvValue), true);
if (sceneVelocityMode == SceneVelocityMode.Hue)
{
visitor.AddShaderChunk(string.Format("{0} hue = (atan2(_MotionVectorTexture.x, _MotionVectorTexture.y) / 3.14159265359 + 1.0) * 0.5;", precision), true);
visitor.AddShaderChunk(string.Format("_MotionVectorTexture = saturate({0}3(abs(hue * 6.0 - 3.0) - 1.0, 2.0 - abs(hue * 6.0 - 2.0), 2.0 - abs(hue * 6.0 - 4.0)));", precision), true);
}
visitor.AddShaderChunk(string.Format("{0} {1} = _MotionVectorTexture;", ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId)), true);
}
public bool RequiresScreenPosition()
{
var uvSlot = FindInputSlot<MaterialSlot>(UVSlotId) as ScreenPositionMaterialSlot;
if (uvSlot == null)
return false;
if (uvSlot.isConnected)
return false;
return uvSlot.RequiresScreenPosition();
}
}
}*/

8
MaterialGraphProject/Assets/NewNodes/Editor/SceneVelocityNode.cs.meta


fileFormatVersion: 2
guid: 8e751ddf46d42b349a993a7438152f82
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

8
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/IMaterialSlotHasValue.cs


namespace UnityEditor.ShaderGraph
{
public interface IMaterialSlotHasValue<T>
{
T defaultValue { get; }
T value { get; }
}
}

56
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/MaterialGraphAsset.cs


using System;
using UnityEngine;
using System.Reflection;
namespace UnityEditor.ShaderGraph
{
static class MaterialGraphAsset
{
public static bool ShaderHasError(Shader shader)
{
var hasErrorsCall = typeof(ShaderUtil).GetMethod("GetShaderErrorCount", BindingFlags.Static | BindingFlags.NonPublic);
var result = hasErrorsCall.Invoke(null, new object[] { shader });
return (int)result != 0;
}
public struct ShaderError
{
public string message;
public string messageDetails;
public string platform;
public string file;
public int line;
public int warning;
}
static MethodInfo s_GetErrorsCall = typeof(ShaderUtil).GetMethod("GetShaderErrors", BindingFlags.Static | BindingFlags.NonPublic);
static Type s_ShaderErrorType = typeof(ShaderUtil).Assembly.GetType("UnityEditor.ShaderError");
static FieldInfo s_ShaderErrorMessageField = s_ShaderErrorType.GetField("message", BindingFlags.Instance | BindingFlags.Public);
static FieldInfo s_ShaderErrorMessageDetailsField = s_ShaderErrorType.GetField("messageDetails", BindingFlags.Instance | BindingFlags.Public);
static FieldInfo s_ShaderErrorPlatformField = s_ShaderErrorType.GetField("platform", BindingFlags.Instance | BindingFlags.Public);
static FieldInfo s_ShaderErrorFileField = s_ShaderErrorType.GetField("file", BindingFlags.Instance | BindingFlags.Public);
static FieldInfo s_ShaderErrorLineField = s_ShaderErrorType.GetField("line", BindingFlags.Instance | BindingFlags.Public);
static FieldInfo s_ShaderErrorWarningField = s_ShaderErrorType.GetField("warning", BindingFlags.Instance | BindingFlags.Public);
public static ShaderError[] GetShaderErrors(Shader shader)
{
var invoke = s_GetErrorsCall.Invoke(null, new object[] { shader });
var objects = (Array)invoke;
var errors = new ShaderError[objects.Length];
for (var i = 0; i < objects.Length; i++)
{
var obj = objects.GetValue(i);
errors[i] = new ShaderError
{
message = (string)s_ShaderErrorMessageField.GetValue(obj),
messageDetails = (string)s_ShaderErrorMessageDetailsField.GetValue(obj),
platform = (string)s_ShaderErrorPlatformField.GetValue(obj),
file = (string)s_ShaderErrorFileField.GetValue(obj),
line = (int)s_ShaderErrorLineField.GetValue(obj),
warning = (int)s_ShaderErrorWarningField.GetValue(obj),
};
}
return errors;
}
}
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Interfaces/Graph.meta


fileFormatVersion: 2
guid: 20d63795c62940409089af61496db945
timeCreated: 1513348939

15
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/FormerNameAttribute.cs


using System;
namespace UnityEditor.ShaderGraph
{
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class FormerNameAttribute : Attribute
{
public string fullName { get; private set; }
public FormerNameAttribute(string fullName)
{
this.fullName = fullName;
}
}
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/FormerNameAttribute.cs.meta


fileFormatVersion: 2
guid: ae5b0289aecc42c2b6f5b5b08b80bdd9
timeCreated: 1513592955

49
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/AmbientNode.cs


using UnityEditor.Graphing;
using UnityEngine;
namespace UnityEditor.ShaderGraph
{
[Title("Input", "Scene", "Ambient")]
public class AmbientNode : AbstractMaterialNode
{
const string kOutputSlotName = "Color";
const string kOutputSlot1Name = "Sky";
const string kOutputSlot2Name = "Equator";
const string kOutputSlot3Name = "Ground";
public const int OutputSlotId = 0;
public const int OutputSlot1Id = 1;
public const int OutputSlot2Id = 2;
public const int OutputSlot3Id = 3;
public AmbientNode()
{
name = "Ambient";
UpdateNodeAfterDeserialization();
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new Vector4MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector4.zero));
AddSlot(new Vector4MaterialSlot(OutputSlot1Id, kOutputSlot1Name, kOutputSlot1Name, SlotType.Output, Vector4.zero));
AddSlot(new Vector4MaterialSlot(OutputSlot2Id, kOutputSlot2Name, kOutputSlot2Name, SlotType.Output, Vector4.zero));
AddSlot(new Vector4MaterialSlot(OutputSlot3Id, kOutputSlot3Name, kOutputSlot3Name, SlotType.Output, Vector4.zero));
RemoveSlotsNameNotMatching(new[] { OutputSlotId, OutputSlot1Id, OutputSlot2Id, OutputSlot3Id });
}
public override string GetVariableNameForSlot(int slotId)
{
switch (slotId)
{
case OutputSlot1Id:
return "unity_AmbientSky";
case OutputSlot2Id:
return "unity_AmbientEquator";
case OutputSlot3Id:
return "unity_AmbientGround";
default:
return "UNITY_LIGHTMODEL_AMBIENT";
}
}
}
}

8
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/AmbientNode.cs.meta


fileFormatVersion: 2
guid: 0f9e9a126b4ecf24d81258763ac4a64d
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

93
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/FogNode.cs


using UnityEngine;
using UnityEditor.Graphing;
namespace UnityEditor.ShaderGraph
{
[Title("Input", "Scene", "Fog")]
public class FogNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction, IMayRequirePosition
{
public FogNode()
{
name = "Fog";
UpdateNodeAfterDeserialization();
}
const int OutputSlotId = 0;
const int OutputSlot1Id = 1;
const string k_OutputSlotName = "Color";
const string k_OutputSlot1Name = "Density";
public override bool hasPreview
{
get { return false; }
}
string GetFunctionName()
{
return string.Format("Unity_Fog_{0}", precision);
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new Vector4MaterialSlot(OutputSlotId, k_OutputSlotName, k_OutputSlotName, SlotType.Output, Vector4.zero));
AddSlot(new Vector1MaterialSlot(OutputSlot1Id, k_OutputSlot1Name, k_OutputSlot1Name, SlotType.Output, 0));
RemoveSlotsNameNotMatching(new[] { OutputSlotId, OutputSlot1Id });
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
var colorValue = GetSlotValue(OutputSlotId, generationMode);
var densityValue = GetSlotValue(OutputSlot1Id, generationMode);
visitor.AddShaderChunk(string.Format("{0} {1};", FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision), GetVariableNameForSlot(OutputSlotId)), false);
visitor.AddShaderChunk(string.Format("{0} {1};", FindOutputSlot<MaterialSlot>(OutputSlot1Id).concreteValueType.ToString(precision), GetVariableNameForSlot(OutputSlot1Id)), false);
visitor.AddShaderChunk(string.Format("{0}(IN.{1}, {2}, {3});", GetFunctionName(), CoordinateSpace.Object.ToVariableName(InterpolatorType.Position), colorValue, densityValue), false);
}
public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
{
registry.ProvideFunction(GetFunctionName(), s =>
{
s.AppendLine("void {0}({1}3 ObjectSpacePosition, out {2} Color, out {3} Density)",
GetFunctionName(),
precision,
FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision),
FindOutputSlot<MaterialSlot>(OutputSlot1Id).concreteValueType.ToString(precision));
using (s.BlockScope())
{
s.AppendLine("Color = unity_FogColor;");
s.AppendLine("{0} clipZ_01 = UNITY_Z_0_FAR_FROM_CLIPSPACE(UnityObjectToClipPos(ObjectSpacePosition).z);", precision);
s.AppendLine("#if defined(FOG_LINEAR)");
using (s.IndentScope())
{
s.AppendLine("{0} fogFactor = saturate(clipZ_01 * unity_FogParams.z + unity_FogParams.w);", precision);
s.AppendLine("Density = fogFactor;");
}
s.AppendLine("#elif defined(FOG_EXP)");
using (s.IndentScope())
{
s.AppendLine("{0} fogFactor = unity_FogParams.y * clipZ_01;", precision);
s.AppendLine("Density = saturate(exp2(-fogFactor));");
}
s.AppendLine("#elif defined(FOG_EXP2)");
using (s.IndentScope())
{
s.AppendLine("{0} fogFactor = unity_FogParams.x * clipZ_01;", precision);
s.AppendLine("Density = saturate(exp2(-fogFactor*fogFactor));");
}
s.AppendLine("#else");
using (s.IndentScope())
{
s.AppendLine("Density = 0.0h;");
}
s.AppendLine("#endif");
}
});
}
public NeededCoordinateSpace RequiresPosition()
{
return CoordinateSpace.Object.ToNeededCoordinateSpace();
}
}
}

8
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/FogNode.cs.meta


fileFormatVersion: 2
guid: f934acb3f675022448ac439d87d84a80
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

41
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/ObjectNode.cs


using UnityEditor.Graphing;
using UnityEngine;
namespace UnityEditor.ShaderGraph
{
[Title("Input", "Scene", "Object")]
public sealed class ObjectNode : AbstractMaterialNode
{
const string kOutputSlotName = "Position";
const string kOutputSlot1Name = "Scale";
public const int OutputSlotId = 0;
public const int OutputSlot1Id = 1;
public ObjectNode()
{
name = "Object";
UpdateNodeAfterDeserialization();
}
public override void UpdateNodeAfterDeserialization()
{
AddSlot(new Vector3MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector3.zero));
AddSlot(new Vector3MaterialSlot(OutputSlot1Id, kOutputSlot1Name, kOutputSlot1Name, SlotType.Output, Vector3.zero));
RemoveSlotsNameNotMatching(new[] { OutputSlotId, OutputSlot1Id });
}
public override string GetVariableNameForSlot(int slotId)
{
switch (slotId)
{
case OutputSlot1Id:
return @"float3(length(float3(unity_ObjectToWorld[0].x, unity_ObjectToWorld[1].x, unity_ObjectToWorld[2].x)),
length(float3(unity_ObjectToWorld[0].y, unity_ObjectToWorld[1].y, unity_ObjectToWorld[2].y)),
length(float3(unity_ObjectToWorld[0].z, unity_ObjectToWorld[1].z, unity_ObjectToWorld[2].z)))";
default:
return "unity_ObjectToWorld._m03_m13_m23";
}
}
}
}

8
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/ObjectNode.cs.meta


fileFormatVersion: 2
guid: 081b8aed5e33ba1418a6a80f7693b9b4
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

39
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/ScreenNode.cs


using UnityEditor.Graphing;
using UnityEngine;
namespace UnityEditor.ShaderGraph
{
[Title("Input", "Scene", "Screen")]
public sealed class ScreenNode : AbstractMaterialNode
{
const string kOutputSlotName = "Width";
const string kOutputSlot1Name = "Height";
public const int OutputSlotId = 0;
public const int OutputSlot1Id = 1;
public ScreenNode()
{
name = "Screen";
UpdateNodeAfterDeserialization();
}
public override void UpdateNodeAfterDeserialization()
{
AddSlot(new Vector1MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, 0));
AddSlot(new Vector1MaterialSlot(OutputSlot1Id, kOutputSlot1Name, kOutputSlot1Name, SlotType.Output, 0));
RemoveSlotsNameNotMatching(new[] { OutputSlotId, OutputSlot1Id });
}
public override string GetVariableNameForSlot(int slotId)
{
switch (slotId)
{
case OutputSlot1Id:
return "_ScreenParams.y";
default:
return "_ScreenParams.x";
}
}
}
}

部分文件因为文件数量过多而无法显示

正在加载...
取消
保存