1
- import { Color , Vector2 , PostProcessingUtils , NearestFilter , Matrix4 } from 'three' ;
1
+ import { Color , Vector2 , PostProcessingUtils , NearestFilter , Matrix4 , DepthTexture , RenderTarget , HalfFloatType } from 'three' ;
2
2
import { add , float , If , Loop , int , Fn , min , max , clamp , nodeObject , PassNode , QuadMesh , texture , NodeMaterial , uniform , uv , vec2 , vec4 , luminance } from 'three/tsl' ;
3
3
4
4
const _quadMesh = /*@__PURE__ */ new QuadMesh ( ) ;
@@ -34,20 +34,34 @@ class TRAAPassNode extends PassNode {
34
34
this . _jitterIndex = 0 ;
35
35
this . _originalProjectionMatrix = new Matrix4 ( ) ;
36
36
37
+ // render targets
38
+
39
+ this . _sampleRenderTarget = new RenderTarget ( 1 , 1 , { type : HalfFloatType } ) ;
40
+ this . _historyRenderTarget = new RenderTarget ( 1 , 1 , { type : HalfFloatType } ) ;
41
+ this . _resolveRenderTarget = new RenderTarget ( 1 , 1 , { type : HalfFloatType } ) ;
42
+
43
+ this . _sampleRenderTarget . depthTexture = new DepthTexture ( ) ;
44
+ this . _sampleRenderTarget . texture . minFiler = NearestFilter ;
45
+ this . _sampleRenderTarget . texture . magFilter = NearestFilter ;
46
+
37
47
// uniforms
38
48
39
49
this . _invSize = uniform ( new Vector2 ( ) ) ;
40
50
41
- // render targets
42
-
43
- this . _sampleRenderTarget = null ;
44
- this . _historyRenderTarget = null ;
51
+ this . _sampleTexture = texture ( this . _sampleRenderTarget . texture ) ;
52
+ this . _depthTexture = texture ( this . _sampleRenderTarget . depthTexture ) ;
53
+ this . _historyTexture = texture ( this . _historyRenderTarget . texture ) ;
54
+ this . _velocityTexture = this . getTextureNode ( 'velocity' ) ;
45
55
46
56
// materials
47
57
48
58
this . _resolveMaterial = new NodeMaterial ( ) ;
49
59
this . _resolveMaterial . name = 'TRAA.Resolve' ;
50
60
61
+ this . _prepassMaterial = new NodeMaterial ( ) ;
62
+ this . _prepassMaterial . name = 'TRAA.Override' ;
63
+ this . _prepassMaterial . colorNode = vec4 ( 0 , 0 , 0 , 1 ) ;
64
+
51
65
}
52
66
53
67
setSize ( width , height ) {
@@ -60,6 +74,7 @@ class TRAAPassNode extends PassNode {
60
74
61
75
this . _sampleRenderTarget . setSize ( this . renderTarget . width , this . renderTarget . height ) ;
62
76
this . _historyRenderTarget . setSize ( this . renderTarget . width , this . renderTarget . height ) ;
77
+ this . _resolveRenderTarget . setSize ( this . renderTarget . width , this . renderTarget . height ) ;
63
78
64
79
this . _invSize . value . set ( 1 / this . renderTarget . width , 1 / this . renderTarget . height ) ;
65
80
@@ -85,11 +100,33 @@ class TRAAPassNode extends PassNode {
85
100
86
101
const needsRestart = this . setSize ( size . width , size . height , renderer ) ;
87
102
88
- //
89
-
90
103
this . _cameraNear . value = camera . near ;
91
104
this . _cameraFar . value = camera . far ;
92
105
106
+ // prepass
107
+
108
+ const mrt = this . getMRT ( ) ;
109
+ const velocityOutput = mrt . get ( 'velocity' ) ;
110
+
111
+ if ( velocityOutput === undefined ) {
112
+
113
+ throw new Error ( 'THREE:TRAAPassNode: Missing velocity output in MRT configuration.' ) ;
114
+
115
+ }
116
+
117
+ renderer . setMRT ( mrt ) ;
118
+ scene . overrideMaterial = this . _prepassMaterial ;
119
+
120
+ renderer . setClearColor ( this . clearColor , this . clearAlpha ) ;
121
+ renderer . setRenderTarget ( this . renderTarget ) ;
122
+ renderer . clear ( ) ;
123
+ renderer . render ( scene , camera ) ;
124
+
125
+ scene . overrideMaterial = null ;
126
+ renderer . setMRT ( null ) ;
127
+
128
+ // configure jitter
129
+
93
130
const viewOffset = {
94
131
95
132
fullWidth : this . renderTarget . width ,
@@ -107,9 +144,6 @@ class TRAAPassNode extends PassNode {
107
144
108
145
const jitterOffset = _JitterVectors [ this . _jitterIndex ] ;
109
146
110
- camera . updateProjectionMatrix ( ) ;
111
- this . _originalProjectionMatrix . copy ( camera . projectionMatrix ) ;
112
-
113
147
camera . setViewOffset (
114
148
115
149
viewOffset . fullWidth , viewOffset . fullHeight ,
@@ -120,28 +154,13 @@ class TRAAPassNode extends PassNode {
120
154
121
155
) ;
122
156
123
- const mrt = this . getMRT ( ) ;
124
- const velocityOutput = mrt . get ( 'velocity' ) ;
125
-
126
- if ( velocityOutput !== undefined ) {
127
-
128
- velocityOutput . setProjectionMatrix ( this . _originalProjectionMatrix ) ;
129
-
130
- } else {
131
-
132
- throw new Error ( 'THREE:TRAAPassNode: Missing velocity output in MRT configuration.' ) ;
133
-
134
- }
135
-
136
- renderer . setMRT ( mrt ) ;
157
+ // render beauty with jitter
137
158
138
159
renderer . setClearColor ( this . clearColor , this . clearAlpha ) ;
139
160
renderer . setRenderTarget ( this . _sampleRenderTarget ) ;
140
161
renderer . clear ( ) ;
141
162
renderer . render ( scene , camera ) ;
142
163
143
- renderer . setMRT ( null ) ;
144
-
145
164
// every time when the dimensions change we need fresh history data. Copy the sample
146
165
// into the history and final render target (no AA happens at that point).
147
166
@@ -151,32 +170,29 @@ class TRAAPassNode extends PassNode {
151
170
// there are currently warnings in the browser console indicating the texture dimensions do not match during the copy.
152
171
// seems like some sort of timing issue
153
172
154
- renderer . setRenderTarget ( this . _historyRenderTarget ) ;
173
+ renderer . setRenderTarget ( this . _historyRenderTarget ) ; // no resolve
155
174
renderer . clear ( ) ;
156
175
176
+ // update history and output
177
+
157
178
renderer . copyTextureToTexture ( this . _sampleRenderTarget . texture , this . _historyRenderTarget . texture ) ;
158
179
renderer . copyTextureToTexture ( this . _sampleRenderTarget . texture , this . renderTarget . texture ) ;
159
180
160
- this . _firstFrame = false ;
161
-
162
181
} else {
163
182
164
183
// resolve
165
184
166
- renderer . setRenderTarget ( this . renderTarget ) ;
185
+ renderer . setRenderTarget ( this . _resolveRenderTarget ) ;
167
186
_quadMesh . material = this . _resolveMaterial ;
168
187
_quadMesh . render ( renderer ) ;
169
188
170
- // update history
189
+ // update history and output
171
190
172
- renderer . copyTextureToTexture ( this . renderTarget . texture , this . _historyRenderTarget . texture ) ;
191
+ renderer . copyTextureToTexture ( this . _resolveRenderTarget . texture , this . _historyRenderTarget . texture ) ;
192
+ renderer . copyTextureToTexture ( this . _resolveRenderTarget . texture , this . renderTarget . texture ) ;
173
193
174
194
}
175
195
176
- // copy depth
177
-
178
- renderer . copyTextureToTexture ( this . _sampleRenderTarget . depthTexture , this . renderTarget . depthTexture ) ;
179
-
180
196
// update jitter index
181
197
182
198
this . _jitterIndex ++ ;
@@ -202,37 +218,12 @@ class TRAAPassNode extends PassNode {
202
218
203
219
}
204
220
205
- velocityOutput . setProjectionMatrix ( null ) ;
206
-
207
221
PostProcessingUtils . restoreRendererAndSceneState ( renderer , scene , _rendererState ) ;
208
222
209
223
}
210
224
211
225
setup ( builder ) {
212
226
213
- if ( this . _sampleRenderTarget === null ) {
214
-
215
- this . _sampleRenderTarget = this . renderTarget . clone ( ) ;
216
- this . _historyRenderTarget = this . renderTarget . clone ( ) ;
217
-
218
- this . _sampleRenderTarget . texture . minFiler = NearestFilter ;
219
- this . _sampleRenderTarget . texture . magFilter = NearestFilter ;
220
-
221
- const velocityTarget = this . _sampleRenderTarget . texture . clone ( ) ;
222
- velocityTarget . isRenderTargetTexture = true ;
223
- velocityTarget . name = 'velocity' ;
224
-
225
- this . _sampleRenderTarget . textures . push ( velocityTarget ) ;
226
-
227
- }
228
-
229
- // textures
230
-
231
- const historyTexture = texture ( this . _historyRenderTarget . texture ) ;
232
- const sampleTexture = texture ( this . _sampleRenderTarget . textures [ 0 ] ) ;
233
- const velocityTexture = texture ( this . _sampleRenderTarget . textures [ 1 ] ) ;
234
- const depthTexture = texture ( this . _sampleRenderTarget . depthTexture ) ;
235
-
236
227
const resolve = Fn ( ( ) => {
237
228
238
229
const uvNode = uv ( ) ;
@@ -250,12 +241,12 @@ class TRAAPassNode extends PassNode {
250
241
Loop ( { start : int ( - 1 ) , end : int ( 1 ) , type : 'int' , condition : '<=' , name : 'y' } , ( { y } ) => {
251
242
252
243
const uvNeighbor = uvNode . add ( vec2 ( float ( x ) , float ( y ) ) . mul ( this . _invSize ) ) . toVar ( ) ;
253
- const colorNeighbor = max ( vec4 ( 0 ) , sampleTexture . uv ( uvNeighbor ) ) . toVar ( ) ; // use max() to avoid propagate garbage values
244
+ const colorNeighbor = max ( vec4 ( 0 ) , this . _sampleTexture . uv ( uvNeighbor ) ) . toVar ( ) ; // use max() to avoid propagate garbage values
254
245
255
246
minColor . assign ( min ( minColor , colorNeighbor ) ) ;
256
247
maxColor . assign ( max ( maxColor , colorNeighbor ) ) ;
257
248
258
- const currentDepth = depthTexture . uv ( uvNeighbor ) . r . toVar ( ) ;
249
+ const currentDepth = this . _depthTexture . uv ( uvNeighbor ) . r . toVar ( ) ;
259
250
260
251
// find the sample position of the closest depth in the neighborhood (used for velocity)
261
252
@@ -272,10 +263,10 @@ class TRAAPassNode extends PassNode {
272
263
273
264
// sampling/reprojection
274
265
275
- const offset = velocityTexture . uv ( closestDepthPixelPosition ) . xy . mul ( vec2 ( 0.5 , - 0.5 ) ) ; // NDC to uv offset
266
+ const offset = this . _velocityTexture . uv ( closestDepthPixelPosition ) . xy . mul ( vec2 ( 0.5 , - 0.5 ) ) ; // NDC to uv offset
276
267
277
- const currentColor = sampleTexture . uv ( uvNode ) ;
278
- const historyColor = historyTexture . uv ( uvNode . sub ( offset ) ) ;
268
+ const currentColor = this . _sampleTexture . uv ( uvNode ) ;
269
+ const historyColor = this . _historyTexture . uv ( uvNode . sub ( offset ) ) ;
279
270
280
271
// clamping
281
272
@@ -311,14 +302,12 @@ class TRAAPassNode extends PassNode {
311
302
312
303
super . dispose ( ) ;
313
304
314
- if ( this . _sampleRenderTarget !== null ) {
315
-
316
- this . _sampleRenderTarget . dispose ( ) ;
317
- this . _historyRenderTarget . dispose ( ) ;
318
-
319
- }
305
+ this . _sampleRenderTarget . dispose ( ) ;
306
+ this . _historyRenderTarget . dispose ( ) ;
307
+ this . _resolveRenderTarget . dispose ( ) ;
320
308
321
309
this . _resolveMaterial . dispose ( ) ;
310
+ this . _prepassMaterial . dispose ( ) ;
322
311
323
312
}
324
313
0 commit comments