SpriteNode.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /**
  2. * @author sunag / http://www.sunag.com.br/
  3. */
  4. import { Node } from '../../core/Node.js';
  5. import { ColorNode } from '../../inputs/ColorNode.js';
  6. function SpriteNode() {
  7. Node.call( this );
  8. this.color = new ColorNode( 0xEEEEEE );
  9. this.spherical = true;
  10. }
  11. SpriteNode.prototype = Object.create( Node.prototype );
  12. SpriteNode.prototype.constructor = SpriteNode;
  13. SpriteNode.prototype.nodeType = "Sprite";
  14. SpriteNode.prototype.build = function ( builder ) {
  15. var output, code;
  16. builder.define( 'SPRITE' );
  17. builder.requires.lights = false;
  18. builder.requires.transparent = this.alpha !== undefined;
  19. if ( builder.isShader( 'vertex' ) ) {
  20. var position = this.position ? this.position.parseAndBuildCode( builder, 'v3', { cache: 'position' } ) : undefined;
  21. builder.mergeUniform( THREE.UniformsUtils.merge( [
  22. THREE.UniformsLib.fog
  23. ] ) );
  24. builder.addParsCode( [
  25. "#include <fog_pars_vertex>",
  26. "#include <logdepthbuf_pars_vertex>",
  27. "#include <clipping_planes_pars_vertex>"
  28. ].join( "\n" ) );
  29. output = [
  30. "#include <clipping_planes_fragment>",
  31. "#include <begin_vertex>"
  32. ];
  33. if ( position ) {
  34. output.push(
  35. position.code,
  36. position.result ? "transformed = " + position.result + ";" : ''
  37. );
  38. }
  39. output.push(
  40. "#include <project_vertex>",
  41. "#include <fog_vertex>",
  42. 'mat4 modelViewMtx = modelViewMatrix;',
  43. 'mat4 modelMtx = modelMatrix;',
  44. // ignore position from modelMatrix (use vary position)
  45. 'modelMtx[3][0] = 0.0;',
  46. 'modelMtx[3][1] = 0.0;',
  47. 'modelMtx[3][2] = 0.0;'
  48. );
  49. if ( ! this.spherical ) {
  50. output.push(
  51. 'modelMtx[1][1] = 1.0;'
  52. );
  53. }
  54. output.push(
  55. // http://www.geeks3d.com/20140807/billboarding-vertex-shader-glsl/
  56. // First colunm.
  57. 'modelViewMtx[0][0] = 1.0;',
  58. 'modelViewMtx[0][1] = 0.0;',
  59. 'modelViewMtx[0][2] = 0.0;'
  60. );
  61. if ( this.spherical ) {
  62. output.push(
  63. // Second colunm.
  64. 'modelViewMtx[1][0] = 0.0;',
  65. 'modelViewMtx[1][1] = 1.0;',
  66. 'modelViewMtx[1][2] = 0.0;'
  67. );
  68. }
  69. output.push(
  70. // Thrid colunm.
  71. 'modelViewMtx[2][0] = 0.0;',
  72. 'modelViewMtx[2][1] = 0.0;',
  73. 'modelViewMtx[2][2] = 1.0;',
  74. "gl_Position = projectionMatrix * modelViewMtx * modelMtx * vec4( transformed, 1.0 );",
  75. "#include <logdepthbuf_vertex>",
  76. "#include <clipping_planes_vertex>",
  77. "#include <fog_vertex>"
  78. );
  79. } else {
  80. builder.addParsCode( [
  81. "#include <fog_pars_fragment>",
  82. "#include <logdepthbuf_pars_fragment>",
  83. "#include <clipping_planes_pars_fragment>"
  84. ].join( "\n" ) );
  85. builder.addCode( [
  86. "#include <clipping_planes_fragment>",
  87. "#include <logdepthbuf_fragment>"
  88. ].join( "\n" ) );
  89. // parse all nodes to reuse generate codes
  90. if ( this.alpha ) this.alpha.parse( builder );
  91. this.color.parse( builder, { slot: 'color' } );
  92. // build code
  93. var alpha = this.alpha ? this.alpha.buildCode( builder, 'f' ) : undefined,
  94. color = this.color.buildCode( builder, 'c', { slot: 'color' } );
  95. if ( alpha ) {
  96. output = [
  97. alpha.code,
  98. '#ifdef ALPHATEST',
  99. 'if ( ' + alpha.result + ' <= ALPHATEST ) discard;',
  100. '#endif',
  101. color.code,
  102. "gl_FragColor = vec4( " + color.result + ", " + alpha.result + " );"
  103. ];
  104. } else {
  105. output = [
  106. color.code,
  107. "gl_FragColor = vec4( " + color.result + ", 1.0 );"
  108. ];
  109. }
  110. output.push(
  111. "#include <tonemapping_fragment>",
  112. "#include <encodings_fragment>",
  113. "#include <fog_fragment>"
  114. );
  115. }
  116. return output.join( "\n" );
  117. };
  118. SpriteNode.prototype.copy = function ( source ) {
  119. Node.prototype.copy.call( this, source );
  120. // vertex
  121. if ( source.position ) this.position = source.position;
  122. // fragment
  123. this.color = source.color;
  124. if ( source.spherical !== undefined ) this.spherical = source.spherical;
  125. if ( source.alpha ) this.alpha = source.alpha;
  126. };
  127. SpriteNode.prototype.toJSON = function ( meta ) {
  128. var data = this.getJSONNode( meta );
  129. if ( ! data ) {
  130. data = this.createJSONNode( meta );
  131. // vertex
  132. if ( this.position ) data.position = this.position.toJSON( meta ).uuid;
  133. // fragment
  134. data.color = this.color.toJSON( meta ).uuid;
  135. if ( this.spherical === false ) data.spherical = false;
  136. if ( this.alpha ) data.alpha = this.alpha.toJSON( meta ).uuid;
  137. }
  138. return data;
  139. };
  140. export { SpriteNode };