GradientSampleNode.cs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. using System;
  2. using UnityEngine;
  3. using UnityEditor;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. namespace AmplifyShaderEditor
  7. {
  8. [Serializable]
  9. [NodeAttributes( "Gradient Sample", "Miscellaneous", "Samples a gradient" )]
  10. public sealed class GradientSampleNode : ParentNode
  11. {
  12. private string m_functionHeader = "SampleGradient( {0}, {1} )";
  13. private string m_functionBody = string.Empty;
  14. private GradientNode m_gradientNode = null;
  15. private InputPort m_gradPort;
  16. private Gradient m_blankGrandient = new Gradient();
  17. private int m_cachedTimeId = -1;
  18. private int m_cachedTypeId = -1;
  19. private int m_cachedColorNumId = -1;
  20. private int m_cachedAlphaNumId = -1;
  21. private Vector4 m_auxVec4 = Vector4.zero;
  22. private string m_functionHeaderStruct = "Gradient( {0} )";
  23. private string m_functionBodyStruct = string.Empty;
  24. protected override void CommonInit( int uniqueId )
  25. {
  26. base.CommonInit( uniqueId );
  27. AddInputPort( WirePortDataType.OBJECT, true, Constants.EmptyPortValue );
  28. AddInputPort( WirePortDataType.FLOAT, false, "Time" );
  29. AddOutputColorPorts( "RGBA", true );
  30. m_gradPort = m_inputPorts[ 0 ];
  31. m_useInternalPortData = true;
  32. m_autoDrawInternalPortData = true;
  33. m_drawPreviewExpander = false;
  34. m_drawPreview = true;
  35. m_showPreview = true;
  36. m_selectedLocation = PreviewLocation.TopCenter;
  37. m_previewShaderGUID = "8a09124cd6e4aa54a996e7487ec16b90";
  38. }
  39. public override void SetPreviewInputs()
  40. {
  41. base.SetPreviewInputs();
  42. if( m_cachedTypeId == -1 )
  43. m_cachedTypeId = Shader.PropertyToID( "_GType" );
  44. if( m_cachedTimeId == -1 )
  45. m_cachedTimeId = Shader.PropertyToID( "_GTime" );
  46. if( m_cachedColorNumId == -1 )
  47. m_cachedColorNumId = Shader.PropertyToID( "_GColorNum" );
  48. if( m_cachedAlphaNumId == -1 )
  49. m_cachedAlphaNumId = Shader.PropertyToID( "_GAlphaNum" );
  50. PreviewMaterial.SetTexture( m_cachedTimeId, m_inputPorts[ 1 ].InputPreviewTexture( ContainerGraph ) );
  51. Gradient curGrad = m_blankGrandient;
  52. if( m_gradientNode != null )
  53. curGrad = m_gradientNode.Gradient;
  54. PreviewMaterial.SetInt( m_cachedTypeId, (int)curGrad.mode );
  55. PreviewMaterial.SetInt( m_cachedColorNumId, curGrad.colorKeys.Length );
  56. PreviewMaterial.SetInt( m_cachedAlphaNumId, curGrad.alphaKeys.Length );
  57. for( int i = 0; i < 8; i++ )
  58. {
  59. if( i < curGrad.colorKeys.Length )
  60. {
  61. m_auxVec4.x = curGrad.colorKeys[ i ].color.r;
  62. m_auxVec4.y = curGrad.colorKeys[ i ].color.g;
  63. m_auxVec4.z = curGrad.colorKeys[ i ].color.b;
  64. m_auxVec4.w = curGrad.colorKeys[ i ].time;
  65. PreviewMaterial.SetVector( "_Col" + i, m_auxVec4 );
  66. }
  67. else
  68. {
  69. PreviewMaterial.SetVector( "_Col" + i, Vector4.zero );
  70. }
  71. }
  72. for( int i = 0; i < 8; i++ )
  73. {
  74. if( i < curGrad.alphaKeys.Length )
  75. {
  76. m_auxVec4.x = curGrad.alphaKeys[ i ].alpha;
  77. m_auxVec4.y = curGrad.alphaKeys[ i ].time;
  78. PreviewMaterial.SetVector( "_Alp" + i, m_auxVec4 );
  79. }
  80. else
  81. {
  82. PreviewMaterial.SetVector( "_Alp" + i, Vector4.zero );
  83. }
  84. }
  85. }
  86. public override void OnInputPortConnected( int portId , int otherNodeId , int otherPortId , bool activateNode = true )
  87. {
  88. if( portId == 0 )
  89. m_gradientNode = RecursiveBackCheck( m_gradPort.GetOutputNode( 0 ) );
  90. base.OnInputPortConnected( portId , otherNodeId , otherPortId , activateNode );
  91. }
  92. public override void OnInputPortDisconnected( int portId )
  93. {
  94. if( portId == 0 )
  95. {
  96. m_gradientNode = null;
  97. }
  98. base.OnInputPortDisconnected( portId );
  99. }
  100. //public override void OnNodeLogicUpdate( DrawInfo drawInfo )
  101. //{
  102. // base.OnNodeLogicUpdate( drawInfo );
  103. // if( m_gradPort.IsConnected )
  104. // {
  105. // if( m_gradientNode == null )
  106. // {
  107. // m_gradientNode = RecursiveBackCheck( m_gradPort.GetOutputNode( 0 ) );
  108. // PreviewIsDirty = true;
  109. // }
  110. // }
  111. // else
  112. // {
  113. // m_gradientNode = null;
  114. // }
  115. //}
  116. GradientNode RecursiveBackCheck( ParentNode node )
  117. {
  118. if( node is GradientNode )
  119. {
  120. return node as GradientNode;
  121. }
  122. else
  123. {
  124. if( node is RelayNode || node is WireNode || node is RegisterLocalVarNode )
  125. {
  126. return RecursiveBackCheck( node.InputPorts[ 0 ].GetOutputNode( 0 ) );
  127. }
  128. else if( node is GetLocalVarNode)
  129. {
  130. var gnode = node as GetLocalVarNode;
  131. if( gnode.CurrentSelected != null )
  132. return RecursiveBackCheck( gnode.CurrentSelected );
  133. else
  134. return null;
  135. }
  136. else
  137. {
  138. return null;
  139. }
  140. }
  141. }
  142. public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar )
  143. {
  144. m_functionBodyStruct = string.Empty;
  145. if( !dataCollector.IsSRP )
  146. {
  147. GradientNode.GenerateGradientStruct( ref m_functionBodyStruct );
  148. dataCollector.AddFunctions( m_functionHeaderStruct, m_functionBodyStruct, "0" );
  149. }
  150. else
  151. {
  152. dataCollector.AddToIncludes( UniqueId, "Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl" );
  153. }
  154. GenerateGradientSampler( dataCollector.IsSRP );
  155. string gradient = "(Gradient)0";
  156. if( m_inputPorts[ 0 ].IsConnected && m_gradientNode != null )
  157. gradient = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector );
  158. string time = m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector );
  159. string functionResult = dataCollector.AddFunctions( m_functionHeader, m_functionBody, gradient, time );
  160. return GetOutputVectorItem( 0, outputId, functionResult );
  161. }
  162. void GenerateGradientSampler( bool isSrp )
  163. {
  164. m_functionBody = string.Empty;
  165. IOUtils.AddFunctionHeader( ref m_functionBody, "float4 SampleGradient( Gradient gradient, float time )" );
  166. IOUtils.AddFunctionLine( ref m_functionBody, "float3 color = gradient.colors[0].rgb;" );
  167. IOUtils.AddFunctionLine( ref m_functionBody, "UNITY_UNROLL" );
  168. IOUtils.AddFunctionLine( ref m_functionBody, "for (int c = 1; c < 8; c++)" );
  169. IOUtils.AddFunctionLine( ref m_functionBody, "{" );
  170. if( isSrp )
  171. IOUtils.AddFunctionLine( ref m_functionBody, "float colorPos = saturate((time - gradient.colors[c-1].w) / ( 0.00001 + (gradient.colors[c].w - gradient.colors[c-1].w)) * step(c, gradient.colorsLength-1));" );
  172. else
  173. IOUtils.AddFunctionLine( ref m_functionBody, "float colorPos = saturate((time - gradient.colors[c-1].w) / ( 0.00001 + (gradient.colors[c].w - gradient.colors[c-1].w)) * step(c, (float)gradient.colorsLength-1));" );
  174. IOUtils.AddFunctionLine( ref m_functionBody, "color = lerp(color, gradient.colors[c].rgb, lerp(colorPos, step(0.01, colorPos), gradient.type));" );
  175. IOUtils.AddFunctionLine( ref m_functionBody, "}" );
  176. IOUtils.AddFunctionLine( ref m_functionBody, "#ifndef UNITY_COLORSPACE_GAMMA" );
  177. if( isSrp )
  178. IOUtils.AddFunctionLine( ref m_functionBody, "color = SRGBToLinear(color);" );
  179. else
  180. IOUtils.AddFunctionLine( ref m_functionBody, "color = half3(GammaToLinearSpaceExact(color.r), GammaToLinearSpaceExact(color.g), GammaToLinearSpaceExact(color.b));" );
  181. IOUtils.AddFunctionLine( ref m_functionBody, "#endif" );
  182. IOUtils.AddFunctionLine( ref m_functionBody, "float alpha = gradient.alphas[0].x;" );
  183. IOUtils.AddFunctionLine( ref m_functionBody, "UNITY_UNROLL" );
  184. IOUtils.AddFunctionLine( ref m_functionBody, "for (int a = 1; a < 8; a++)" );
  185. IOUtils.AddFunctionLine( ref m_functionBody, "{" );
  186. if( isSrp )
  187. IOUtils.AddFunctionLine( ref m_functionBody, "float alphaPos = saturate((time - gradient.alphas[a-1].y) / ( 0.00001 + (gradient.alphas[a].y - gradient.alphas[a-1].y)) * step(a, gradient.alphasLength-1));" );
  188. else
  189. IOUtils.AddFunctionLine( ref m_functionBody, "float alphaPos = saturate((time - gradient.alphas[a-1].y) / ( 0.00001 + (gradient.alphas[a].y - gradient.alphas[a-1].y)) * step(a, (float)gradient.alphasLength-1));" );
  190. IOUtils.AddFunctionLine( ref m_functionBody, "alpha = lerp(alpha, gradient.alphas[a].x, lerp(alphaPos, step(0.01, alphaPos), gradient.type));" );
  191. IOUtils.AddFunctionLine( ref m_functionBody, "}" );
  192. IOUtils.AddFunctionLine( ref m_functionBody, "return float4(color, alpha);" );
  193. IOUtils.CloseFunctionBody( ref m_functionBody );
  194. }
  195. }
  196. }