Skip to content

On impeller, the vertices API is off by 1 pixel when using fragment shaders and textureCoordinates #151355

@renancaraujo

Description

@renancaraujo

Steps to reproduce

Given any project, in the stable channel:

  • use draw vertices to paint some triangles using a Paint object as texture with a fragment shader.
  • if you specify textureCoordinates, the bottom and right edges will be off by 1 pixel.

Expected results

To have the proper pixels painted.

Actual results

Pixels painted are removed by 1 pixel in the left and bottom edges. See screenshots and code sample below.

Code sample

Code sample

For example, given that we are painting in a canvas region of size 100x100.
If we divide the canavs region by 4 quadrants and paint the following vertices:

// Two triangles covering the top left quadrant of the region
final vertices1 = Float32List.fromList([
  0.0, 0.0,
  50.0, 0.0,
  50.0, 50.0,
  0.0, 0.0,
  0.0, 50.0,
  50.0, 50.0,
]);

canvas.drawVertices(
  Vertices.raw(
    VertexMode.triangles,
    vertices1,
    textureCoordinates: Float32List.fromList(vertices1),
  ),
  BlendMode.srcOver,
  Paint()..shader = shader, // any fragment shader
);

// Two triangles covering the top right quadrant of the region
final vertices2 = Float32List.fromList([
  50.0, 0.0,
  100.0, 0.0,
  100.0, 50.0,
  50.0, 0.0,
  50.0, 50.0,
  100.0, 50.0,
]);

canvas.drawVertices(
  Vertices.raw(
    VertexMode.triangles,
    vertices2,
    textureCoordinates: Float32List.fromList(vertices2),
  ),
  BlendMode.srcOver,
  Paint()..shader = shader, // any fragment shader
);

// Two triangles covering the bottom left quadrant of the region
final vertices3 = Float32List.fromList([
  0.0, 50.0,
  50.0 50.0,
  50.0, 100.0,
  0.0, 50.0,
  0.0, 100.0,
  50.0, 100.0,
]);

canvas.drawVertices(
  Vertices.raw(
    VertexMode.triangles,
    vertices3,
    textureCoordinates: Float32List.fromList(vertices3),
  ),
  BlendMode.srcOver,
  Paint()..shader = shader, // any fragment shader
);

// Two triangles covering the bottom right quadrant of the region
final vertices4 = Float32List.fromList([
  50.0, 50.0,
  100.0, 50.0,
  100.0, 100.0,
  50.0, 50.0,
  50.0, 100.0,
  100.0, 100.0,
]);

canvas.drawVertices(
  Vertices.raw(
    VertexMode.triangles,
    vertices4,
    textureCoordinates: Float32List.fromList(vertices4),
  ),
  BlendMode.srcOver,
  Paint()..shader = shader, // any fragment shader
);

Reproducible sample

Ive created a reproducible sample here: https://github.com/renancaraujo/impeller_drawvertices_issue

Screenshots or Video

Screenshots / Video demonstration (impeller)

The gaps observed when running with impeller on macos with pixel ratio of 1:

Screenshot 2024-07-05 at 22 45 24

Screenshots / Video demonstration (skia)

The gap is not observed when running with skia in the same environment:
Screenshot 2024-07-05 at 22 45 52

Logs

Logs

Logs are irrelevant

Flutter Doctor output

Doctor output
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.22.2, on macOS 14.5 23F79 darwin-arm64,
    locale en-REDACTED)
[✓] Android toolchain - develop for Android devices (Android SDK version
    34.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 16.0)
[✓] Chrome - develop for the web
[✓] Android Studio (version REDACTED)
[✓] VS Code (version REDACTED)
[✓] Connected device (4 available)
[✓] Network resources

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions