godotengine / godot

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

Follow the default texture filter project setting in 2D shaders if no filtering hint is specified #57679

Open rakkarage opened 2 years ago

rakkarage commented 2 years ago

Godot version

v4.0.alpha1.official [31a7ddbf8]

System information

Windows 10

Issue description

Animation Shader

This shader which I am using to animate tiles makes them blurry in 4? Maybe not related to TileSet. Just where I noticed it. I changed the Project Settings -> Rendering -> Textures -> Default Texture Filter to get sharp pixel graphics maybe there is a way to make the shader use that setting too?

shader_type canvas_item;
render_mode unshaded;

uniform sampler2D frames: hint_albedo;
uniform float count;
uniform float duration;
uniform float width;
uniform float startX = 0;

void fragment() {
    float frame = floor(mod(TIME, count * duration) / duration);
    float offset = floor((UV.x - startX) / width);
    COLOR = texture(frames, UV + vec2((mod(offset + frame, count) - offset) * width, 0));
}

Thanks.

Steps to reproduce

  1. Open TileSetShader.tscn, blurry animations
  2. Open TileSetAnimation.tscn, clear animations

Minimal reproduction project

https://github.com/rakkarage/NewTileMapTest

Calinou commented 2 years ago

Since filter modes are no longer stored in the texture itself but in the usage, you need to add filter_nearest to your frames sampler as follows:

uniform sampler2D frames : filter_nearest, hint_albedo;

We should probably figure out a way to make shaders obey the default texture filter configured in 2D if no hint is provided. For 3D however, we don't have a default texture filter option yet.

jdellinger commented 5 months ago

How would you resolve this for the built-in TEXTURE inside the fragment() method in a canvas_item shader? I applied a shader to a tile in a tileset, but there is no way to override the filter for the built-in TEXTURE. Since I want to apply the shader to the tile, I'm not passing the texture as a uniform parameter.

I'm using Godot 4.2.2.stable. I have Project Settings -> Rendering -> Textures -> Default Texture Filter set to Nearest for sharp pixel art. In a TileSet the sprite sheet tiles are sharp as expected, but even just adding a new ShaderMaterial to a tile causes the tile to become blurry (even without adding a shader at all).

clayjohn commented 5 months ago

@jdellinger You can control the filter property of the built in TEXTURE using the texture_filter property on the node itself.

By default the filter setting is inherited from it's parent. But you can override the setting on a per-node basis:

image

jdellinger commented 5 months ago

@clayjohn Thanks.. That's what I assumed. However, that doesn't seem to be working correctly so I'm not sure if it is a bug or not. Even with that set to nearest, I still have the blurry texture issue. See attached screenshots. The tile is sharp initially with no shader material applied. As soon as I add a new shader material to the tile it becomes blurry as if it is using a linear filter. Adding an actual shader to the material doesn't change it either.

sharp_without_shader_material

blurry_with_new_shader_material

clayjohn commented 5 months ago

Hmm, that is definitely odd and likely warrants its own bug report. Could you make a new bug report and fill out all the information, including the MRP? I'd be happy to take a closer look.

@groud Is there something happening with the internal tilemap hierarchy here that might explain things here? To me it looks like the tile is losing the inheritance from the tilemap when a custom shader is used

groud commented 4 months ago

@groud Is there something happening with the internal tilemap hierarchy here that might explain things here? To me it looks like the tile is losing the inheritance from the tilemap when a custom shader is used

The way things are rendered in the atlas editor is unrelated to how TileMap works internally (I'm not using TileMaps to render the tiles there).

I'll have a look, but I suspect the dedicated canvas items used in the editor to draw the tiles might not be updated correctly.

groud commented 4 months ago

I've just checked, I cannot reproduce the issue on the latest master.

jdellinger commented 4 months ago

@groud I tried on 4.3.beta2 and could not reproduce either. Looks like it is not an issue in 4.3 so I'll just stay on the beta. Thanks!

arkology commented 1 month ago

Is this issue still valid?

clayjohn commented 1 month ago

Is this issue still valid?

Yes. The user is asking for the rendering/textures/canvas_textures/default_texture_repeat project setting to affect all samplers on canvas_item shaders which isn't what it does now. It is the default only for the built in TEXTURE of canvas items.

The other comments are about an unrelated issue that has been resolved.

arkology commented 1 month ago

@clayjohn Thanks for the answer! Please take a look again. The whole issue is only about filtering. But of course it will be also great to expand this issue for repeat.

clayjohn commented 1 month ago

Sorry, I just copy-pasted the wrong property! It is directly below filter

arkology commented 1 month ago

Related to https://github.com/godotengine/godot/issues/74332