Explorar el Código

TSL: `viewportTexture()` cache `FramebufferTexture` according to `RenderTarget` (#31343)

* FramebufferTexture cache according to RenderTarget

* cleanup

* revision
sunag hace 6 meses
padre
commit
287727dd37
Se han modificado 1 ficheros con 67 adiciones y 7 borrados
  1. 67 7
      src/nodes/display/ViewportTextureNode.js

+ 67 - 7
src/nodes/display/ViewportTextureNode.js

@@ -35,10 +35,18 @@ class ViewportTextureNode extends TextureNode {
 	 */
 	constructor( uvNode = screenUV, levelNode = null, framebufferTexture = null ) {
 
+		let defaultFramebuffer = null;
+
 		if ( framebufferTexture === null ) {
 
-			framebufferTexture = new FramebufferTexture();
-			framebufferTexture.minFilter = LinearMipmapLinearFilter;
+			defaultFramebuffer = new FramebufferTexture();
+			defaultFramebuffer.minFilter = LinearMipmapLinearFilter;
+
+			framebufferTexture = defaultFramebuffer;
+
+		} else {
+
+			defaultFramebuffer = framebufferTexture;
 
 		}
 
@@ -52,6 +60,16 @@ class ViewportTextureNode extends TextureNode {
 		 */
 		this.generateMipmaps = false;
 
+		/**
+		 * The reference framebuffer texture. This is used to store the framebuffer texture
+		 * for the current render target. If the render target changes, a new framebuffer texture
+		 * is created automatically.
+		 *
+		 * @type {FramebufferTexture}
+		 * @default null
+		 */
+		this.defaultFramebuffer = defaultFramebuffer;
+
 		/**
 		 * This flag can be used for type testing.
 		 *
@@ -62,24 +80,64 @@ class ViewportTextureNode extends TextureNode {
 		this.isOutputTextureNode = true;
 
 		/**
-		 * The `updateBeforeType` is set to `NodeUpdateType.FRAME` since the node renders the
-		 * scene once per frame in its {@link ViewportTextureNode#updateBefore} method.
+		 * The `updateBeforeType` is set to `NodeUpdateType.RENDER` since the node renders the
+		 * scene once per render in its {@link ViewportTextureNode#updateBefore} method.
 		 *
 		 * @type {string}
 		 * @default 'frame'
 		 */
-		this.updateBeforeType = NodeUpdateType.FRAME;
+		this.updateBeforeType = NodeUpdateType.RENDER;
+
+		/**
+		 * The framebuffer texture for the current renderer context.
+		 *
+		 * @type {WeakMap}
+		 * @private
+		 */
+		this._textures = new WeakMap();
+
+	}
+
+	getFrameBufferTexture( reference = null ) {
+
+		const defaultFramebuffer = this.referenceNode ? this.referenceNode.defaultFramebuffer : this.defaultFramebuffer;
+
+		if ( reference === null ) {
+
+			return defaultFramebuffer;
+
+		}
+
+		if ( this._textures.has( reference ) === false ) {
+
+			const framebufferTexture = defaultFramebuffer.clone();
+
+			this._textures.set( reference, framebufferTexture );
+
+		}
+
+		return this._textures.get( reference );
 
 	}
 
 	updateBefore( frame ) {
 
 		const renderer = frame.renderer;
-		renderer.getDrawingBufferSize( _size );
+		const renderTarget = renderer.getRenderTarget();
+
+		if ( renderTarget === null ) {
+
+			renderer.getDrawingBufferSize( _size );
+
+		} else {
+
+			_size.set( renderTarget.width, renderTarget.height );
+
+		}
 
 		//
 
-		const framebufferTexture = this.value;
+		const framebufferTexture = this.getFrameBufferTexture( renderTarget );
 
 		if ( framebufferTexture.image.width !== _size.width || framebufferTexture.image.height !== _size.height ) {
 
@@ -98,6 +156,8 @@ class ViewportTextureNode extends TextureNode {
 
 		framebufferTexture.generateMipmaps = currentGenerateMipmaps;
 
+		this.value = framebufferTexture;
+
 	}
 
 	clone() {

粤ICP备19079148号