Skip to content

fix!: Scale the subtree to the pixel ratio in rasterizeSubtree - #4162

Merged
ufrshubham merged 3 commits into
mainfrom
devkage/fix-rasterize-subtree-pixel-ratio
Oct 29, 2026
Merged

ufrshubham merged 3 commits into
mainfrom
devkage/fix-rasterize-subtree-pixel-ratio

Conversation

@ufrshubham

@ufrshubham ufrshubham commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

Description

PostProcess.rasterizeSubtree created an image of pixelRatio * size pixels, but recorded the subtree at logical size. On any screen with a device pixel ratio above 1, the subtree only filled the top-left corner of the image, so a shader sampling it with coordinates from 0 to 1 showed the subtree shrunk by the pixel ratio. This is the scaled down and deformed output reported in #3766.

rasterizeSubtree now scales the recording canvas by pixelRatio, so the subtree fills the whole image at full resolution.

Other changes:

  • The crystal ball example worked around the bug by dividing its texture coordinates by the pixel ratio in the ground shader. That workaround is removed.
  • The pixelRatio and rasterizeSubtree dartdocs and the post processing docs now say that the image covers the whole subtree.
  • New unit tests read back the rasterized pixels at pixel ratios 1, 1.5, 2 and 3.
  • New golden tests in flame check that drawing the rasterized subtree at the component size matches rendering the subtree directly.

Without the fix, all of the new tests above pixel ratio 1 fail.

Checklist

  • I have followed the Contributor Guide when preparing my PR.
  • I have updated/added tests for ALL new/updated/fixed functionality.
  • I have updated/added relevant documentation in docs and added dartdoc comments with ///.
  • I have updated/added relevant examples in examples or docs.

Breaking Change?

  • Yes, this PR is a breaking change.
  • No, this PR is not a breaking change.

Migration instructions

The image returned by PostProcess.rasterizeSubtree is the same size as before, but the subtree now fills all of it instead of only its top-left corner.

If your shader compensated for the old behavior, remove that workaround. For example, a shader that divided its texture coordinates by the pixel ratio should now sample with coordinates from 0 to 1 across the size of the post process:

// Before
vec4 color = texture(uTexture, uv / uPixelRatio);

// After
vec4 color = texture(uTexture, uv);

Shaders that already sampled with coordinates from 0 to 1 need no changes. They now render correctly on screens with a device pixel ratio above 1.

Related Issues

Closes #3766

`PostProcess.rasterizeSubtree` created an image of `pixelRatio * size` pixels
but recorded the subtree at logical size, so the subtree only filled the top
left corner of the image. Shaders sampling it with coordinates from 0 to 1
showed the subtree shrunk by the pixel ratio on high density screens.

The recording canvas is now scaled by the pixel ratio, so the subtree fills
the whole image. Shaders that worked around this by dividing the texture
coordinates by the pixel ratio, like the crystal ball ground shader, must drop
that workaround.

Fixes #3766
Comment thread examples/test/post_process/curved_screen_shader_test.dart Outdated
The flame package tests already cover the bug from #3766, so the examples don't need their own copy of the reporter's shader and image.
@ufrshubham
ufrshubham merged commit 50f0063 into main Oct 29, 2026
8 checks passed
@ufrshubham
ufrshubham deleted the devkage/fix-rasterize-subtree-pixel-ratio branch October 29, 2026 17:06
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.

Weird behavior with Flame Shaders compared to pure flutter shader

2 participants