How do I make my shader tile properly?

Godot Version

v4.5.stable.official [876b29033]

Question

I’m currently porting my hella old project from GD3 to GD4 and a lot of things broke in the process, including all the shaders. Here’s the screen transition shader code:

shader_type canvas_item;


uniform int tile_size = 16;
uniform float progress: hint_range(0.0, 1.0) = 0.5;

const vec2 rect_size = vec2(752.0, 272.0);


void fragment() {
	float num_lines = rect_size.x / float(tile_size);
	vec2 tiled_uv = vec2(fract(UV.x * num_lines / 2.0), UV.y);

	if (tiled_uv.x < 0.5) {
		if (tiled_uv.y < progress) {
			COLOR = COLOR;
		} else {
			discard;
		}
	} else {
		if (tiled_uv.y > 1.0 - progress) {
			COLOR = COLOR;
		} else {
			discard;
		}
	}
}

It uses a constant for the rect size because that was the biggest viewport size I could think of where the game window border could reasonably extend. But now that I’m testing it in my actual game viewport without borders, it obviously doesn’t look right.

It’s supposed to create 16px wide alternating stripes on each side of the screen, but those stripes in the image are definitely smaller than that. So my main question is, how do I make the shader tile properly regardless of the texture size? And my other question is, is there a way to rewrite the COLOR = COLOR bits as that seems kinda redundant?

You can use SCREEN_UV and SCREEN_PIXEL_SIZE

Uh, for what exactly? Also, wouldn’t that get messed up if the window scale is set to 2x, 3x etc?

For keeping the texture size constant in terms of screen pixels.

I’m a bit dumb and don’t understand what exactly I need to change. Does this mean I have to rewrite the entire shader because it just won’t work the way it is with only some minor change?

The shader is only few lines long. Rewriting it and changing it is practically the same thing :wink:

You can rewrite it so it doesn’t need rect_size uniform at all. You can calculate UVs to ensure your step constancy in screen pixels using those two built ins I mentioned.