Skip to content

FSR1Node: Add FSR 1 port for WebGPURenderer.#33339

Merged
Mugen87 merged 5 commits intomrdoob:devfrom
Mugen87:dev6
Apr 6, 2026
Merged

FSR1Node: Add FSR 1 port for WebGPURenderer.#33339
Mugen87 merged 5 commits intomrdoob:devfrom
Mugen87:dev6

Conversation

@Mugen87
Copy link
Copy Markdown
Collaborator

@Mugen87 Mugen87 commented Apr 6, 2026

Related issue: -

Description

The PR adds a TSL Port of FSR 1 for WebGPURenderer. I've experimented with Spatial Upscaler recently and I think it's good to have at least one upscaling option in three.js.

I've also tested a Bicubic upscaler but the differences to the default Bilinear are so minor that it makes more sense to use FSR 1. FSR 1 internally works with two passes, one that upscales and other one that sharpens the image. I've used the "Little Tokyo" asset in the new webgpu_upscaling_fsr1 demo since it has a variety of features that are good for comparison.

Vegetation

Bilinear (0.5x) FSR1 (0.5x) Full Native
Bildschirmfoto 2026-04-06 um 10 24 26 Bildschirmfoto 2026-04-06 um 10 23 06 Bildschirmfoto 2026-04-06 um 10 24 51

Text

Bilinear (0.5x) FSR1 (0.5x) Full Native
Bildschirmfoto 2026-04-06 um 10 27 01 Bildschirmfoto 2026-04-06 um 10 27 54 Bildschirmfoto 2026-04-06 um 10 28 20

Details

Bilinear (0.5x) FSR1 (0.5x) Full Native
Bildschirmfoto 2026-04-06 um 10 29 34 Bildschirmfoto 2026-04-06 um 10 29 50 Bildschirmfoto 2026-04-06 um 10 30 03

You can see that FSR 1 produce a better result that Bilinear although it is not comparable with an image rendered in full native resolution which is as expected though. But because of it's easy setup and it's good results, I think FSR 1 is still a worthwhile addition.

That said, one should keep in mind that FSR 1 has it's own overhead and not every scene will benefit from it. Many three.js scenes are so simple that they will be rendered faster in full native resolution instead of e.g. half resolution and upscale with FSR 1. Only use FSR 1 if the app is actually fragment shader bound and lowering the internal resolution brings you back to your target framerate.

Compared to the original FSR 1 source of AMD, the port has not the same performance level in the shader because a) we don't make any use of textureGather() (not available in WebGL 2) and b) we can't make use of packed math (e.g. two 16-bit ops in parallel) which would significantly lower arithmetic costs. This is a general restriction of the web platform though. Besides, a render pass is in general more expensive in the web than compared to native apps. Since FSR 1 requires two passes, the related overhead is more noticeable than in native environments.

Live Link

https://rawcdn.githack.com/Mugen87/three.js/9ce5a585f373cfbe2bd55f009c539f480b45fbe3/examples/webgpu_upscaling_fsr1.html

@Mugen87 Mugen87 added this to the r184 milestone Apr 6, 2026
@Mugen87 Mugen87 merged commit b75d0c3 into mrdoob:dev Apr 6, 2026
9 checks passed
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.

1 participant