Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FilterQuality.high drawing output is pixelted on both canvas and overlay #2551

Closed
patolax opened this issue May 24, 2023 · 22 comments · Fixed by #2733
Closed

FilterQuality.high drawing output is pixelted on both canvas and overlay #2551

patolax opened this issue May 24, 2023 · 22 comments · Fixed by #2733
Labels
bug Flutter issue This problem is likely caused by the Flutter framework

Comments

@patolax
Copy link

patolax commented May 24, 2023

My code is below and the drawing output. The sprite size used is 512x512.
The game has no scaling and this is a simple 2D game.

As shown by the code we use size to scale the sprite size as required by the game and paint.filterQuality = FilterQuality.high; to improve output quality.

The image shows, what's drawn on canvas and an overlay dialog box.
As you can see lines and edges are super pixelated on both canvas and overlay. How can I improve this output?
(any vertical or horizontal line looks ok)

class Sprite extends SpriteComponent {

  Sprite(double size) {
    size = Vector2(size , size);
    init(piece);
  }

  
  void init() async {
    sprite = Sprite(await Flame.images.load('path');
    paint.filterQuality = FilterQuality.high;
  }
}

image

@patolax patolax added the bug label May 24, 2023
@spydon
Copy link
Member

spydon commented May 24, 2023

Is this on all platforms? Have you tried with a Flutter versions before 3.10.0?

@patolax
Copy link
Author

patolax commented May 24, 2023

I think I am using
environment:
sdk: '>=2.18.4 <3.0.0'
dependencies:
flame: ^1.6.0

@spydon
Copy link
Member

spydon commented May 24, 2023

What does flutter --version say?

@patolax
Copy link
Author

patolax commented May 24, 2023

What does flutter --version say?

Flutter 3.10.0 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 84a1e904f4 (2 weeks ago) • 2023-05-09 07:41:44 -0700
Engine • revision d44b5a94c9
Tools • Dart 3.0.0 • DevTools 2.23.1

As I said, if the image size is 100x100 output is perfect on both overlay and canvas. Anything above 200x200 gets distorted.

@patolax
Copy link
Author

patolax commented May 26, 2023

@spydon anything I can look at here? 100x00 is ok for now but the issue is on tablets this might not look nice.

@spydon
Copy link
Member

spydon commented May 26, 2023

Did you try with a flutter version before 3.10? So that we can rule out a regression from flutter?

@patolax
Copy link
Author

patolax commented May 29, 2023

@spydon

There is no difference in output fluter 3.0.0. 512x512 pixelates while 100x100 works.

image

Flutter 3.0.0 • channel stable • https://github.com/flutter/flutter.git
Framework • revision ee4e09cce0 (1 year, 1 month ago) • 2022-05-09 16:45:18 -0700
Engine • revision d1b9a6938a
Tools • Dart 2.17.0 • DevTools 2.12.2

@spydon
Copy link
Member

spydon commented May 29, 2023

And what size did you say that the image was?

@patolax
Copy link
Author

patolax commented May 29, 2023

100px x100px works. anything bigger ends up with this issue. e,g, was 512x512

@spydon
Copy link
Member

spydon commented May 29, 2023

I mean the source image, what size is that?

@spydon
Copy link
Member

spydon commented May 29, 2023

Ah that is the size for the source image, that's strange. Can you upload the images here?

@patolax
Copy link
Author

patolax commented May 29, 2023

100
king_black
512
king_black

@spydon
Copy link
Member

spydon commented May 29, 2023

And what size are you rendering it at? I would guess that you're scaling down the larger image in the SpriteComponent? Because the large image renders just fine in it's normal resolution for me.
Try to change the size of the Image object and then pass that to a Sprite object that you then pass to the SpriteComponent.

@patolax
Copy link
Author

patolax commented May 29, 2023

When I debug the size of the sprite is 46. Basically, think of it as fill screen width/8.
This is the test phone Resolution (Pixels)
1600 x 720.

My Code can be found at the top. Can you give me hints as to how to implement what you are saying?
(also I use an Image widget in the overlay dialog. That also renders poorly if the image is large). See the first post image for example.

@spydon
Copy link
Member

spydon commented May 29, 2023

There is an extension on Image in Flame where you can resize the image, so it would be something like this:

class ChessPiece extends SpriteComponent {
  final double sideLength;
  ChessPiece(this.sideLength) : super(size: Vector2.all(sideLength);

  @override
  Future<void> onLoad() async {
    final sourceImage = Flame.images.load('path');
    final image = sourceImage.resize(size);
    sprite = Sprite(image);
  }
}

if that doesn't work I would try to use a FixedResolutionViewport and have the source image size close to the size that it will render as.

@patolax
Copy link
Author

patolax commented May 29, 2023

image
That did not work, it even screwed up 100x100 image that worked.

I found this from Stackoverflow.

is this what you mean, how can I integrate this into my code?

 camera.viewport =
        FixedResolutionViewport(Vector2(side, maxSide), clip: false);

    final fieldSprite = await loadSprite('field_checkered.png');
    final field = SpriteComponent(
      sprite: fieldSprite,
      size: Vector2(side, maxSide),
    );

@spydon
Copy link
Member

spydon commented May 29, 2023

That is the old way of doing it, now you should use the CameraComponent instead, you can read more about how to set it up here:
https://docs.flame-engine.org/latest/flame/camera_component.html

@patolax
Copy link
Author

patolax commented May 30, 2023

This is my code with a camera. I reverted the image resizing logic you recommend earlier. I don't see any difference.

image

final camera = CameraComponent.withFixedResolution(
      world: _world,
      width: size.x,
      height: size.x,
    );
    camera.viewfinder.anchor = Anchor.topLeft;
    add(_world);
    add(camera);

@spydon
Copy link
Member

spydon commented May 30, 2023

Seems like this is a regression in Flutter then (or it's just particularly bad on your image), you could try the same thing in a CustomPainter to see if you get the same result in pure flutter.

@spydon
Copy link
Member

spydon commented Sep 11, 2023

@patolax did you ever try this in a custom painter? To see whether the issue is with Flutter or not.

@patolax
Copy link
Author

patolax commented Sep 12, 2023

FilterQulity.Medium is what's best apparently. This is a flutter issue. FilterQulity.Medium fixed it for me.

@spydon spydon added the Flutter issue This problem is likely caused by the Flutter framework label Sep 12, 2023
@spydon
Copy link
Member

spydon commented Sep 12, 2023

Oooh, thanks for the info! It even says so in the dartdocs.

spydon added a commit that referenced this issue Sep 12, 2023
According to the Flutter docs, tests and #2551 FilterQuality.high is actually producing worse output than FilterQuality.medium in almost all cases (the exception is when you use a very high scale factor).
This PRs set the places we have defined as high to medium instead.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Flutter issue This problem is likely caused by the Flutter framework
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants