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

TEXTURE_PIXEL_SIZE incorrect when used in a tilemap #85044

Closed
securas opened this issue Nov 18, 2023 · 5 comments
Closed

TEXTURE_PIXEL_SIZE incorrect when used in a tilemap #85044

securas opened this issue Nov 18, 2023 · 5 comments

Comments

@securas
Copy link

securas commented Nov 18, 2023

Godot version

4.2 RC1

System information

Windows 10

Issue description

The same canvas item shader yields different results when used in a tilemap and in a sprite2D.
In the sprite 2D, the value of TEXTURE_PIXEL_SIZE is correct.
In tilemap, the value of TEXTURE_PIXEL_SIZE is somehow different.

I'm not sure if there is some design decision involved in this. But for the sake of consistency, TEXTURE_PIXEL_SIZE should be the same in all cases, as was in previous versions.

Steps to reproduce

I'm including an example project. There are 2 nodes: Sprite2D and a Tilemap with the same canvas material applied to both. The sprite2D has the expected behavior.

Minimal reproduction project

test_uv_tilemap.zip

@arkology
Copy link
Contributor

arkology commented Nov 18, 2023

This is expected, isn't it? You are using texture padding in tileset - it creates new texture with padding.

@securas
Copy link
Author

securas commented Nov 18, 2023

This is expected, isn't it? You are using texture padding in tileset - it creates new texture with padding.

I hope not. Not only breaks compatibility but prevents reusing shaders and provide ambiguity to the definitions. How did prior Godot versions work?

@arkology
Copy link
Contributor

I apologize if above comment was not clear.
This is expected. You are using Texture Padding in Tileset (which is set by default actually). Texture padding creates new internal texture with additional "borders" around every tile. Texture padding avoids a common artifact where lines appear between tiles (see https://docs.godotengine.org/en/latest/classes/class_tilesetatlassource.html#class-tilesetatlassource-property-use-texture-padding)
Shader uses this new created texture with additional "border" around tiles. So TEXTURE_PIXEL_SIZE is correct, shader do exactly what it should.
You should disable "Use texture padding" for Tileset atlas.
Godot_v4 2-rc1_win64_HsnAwr1hxM

@kleonc
Copy link
Member

kleonc commented Nov 18, 2023

As arkology already explained the shader works as expected and the "unexpected behavior" is indeed caused by the generated runtime texture with padding.

Original texture Padded runtime texture
Ng1OVvAdOE Godot_v4 2-rc1_win64_Xxsf56D9RP

Here's Counter3's script used for showing the runtime texture (shown in the table above):

@tool
extends Sprite2D

func _process(delta: float) -> void:
	var tm := $"../TileMap" as TileMap
	if tm == null: return

	var ts := tm.tile_set
	if ts == null: return

	var source := ts.get_source(0) as TileSetAtlasSource
	if source == null: return

	texture = source.get_runtime_texture()

Shader modified to take the padding into account works as expected:

shader_type canvas_item;

void fragment() {
	float frame = mod( floor( TIME ), 4.0 );
	vec2 uv = UV;
	uv.x += TEXTURE_PIXEL_SIZE.x * (8.0 + 2.0) * frame;
	COLOR = textureLod( TEXTURE, uv, 0.0 );
}

rchFnIJSX0


So that's not a bug, not sure if anything needs to be improved here. One possibility could be e.g. adding a warning when a TileMap has a ShaderMaterial assigned and texture padding is enabled, or something like that. 🤔 I'm against adding warnings all over the place though (assuming such warnings could not be turned off, like e.g. #69895; if specific node warnings could be turned off then I wouldn't mind some additional "info-warnings").

@securas
Copy link
Author

securas commented Nov 18, 2023

I apologize if above comment was not clear.
This is expected. You are using Texture Padding in Tileset (which is set by default actually). Texture padding creates new internal texture with additional "borders" around every tile. Texture padding avoids a common artifact where lines appear between tiles (see https://docs.godotengine.org/en/latest/classes/class_tilesetatlassource.html#class-tilesetatlassource-property-use-texture-padding)
Shader uses this new created texture with additional "border" around tiles. So TEXTURE_PIXEL_SIZE is correct, shader do exactly what it should.
You should disable "Use texture padding" for Tileset atlas.
Godot_v4 2-rc1_win64_HsnAwr1hxM

Thanks for the clarification. I wasn’t aware of this feature. I’m not a big fan of warnings as well but I would suggest changing the default behavior as the generated textures can get quite large. I guess that’s a issue to be discussed elsewhere.

once again, thanks for the explanations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants