Преглед изворни кода

TSL: Fix performance of `viewportTexture()` (#31591)

* fix cache and reference

* fix shared frame buffer

* TexturesNode: Introduce `getBase()`

* Update ViewportTextureNode.js
sunag пре 9 месеци
родитељ
комит
62623db5dd

+ 18 - 8
src/nodes/accessors/TextureNode.js

@@ -548,7 +548,7 @@ class TextureNode extends UniformNode {
 
 		const textureNode = this.clone();
 		textureNode.uvNode = nodeObject( uvNode );
-		textureNode.referenceNode = this.getSelf();
+		textureNode.referenceNode = this.getBase();
 
 		return nodeObject( textureNode );
 
@@ -576,7 +576,7 @@ class TextureNode extends UniformNode {
 
 		const textureNode = this.clone();
 		textureNode.biasNode = nodeObject( amountNode ).mul( maxMipLevel( textureNode ) );
-		textureNode.referenceNode = this.getSelf();
+		textureNode.referenceNode = this.getBase();
 
 		const map = textureNode.value;
 
@@ -602,7 +602,7 @@ class TextureNode extends UniformNode {
 
 		const textureNode = this.clone();
 		textureNode.levelNode = nodeObject( levelNode );
-		textureNode.referenceNode = this.getSelf();
+		textureNode.referenceNode = this.getBase();
 
 		return nodeObject( textureNode );
 
@@ -630,12 +630,22 @@ class TextureNode extends UniformNode {
 
 		const textureNode = this.clone();
 		textureNode.biasNode = nodeObject( biasNode );
-		textureNode.referenceNode = this.getSelf();
+		textureNode.referenceNode = this.getBase();
 
 		return nodeObject( textureNode );
 
 	}
 
+	/**
+	 * Returns the base texture of this node.
+	 * @return {TextureNode} The base texture node.
+	 */
+	getBase() {
+
+		return this.referenceNode ? this.referenceNode.getBase() : this.getSelf();
+
+	}
+
 	/**
 	 * Samples the texture by executing a compare operation.
 	 *
@@ -646,7 +656,7 @@ class TextureNode extends UniformNode {
 
 		const textureNode = this.clone();
 		textureNode.compareNode = nodeObject( compareNode );
-		textureNode.referenceNode = this.getSelf();
+		textureNode.referenceNode = this.getBase();
 
 		return nodeObject( textureNode );
 
@@ -663,7 +673,7 @@ class TextureNode extends UniformNode {
 
 		const textureNode = this.clone();
 		textureNode.gradNode = [ nodeObject( gradNodeX ), nodeObject( gradNodeY ) ];
-		textureNode.referenceNode = this.getSelf();
+		textureNode.referenceNode = this.getBase();
 
 		return nodeObject( textureNode );
 
@@ -679,7 +689,7 @@ class TextureNode extends UniformNode {
 
 		const textureNode = this.clone();
 		textureNode.depthNode = nodeObject( depthNode );
-		textureNode.referenceNode = this.getSelf();
+		textureNode.referenceNode = this.getBase();
 
 		return nodeObject( textureNode );
 
@@ -779,7 +789,7 @@ export const texture = ( value = EmptyTexture, uvNode = null, levelNode = null,
 	if ( value && value.isTextureNode === true ) {
 
 		textureNode = nodeObject( value.clone() );
-		textureNode.referenceNode = value.getSelf(); // Ensure the reference is set to the original node
+		textureNode.referenceNode = value.getBase(); // Ensure the reference is set to the original node
 
 		if ( uvNode !== null ) textureNode.uvNode = nodeObject( uvNode );
 		if ( levelNode !== null ) textureNode.levelNode = nodeObject( levelNode );

+ 6 - 0
src/nodes/display/ViewportSharedTextureNode.js

@@ -39,6 +39,12 @@ class ViewportSharedTextureNode extends ViewportTextureNode {
 
 	}
 
+	getFrameBufferTexture() {
+
+		return _sharedFramebuffer;
+
+	}
+
 	updateReference() {
 
 		return this;

+ 31 - 10
src/nodes/display/ViewportTextureNode.js

@@ -80,13 +80,13 @@ class ViewportTextureNode extends TextureNode {
 		this.isOutputTextureNode = true;
 
 		/**
-		 * The `updateBeforeType` is set to `NodeUpdateType.RENDER` since the node renders the
-		 * scene once per render in its {@link ViewportTextureNode#updateBefore} method.
+		 * The `updateBeforeType` is set to `NodeUpdateType.FRAME` since the node renders the
+		 * scene once per frame in its {@link ViewportTextureNode#updateBefore} method.
 		 *
 		 * @type {string}
 		 * @default 'frame'
 		 */
-		this.updateBeforeType = NodeUpdateType.RENDER;
+		this.updateBeforeType = NodeUpdateType.FRAME;
 
 		/**
 		 * The framebuffer texture for the current renderer context.
@@ -94,13 +94,26 @@ class ViewportTextureNode extends TextureNode {
 		 * @type {WeakMap<RenderTarget, FramebufferTexture>}
 		 * @private
 		 */
-		this._textures = new WeakMap();
+		this._cacheTextures = new WeakMap();
 
 	}
 
 	getFrameBufferTexture( reference = null ) {
 
-		const defaultFramebuffer = this.referenceNode ? this.referenceNode.defaultFramebuffer : this.defaultFramebuffer;
+		let defaultFramebuffer;
+		let cacheTextures;
+
+		if ( this.referenceNode ) {
+
+			defaultFramebuffer = this.referenceNode.defaultFramebuffer;
+			cacheTextures = this.referenceNode._cacheTextures;
+
+		} else {
+
+			defaultFramebuffer = this.defaultFramebuffer;
+			cacheTextures = this._cacheTextures;
+
+		}
 
 		if ( reference === null ) {
 
@@ -108,15 +121,25 @@ class ViewportTextureNode extends TextureNode {
 
 		}
 
-		if ( this._textures.has( reference ) === false ) {
+		if ( cacheTextures.has( reference ) === false ) {
 
 			const framebufferTexture = defaultFramebuffer.clone();
 
-			this._textures.set( reference, framebufferTexture );
+			cacheTextures.set( reference, framebufferTexture );
 
 		}
 
-		return this._textures.get( reference );
+		return cacheTextures.get( reference );
+
+	}
+
+	updateReference( frame ) {
+
+		const renderTarget = frame.renderer.getRenderTarget();
+
+		this.value = this.getFrameBufferTexture( renderTarget );
+
+		return this.value;
 
 	}
 
@@ -156,8 +179,6 @@ class ViewportTextureNode extends TextureNode {
 
 		framebufferTexture.generateMipmaps = currentGenerateMipmaps;
 
-		this.value = framebufferTexture;
-
 	}
 
 	clone() {

粤ICP备19079148号