Skip to content

Fixes framebuffer caching with multiple references of different sizes#32690

Merged
sunag merged 4 commits into
mrdoob:devfrom
io-gui:fixes/sharedDepthTexture
Mar 2, 2026
Merged

Fixes framebuffer caching with multiple references of different sizes#32690
sunag merged 4 commits into
mrdoob:devfrom
io-gui:fixes/sharedDepthTexture

Conversation

@arodic

@arodic arodic commented Jan 8, 2026

Copy link
Copy Markdown
Contributor

#Change summary

The Root Cause of #32689

  • ViewportDepthTextureNode: Uses a singleton _sharedDepthbuffer that is shared across all RenderTargets/CanvasTargets. This causes brute-force destruction and re-creation of depth buffer per reference on every rendered frame if references are not exactly the same size. This affects both CanvasTarget and RenderTarget

  • ViewporTextureNode Does not consider CanvasTarget as a reference. It simply does not do caching for CanvasTargets

  • Renderer: Uses a single _frameBufferTarget that resizes for each canvas (if not exactly the same size), triggering
    depthTexture.needsUpdate = true and causing texture recreation

The Fix for #32689

  • ViewportDepthTextureNode removed getTextureForReference() override to allow texture caching. Now it caches depth textures per reference

  • ViewportTextureNode Added check for CanvasTarget. Previous implementation considered RenderTargets only.

  • Renderer Changed _frameBufferTarget to _frameBufferTargets (Map<CanvasTarget, RenderTarget>). Each canvas target now gets its own framebuffer target instead of sharing one

This allows multi-canvas rendering with different sizes and tone mapping enabled without constant texture buffer recreation.

@arodic arodic force-pushed the fixes/sharedDepthTexture branch 2 times, most recently from 65169bc to 17ae2b6 Compare January 8, 2026 23:47
@github-actions

github-actions Bot commented Jan 8, 2026

Copy link
Copy Markdown

📦 Bundle size

Full ESM build, minified and gzipped.

Before After Diff
WebGL 357.49
84.84
357.49
84.84
+0 B
+0 B
WebGPU 621.89
172.77
622.07
172.79
+176 B
+21 B
WebGPU Nodes 620.49
172.53
620.67
172.55
+176 B
+18 B

🌳 Bundle size after tree-shaking

Minimal build including a renderer, camera, empty scene, and dependencies.

Before After Diff
WebGL 490.27
119.86
490.27
119.86
+0 B
+0 B
WebGPU 692.79
188.01
692.97
188.03
+176 B
+21 B
WebGPU Nodes 642.17
175.11
642.35
175.13
+176 B
+23 B

@arodic arodic force-pushed the fixes/sharedDepthTexture branch from 17ae2b6 to 0f44cd5 Compare January 8, 2026 23:49
@arodic arodic marked this pull request as ready for review January 9, 2026 00:09
@arodic arodic changed the title Fixes/shared depth texture Fixes framebuffer caching with multiple RenderTargets/CanvasTargets Jan 9, 2026
@arodic arodic force-pushed the fixes/sharedDepthTexture branch 2 times, most recently from 538f416 to a5ceff2 Compare January 9, 2026 00:30
Comment thread src/nodes/display/ViewportTextureNode.js Outdated
@arodic arodic force-pushed the fixes/sharedDepthTexture branch 2 times, most recently from 23d839d to c7dd472 Compare January 9, 2026 01:32
@arodic arodic force-pushed the fixes/sharedDepthTexture branch 3 times, most recently from c2b2888 to 2806820 Compare January 9, 2026 07:56
@arodic

arodic commented Jan 9, 2026

Copy link
Copy Markdown
Contributor Author

I cleaned up all the slop. This should be minimal and pretty clean implementation fixing the bug. Ready for review!

@arodic arodic changed the title Fixes framebuffer caching with multiple RenderTargets/CanvasTargets Fixes framebuffer caching with multiple references of different sizes Jan 9, 2026
Comment thread src/nodes/display/ViewportTextureNode.js Outdated
@arodic arodic force-pushed the fixes/sharedDepthTexture branch from 2806820 to addc6ce Compare January 25, 2026 01:01
@arodic arodic force-pushed the fixes/sharedDepthTexture branch from addc6ce to b25bbd4 Compare January 25, 2026 01:23
@arodic

arodic commented Feb 2, 2026

Copy link
Copy Markdown
Contributor Author

I also added tests (generated by Opus 4.5) ViewportDepthTextureNode.tests.js‎

Let me know if this is needed. From what I can tell, it tests for the correct edge case.

@sunag sunag added this to the r183 milestone Feb 4, 2026
@@ -1312,7 +1311,7 @@ class Renderer {

frameBufferTarget.isPostProcessingRenderTarget = true;

this._frameBufferTarget = frameBufferTarget;
this._frameBufferTargets.set( canvasTarget, frameBufferTarget );

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add an individual dispose event for each CanvasTarget?

@sunag sunag merged commit 91117d0 into mrdoob:dev Mar 2, 2026
10 checks passed
@Mugen87

Mugen87 commented Mar 18, 2026

Copy link
Copy Markdown
Collaborator

While working on some viewport/scissor related logic, I have found out this PR broke webgpu_multiple_canvas. You see the same mesh everywhere instead of different ones like in prod:

https://threejs.org/examples/webgpu_multiple_canvas

Right before this PR, dev was fine.

@arodic

arodic commented Mar 18, 2026

Copy link
Copy Markdown
Contributor Author

@Mugen87 interesting. Ili take a look. Curious why screenshot tests didn’t pick this up?

@Mugen87

Mugen87 commented Mar 18, 2026

Copy link
Copy Markdown
Collaborator

webgpu_multiple_canvas is on the exception list because it's a WebGPU only demo and the CI relies on WebGL 2 (it does not support WebGPU yet).

@arodic

arodic commented Mar 18, 2026

Copy link
Copy Markdown
Contributor Author

@Mugen87 I drafted two PRs #33209 and #33210

Personally I'm leaning towards the latter. Lmk wdyt?

@Mugen87

Mugen87 commented Mar 18, 2026

Copy link
Copy Markdown
Collaborator

I would prefer if @sunag decides for a solution here 😇 . He knows this part of the library best.

@sunag

sunag commented Mar 25, 2026

Copy link
Copy Markdown
Collaborator

@arodic Thanks for the PRs, I implemented a solution similar to yours but caching the Quads; the problem with caching the nodes after all the changes was the need to revalidate the shader, which made it a bit less efficient.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants