Skip to content

Commit 42048f8

Browse files
authored
TSL: Add MRT support for traaPass() (#31361)
* TRAAPassNode: Add support for MRT * add `getIndexes()` * cleanup
1 parent d334468 commit 42048f8

File tree

2 files changed

+78
-20
lines changed

2 files changed

+78
-20
lines changed

examples/jsm/tsl/display/TRAAPassNode.js

Lines changed: 51 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Color, Vector2, NearestFilter, Matrix4, RendererUtils, PassNode, QuadMesh, NodeMaterial } from 'three/webgpu';
2-
import { add, float, If, Loop, int, Fn, min, max, clamp, nodeObject, texture, uniform, uv, vec2, vec4, luminance } from 'three/tsl';
2+
import { add, float, If, Loop, int, Fn, min, max, clamp, nodeObject, texture, uniform, uv, vec2, vec4, luminance, output, mrt, textureLoad, screenCoordinate } from 'three/tsl';
33

44
const _quadMesh = /*@__PURE__*/ new QuadMesh();
55
const _size = /*@__PURE__*/ new Vector2();
@@ -105,6 +105,15 @@ class TRAAPassNode extends PassNode {
105105
*/
106106
this._historyRenderTarget = null;
107107

108+
/**
109+
* The MRT for the transfer step.
110+
*
111+
* @private
112+
* @type {?MRTNode}
113+
* @default null
114+
*/
115+
this._transferMRT = null;
116+
108117
/**
109118
* Material used for the resolve step.
110119
*
@@ -204,29 +213,21 @@ class TRAAPassNode extends PassNode {
204213

205214
// configure velocity
206215

207-
const mrt = this.getMRT();
208-
const velocityOutput = mrt.get( 'velocity' );
209-
210-
if ( velocityOutput !== undefined ) {
216+
const currentMRT = this.getMRT();
217+
const velocityOutput = currentMRT.get( 'velocity' );
211218

212-
velocityOutput.setProjectionMatrix( this._originalProjectionMatrix );
213-
214-
} else {
215-
216-
throw new Error( 'THREE:TRAAPassNode: Missing velocity output in MRT configuration.' );
217-
218-
}
219+
velocityOutput.setProjectionMatrix( this._originalProjectionMatrix );
219220

220221
// render sample
221222

222-
renderer.setMRT( mrt );
223+
renderer.setMRT( currentMRT );
223224

224225
renderer.setClearColor( this.clearColor, this.clearAlpha );
225226
renderer.setRenderTarget( this._sampleRenderTarget );
226227
renderer.render( scene, camera );
227228

228229
renderer.setRenderTarget( null );
229-
renderer.setMRT( null );
230+
renderer.setMRT( this._transferMRT );
230231

231232
// every time when the dimensions change we need fresh history data. Copy the sample
232233
// into the history and final render target (no AA happens at that point).
@@ -312,19 +313,49 @@ class TRAAPassNode extends PassNode {
312313
this._sampleRenderTarget.texture.minFiler = NearestFilter;
313314
this._sampleRenderTarget.texture.magFilter = NearestFilter;
314315

315-
const velocityTarget = this._sampleRenderTarget.texture.clone();
316-
velocityTarget.isRenderTargetTexture = true;
317-
velocityTarget.name = 'velocity';
316+
const currentMRT = this.getMRT();
317+
318+
if ( currentMRT === null ) {
319+
320+
throw new Error( 'THREE:TRAAPassNode: Missing MRT configuration.' );
318321

319-
this._sampleRenderTarget.textures.push( velocityTarget ); // for MRT
322+
} else if ( currentMRT.has( 'velocity' ) === false ) {
323+
324+
throw new Error( 'THREE:TRAAPassNode: Missing velocity output in MRT configuration.' );
325+
326+
}
327+
328+
this._texturesIndex = currentMRT.getIndexes( this.renderTarget );
329+
330+
const transferNodes = {};
331+
332+
for ( const name in this._texturesIndex ) {
333+
334+
if ( name === 'output' ) {
335+
336+
transferNodes[ name ] = output;
337+
338+
} else {
339+
340+
const index = this._texturesIndex[ name ];
341+
342+
transferNodes[ name ] = textureLoad( this._sampleRenderTarget.textures[ index ], screenCoordinate );
343+
344+
}
345+
346+
}
347+
348+
this._transferMRT = mrt( transferNodes );
320349

321350
}
322351

323352
// textures
324353

354+
const velocityIndex = this._texturesIndex[ 'velocity' ];
355+
325356
const historyTexture = texture( this._historyRenderTarget.texture );
326357
const sampleTexture = texture( this._sampleRenderTarget.textures[ 0 ] );
327-
const velocityTexture = texture( this._sampleRenderTarget.textures[ 1 ] );
358+
const velocityTexture = texture( this._sampleRenderTarget.textures[ velocityIndex ] );
328359
const depthTexture = texture( this._sampleRenderTarget.depthTexture );
329360

330361
const resolve = Fn( () => {
@@ -395,7 +426,7 @@ class TRAAPassNode extends PassNode {
395426

396427
// materials
397428

398-
this._resolveMaterial.fragmentNode = resolve();
429+
this._resolveMaterial.colorNode = resolve();
399430

400431
return super.setup( builder );
401432

src/nodes/core/MRTNode.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,33 @@ class MRTNode extends OutputStructNode {
112112

113113
}
114114

115+
/**
116+
* Returns the indexes of the MRT outputs in the current render target.
117+
*
118+
* @param {RenderTarget} renderTarget - The render target to get the indexes for.
119+
* @return {Array<number>} The indexes of the MRT outputs.
120+
*/
121+
getIndexes( renderTarget ) {
122+
123+
const textures = renderTarget.textures;
124+
const indexLib = {};
125+
126+
for ( const name in this.outputNodes ) {
127+
128+
const index = getTextureIndex( textures, name );
129+
130+
if ( index !== - 1 ) {
131+
132+
indexLib[ name ] = index;
133+
134+
}
135+
136+
}
137+
138+
return indexLib;
139+
140+
}
141+
115142
setup( builder ) {
116143

117144
const outputNodes = this.outputNodes;

0 commit comments

Comments
 (0)