Shader - How can I get current position of pixel, local to the texture

Godot Version



I want to hide part of my sprite, based on an input, from left to right. It’s an xp bar.

This would work perfectly normally:

shader_type canvas_item;
uniform float percentFilled = 1;
void fragment() {
	if (UV[0] < percentFilled ) {COLOR = texture(TEXTURE, UV);}
	else {COLOR = vec4(0.0,0.0,0.0,0.0);}

But my bar isn’t just a static sprite, it’s a 9patchrect, which means the UVs are being manipulated to draw it, so I can’t use the position of the UVs, since they don’t map 1:1 with the position I want.

Is there any way to get the position of the current pixel on my 9patchrect other than UV?

you can use a varying to get local pixel coordinates from the vertex shader to the fragment shader. But you’ll need to keep track of the width in pixels of the progress bar and update the uniform so it knows how far a pixel is percent-wise.

Also here’s how to do the same thing without if/else

shader_type canvas_item;

varying float progress_vert;
uniform float percent = 0.8;
uniform float width = 40.;

void vertex() {
	progress_vert = VERTEX.x / width;

void fragment() {
	// if (progress_vert < percent ) {COLOR = texture(TEXTURE, UV);}
	// else {COLOR = vec4(0.0);}
	// Branchless
	vec4 tex_read = texture(TEXTURE, UV);
	tex_read.a = 1. - step(percent, progress_vert);
	COLOR = tex_read;
	// for a more general solution to switch between 2 colors:
	// COLOR = mix(vec4(0.), tex_read, 1. - step(percent, progress_vert));

Should also be able to floor VERTEX.x in the vertex shader to get whole pixel values, assuming the local coordinate space pixels = texture pixel size