Skip to content

Instantly share code, notes, and snippets.

@wolfenrain
Created November 10, 2022 22:25
Show Gist options
  • Save wolfenrain/34ddd6f26864532237c21eb49187a5c9 to your computer and use it in GitHub Desktop.
Save wolfenrain/34ddd6f26864532237c21eb49187a5c9 to your computer and use it in GitHub Desktop.
GLSL outline shaders made for Flutter with Umbra
uniform vec2 imageResolution;
uniform float lineThickness;
uniform vec4 lineColor;
uniform sampler2D image;
bool check_bounds(vec4 a, vec4 b, vec4 c, vec4 d, vec4 e, vec4 f, vec4 g, vec4 h) {
if (a.a < 0.5) return true;
if (b.a < 0.5) return true;
if (c.a < 0.5) return true;
if (d.a < 0.5) return true;
if (e.a < 0.5) return true;
if (f.a < 0.5) return true;
if (g.a < 0.5) return true;
if (h.a < 0.5) return true;
return false;
}
vec4 fragment(vec2 uv, vec2 fragCoord) {
vec2 TEXTURE_PIXEL_SIZE = vec2(1.0) / imageResolution;
vec2 size = TEXTURE_PIXEL_SIZE * lineThickness;
vec4 color = texture(image, uv);
if (color.a > 0.5) {
if (check_bounds(
texture(image, uv + vec2(-size.x, -size.y)), // top left
texture(image, uv + vec2(0, -size.y)), // top center
texture(image, uv + vec2(size.x, -size.y)), // top right
texture(image, uv + vec2(-size.x, 0)), // center left
texture(image, uv + vec2(size.x, 0)), // center right
texture(image, uv + vec2(-size.x, size.y)), // bottom left
texture(image, uv + vec2(0, size.y)), // bottom center
texture(image, uv + vec2(size.x, size.y)) // bottom right
)) {
color = lineColor;
}
// Ensure that the bounding box is outlined if required.
if (uv.x < size.x) color = lineColor;
if (uv.y < size.y) color = lineColor;
if (uv.y > 1.0 - size.y) color = lineColor;
if (uv.x > 1.0 - size.x) color = lineColor;
}
return color;
}
uniform vec2 imageResolution;
uniform float lineThickness;
uniform vec4 lineColor;
uniform sampler2D image;
bool check_bounds(vec4 a, vec4 b, vec4 c, vec4 d, vec4 e, vec4 f, vec4 g, vec4 h) {
if (a.a > 0.5) return true;
if (b.a > 0.5) return true;
if (c.a > 0.5) return true;
if (d.a > 0.5) return true;
if (e.a > 0.5) return true;
if (f.a > 0.5) return true;
if (g.a > 0.5) return true;
if (h.a > 0.5) return true;
return false;
}
vec4 fragment(vec2 uv, vec2 fragCoord) {
vec2 TEXTURE_PIXEL_SIZE = vec2(1.0) / imageResolution;
vec2 size = TEXTURE_PIXEL_SIZE * lineThickness;
vec4 color = texture(image, uv);
if (color.a < 0.5) {
if (check_bounds(
texture(image, uv + vec2(-size.x, -size.y)), // top left
texture(image, uv + vec2(0, -size.y)), // top center
texture(image, uv + vec2(size.x, -size.y)), // top right
texture(image, uv + vec2(-size.x, 0)), // center left
texture(image, uv + vec2(size.x, 0)), // center right
texture(image, uv + vec2(-size.x, size.y)), // bottom left
texture(image, uv + vec2(0, size.y)), // bottom center
texture(image, uv + vec2(size.x, size.y)) // bottom right
)) {
color = lineColor;
}
}
if (color.a > 0.5) {
// Ensure that the bounding box is outlined if required.
if (uv.x < size.x) color = lineColor;
if (uv.y < size.y) color = lineColor;
if (uv.y > 1.0 - size.y) color = lineColor;
if (uv.x > 1.0 - size.x) color = lineColor;
}
return color;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment