godotengine / godot

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

Blurry PointLight2D texture in Gl_compatibility backend #90360

Open MrAnimatronic-Dev opened 3 months ago

MrAnimatronic-Dev commented 3 months ago

Tested versions

System information

Issue description

When using a PointLight2D in my test features project, in the moment when add the light texture, it appears blurry (the tree in the left of the next image) when i using GL_Compatibility backend and not pixel-perfect (like the Sprite2D tree in the right of the image), but when recreate the light in the mobile and forward+ backends, the light not looks blurry and look pixel-perfect exactly as it should appear.

image

Note: I have tested the same thing in Godot 3 LTS, and the light appears pixel-perfect in all available backends for that version.

Steps to reproduce

  1. Create a project in any version of Godot 4 (alpha, beta, RC, and stable).
  2. Create a 2D scene and add a dark background.
  3. Add a canvas modulate and set in the color property a dark color.
  4. Add a PointLight2D to the scene and assign a pixel art texture in the texture property.

Minimal reproduction project (MRP)

follow the previous steps.

clayjohn commented 3 months ago

It looks like the problem is that PointLight2Ds use the texture filter of the CanvasItem underneath them in the RD backends.

In Compatibility, the linear filter is always used.

So we need to update the light texture's filter and repeat mode when we update the filter and repeat mode of the main texture here: https://github.com/godotengine/godot/blob/dc91479082bd9cd56cd74282573492fe1ba9618a/drivers/gles3/rasterizer_canvas_gles3.cpp#L2262-L2263

MrAnimatronic-Dev commented 3 months ago

Additional information added:

this is the parameter that i use in project settings: image

yadongqu commented 3 months ago

For me though, the PointLight2D texture filter field seems to be ignored or overwritten for all backends. no matter what filter method I choose, It has no effect on both vulkan and opengl backends.

tested versions are 4.2.1 and 4.3 dev 5

tested machine: Windows 11 with intel 9900 with UHD 630 graphics.

alasher commented 2 months ago

Greetings all, I've been taking a look at this issue as a first-time contributor, but had some questions on how it should be fixed.

In the GLES backend, It appears that the texture of the light itself is loaded from a texture atlas that is shared by all lights. I verified that changing the filter mode of this texture atlas in texture_storage.cpp did change the filter mode of the light texture. But there's a problem: if we want each light's texture to have a separate filter setting (which the editor allows) then I believe we'd have to re-bind this texture with the new settings before each time we draw a light - but from my analysis in RenderDoc it appears it's drawing both lights at the same time? So it seems like this isn't an easy option, but please let me know if there's another way.

So if we assume we cannot change the texture filter mode for each light, then I think it's fair to assume we should simply configure the texture atlas to use the project default setting. I suppose we could add a function that allows us to configure the filter/blend mode of the texture atlas? Something like void teture_storage::texture_atlas_set_filter(RS::CanvasItemTextureFilter filter) seems like it'd work, which would be called at some point on setup presumably. But because this is my first issue I would love a quick sanity check to see if this sounds reasonable.

Thank you!

clayjohn commented 2 months ago

@alasher the filter and repeat modes for the light atlas should be updated before each draw call based on the filter and repeat modes for the CanvasItem being drawn.

We don't need each light to have a separate filter setting as the filter setting comes from the CanvasItem, not the light itself