NodeKeywords.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. import VarNode from './VarNode.js';
  2. import PropertyNode from './PropertyNode.js';
  3. import PositionNode from '../accessors/PositionNode.js';
  4. import NormalNode from '../accessors/NormalNode.js';
  5. import { PI, RECIPROCAL_PI, EPSILON } from '../consts/MathConsts.js';
  6. import { saturateMacro, whiteComplementMacro } from '../functions/MathFunctions.js';
  7. class NodeKeywords {
  8. static PI = 'PI';
  9. static RECIPROCAL_PI = 'RECIPROCAL_PI';
  10. static EPSILON = 'EPSILON';
  11. static Saturate = 'saturate';
  12. static WhiteComplement = 'whiteComplement';
  13. static PositionLocal = 'PositionLocal';
  14. static PositionWorld = 'PositionWorld';
  15. static PositionView = 'PositionView';
  16. static PositionViewDirection = 'PositionViewDirection';
  17. static NormalLocal = 'NormalLocal';
  18. static NormalWorld = 'NormalWorld';
  19. static NormalView = 'NormalView';
  20. static Irradiance = 'Irradiance';
  21. static ReflectedLightIndirectDiffuse = 'ReflectedLightIndirectDiffuse';
  22. static ReflectedLightIndirectSpecular = 'ReflectedLightIndirectSpecular';
  23. static ReflectedLightDirectDiffuse = 'ReflectedLightDirectDiffuse';
  24. static ReflectedLightDirectSpecular = 'ReflectedLightDirectSpecular';
  25. static MaterialDiffuseColor = 'MaterialDiffuseColor';
  26. // STANDARD
  27. static MaterialRoughness = 'MaterialRoughness';
  28. static MaterialMetalness = 'MaterialMetalness';
  29. static MaterialSpecularTint = 'MaterialSpecularTint';
  30. constructor() {
  31. this.keywords = [
  32. // consts
  33. NodeKeywords.PI,
  34. NodeKeywords.RECIPROCAL_PI,
  35. NodeKeywords.EPSILON,
  36. // variadic macros
  37. NodeKeywords.Saturate,
  38. NodeKeywords.WhiteComplement,
  39. // nodes
  40. NodeKeywords.PositionLocal,
  41. NodeKeywords.PositionWorld,
  42. NodeKeywords.PositionView,
  43. NodeKeywords.PositionViewDirection,
  44. NodeKeywords.NormalLocal,
  45. NodeKeywords.NormalWorld,
  46. NodeKeywords.NormalView,
  47. // vars -> float
  48. NodeKeywords.MaterialRoughness,
  49. NodeKeywords.MaterialMetalness,
  50. // vars -> vec3
  51. NodeKeywords.Irradiance,
  52. NodeKeywords.ReflectedLightIndirectDiffuse,
  53. NodeKeywords.ReflectedLightIndirectSpecular,
  54. NodeKeywords.ReflectedLightDirectDiffuse,
  55. NodeKeywords.ReflectedLightDirectSpecular,
  56. NodeKeywords.MaterialSpecularTint,
  57. // vars -> vec4
  58. NodeKeywords.MaterialDiffuseColor
  59. ];
  60. this.nodes = [];
  61. }
  62. getNode( name ) {
  63. let node = this.nodes[ name ];
  64. if ( node === undefined ) {
  65. switch ( name ) {
  66. case NodeKeywords.PI:
  67. node = PI;
  68. break;
  69. case NodeKeywords.RECIPROCAL_PI:
  70. node = RECIPROCAL_PI;
  71. break;
  72. case NodeKeywords.EPSILON:
  73. node = EPSILON;
  74. break;
  75. case NodeKeywords.Saturate:
  76. node = saturateMacro;
  77. break;
  78. case NodeKeywords.WhiteComplement:
  79. node = whiteComplementMacro;
  80. break;
  81. case NodeKeywords.PositionLocal:
  82. node = new VarNode( new PositionNode( PositionNode.LOCAL ), name );
  83. break;
  84. case NodeKeywords.PositionWorld:
  85. node = new VarNode( new PositionNode( PositionNode.WORLD ), name );
  86. break;
  87. case NodeKeywords.PositionView:
  88. node = new VarNode( new PositionNode( PositionNode.VIEW ), name );
  89. break;
  90. case NodeKeywords.PositionViewDirection:
  91. node = new VarNode( new PositionNode( PositionNode.VIEW_DIRECTION ), name );
  92. break;
  93. case NodeKeywords.NormalLocal:
  94. node = new VarNode( new NormalNode( NormalNode.LOCAL ), name );
  95. break;
  96. case NodeKeywords.NormalWorld:
  97. node = new VarNode( new NormalNode( NormalNode.WORLD ), name );
  98. break;
  99. case NodeKeywords.NormalView:
  100. node = new VarNode( new NormalNode( NormalNode.VIEW ), name );
  101. break;
  102. // floats properties
  103. case NodeKeywords.MaterialRoughness:
  104. case NodeKeywords.MaterialMetalness:
  105. node = new PropertyNode( name, 'float' );
  106. break;
  107. // vec3 properties
  108. case NodeKeywords.Irradiance:
  109. case NodeKeywords.ReflectedLightIndirectDiffuse:
  110. case NodeKeywords.ReflectedLightIndirectSpecular:
  111. case NodeKeywords.ReflectedLightDirectDiffuse:
  112. case NodeKeywords.ReflectedLightDirectSpecular:
  113. case NodeKeywords.MaterialSpecularTint:
  114. node = new PropertyNode( name, 'vec3' );
  115. break;
  116. // vec4 properties
  117. case NodeKeywords.MaterialDiffuseColor:
  118. node = new PropertyNode( name, 'vec4' );
  119. break;
  120. }
  121. if ( node !== undefined ) {
  122. this.nodes[ name ] = node;
  123. }
  124. }
  125. return node;
  126. }
  127. parse( code ) {
  128. const keywordNames = this.keywords;
  129. const regExp = new RegExp( `\\b${keywordNames.join( '\\b|\\b' )}\\b`, 'g' );
  130. const codeKeywords = code.match( regExp );
  131. const keywords = [];
  132. if ( codeKeywords !== null ) {
  133. for ( const keyword of codeKeywords ) {
  134. const node = this.getNode( keyword );
  135. if ( keywords.indexOf( node ) === - 1 ) {
  136. keywords.push( node );
  137. }
  138. }
  139. }
  140. return keywords;
  141. }
  142. include( builder, code ) {
  143. const keywords = this.parse( code );
  144. for ( const keywordNode of keywords ) {
  145. keywordNode.build( builder );
  146. }
  147. }
  148. }
  149. export default NodeKeywords;