godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
88.95k stars 20.17k forks source link

Blurred sprite after movement #66527

Open lorenzo-arena opened 1 year ago

lorenzo-arena commented 1 year ago

Godot version

4.0-beta1

System information

PopOS 22.04, Ryzen 3700U Vega 10 iGPU

Issue description

I'm trying to make a simple 2D pixel art movement; I have a sprite against a background and the sprite can be moved only sideways. Sometimes, but not always, after a movement when the pumpkin stops it gets blurred as in the picture (it's not moving there). Sometimes instead it is sharp and clear. Filter settings for the texture are good for pixel art, which gets rendered correctly.

blurred

Steps to reproduce

I used a CharacterBody2D with a sprite node as a children. The body has a script attached to it to move:

extends CharacterBody2D

var speed := 100

func _physics_process(delta):
    var left_right = -Input.get_action_strength("ui_left") + Input.get_action_strength("ui_right")  
    position.x += left_right * speed * delta

Minimal reproduction project

godot-66527-minimal.zip

Production edit: added the MRP to the description.

Zireael07 commented 1 year ago

Floating point imprecision, I guess?

Delta is a floating point value and so is get_action_strength. Does floor() (or ceil() or casting to int()) fix the issue? You could also try snapping to grid via the toolbar button.

Calinou commented 1 year ago

Related to https://github.com/godotengine/godot/issues/57221. This is a difficult problem to solve: https://github.com/godotengine/godot/issues/57221#issuecomment-1022917087

@lorenzo-arena Please upload a minimal reproduction project to make this easier to troubleshoot.

lorenzo-arena commented 1 year ago

Here is a simple project which reproduces the problem: godot-66527-minimal.zip

Floating point imprecision, I guess?

I also tried to see if rounding fixes the issue and in fact it does: using

position.x += round(left_right * speed * delta) as float

instead of

position.x += left_right * speed * delta

doesn't produce the issue anymore.

lorenzo-arena commented 1 year ago

Also using move_and_slide causes the issue

lorenzo-arena commented 1 year ago

@Calinou should this be solved (even when using move_and_slide) when setting both the snap options?

clayjohn commented 1 year ago

@Calinou should this be solved (even when using move_and_slide) when setting both the snap options?

IMO the snap options should eliminate this artifact entirely.

lorenzo-arena commented 1 year ago

To give a couple more informations on this.. In the reproduction project I use a structure like:

where the viewport has the pixel art canvas size set as the size (256x144). Stretch mode is set to viewport, and the output resolution is set to 1280x720.

In other projects if I try to set stretch mode to viewport, window size to something low res like 256x144 and then the test size to 1280x720 the blurriness don't happen. Why is this happening? Shouldn't the viewport behave in the same way?

Calinou commented 1 year ago

In other projects if I try to set stretch mode to viewport, window size to something low res like 256x144 and then the test size to 1280x720 the blurriness don't happen. Why is this happening? Shouldn't the viewport behave in the same way?

Using the viewport stretch mode on the root viewport uses nearest-neighbor filtering, while SubViewport will use bilinear filtering unless you override the option in the CanvasItem section of the SubViewport properties.

Also, the pixel snap options are set on a per-viewport basis. The project setting only affects the root viewport; you need to enable the pixel snap properties on the SubViewport if you wish it to behave the same way.

lorenzo-arena commented 1 year ago

Actually snapping on the right viewport seems to work, yes. I have to snap the position; vertex snapping doesn't seem to have any effect.

dewald-els commented 1 year ago

I'm not sure this is still relevant, but in Godot 4, switching the stretch mode to canvas_itemscompletely removed the blurry sprites while using move_and_slide.

lorenzo-arena commented 1 year ago

@dewald-els this is true but using canvas_items allows for subpixel positioning, which is incompatible with a real "pixel perfect" aspect

69ShadesOfPeanut commented 1 year ago

I'm now experiencing this issue and been searching for ages for a way to fix it