NodeKeywords.js 5.1 KB

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