| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 | import {	Mesh,	OrthographicCamera,	PlaneGeometry,	Scene,	WebGLRenderTarget} from '../../../../build/three.module.js';import { NodeBuilder } from '../core/NodeBuilder.js';import { NodeMaterial } from '../materials/NodeMaterial.js';import { TextureNode } from './TextureNode.js';class RTTNode extends TextureNode {	constructor( width, height, input, options = {} ) {		const renderTarget = new WebGLRenderTarget( width, height, options );		super( renderTarget.texture );		this.input = input;		this.clear = options.clear !== undefined ? options.clear : true;		this.renderTarget = renderTarget;		this.material = new NodeMaterial();		this.camera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );		this.scene = new Scene();		this.quad = new Mesh( new PlaneGeometry( 2, 2 ), this.material );		this.quad.frustumCulled = false; // Avoid getting clipped		this.scene.add( this.quad );		this.render = true;	}	build( builder, output, uuid ) {		const rttBuilder = new NodeBuilder();		rttBuilder.nodes = builder.nodes;		rttBuilder.updaters = builder.updaters;		this.material.fragment.value = this.input;		this.material.build( { builder: rttBuilder } );		return super.build( builder, output, uuid );	}	updateFramesaveTo( frame ) {		this.saveTo.render = false;		if ( this.saveTo !== this.saveToCurrent ) {			if ( this.saveToMaterial ) this.saveToMaterial.dispose();			const material = new NodeMaterial();			material.fragment.value = this;			material.build();			const scene = new Scene();			const quad = new Mesh( new PlaneGeometry( 2, 2 ), material );			quad.frustumCulled = false; // Avoid getting clipped			scene.add( quad );			this.saveToScene = scene;			this.saveToMaterial = material;		}		this.saveToCurrent = this.saveTo;		frame.renderer.setRenderTarget( this.saveTo.renderTarget );		if ( this.saveTo.clear ) frame.renderer.clear();		frame.renderer.render( this.saveToScene, this.camera );	}	updateFrame( frame ) {		if ( frame.renderer ) {			// from the second frame			if ( this.saveTo && this.saveTo.render === false ) {				this.updateFramesaveTo( frame );			}			if ( this.render ) {				if ( this.material.uniforms.renderTexture ) {					this.material.uniforms.renderTexture.value = frame.renderTexture;				}				frame.renderer.setRenderTarget( this.renderTarget );				if ( this.clear ) frame.renderer.clear();				frame.renderer.render( this.scene, this.camera );			}			// first frame			if ( this.saveTo && this.saveTo.render === true ) {				this.updateFramesaveTo( frame );			}		} else {			console.warn( 'RTTNode need a renderer in NodeFrame' );		}	}	copy( source ) {		super.copy( source );		this.saveTo = source.saveTo;		return this;	}	toJSON( meta ) {		let data = this.getJSONNode( meta );		if ( ! data ) {			data = super.toJSON( meta );			if ( this.saveTo ) data.saveTo = this.saveTo.toJSON( meta ).uuid;		}		return data;	}}RTTNode.prototype.nodeType = 'RTT';export { RTTNode };
 |