9-slice shader
Simple shader that implements 9-patch/9-slice behaviour.
There are situations when you can’t use 9-patch rect but have to use Sprite. This shader is exactly for theese situations.
Considerations:
Don’t overuse it. When you use shader in Sprite it will require separate draw call interfearing with batching. thus if have too many(more than few dozen I guess) of such sprites your performance can degrade.
For this to work you need to add this code to your Sprite:tool
extends Sprite
func _ready():
set_notify_transform(true)
func _notification(what):
if what == NOTIFICATION_TRANSFORM_CHANGED:
get_material().set_shader_param("scale", scale)
Shader code
shader_type canvas_item;
uniform vec2 scale;
uniform int right;
uniform int top;
uniform int left;
uniform int bottom;
float map(float value, float originalMin, float originalMax, float newMin, float newMax) {
return (value - originalMin) / (originalMax - originalMin) * (newMax - newMin) + newMin;
}
float process_axis(float coord, float pixel, float texture_pixel, float start, float end) {
if (coord > 1.0 - end * pixel) {
return map(coord, 1.0 - end * pixel, 1.0, 1.0 - texture_pixel * end, 1.0);
} else if (coord > start * pixel) {
return map(coord, start * pixel, 1.0 - end * pixel, start * texture_pixel, 1.0 - end * texture_pixel);
} else {
return map(coord, 0.0, start * pixel, 0.0, start * texture_pixel);
}
}
void fragment() {
vec2 pixel_size = TEXTURE_PIXEL_SIZE / scale;
vec2 mappedUV = vec2(
process_axis(UV.x, pixel_size.x, TEXTURE_PIXEL_SIZE.x, float(left), float(right)),
process_axis(UV.y, pixel_size.y, TEXTURE_PIXEL_SIZE.y, float(top), float(bottom))
);
COLOR = texture(TEXTURE, mappedUV);
}
I make a simple benchmark test for the shader, it almost has same performance with the origin sprite, so maybe you don’t need worry about the performance problem:D
doesn’t work properly with AtlasTexture