Post stamp border

Shader code
## Post stamp border
## @author: MBorecki - https://github.com/mborecki | https://bsky.app/profile/mborecki.pl

shader_type canvas_item;

// Hole radius in pixels
uniform float hole_radius = 10.0;

// Smoothstep for antialiasing
uniform float edge_smoothstep = .5;

// Node size in pixels (Have to inject it by node script)
instance uniform vec2 size = vec2(100.0, 100.0);
instance uniform vec4 border_color: source_color = vec4(1.0);
instance uniform vec4 shadow_color : source_color = vec4(1.0, 0.0, 0.0, .5);
// Shadow offset
instance uniform vec2 shadow = vec2(3.0, 5.0);

// UV in Pixels
varying vec2 uv_pixels;

void vertex() {

    // Środek ustawiamy na (0.5, 0.5)
    vec2 norm_pos = UV - vec2(0.5);
    
    // Margines potrzebny aby narysować cień
    float margin_pixels = max(abs(shadow.x), abs(shadow.y));
    
    // VERTEX powiększony o margines
    VERTEX += norm_pos * margin_pixels * 2.0;
    
    // uv w pixelach
    uv_pixels = norm_pos * (size + margin_pixels * 2.0);
}

// Budujemy jednocześnie obie strony ramki w kierunku jednej osi
float build_border(float main_axis_position, float cross_axis_position, float obj_dimention, float obj_cross_dimention) {
  // Zakładam że ramka składa się z n dziur o promieniu r, 
  // rozdzielonych przerwami o wymiarze p >= r.
  // Pierwsze dziury zaczynają sie na rogach
  
  // Teoretyczna ilość dziur (nie licząc narożnych).
  float fnX = obj_dimention / (3.0 * hole_radius) - 1.0;
  
  // Praktyczne (całkowita) ilość dziur.
  float nX = floor(fnX);
  
  // Szerokość obiektu jezeli x = r;
  float ideal_obj_width = 3.0 * hole_radius * (1.0 + nX);
  
  // Róznica między idealną a prawdziwą szerokością obiektu
  float dnX = obj_dimention - ideal_obj_width;
  
  // Ilość przerw
  float pX = nX + 1.0;
  
  // Korekta szerokości przerwy.
  float dpWidht = dnX / pX;
  
  // Realna szerokość przerw
  float pWidth = hole_radius + dpWidht;
  
  // Kazdy segment składa się z dwóch promieni dziury i jednej przerwy
  // Szerowkość segmentu.
  float segmentWidth = 2.0 * hole_radius + pWidth;

  // Wyliczamy x w relacji do segmentu
  float dx = mod(main_axis_position, segmentWidth);
  dx -= step(segmentWidth / 2.0, dx) * segmentWidth;

  // Dziura górna
  vec2 c1 = vec2(0.0, 0.0);
  // Dzira dolna
  vec2 c2 = vec2(0.0, obj_cross_dimention);
  
  // UV w segmencie w pixelach
  vec2 uv = vec2(dx, cross_axis_position);
  
  // Odleglość od górnej dziury
  float l1 = length(uv - c1);
  
  // Odleglość od dolnej dziury
  float l2 = length(uv - c2);
  
  // Odleglość do najbliższej dziury
  float l = min(l1, l2);
  
  // Smoothstep aby pozbyć się pixelozy przy obracaniu obiektem
  return smoothstep(hole_radius - edge_smoothstep, hole_radius + edge_smoothstep, l);
}

// Kształ zbudowany jest z dwóch części: wzoru osi X i wzoru osi Y;
float get_shape(float x, float y) {
  vec2 half_size = size / 2.0;
  float is_in_shape = step(-half_size.x, x) * step(x, half_size.x) * step(-half_size.y, y) * step(y, half_size.y);
  
  float _x = x + half_size.x;
  float _y = y + half_size.y;
  float x_alpha = build_border(_x, _y, size.x, size.y);
  float y_alpha = build_border(_y, _x, size.y, size.x);
  return is_in_shape * x_alpha * y_alpha;
}

void fragment() {
  float x = uv_pixels.x;
  float y = uv_pixels.y;
  
  // Głowny kształ znaczka
  float shape = get_shape(x, y);
  
  // Przesunięsie cienia
  float _sx = x + size.x / 2.0 - shadow.x;
  float _sy = y + size.y / 2.0 - shadow.y;
  
  // Kształ cienia
  float shadow_shape = get_shape(x - shadow.x, y - shadow.y);
  
  vec4 final_color_1 = mix(vec4(shadow_color.rgb, 0.0), shadow_color, shadow_shape);
  vec4 final_color_2 = mix(vec4(border_color.rgb, 0.0), shadow_color, shape);
  
  vec4 final_color = mix(final_color_1, border_color, shape);
  
  COLOR = final_color;
  
}
Live Preview
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

guest

0 Comments
Oldest
Newest Most Voted