TessellationOpHelper.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  1. // Amplify Shader Editor - Visual Shader Editing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. using System;
  4. using System.Collections.Generic;
  5. using UnityEngine;
  6. using UnityEditor;
  7. namespace AmplifyShaderEditor
  8. {
  9. [Serializable]
  10. public sealed class TessellationOpHelper
  11. {
  12. public const string TessellationPortStr = "Tessellation";
  13. public const string TessSurfParam = "tessellate:tessFunction";
  14. public const string TessInclude = "Tessellation.cginc";
  15. //public const string CustomAppData = "\t\tstruct appdata\n" +
  16. // "\t\t{\n" +
  17. // "\t\t\tfloat4 vertex : POSITION;\n" +
  18. // "\t\t\tfloat4 tangent : TANGENT;\n" +
  19. // "\t\t\tfloat3 normal : NORMAL;\n" +
  20. // "\t\t\tfloat4 texcoord : TEXCOORD0;\n" +
  21. // "\t\t\tfloat4 texcoord1 : TEXCOORD1;\n" +
  22. // "\t\t\tfloat4 texcoord2 : TEXCOORD2;\n" +
  23. // "\t\t\tfloat4 texcoord3 : TEXCOORD3;\n" +
  24. // "\t\t\tfixed4 color : COLOR;\n" +
  25. // "\t\t\tUNITY_VERTEX_INPUT_INSTANCE_ID\n" +
  26. // "\t\t};\n\n";
  27. private const string TessUniformName = "_TessValue";
  28. private const string TessMinUniformName = "_TessMin";
  29. private const string TessMaxUniformName = "_TessMax";
  30. //private GUIContent EnableTessContent = new GUIContent( "Tessellation", "Activates the use of tessellation which subdivides polygons to increase geometry detail using a set of rules\nDefault: OFF" );
  31. private GUIContent TessFactorContent = new GUIContent( "Tess", "Tessellation factor\nDefault: 4" );
  32. private GUIContent TessMinDistanceContent = new GUIContent( "Min", "Minimum tessellation distance\nDefault: 10" );
  33. private GUIContent TessMaxDistanceContent = new GUIContent( "Max", "Maximum tessellation distance\nDefault: 25" );
  34. private readonly int[] TesselationTypeValues = { 0, 1, 2, 3 };
  35. private readonly string[] TesselationTypeLabels = { "Distance-based", "Fixed", "Edge Length", "Edge Length Cull" };
  36. private readonly string TesselationTypeStr = "Type";
  37. private const string TessProperty = "_TessValue( \"Max Tessellation\", Range( 1, 32 ) ) = {0}";
  38. private const string TessMinProperty = "_TessMin( \"Tess Min Distance\", Float ) = {0}";
  39. private const string TessMaxProperty = "_TessMax( \"Tess Max Distance\", Float ) = {0}";
  40. private const string TessFunctionOpen = "\t\tfloat4 tessFunction( {0} v0, {0} v1, {0} v2 )\n\t\t{{\n";
  41. private const string TessFunctionClose = "\t\t}\n";
  42. // Custom function
  43. private const string CustomFunctionBody = "\t\t\treturn {0};\n";
  44. // Distance based function
  45. private const string DistBasedTessFunctionBody = "\t\t\treturn UnityDistanceBasedTess( v0.vertex, v1.vertex, v2.vertex, _TessMin, _TessMax, _TessValue );\n";
  46. // Fixed amount function
  47. private const string FixedAmountTessFunctionOpen = "\t\tfloat4 tessFunction( )\n\t\t{\n";
  48. private const string FixedAmountTessFunctionBody = "\t\t\treturn _TessValue;\n";
  49. // Edge Length
  50. private GUIContent EdgeLengthContent = new GUIContent( "Edge Length", "Tessellation levels ccomputed based on triangle edge length on the screen\nDefault: 4" );
  51. private const string EdgeLengthTessProperty = "_EdgeLength ( \"Edge length\", Range( 2, 50 ) ) = {0}";
  52. private const string EdgeLengthTessUniformName = "_EdgeLength";
  53. private const string EdgeLengthTessFunctionBody = "\t\t\treturn UnityEdgeLengthBasedTess (v0.vertex, v1.vertex, v2.vertex, _EdgeLength);\n";
  54. private const string EdgeLengthTessCullFunctionBody = "\t\t\treturn UnityEdgeLengthBasedTessCull (v0.vertex, v1.vertex, v2.vertex, _EdgeLength , _TessMaxDisp );\n";
  55. private const string EdgeLengthTessMaxDispProperty = "_TessMaxDisp( \"Max Displacement\", Float ) = {0}";
  56. private const string EdgeLengthTessMaxDispUniformName = "_TessMaxDisp";
  57. private GUIContent EdgeLengthTessMaxDisplacementContent = new GUIContent( "Max Disp.", "Max Displacement" );
  58. // Phong
  59. private GUIContent PhongEnableContent = new GUIContent( "Phong", "Modifies positions of the subdivided faces so that the resulting surface follows the mesh normals a bit\nDefault: OFF" );
  60. private GUIContent PhongStrengthContent = new GUIContent( "Strength", "Strength\nDefault: 0.5" );
  61. public const string PhongStrengthParam = "tessphong:_TessPhongStrength";
  62. private const string PhongStrengthProperty = "_TessPhongStrength( \"Phong Tess Strength\", Range( 0, 1 ) ) = {0}";
  63. private const string PhongStrengthUniformName = "_TessPhongStrength";
  64. [SerializeField]
  65. private bool m_enabled = false;
  66. //private bool m_expanded = false;
  67. [SerializeField]
  68. private int m_tessType = 2;
  69. [SerializeField]
  70. private float m_tessMinDistance = 10f;
  71. [SerializeField]
  72. private float m_tessMaxDistance = 25f;
  73. [SerializeField]
  74. private float m_tessFactor = 15f;
  75. [SerializeField]
  76. private float m_phongStrength = 0.5f;
  77. [SerializeField]
  78. private bool m_phongEnabled = false;
  79. [SerializeField]
  80. private string[] m_customData = { string.Empty, string.Empty, string.Empty };
  81. [SerializeField]
  82. private bool m_hasCustomFunction = false;
  83. [SerializeField]
  84. private string m_customFunction = String.Empty;
  85. [SerializeField]
  86. private string m_additionalData = string.Empty;
  87. [SerializeField]
  88. private StandardSurfaceOutputNode m_parentSurface;
  89. private Dictionary<string, bool> m_additionalDataDict = new Dictionary<string, bool>();
  90. private int m_masterNodeIndexPort = 0;
  91. private int m_vertexOffsetIndexPort = 0;
  92. //private int m_orderIndex = 1000;
  93. public void Draw( UndoParentNode owner, GUIStyle toolbarstyle, Material mat, bool connectedInput )
  94. {
  95. Color cachedColor = GUI.color;
  96. GUI.color = new Color( cachedColor.r, cachedColor.g, cachedColor.b, 0.5f );
  97. EditorGUILayout.BeginHorizontal( toolbarstyle );
  98. GUI.color = cachedColor;
  99. EditorGUI.BeginChangeCheck();
  100. m_parentSurface.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedTesselation = GUILayout.Toggle( m_parentSurface.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedTesselation, " Tessellation", UIUtils.MenuItemToggleStyle, GUILayout.ExpandWidth( true ) );
  101. if ( EditorGUI.EndChangeCheck() )
  102. {
  103. EditorPrefs.SetBool( "ExpandedTesselation", m_parentSurface.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedTesselation );
  104. }
  105. EditorGUI.BeginChangeCheck();
  106. m_enabled = owner.EditorGUILayoutToggle( string.Empty, m_enabled, UIUtils.MenuItemEnableStyle, GUILayout.Width( 16 ) );
  107. if ( EditorGUI.EndChangeCheck() )
  108. {
  109. if ( m_enabled )
  110. UpdateToMaterial( mat, !connectedInput );
  111. UIUtils.RequestSave();
  112. }
  113. EditorGUILayout.EndHorizontal();
  114. m_enabled = m_enabled || connectedInput;
  115. if ( m_parentSurface.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedTesselation )
  116. {
  117. cachedColor = GUI.color;
  118. GUI.color = new Color( cachedColor.r, cachedColor.g, cachedColor.b, ( EditorGUIUtility.isProSkin ? 0.5f : 0.25f ) );
  119. EditorGUILayout.BeginVertical( UIUtils.MenuItemBackgroundStyle );
  120. GUI.color = cachedColor;
  121. EditorGUILayout.Separator();
  122. EditorGUI.BeginDisabledGroup( !m_enabled );
  123. EditorGUI.indentLevel += 1;
  124. m_phongEnabled = owner.EditorGUILayoutToggle( PhongEnableContent, m_phongEnabled );
  125. if ( m_phongEnabled )
  126. {
  127. EditorGUI.indentLevel += 1;
  128. EditorGUI.BeginChangeCheck();
  129. m_phongStrength = owner.EditorGUILayoutSlider( PhongStrengthContent, m_phongStrength, 0.0f, 1.0f );
  130. if ( EditorGUI.EndChangeCheck() && mat != null )
  131. {
  132. if ( mat.HasProperty( PhongStrengthUniformName ) )
  133. mat.SetFloat( PhongStrengthUniformName, m_phongStrength );
  134. }
  135. EditorGUI.indentLevel -= 1;
  136. }
  137. bool guiEnabled = GUI.enabled;
  138. GUI.enabled = !connectedInput && m_enabled;
  139. m_tessType = owner.EditorGUILayoutIntPopup( TesselationTypeStr, m_tessType, TesselationTypeLabels, TesselationTypeValues );
  140. switch ( m_tessType )
  141. {
  142. case 0:
  143. {
  144. EditorGUI.BeginChangeCheck();
  145. m_tessFactor = owner.EditorGUILayoutSlider( TessFactorContent, m_tessFactor, 1, 32 );
  146. if ( EditorGUI.EndChangeCheck() && mat != null )
  147. {
  148. if ( mat.HasProperty( TessUniformName ) )
  149. mat.SetFloat( TessUniformName, m_tessFactor );
  150. }
  151. EditorGUI.BeginChangeCheck();
  152. m_tessMinDistance = owner.EditorGUILayoutFloatField( TessMinDistanceContent, m_tessMinDistance );
  153. if ( EditorGUI.EndChangeCheck() && mat != null )
  154. {
  155. if ( mat.HasProperty( TessMinUniformName ) )
  156. mat.SetFloat( TessMinUniformName, m_tessMinDistance );
  157. }
  158. EditorGUI.BeginChangeCheck();
  159. m_tessMaxDistance = owner.EditorGUILayoutFloatField( TessMaxDistanceContent, m_tessMaxDistance );
  160. if ( EditorGUI.EndChangeCheck() && mat != null )
  161. {
  162. if ( mat.HasProperty( TessMaxUniformName ) )
  163. mat.SetFloat( TessMaxUniformName, m_tessMaxDistance );
  164. }
  165. }
  166. break;
  167. case 1:
  168. {
  169. EditorGUI.BeginChangeCheck();
  170. m_tessFactor = owner.EditorGUILayoutSlider( TessFactorContent, m_tessFactor, 1, 32 );
  171. if ( EditorGUI.EndChangeCheck() && mat != null )
  172. {
  173. if ( mat.HasProperty( TessUniformName ) )
  174. mat.SetFloat( TessUniformName, m_tessFactor );
  175. }
  176. }
  177. break;
  178. case 2:
  179. {
  180. EditorGUI.BeginChangeCheck();
  181. m_tessFactor = owner.EditorGUILayoutSlider( EdgeLengthContent, m_tessFactor, 2, 50 );
  182. if ( EditorGUI.EndChangeCheck() && mat != null )
  183. {
  184. if ( mat.HasProperty( EdgeLengthTessUniformName ) )
  185. mat.SetFloat( EdgeLengthTessUniformName, m_tessFactor );
  186. }
  187. }
  188. break;
  189. case 3:
  190. {
  191. EditorGUI.BeginChangeCheck();
  192. m_tessFactor = owner.EditorGUILayoutSlider( EdgeLengthContent, m_tessFactor, 2, 50 );
  193. if ( EditorGUI.EndChangeCheck() && mat != null )
  194. {
  195. if ( mat.HasProperty( EdgeLengthTessUniformName ) )
  196. mat.SetFloat( EdgeLengthTessUniformName, m_tessFactor );
  197. }
  198. EditorGUI.BeginChangeCheck();
  199. m_tessMaxDistance = owner.EditorGUILayoutFloatField( EdgeLengthTessMaxDisplacementContent, m_tessMaxDistance );
  200. if ( EditorGUI.EndChangeCheck() && mat != null )
  201. {
  202. if ( mat.HasProperty( TessMinUniformName ) )
  203. mat.SetFloat( TessMinUniformName, m_tessMaxDistance );
  204. }
  205. }
  206. break;
  207. }
  208. GUI.enabled = guiEnabled;
  209. EditorGUI.indentLevel -= 1;
  210. EditorGUI.EndDisabledGroup();
  211. EditorGUILayout.Separator();
  212. EditorGUILayout.EndVertical();
  213. }
  214. }
  215. public void UpdateToMaterial( Material mat, bool updateInternals )
  216. {
  217. if ( mat == null )
  218. return;
  219. if ( m_phongEnabled )
  220. {
  221. if ( mat.HasProperty( PhongStrengthUniformName ) )
  222. mat.SetFloat( PhongStrengthUniformName, m_phongStrength );
  223. }
  224. if ( updateInternals )
  225. {
  226. switch ( m_tessType )
  227. {
  228. case 0:
  229. {
  230. if ( mat.HasProperty( TessUniformName ) )
  231. mat.SetFloat( TessUniformName, m_tessFactor );
  232. if ( mat.HasProperty( TessMinUniformName ) )
  233. mat.SetFloat( TessMinUniformName, m_tessMinDistance );
  234. if ( mat.HasProperty( TessMaxUniformName ) )
  235. mat.SetFloat( TessMaxUniformName, m_tessMaxDistance );
  236. }
  237. break;
  238. case 1:
  239. {
  240. if ( mat.HasProperty( TessUniformName ) )
  241. mat.SetFloat( TessUniformName, m_tessFactor );
  242. }
  243. break;
  244. case 2:
  245. {
  246. if ( mat.HasProperty( EdgeLengthTessUniformName ) )
  247. mat.SetFloat( EdgeLengthTessUniformName, m_tessFactor );
  248. }
  249. break;
  250. case 3:
  251. {
  252. if ( mat.HasProperty( EdgeLengthTessUniformName ) )
  253. mat.SetFloat( EdgeLengthTessUniformName, m_tessFactor );
  254. if ( mat.HasProperty( TessMinUniformName ) )
  255. mat.SetFloat( TessMinUniformName, m_tessMaxDistance );
  256. }
  257. break;
  258. }
  259. }
  260. }
  261. public void ReadFromString( ref uint index, ref string[] nodeParams )
  262. {
  263. m_enabled = Convert.ToBoolean( nodeParams[ index++ ] );
  264. m_tessType = Convert.ToInt32( nodeParams[ index++ ] );
  265. m_tessFactor = Convert.ToSingle( nodeParams[ index++ ] );
  266. m_tessMinDistance = Convert.ToSingle( nodeParams[ index++ ] );
  267. m_tessMaxDistance = Convert.ToSingle( nodeParams[ index++ ] );
  268. if ( UIUtils.CurrentShaderVersion() > 3001 )
  269. {
  270. m_phongEnabled = Convert.ToBoolean( nodeParams[ index++ ] );
  271. m_phongStrength = Convert.ToSingle( nodeParams[ index++ ] );
  272. }
  273. }
  274. public void WriteToString( ref string nodeInfo )
  275. {
  276. IOUtils.AddFieldValueToString( ref nodeInfo, m_enabled );
  277. IOUtils.AddFieldValueToString( ref nodeInfo, m_tessType );
  278. IOUtils.AddFieldValueToString( ref nodeInfo, m_tessFactor );
  279. IOUtils.AddFieldValueToString( ref nodeInfo, m_tessMinDistance );
  280. IOUtils.AddFieldValueToString( ref nodeInfo, m_tessMaxDistance );
  281. IOUtils.AddFieldValueToString( ref nodeInfo, m_phongEnabled );
  282. IOUtils.AddFieldValueToString( ref nodeInfo, m_phongStrength );
  283. }
  284. public string Uniforms()
  285. {
  286. string uniforms = string.Empty;
  287. switch( m_tessType )
  288. {
  289. case 0:
  290. {
  291. if( !m_hasCustomFunction )
  292. {
  293. //Tess
  294. uniforms += "\t\tuniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + TessUniformName + ";\n";
  295. //Min
  296. uniforms += "\t\tuniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + TessMinUniformName + ";\n";
  297. //Max
  298. uniforms += "\t\tuniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + TessMaxUniformName + ";\n";
  299. }
  300. }
  301. break;
  302. case 1:
  303. //Tess
  304. if( !m_hasCustomFunction )
  305. {
  306. uniforms += "\t\tuniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + TessUniformName + ";\n";
  307. }
  308. break;
  309. case 2:
  310. if( !m_hasCustomFunction )
  311. {
  312. uniforms += "\t\tuniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float , WirePortDataType.FLOAT ) + " " + EdgeLengthTessUniformName + ";\n";
  313. }
  314. break;
  315. case 3:
  316. if( !m_hasCustomFunction )
  317. {
  318. uniforms += "\t\tuniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float , WirePortDataType.FLOAT ) + " " + EdgeLengthTessUniformName + ";\n";
  319. uniforms += "\t\tuniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float , WirePortDataType.FLOAT ) + " " + EdgeLengthTessMaxDispUniformName + ";\n";
  320. }
  321. break;
  322. }
  323. if( m_phongEnabled )
  324. {
  325. uniforms += "\t\tuniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + PhongStrengthUniformName + ";\n" ;
  326. }
  327. return uniforms;
  328. }
  329. public void AddToDataCollector( ref MasterNodeDataCollector dataCollector, int reorder )
  330. {
  331. int orderIndex = reorder;
  332. switch ( m_tessType )
  333. {
  334. case 0:
  335. {
  336. dataCollector.AddToIncludes( -1, TessellationOpHelper.TessInclude );
  337. if ( !m_hasCustomFunction )
  338. {
  339. //Tess
  340. dataCollector.AddToProperties( -1, string.Format( TessProperty, m_tessFactor ), orderIndex++ );
  341. dataCollector.AddToUniforms( -1, "uniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + TessUniformName + ";" );
  342. //Min
  343. dataCollector.AddToProperties( -1, string.Format( TessMinProperty, m_tessMinDistance ), orderIndex++ );
  344. dataCollector.AddToUniforms( -1, "uniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + TessMinUniformName + ";" );
  345. //Max
  346. dataCollector.AddToProperties( -1, string.Format( TessMaxProperty, m_tessMaxDistance ), orderIndex++ );
  347. dataCollector.AddToUniforms( -1, "uniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + TessMaxUniformName + ";" );
  348. }
  349. }
  350. break;
  351. case 1:
  352. {
  353. //Tess
  354. if ( !m_hasCustomFunction )
  355. {
  356. dataCollector.AddToProperties( -1, string.Format( TessProperty, m_tessFactor ), orderIndex++ );
  357. dataCollector.AddToUniforms( -1, "uniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + TessUniformName + ";" );
  358. }
  359. }
  360. break;
  361. case 2:
  362. {
  363. dataCollector.AddToIncludes( -1, TessellationOpHelper.TessInclude );
  364. //Tess
  365. if ( !m_hasCustomFunction )
  366. {
  367. dataCollector.AddToProperties( -1, string.Format( EdgeLengthTessProperty, m_tessFactor ), orderIndex++ );
  368. dataCollector.AddToUniforms( -1, "uniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + EdgeLengthTessUniformName + ";" );
  369. }
  370. }
  371. break;
  372. case 3:
  373. {
  374. dataCollector.AddToIncludes( -1, TessellationOpHelper.TessInclude );
  375. if ( !m_hasCustomFunction )
  376. {
  377. //Tess
  378. dataCollector.AddToProperties( -1, string.Format( EdgeLengthTessProperty, m_tessFactor ), orderIndex++ );
  379. dataCollector.AddToUniforms( -1, "uniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + EdgeLengthTessUniformName + ";" );
  380. //Max Displacement
  381. dataCollector.AddToProperties( -1, string.Format( EdgeLengthTessMaxDispProperty, m_tessMaxDistance ), orderIndex++ );
  382. dataCollector.AddToUniforms( -1, "uniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + EdgeLengthTessMaxDispUniformName + ";" );
  383. }
  384. }
  385. break;
  386. }
  387. if ( m_phongEnabled )
  388. {
  389. dataCollector.AddToProperties( -1, string.Format( PhongStrengthProperty, m_phongStrength ), orderIndex++ );
  390. dataCollector.AddToUniforms( -1, "uniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + PhongStrengthUniformName + ";" );
  391. }
  392. }
  393. //ToDo: Optimize material property fetches to use Id instead of string
  394. public void UpdateFromMaterial( Material mat )
  395. {
  396. if ( m_enabled )
  397. {
  398. if ( m_phongEnabled )
  399. {
  400. if ( mat.HasProperty( PhongStrengthUniformName ) )
  401. m_phongStrength = mat.GetFloat( PhongStrengthUniformName );
  402. }
  403. switch ( m_tessType )
  404. {
  405. case 0:
  406. {
  407. if ( mat.HasProperty( TessUniformName ) )
  408. m_tessFactor = mat.GetFloat( TessUniformName );
  409. if ( mat.HasProperty( TessMinUniformName ) )
  410. m_tessMinDistance = mat.GetFloat( TessMinUniformName );
  411. if ( mat.HasProperty( TessMaxUniformName ) )
  412. m_tessMaxDistance = mat.GetFloat( TessMaxUniformName );
  413. }
  414. break;
  415. case 1:
  416. {
  417. if ( mat.HasProperty( TessUniformName ) )
  418. m_tessFactor = mat.GetFloat( TessUniformName );
  419. }
  420. break;
  421. case 2:
  422. {
  423. if ( mat.HasProperty( EdgeLengthTessUniformName ) )
  424. m_tessFactor = mat.GetFloat( EdgeLengthTessUniformName );
  425. }
  426. break;
  427. case 3:
  428. {
  429. if ( mat.HasProperty( EdgeLengthTessUniformName ) )
  430. m_tessFactor = mat.GetFloat( EdgeLengthTessUniformName );
  431. if ( mat.HasProperty( EdgeLengthTessMaxDispUniformName ) )
  432. m_tessMaxDistance = mat.GetFloat( EdgeLengthTessMaxDispUniformName );
  433. }
  434. break;
  435. }
  436. }
  437. }
  438. public void WriteToOptionalParams( ref string optionalParams )
  439. {
  440. optionalParams += TessellationOpHelper.TessSurfParam + Constants.OptionalParametersSep;
  441. if ( m_phongEnabled )
  442. {
  443. optionalParams += TessellationOpHelper.PhongStrengthParam + Constants.OptionalParametersSep;
  444. }
  445. }
  446. public void Reset()
  447. {
  448. m_hasCustomFunction = false;
  449. m_customFunction = string.Empty;
  450. m_additionalData = string.Empty;
  451. m_additionalDataDict.Clear();
  452. switch ( m_tessType )
  453. {
  454. case 0:
  455. {
  456. m_customData[ 0 ] = TessUniformName;
  457. m_customData[ 1 ] = TessMinUniformName;
  458. m_customData[ 2 ] = TessMaxUniformName;
  459. }
  460. break;
  461. case 1:
  462. {
  463. m_customData[ 0 ] = TessUniformName;
  464. m_customData[ 1 ] = string.Empty;
  465. m_customData[ 2 ] = string.Empty;
  466. }
  467. break;
  468. case 2:
  469. {
  470. m_customData[ 0 ] = EdgeLengthTessUniformName;
  471. m_customData[ 1 ] = string.Empty;
  472. m_customData[ 2 ] = string.Empty;
  473. }
  474. break;
  475. case 3:
  476. {
  477. m_customData[ 0 ] = EdgeLengthTessUniformName;
  478. m_customData[ 1 ] = EdgeLengthTessMaxDispUniformName;
  479. m_customData[ 2 ] = string.Empty;
  480. }
  481. break;
  482. }
  483. }
  484. public string GetCurrentTessellationFunction( ref MasterNodeDataCollector dataCollector )
  485. {
  486. string finalTessFunctionOpen = string.Format( TessFunctionOpen , dataCollector.SurfaceVertexStructure );
  487. if ( m_hasCustomFunction )
  488. {
  489. return finalTessFunctionOpen +
  490. m_customFunction +
  491. TessFunctionClose;
  492. }
  493. string tessFunction = string.Empty;
  494. switch ( m_tessType )
  495. {
  496. case 0:
  497. {
  498. tessFunction = finalTessFunctionOpen +
  499. DistBasedTessFunctionBody +
  500. TessFunctionClose;
  501. }
  502. break;
  503. case 1:
  504. {
  505. tessFunction = FixedAmountTessFunctionOpen +
  506. FixedAmountTessFunctionBody +
  507. TessFunctionClose;
  508. }
  509. break;
  510. case 2:
  511. {
  512. tessFunction = finalTessFunctionOpen +
  513. EdgeLengthTessFunctionBody +
  514. TessFunctionClose;
  515. }
  516. break;
  517. case 3:
  518. {
  519. tessFunction = finalTessFunctionOpen +
  520. EdgeLengthTessCullFunctionBody +
  521. TessFunctionClose;
  522. }
  523. break;
  524. }
  525. return tessFunction;
  526. }
  527. public void AddAdditionalData( string data )
  528. {
  529. if ( !m_additionalDataDict.ContainsKey( data ) )
  530. {
  531. m_additionalDataDict.Add( data, true );
  532. m_additionalData += data;
  533. }
  534. }
  535. public void AddCustomFunction( string returnData )
  536. {
  537. m_hasCustomFunction = true;
  538. m_customFunction = m_additionalData + string.Format( CustomFunctionBody, returnData );
  539. }
  540. public void Destroy()
  541. {
  542. m_additionalDataDict.Clear();
  543. m_additionalDataDict = null;
  544. }
  545. public bool IsTessellationPort( int index )
  546. {
  547. return index == m_masterNodeIndexPort;
  548. }
  549. public bool EnableTesselation { get { return m_enabled; } }
  550. public int TessType { get { return m_tessType; } }
  551. public int MasterNodeIndexPort
  552. {
  553. get { return m_masterNodeIndexPort; }
  554. set { m_masterNodeIndexPort = value; }
  555. }
  556. public int VertexOffsetIndexPort
  557. {
  558. get { return m_vertexOffsetIndexPort; }
  559. set { m_vertexOffsetIndexPort = value; }
  560. }
  561. public StandardSurfaceOutputNode ParentSurface { get { return m_parentSurface; } set { m_parentSurface = value; } }
  562. }
  563. }