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.


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:
extends Sprite

func _ready():

func _notification(what):
        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);
9-patch, 9-slice, nine-patch, nine-slice
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

Related shaders

2D Hologram Shader

Half-Tone Comic Shader

PS1 Shader

Inline Feedbacks
View all comments