Skip to content

fix(impeller): preserve SDF gradient shader coordinate precision - #195036

Closed
richyo-codes wants to merge 4 commits into
flutter:masterfrom
richyo-codes:fix/impeller-sdf-gradient-precision
Closed

richyo-codes wants to merge 4 commits into
flutter:masterfrom
richyo-codes:fix/impeller-sdf-gradient-precision

Conversation

@richyo-codes

@richyo-codes richyo-codes commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #195159.

Prevents Impeller’s SDF gradient shaders from abruptly switching to the final color when mediump calculations overflow.

Affected files

  • engine/src/flutter/impeller/compiler/shader_lib/impeller/gradient.glsl
  • engine/src/flutter/impeller/entity/shaders/uber_sdf_common.glsl

For a 400-pixel linear gradient on FP16 implementations, the dot product exceeds the maximum finite value of 65,504 before normalization. Radial distance calculations are also affected.

This keeps gradient coordinates, inverse lengths, linear/radial calculations, and the resulting gradient parameter at highp.

Testing

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance.

Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the gemini-code-assist bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

Keep gradient coordinates, inverse lengths, and shared linear/radial calculations at high precision. Mediump dot products can overflow on ordinary desktop-sized gradients and clamp abruptly to the final color.

(cherry picked from commit c4ce654512e94413dbb2880e9eb937ad70b03876)
@github-actions github-actions Bot added engine flutter/engine related. See also e: labels. e: impeller Impeller rendering backend issues and features requests labels Oct 22, 2026
Render horizontal, diagonal, and radial gradients through the SDF backend and check GPU pixel readback against analytic color samples. Cover coordinates whose intermediate dot products or lengths overflow mediump despite a normalized gradient parameter below one.

Validation: C++ formatting and diff checks; translation-unit compilation with branch headers. Executed against cached integration engine objects on Mesa llvmpipe: the corrected shaders pass, while replacing only the SDF shader sources with their pre-fix versions produces 16 failed color assertions. Metal execution and a fresh full branch build remain outstanding.
@richyo-codes richyo-codes changed the title fix(impeller): preserve SDF gradient coordinate precision fix(impeller): preserve SDF gradient shader coordinate precision Oct 23, 2026
@b-luk

b-luk commented Oct 29, 2026

Copy link
Copy Markdown
Contributor

@richyo-codes I think this PR is ready for review, but it's stuck in "draft" because you already have two other active PRs in the repo. Sorry about the active PR limit. It causes some road bumps for cases like this, and it's something that the people in charge of the review process are looking into as an area of improvement.

Do you mind if I create a fork of this PR so that we can have an "active" version to work on? It will still attribute you as a collaborator since your commit will be moved over.

@richyo-codes
richyo-codes marked this pull request as ready for review October 29, 2026 19:53
@richyo-codes

richyo-codes commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor Author

@richyo-codes I think this PR is ready for review, but it's stuck in "draft" because you already have two other active PRs in the repo. Sorry about the active PR limit. It causes some road bumps for cases like this, and it's something that the people in charge of the review process are looking into as an area of improvement.

Do you mind if I create a fork of this PR so that we can have an "active" version to work on? It will still attribute you as a collaborator since your commit will be moved over.

Hi @b-luk . I re-shuffled my PR's to allocate "Ready" to this one. So no fork should be required.
Thanks.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request updates the Impeller gradient shaders and common SDF shader code to use highp precision for gradient coordinates, lengths, and calculations, preventing overflow issues on medium precision. It also adds a comprehensive unit test, SDFGradientCoordinatePrecision, to verify correct rendering of large gradients. The review feedback suggests correcting a typo (positon to position) in gradient.glsl and removing an unused include (dl_dispatcher.h) in the unit test file.

Comment on lines +154 to 159
highp float IPComputeLinearGradientT(highp vec2 positon,
highp vec2 start,
highp vec2 delta,
highp float inv_gradient_length) {
return dot(positon - start, delta) * inv_gradient_length;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

There is a typo in the parameter name positon (should be position). Correcting this improves code readability and consistency with other parameter names in the shader library.

highp float IPComputeLinearGradientT(highp vec2 position,
                                     highp vec2 start,
                                     highp vec2 delta,
                                     highp float inv_gradient_length) {
  return dot(position - start, delta) * inv_gradient_length;
}
References
  1. Optimize for readability: Code is read more often than it is written. (link)

#include "flutter/testing/testing.h"
#include "impeller/core/device_buffer.h"
#include "impeller/core/device_buffer_descriptor.h"
#include "impeller/display_list/dl_dispatcher.h"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The include #include "impeller/display_list/dl_dispatcher.h" is not used in this test file. Removing unused includes keeps the codebase clean and adheres to the Google C++ Style Guide.

References
  1. C++ code should follow the Google C++ Style Guide, which discourages unused includes. (link)

@b-luk b-luk added the CICD Run CI/CD label Oct 29, 2026
@flutter-dashboard flutter-dashboard Bot removed the CICD Run CI/CD label Oct 30, 2026
@richyo-codes

Copy link
Copy Markdown
Contributor Author

There was a ci.yaml error, so I re-synced the branch. @b-luk will need to re-add CICD label

@b-luk b-luk added the CICD Run CI/CD label Oct 30, 2026
@richyo-codes

richyo-codes commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor Author
  • Change ubersdf to highp float precision #195703
    proposes changing default Uber SBF type from mediump to highp, which would also resolve this issue. However, I argue this PR is still valid as we isolated specific variables we know in fact need to be highp in order for gradients to work. This would ensure gradients remain functional if default precision ever reverted.

@b-luk

b-luk commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

@richyo-codes Thanks for the detailed analysis and the proposed fix. But I am closing this in favor of #195703. That fix consolidates the highp requirement in one place at the root of the SDF shader and covers other cases (circles, ovals, arcs) in addition to gradients, so it's preferable over this fix which only handles the gradient case and requires changes across multiple parameters and callers.

@b-luk b-luk closed this Nov 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD e: impeller Impeller rendering backend issues and features requests engine flutter/engine related. See also e: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Impeller SDF gradient shader overflows mediump precision resulting in abrupt color transition

2 participants