BasicNode.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. import { Node } from '../../core/Node.js';
  2. import { ColorNode } from '../../inputs/ColorNode.js';
  3. class BasicNode extends Node {
  4. constructor() {
  5. super();
  6. this.color = new ColorNode( 0xFFFFFF );
  7. }
  8. generate( builder ) {
  9. let code;
  10. if ( builder.isShader( 'vertex' ) ) {
  11. const position = this.position ? this.position.analyzeAndFlow( builder, 'v3', { cache: 'position' } ) : undefined;
  12. builder.addParsCode( [
  13. 'varying vec3 vViewPosition;',
  14. '#ifndef FLAT_SHADED',
  15. ' varying vec3 vNormal;',
  16. '#endif',
  17. ].join( '\n' ) );
  18. const output = [
  19. '#include <beginnormal_vertex>',
  20. '#include <defaultnormal_vertex>',
  21. '#ifndef FLAT_SHADED', // Normal computed with derivatives when FLAT_SHADED
  22. ' vNormal = normalize( transformedNormal );',
  23. '#endif',
  24. '#include <begin_vertex>',
  25. ];
  26. if ( position ) {
  27. output.push(
  28. position.code,
  29. position.result ? 'transformed = ' + position.result + ';' : ''
  30. );
  31. }
  32. output.push(
  33. '#include <morphtarget_vertex>',
  34. '#include <skinning_vertex>',
  35. '#include <project_vertex>',
  36. '#include <fog_vertex>',
  37. '#include <logdepthbuf_vertex>',
  38. '#include <clipping_planes_vertex>',
  39. ' vViewPosition = - mvPosition.xyz;',
  40. '#include <worldpos_vertex>',
  41. '#include <shadowmap_vertex>'
  42. );
  43. code = output.join( '\n' );
  44. } else {
  45. // Analyze all nodes to reuse generate codes
  46. this.color.analyze( builder, { slot: 'color' } );
  47. if ( this.alpha ) this.alpha.analyze( builder );
  48. if ( this.mask ) this.mask.analyze( builder );
  49. // Build code
  50. const color = this.color.flow( builder, 'c', { slot: 'color' } );
  51. const alpha = this.alpha ? this.alpha.flow( builder, 'f' ) : undefined;
  52. const mask = this.mask ? this.mask.flow( builder, 'b' ) : undefined;
  53. builder.requires.transparent = alpha !== undefined;
  54. builder.addParsCode( [
  55. 'varying vec3 vViewPosition;',
  56. '#ifndef FLAT_SHADED',
  57. ' varying vec3 vNormal;',
  58. '#endif',
  59. ].join( '\n' ) );
  60. const output = [
  61. // add before: prevent undeclared normal
  62. '#include <normal_fragment_begin>',
  63. color.code,
  64. ];
  65. if ( mask ) {
  66. output.push(
  67. mask.code,
  68. 'if ( ! ' + mask.result + ' ) discard;'
  69. );
  70. }
  71. if ( alpha ) {
  72. output.push(
  73. alpha.code,
  74. '#ifdef ALPHATEST',
  75. ' if ( ' + alpha.result + ' <= ALPHATEST ) discard;',
  76. '#endif'
  77. );
  78. }
  79. if ( alpha ) {
  80. output.push( 'gl_FragColor = vec4(' + color.result + ', ' + alpha.result + ' );' );
  81. } else {
  82. output.push( 'gl_FragColor = vec4(' + color.result + ', 1.0 );' );
  83. }
  84. code = output.join( '\n' );
  85. }
  86. return code;
  87. }
  88. copy( source ) {
  89. super.copy( source );
  90. this.color = source.color;
  91. if ( source.position ) this.position = source.position;
  92. if ( source.alpha ) this.alpha = source.alpha;
  93. if ( source.mask ) this.mask = source.mask;
  94. return this;
  95. }
  96. toJSON( meta ) {
  97. let data = this.getJSONNode( meta );
  98. if ( ! data ) {
  99. data = this.createJSONNode( meta );
  100. data.color = this.color.toJSON( meta ).uuid;
  101. if ( this.position ) data.position = this.position.toJSON( meta ).uuid;
  102. if ( this.alpha ) data.alpha = this.alpha.toJSON( meta ).uuid;
  103. if ( this.mask ) data.mask = this.mask.toJSON( meta ).uuid;
  104. }
  105. return data;
  106. }
  107. }
  108. BasicNode.prototype.nodeType = 'Basic';
  109. export { BasicNode };