RTTNode.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import {
  2. Mesh,
  3. OrthographicCamera,
  4. PlaneGeometry,
  5. Scene,
  6. WebGLRenderTarget
  7. } from '../../../../build/three.module.js';
  8. import { NodeBuilder } from '../core/NodeBuilder.js';
  9. import { NodeMaterial } from '../materials/NodeMaterial.js';
  10. import { TextureNode } from './TextureNode.js';
  11. function RTTNode( width, height, input, options ) {
  12. options = options || {};
  13. this.input = input;
  14. this.clear = options.clear !== undefined ? options.clear : true;
  15. this.renderTarget = new WebGLRenderTarget( width, height, options );
  16. this.material = new NodeMaterial();
  17. this.camera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
  18. this.scene = new Scene();
  19. this.quad = new Mesh( new PlaneGeometry( 2, 2 ), this.material );
  20. this.quad.frustumCulled = false; // Avoid getting clipped
  21. this.scene.add( this.quad );
  22. this.render = true;
  23. TextureNode.call( this, this.renderTarget.texture );
  24. }
  25. RTTNode.prototype = Object.create( TextureNode.prototype );
  26. RTTNode.prototype.constructor = RTTNode;
  27. RTTNode.prototype.nodeType = 'RTT';
  28. RTTNode.prototype.build = function ( builder, output, uuid ) {
  29. var rttBuilder = new NodeBuilder();
  30. rttBuilder.nodes = builder.nodes;
  31. rttBuilder.updaters = builder.updaters;
  32. this.material.fragment.value = this.input;
  33. this.material.build( { builder: rttBuilder } );
  34. return TextureNode.prototype.build.call( this, builder, output, uuid );
  35. };
  36. RTTNode.prototype.updateFramesaveTo = function ( frame ) {
  37. this.saveTo.render = false;
  38. if ( this.saveTo !== this.saveToCurrent ) {
  39. if ( this.saveToMaterial ) this.saveToMaterial.dispose();
  40. var material = new NodeMaterial();
  41. material.fragment.value = this;
  42. material.build();
  43. var scene = new Scene();
  44. var quad = new Mesh( new PlaneGeometry( 2, 2 ), material );
  45. quad.frustumCulled = false; // Avoid getting clipped
  46. scene.add( quad );
  47. this.saveToScene = scene;
  48. this.saveToMaterial = material;
  49. }
  50. this.saveToCurrent = this.saveTo;
  51. frame.renderer.setRenderTarget( this.saveTo.renderTarget );
  52. if ( this.saveTo.clear ) frame.renderer.clear();
  53. frame.renderer.render( this.saveToScene, this.camera );
  54. };
  55. RTTNode.prototype.updateFrame = function ( frame ) {
  56. if ( frame.renderer ) {
  57. // from the second frame
  58. if ( this.saveTo && this.saveTo.render === false ) {
  59. this.updateFramesaveTo( frame );
  60. }
  61. if ( this.render ) {
  62. if ( this.material.uniforms.renderTexture ) {
  63. this.material.uniforms.renderTexture.value = frame.renderTexture;
  64. }
  65. frame.renderer.setRenderTarget( this.renderTarget );
  66. if ( this.clear ) frame.renderer.clear();
  67. frame.renderer.render( this.scene, this.camera );
  68. }
  69. // first frame
  70. if ( this.saveTo && this.saveTo.render === true ) {
  71. this.updateFramesaveTo( frame );
  72. }
  73. } else {
  74. console.warn( 'RTTNode need a renderer in NodeFrame' );
  75. }
  76. };
  77. RTTNode.prototype.copy = function ( source ) {
  78. TextureNode.prototype.copy.call( this, source );
  79. this.saveTo = source.saveTo;
  80. return this;
  81. };
  82. RTTNode.prototype.toJSON = function ( meta ) {
  83. var data = this.getJSONNode( meta );
  84. if ( ! data ) {
  85. data = TextureNode.prototype.toJSON.call( this, meta );
  86. if ( this.saveTo ) data.saveTo = this.saveTo.toJSON( meta ).uuid;
  87. }
  88. return data;
  89. };
  90. export { RTTNode };