some optimizations for postprocessing in webxr
@mrdoob the postprocessing step wasn't using anti-aliasing. I fixed this by passing this antialias attribute to the rendertargets. The rendertargets were resolving depth which wasn't used. I turned that off.
I see that the code is rendering to a lot of rendertargets. Is that expected? In order I see:
Surface 0 | 3360x1760 | color 32bit, depth 24bit, stencil 0 bit, MSAA 4 -> clear from browser code
Surface 1 | 4096x4096 | color 32bit, depth 24bit, stencil 0 bit, MSAA 1 -> 4k x 4k shadowmap?
Surface 2 | 3360x1760 | color 64bit, depth 24bit, stencil 0 bit, MSAA 4
Surface 3 | 1680x880 | color 64bit, depth 24bit, stencil 0 bit, MSAA 4
Surface 4 | 1680x880 | color 64bit, depth 24bit, stencil 0 bit, MSAA 4
Surface 5 | 1680x880 | color 64bit, depth 24bit, stencil 0 bit, MSAA 4
Surface 6 | 840 x440 | color 64bit, depth 24bit, stencil 0 bit, MSAA 4
Surface 7 | 840 x440 | color 64bit, depth 24bit, stencil 0 bit, MSAA 4
Surface 8 | 420 x220 | color 64bit, depth 24bit, stencil 0 bit, MSAA 4
Surface 9 | 420 x220 | color 64bit, depth 24bit, stencil 0 bit, MSAA 4
Surface 10 | 210 x110 | color 64bit, depth 24bit, stencil 0 bit, MSAA 4
Surface 11 | 210 x110 | color 64bit, depth 24bit, stencil 0 bit, MSAA 4
Surface 12 | 105 x55 | color 64bit, depth 24bit, stencil 0 bit, MSAA 4
Surface 13 | 105 x55 | color 64bit, depth 24bit, stencil 0 bit, MSAA 4
Surface 14 | 1680x880 | color 64bit, depth 24bit, stencil 0 bit, MSAA 4
Surface 15 | 3360x1760 | color 64bit, depth 24bit, stencil 0 bit, MSAA 4 -> uses expensive loadcolor
Surface 16 | 3360x1760 | color 32bit, depth 24bit, stencil 0 bit, MSAA 4 -> final blit to destination
Are all these passes needed or can we combine some? Each pass will flush color data to the main memory. Surface 15 also loads it from main memory. Is that needed or is it the same as surface 2? (If you don't know, I can debug it)
This contribution is funded by Meta
📦 Bundle size
Full ESM build, minified and gzipped.
| Before | After | Diff | |
|---|---|---|---|
| WebGL | 355.12 84.44 |
355.16 84.45 |
+44 B +9 B |
| WebGPU | 616.35 171.06 |
616.35 171.06 |
+0 B +0 B |
| WebGPU Nodes | 614.96 170.8 |
614.96 170.8 |
+0 B +0 B |
🌳 Bundle size after tree-shaking
Minimal build including a renderer, camera, empty scene, and dependencies.
| Before | After | Diff | |
|---|---|---|---|
| WebGL | 487.46 119.37 |
487.5 119.38 |
+44 B +7 B |
| WebGPU | 687.26 186.66 |
687.26 186.66 |
+0 B +0 B |
| WebGPU Nodes | 637.11 173.88 |
637.11 173.88 |
+0 B +0 B |
the postprocessing step wasn't using anti-aliasing. I fixed this by passing this antialias attribute to the rendertargets.
It would be cleaner to do something like this:
render( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
if ( this._currentSamples !== readBuffer.samples ) {
this._currentSamples = readBuffer.samples;
this._updateRenderTargetSamples( readBuffer.samples );
}
// ...
}
But I'm not sure antialiasing is really needed for the bloom. Can you revert that change for now?
The resolveDepthBuffer: false change is good 👍
Are all these passes needed or can we combine some?
I think they're needed. That's how the algorithm works.
Surface 15 also loads it from main memory. Is that needed or is it the same as surface 2? (If you don't know, I can debug it)
I don't know actually, would be great if you can take a look 🙏
the postprocessing step wasn't using anti-aliasing. I fixed this by passing this antialias attribute to the rendertargets.
It would be cleaner to do something like this:
render( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) { if ( this._currentSamples !== readBuffer.samples ) { this._currentSamples = readBuffer.samples; this._updateRenderTargetSamples( readBuffer.samples ); } // ... }But I'm not sure antialiasing is really needed for the bloom. Can you revert that change for now?
Sure, but I think it should be added. The graphics looks very jaggy without it.
Surface 15 also loads it from main memory. Is that needed or is it the same as surface 2? (If you don't know, I can debug it)
I don't know actually, would be great if you can take a look 🙏
OK, I'll take a look.
But I'm not sure antialiasing is really needed for the bloom. Can you revert that change for now?
Sure, but I think it should be added. The graphics looks very jaggy without it.
I updated the code in https://github.com/cabanier/three.js/commit/1d66efc9ccfff396d75f9b77e4d7dfa075e81ff7 so MSAA is applied to the post processing passes. In a follow up commit I'll remove it
Surface 15 also loads it from main memory. Is that needed or is it the same as surface 2? (If you don't know, I can debug it)
I don't know actually, would be great if you can take a look 🙏
OK, I'll take a look.
I inspected the code and the passes are reading from the buffer that is then used to composite the final images. It seems that this is by design.
Hey Rik, I've tried to clean this up but I'm too confused... You tried to change too many things at once and I don't know what the side effects are. I was going to try to add this to r182 but I'm afraid I'll have to leave this for next release.
Hey Rik, I've tried to clean this up but I'm too confused... You tried to change too many things at once and I don't know what the side effects are. I was going to try to add this to r182 but I'm afraid I'll have to leave this for next release.
No worries. The changes to WebGLOutput.js were needed to avoid jaggies but we can add that later.
@mrdoob do you want me to add another PR for the MSAA? It seems this one will just discard depth.