I'm trying to create a shader which decides the silhouette of the sprite by giving a texture (sampler2D) as input in shader parameter and clips anything outside it's bound
And so far this is what I've been able to come up with:
shader_type canvas_item;
uniform sampler2D clip_texture;
void fragment(){
vec4 color = texture(clip_texture, UV);
if(color.a==0.0)
COLOR=vec4(0.0, 0.0, 0.0, 0.0);
else
COLOR=texture(TEXTURE, UV);
}
But this approach seems to squeeze the Clip Texture
to the sprite resolution
I'm guessing UV being between 0.0 - 1.0 for both has something to do with this
So how do I fix this ?
Edit: further explanation on what I'm trying to achieve
Assume an image placed on top of another image (The image being placed on top will be passed as shader parameter)
Now if we crop only the overlapping part:
Now ofc we should also be able to move the location of the image placed on top (maybe pass x-y shader parameters?) and get the same effect:
This is what I'm trying to achieve using shaders
The problem was that the 0.0 - 1.0 is the UV from icon.png
, so 1.0 maps the extents of the clip texture to 64x64, shrinking it.
shader_type canvas_item;
uniform sampler2D clip_texture;
uniform vec2 clip_texture_size;
void fragment(){
vec2 texture_size = 1.0 / TEXTURE_PIXEL_SIZE;
vec2 texture_ratio = texture_size / clip_texture_size;
vec2 clip_UV = UV * texture_ratio;
vec4 color = texture(clip_texture, clip_UV);
if(color.a==0.0)
COLOR=vec4(0.0, 0.0, 0.0, 0.0);
else
COLOR=texture(TEXTURE, UV);
}
For icon.png
, TEXTURE_PIXEL_SIZE
is equal to vec2(1.0/64.0, 1.0/64.0)
. The reciprocal of this is the texture size: 1.0 / TEXTURE_PIXEL_SIZE
. If you divide the texture size by the clip texture size, this gives the ratio between the texture and the clip texture.
You can determine the size of a texture with textureSize()
instead of using a uniform, but it is only available in GLES 3.
Here is a version with an offset uniform per your edit:
shader_type canvas_item;
uniform sampler2D clip_texture;
uniform vec2 clip_texture_size;
uniform vec2 clip_texture_offset;
void fragment(){
vec2 texture_size = (1.0 / TEXTURE_PIXEL_SIZE);
vec2 texture_ratio = texture_size / clip_texture_size;
vec2 clip_UV = UV * texture_ratio + clip_texture_offset;
vec4 color;
if (clip_UV.x > 1.0 || clip_UV.x < 0.0 || clip_UV.y > 1.0 || clip_UV.y < 0.0) {
color = vec4(0.0, 0.0, 0.0, 0.0)
}
else {
color = texture(clip_texture, clip_UV);
}
if(color.a==0.0)
COLOR=vec4(0.0, 0.0, 0.0, 0.0);
else
COLOR=texture(TEXTURE, UV);
}